1
0
This commit is contained in:
Scott E. Graves
2017-03-16 20:26:53 -05:00
parent 258c8a30d7
commit de7a17aec4
2684 changed files with 0 additions and 775356 deletions

View File

@@ -1,538 +0,0 @@
<?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.config.gnu.exe.debug.1034724773">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1034724773" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<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"/>
<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"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1034724773" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1034724773." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.898681687" name="Linux GCC" nonInternalBuilderId="cdt.managedbuild.target.gnu.builder.exe.debug" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.25715897" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${ProjDirPath}/build" id="cdt.managedbuild.target.gnu.builder.exe.debug.1103730408" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.836634439" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool command="g++" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1817615032" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.750523151" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1248186067" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1310903331" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.796464367" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1202477623" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.debug.option.debugging.level.280470620" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1655653012" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1058275134" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1061662206" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
<option id="gnu.cpp.link.option.libs.1966761747" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="pthread"/>
<listOptionValue builtIn="false" value="dl"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1636986986" 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.exe.debug.258570404" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1571334436" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
<path value=""/>
</doc-comment-owner>
</storageModule>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.326780594">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.326780594" moduleId="org.eclipse.cdt.core.settings" name="Release">
<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}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.326780594" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.326780594." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1521127462" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1294814790" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
<builder arguments="BUILD=Release" buildPath="${ProjDirPath}" command="make" id="cdt.managedbuild.target.gnu.builder.exe.release.1733496537" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.446006787" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.2105828055" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.1921346334" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1660521780" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1064866729" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1329805514" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.2130170048" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.release.option.debugging.level.1028604453" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1173224902" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1484631410" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1493084285" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1398815353" 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.exe.release.1362356526" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.831278578" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
<path value=""/>
</doc-comment-owner>
</storageModule>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="SQLiteC++.cdt.managedbuild.target.gnu.exe.2007535171" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
</storageModule>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/SQLiteCpp"/>
</configuration>
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/SQLiteCpp"/>
</configuration>
</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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.326780594;cdt.managedbuild.config.gnu.exe.release.326780594.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1329805514;cdt.managedbuild.tool.gnu.c.compiler.input.1173224902">
<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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1034724773;cdt.managedbuild.config.gnu.exe.debug.1034724773.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1817615032;cdt.managedbuild.tool.gnu.cpp.compiler.input.1310903331">
<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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.326780594;cdt.managedbuild.config.gnu.exe.release.326780594.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.2105828055;cdt.managedbuild.tool.gnu.cpp.compiler.input.1064866729">
<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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1034724773;cdt.managedbuild.config.gnu.exe.debug.1034724773.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.796464367;cdt.managedbuild.tool.gnu.c.compiler.input.1655653012">
<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 &quot;${plugin_state_location}/${specs_file}&quot;'" 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 &quot;${plugin_state_location}/specs.cpp&quot;'" 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 &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
</cproject>

View File

@@ -1,29 +0,0 @@
Debug
Release
build
example1
*.a
/SQLiteCpp.sln
*.ncb
*.suo
*.user
*sdf
*.vc*
*~
doc
core
*ipch
.settings/
CMakeCache.txt
CMakeFiles
*.cmake
*.dir
Testing
Win32
SQLiteCpp_example1
SQLiteCpp_tests
!FindSQLiteCpp.cmake

View File

@@ -1,3 +0,0 @@
[submodule "googletest"]
path = googletest
url = https://github.com/google/googletest.git

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SQLiteC++</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
<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>-j</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>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

View File

@@ -1,163 +0,0 @@
# Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
# request for Ubuntu 14.04 Trusty VM
sudo: true
dist: trusty
cache:
apt: true
# NOTE: no language, so that we can set CXX and CC env vars as required
#language: cpp
matrix:
include:
# gcc default
- compiler: gcc
env:
- CC=gcc
- CXX=g++
# gcc 4.9 std=default
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.9
env:
- CC=gcc-4.9
- CXX=g++-4.9
# gcc 5 std=c++03
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- CC=gcc-5
- CXX=g++-5
- CXXFLAGS="-std=c++03"
# gcc 5 std=c++11
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- CC=gcc-5
- CXX=g++-5
- CXXFLAGS="-std=c++11"
# gcc 5 std=c++14
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- CC=gcc-5
- CXX=g++-5
- CXXFLAGS="-std=c++14"
# gcc 5 std=c++1z
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-5
env:
- CC=gcc-5
- CXX=g++-5
- CXXFLAGS="-std=c++1z"
# gcc 6 std=c++14
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- CXX=g++-6
- CXXFLAGS="-std=c++14"
# gcc 6 std=c++1z
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- CC=gcc-6
- CXX=g++-6
- CXXFLAGS="-std=c++1z"
# gcc 6 std=c++14 all warnings, pedantic
- compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-6
env:
- CC=gcc-6
- CXX=g++-6
- CXXFLAGS="-std=c++14 -Wall -Wextra -pedantic"
# clang default
- compiler: clang
env:
- CC=clang
- CXX=clang++
# clang 3.8
- compiler: clang
os: linux
env:
- CC=clang
- CXX=clang++
- LLVM_VERSION=3.8.0
- LLVM_ARCHIVE_PATH=$HOME/clang+llvm.tar.xz
- CPPFLAGS="-I $HOME/clang-$LLVM_VERSION/include/c++/v1"
- CXXFLAGS=-lc++
- PATH=$HOME/clang-$LLVM_VERSION/bin:$PATH
- LD_LIBRARY_PATH=$HOME/clang-$LLVM_VERSION/lib:$LD_LIBRARY_PATH
before_install:
- wget http://llvm.org/releases/$LLVM_VERSION/clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-14.04.tar.xz -O $LLVM_ARCHIVE_PATH
- mkdir $HOME/clang-$LLVM_VERSION
- tar xf $LLVM_ARCHIVE_PATH -C $HOME/clang-$LLVM_VERSION --strip-components 1
# os x
- compiler: clang
os: osx
osx_image: xcode8
#install:
# - brew install cmake
env:
- CC=clang
- CXX=clang
- CXXFLAGS=-lstdc++
before_install:
- if [[ "$CXX" == "g++" ]]; then pip install --user cpp-coveralls ; fi
# scripts to run before build
before_script:
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_USE_GCOV=ON -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
# build examples, and run tests (ie make & make test)
script:
- cmake --build .
- ctest --verbose --output-on-failure
# generate and publish GCov coveralls results
after_success:
- if [[ "$CXX" == "g++" ]]; then coveralls --root .. -e examples -e googletest -e sqlite3 -e tests -E ".*feature_tests.*" -E ".*CompilerId.*" --gcov-options '\-lp' ; fi

View File

@@ -1,96 +0,0 @@
Mar 30 2012
Start of a new thin C++ SQLite wrapper
Apr 2 2012
The wrapper is functionnal
Added documentation and examples
Publication on GitHub
Version 0.1.0 - Apr 4 2012
Added a Database::exec() methode to execute simple SQL statement
Added a version number like in sqlite3.h, starting with 0.1.0
Version 0.2.0 - Apr 11 2012
Added getLastInsertId() and setBusyTimout()
Added bind() by name methods
Version 0.3.0 - Apr 16 2012
Added an easy wrapper Database::execAngGet()
Version 0.4.0 - Apr 23 2012
Added a Database::tableExists() easy to use function
Dec 10 2012
Added a Statement::exec() method to execute a one-step query with no expected result
Version 0.5.0 - March 9 2013
Added assert() on errors on destructors
Added getBytes()
Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull
Added bind() for binary blob data
Version 0.5.1 - April 7 2013
Added Column::getName()
Version 0.6.0 - November 22 2013
Renamed Column::getName() to Column::getOriginName()
Added Column::getName()
Version 0.7.0 - January 9 2014
Added Database::createFunction()
Added std::string version of existing APIs
Improved CMake with more build options and Doxygen auto-detection
Version 0.8.0 - February 26 2014
Database constructor support opening a database with a custom VFS (default to NULL)
Changed Column::getText() to return empty string "" by default instead of NULL pointer (to handle std::string conversion)
Version 1.0.0 - May 3 2015
Public headers file moved to include/ dir
Added support to biicode in CMakeLists.txt
Added Unit Tests
Added aBusyTimeoutMs parameter to Database() constructors
Added Database::getTotalChanges()
Added Database::getErrorCode()
Added Statement::clearBindings()
Added Statement::getColumn(aName)
Added Statement::getErrorCode()
Added Statement::getColumnName(aIndex)
Added Statement::getColumnOriginName(aIndex)
Version 1.1.0 - May 18 2015
Fixed valgrind error on Database destructor
Added Database::loadExtension
Version 1.2.0 - September 9 2015
Fixed build with GCC 5.1.0
Fixed MSVC release build warning
Fixed CppDepends warnings
Updated documentation on installation
Added Database::getHandle()
Version 1.3.0 - November 1 2015
Fixed build with Visual Studio 2015
Further improvements to README
Added Backup class
Version 1.3.1 - February 10 2016
Swith Linux/Mac build to the provided SQLite3 C library
Update SQLite3 from 3.8.8.3 to latest 3.10.2 (2016-01-20)
Remove warnings
Remove biicode support (defunct service, servers will shutdown the 16th of February 2016)
Version 2.0.0 - July 25 2016
Update SQLite3 from 3.10.2 to latest 3.13 (2016-05-18)
Move #include <sqlite3.h> from headers to .cpp files only using forward declarations
Add Database::VERSION to reach SQLITE_VERSION without including sqlite3.h in application code
Add getLibVersion() and getLibVersionNumber() to get runtime version of the library
Better exception messages when Statements fail PR #84
Variadic templates for bind() (C++14) PR #85
Add Statement::bindNoCopy() methods for strings, using SQLITE_STATIC to avoid internal copy by SQLite3 PR #86
Add Statement::bind() overload for uint32_t, and Column::getUint() and cast operator to uint32_t PR #86
Use the new SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION from SQLite 3.13 for security reason
Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount()
Remove Column::errmsg() method : use Database or Statement equivalents
More unit tests, with code coverage status on the GitHub page
Do not force MSVC to use static runtime if unit-tests are not build

View File

@@ -1,286 +0,0 @@
# Main CMake file for compiling the library itself, examples and tests.
#
# Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
#
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT)
cmake_minimum_required(VERSION 2.8.12) # first version with add_compile_options()
project(SQLiteCpp)
# Define useful variables to handle OS differences:
if (WIN32)
set(DEV_NULL "NUL")
else (WIN32) # UNIX
set(DEV_NULL "/dev/null")
endif (WIN32)
# then Compiler/IDE differences:
if (MSVC)
set(CPPLINT_ARG_OUTPUT "--output=vs7")
set(CPPCHECK_ARG_TEMPLATE "--template=vs")
# disable Visual Studio warnings for fopen() used in the example
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
# Flags for linking with multithread static C++ runtime, required by googletest
if (SQLITECPP_BUILD_TESTS)
message(STATUS "Linking against multithread static C++ runtime for unit tests with googletest")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif (SQLITECPP_BUILD_TESTS)
else (MSVC)
set(CPPLINT_ARG_OUTPUT "--output=eclipse")
set(CPPCHECK_ARG_TEMPLATE "--template=gcc")
# Useful compile flags and extra warnings
add_compile_options(-fstack-protector -Wall -Winit-self -Wswitch-enum -Wshadow -Winline)
if (CMAKE_COMPILER_IS_GNUCXX)
# GCC flags
if (SQLITECPP_USE_GCOV AND CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
message (STATUS "Using GCov instrumentation")
else ()
message (WARNING "GCov instrumentation works best in Debug mode")
endif ()
add_compile_options (-coverage) # NOTE would be usefull but not working with current google test and gcc 4.8 -fkeep-inline-functions
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
endif ()
endif (CMAKE_COMPILER_IS_GNUCXX)
endif (MSVC)
# and then common variables
set(CPPLINT_ARG_VERBOSE "--verbose=3")
set(CPPLINT_ARG_LINELENGTH "--linelength=120")
# Print CXX compiler information
message (STATUS "CMAKE_CXX_COMPILER '${CMAKE_CXX_COMPILER}' '${CMAKE_CXX_COMPILER_ID}' '${CMAKE_CXX_COMPILER_VERSION}'")
# Print CXX FLAGS
message (STATUS "CMAKE_CXX_FLAGS '${CMAKE_CXX_FLAGS}'")
if (MSVC)
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
else (NOT MSVC)
if (CMAKE_BUILD_TYPE STREQUAL Debug)
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
elseif (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
elseif (CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
else ()
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
endif ()
endif ()
# Options relative to SQLite and SQLiteC++ functions
option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON)
if (SQLITE_ENABLE_COLUMN_METADATA)
# Enable the use of SQLite column metadata and Column::getColumnOriginName() method,
# Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X).
add_definitions(-DSQLITE_ENABLE_COLUMN_METADATA)
endif (SQLITE_ENABLE_COLUMN_METADATA)
option(SQLITE_ENABLE_ASSERT_HANDLER "Enable the user defintion of a assertion_failed() handler." OFF)
if (SQLITE_ENABLE_ASSERT_HANDLER)
# Enable the user defintion of a assertion_failed() handler (default to false, easier to handler for begginers).
add_definitions(-DSQLITECPP_ENABLE_ASSERT_HANDLER)
endif (SQLITE_ENABLE_ASSERT_HANDLER)
## Build the C++ Wrapper ##
# adding a new file require explicittly modifing the CMakeLists.txt
# so that CMake knows that it should rebuild the project (it is best practice)
# list of sources files of the library
set(SQLITECPP_SRC
${PROJECT_SOURCE_DIR}/src/Backup.cpp
${PROJECT_SOURCE_DIR}/src/Column.cpp
${PROJECT_SOURCE_DIR}/src/Database.cpp
${PROJECT_SOURCE_DIR}/src/Exception.cpp
${PROJECT_SOURCE_DIR}/src/Statement.cpp
${PROJECT_SOURCE_DIR}/src/Transaction.cpp
)
source_group(src FILES ${SQLITECPP_SRC})
# list of header files of the library
set(SQLITECPP_INC
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/SQLiteCpp.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Assertion.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Backup.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h
)
source_group(inc FILES ${SQLITECPP_INC})
# list of test files of the library
set(SQLITECPP_TESTS
tests/Column_test.cpp
tests/Database_test.cpp
tests/Statement_test.cpp
tests/Backup_test.cpp
tests/Transaction_test.cpp
tests/VariadicBind_test.cpp
)
source_group(tests FILES ${SQLITECPP_TESTS})
# list of example files of the library
set(SQLITECPP_EXAMPLES
examples/example1/main.cpp
)
source_group(example1 FILES ${SQLITECPP_EXAMPLES})
# list of doc files of the library
set(SQLITECPP_DOC
README.md
LICENSE.txt
CHANGELOG.txt
TODO.txt
)
source_group(doc FILES ${SQLITECPP_DOC})
# list of script files of the library
set(SQLITECPP_SCRIPT
.travis.yml
appveyor.yml
build.bat
build.sh
cpplint.py
Doxyfile
FindSQLiteCpp.cmake
)
source_group(scripts FILES ${SQLITECPP_SCRIPT})
# All includes are relative to the "include" directory
include_directories("${PROJECT_SOURCE_DIR}/include")
# add sources of the wrapper as a "SQLiteCpp" static library
add_library(SQLiteCpp ${SQLITECPP_SRC} ${SQLITECPP_INC} ${SQLITECPP_DOC} ${SQLITECPP_SCRIPT})
target_include_directories(SQLiteCpp PUBLIC "${PROJECT_SOURCE_DIR}/include")
if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fPIC")
endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
## Build provided copy of SQLite3 C library ##
option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON)
if (SQLITECPP_INTERNAL_SQLITE)
# build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package
add_subdirectory(sqlite3)
include_directories("${PROJECT_SOURCE_DIR}/sqlite3")
target_include_directories(sqlite3 PUBLIC "${PROJECT_SOURCE_DIR}/sqlite3")
endif (SQLITECPP_INTERNAL_SQLITE)
# Optional additional targets:
option(SQLITECPP_RUN_CPPLINT "Run cpplint.py tool for Google C++ StyleGuide." ON)
if (SQLITECPP_RUN_CPPLINT)
find_package(PythonInterp)
if (PYTHONINTERP_FOUND)
# add a cpplint target to the "all" target
add_custom_target(SQLiteCpp_cpplint
ALL
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cpplint.py ${CPPLINT_ARG_OUTPUT} ${CPPLINT_ARG_VERBOSE} ${CPPLINT_ARG_LINELENGTH} ${SQLITECPP_SRC} ${SQLITECPP_INC}
)
endif (PYTHONINTERP_FOUND)
else (SQLITECPP_RUN_CPPLINT)
message(STATUS "SQLITECPP_RUN_CPPLINT OFF")
endif (SQLITECPP_RUN_CPPLINT)
option(SQLITECPP_RUN_CPPCHECK "Run cppcheck C++ static analysis tool." ON)
if (SQLITECPP_RUN_CPPCHECK)
find_program(CPPCHECK_EXECUTABLE NAMES cppcheck)
if (CPPCHECK_EXECUTABLE)
# add a cppcheck target to the "all" target
add_custom_target(SQLiteCpp_cppcheck
ALL
COMMAND ${CPPCHECK_EXECUTABLE} -j 8 cppcheck --enable=style --quiet ${CPPCHECK_ARG_TEMPLATE} ${PROJECT_SOURCE_DIR}/src
)
execute_process(COMMAND "${CPPCHECK_EXECUTABLE}" --version OUTPUT_VARIABLE CPPCHECK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
message(STATUS "Found Cppcheck: ${CPPCHECK_EXECUTABLE} ${CPPCHECK_VERSION}")
else (CPPCHECK_EXECUTABLE)
message(STATUS "Could NOT find cppcheck")
endif (CPPCHECK_EXECUTABLE)
else (SQLITECPP_RUN_CPPCHECK)
message(STATUS "SQLITECPP_RUN_CPPCHECK OFF")
endif (SQLITECPP_RUN_CPPCHECK)
option(SQLITECPP_RUN_DOXYGEN "Run Doxygen C++ documentation tool." OFF)
if (SQLITECPP_RUN_DOXYGEN)
find_package(Doxygen)
if (DOXYGEN_FOUND)
# add a Doxygen target to the "all" target
add_custom_target(SQLiteCpp_doxygen
ALL
COMMAND doxygen Doxyfile > ${DEV_NULL}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)
endif (DOXYGEN_FOUND)
else (SQLITECPP_RUN_DOXYGEN)
message(STATUS "SQLITECPP_RUN_DOXYGEN OFF")
endif (SQLITECPP_RUN_DOXYGEN)
option(SQLITECPP_BUILD_EXAMPLES "Build examples." OFF)
if (SQLITECPP_BUILD_EXAMPLES)
# add the basic example executable
add_executable(SQLiteCpp_example1 ${SQLITECPP_EXAMPLES})
target_link_libraries(SQLiteCpp_example1 SQLiteCpp sqlite3)
# Link target with pthread and dl for linux
if (UNIX)
target_link_libraries(SQLiteCpp_example1 pthread)
if (NOT APPLE)
target_link_libraries(SQLiteCpp_example1 dl)
endif ()
elseif (MSYS OR MINGW)
target_link_libraries(SQLiteCpp_example1 ssp)
endif ()
else (SQLITECPP_BUILD_EXAMPLES)
message(STATUS "SQLITECPP_BUILD_EXAMPLES OFF")
endif (SQLITECPP_BUILD_EXAMPLES)
option(SQLITECPP_BUILD_TESTS "Build and run tests." OFF)
if (SQLITECPP_BUILD_TESTS)
# deactivate some warnings for compiling the gtest library
if (NOT MSVC)
add_compile_options(-Wno-variadic-macros -Wno-long-long -Wno-switch-enum -Wno-float-equal -Wno-conversion-null -Wno-switch-default -Wno-pedantic)
endif (NOT MSVC)
# add the subdirectory containing the CMakeLists.txt for the gtest library
# TODO: under Linux, uses libgtest-dev if found
# TODO: move to the new googletest Github repository
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt")
message(FATAL_ERROR "Missing 'googletest' submodule! Either use 'git init submodule' and 'git update submodule' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF")
endif ()
add_subdirectory(googletest)
include_directories("${PROJECT_SOURCE_DIR}/googletest/googletest/include")
# add the unit test executable
add_executable(SQLiteCpp_tests ${SQLITECPP_TESTS})
target_link_libraries(SQLiteCpp_tests gtest_main SQLiteCpp sqlite3)
# Link target with dl for linux
if (UNIX AND NOT APPLE)
target_link_libraries(SQLiteCpp_tests dl)
endif ()
# add a "test" target:
enable_testing()
# does the tests pass?
add_test(UnitTests SQLiteCpp_tests)
if (SQLITECPP_BUILD_EXAMPLES)
# does the example1 runs successfully?
add_test(Example1Run SQLiteCpp_example1)
endif (SQLITECPP_BUILD_EXAMPLES)
else (SQLITECPP_BUILD_TESTS)
message(STATUS "SQLITECPP_BUILD_TESTS OFF")
endif (SQLITECPP_BUILD_TESTS)

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +0,0 @@
# @file CMakeLists.txt
# @ingroup SQLiteCpp
# @brief SQLiteCpp CMake module.
#
# Copyright (c) 2010-2014 Kartik Kumar (me@kartikkumar.com)
#
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT)
macro(_sqlitecpp_check_version)
file(READ "${SQLITECPP_INCLUDE_DIR}/SQLiteCpp.h" _sqlitecpp_header)
string(REGEX MATCH "define[ \t]+SQLITECPP_VERSION_NUMBER[ \t]+([0-9]+)"
_sqlitecpp_version_match "${_sqlitecpp_header}")
set(SQLITECPP_VERSION "${CMAKE_MATCH_1}")
if(${SQLITECPP_VERSION} VERSION_LESS ${SQLiteCpp_FIND_VERSION})
set(SQLITECPP_VERSION_OK FALSE)
else(${SQLITECPP_VERSION} VERSION_LESS ${SQLiteCpp_FIND_VERSION})
set(SQLITECPP_VERSION_OK TRUE)
endif(${SQLITECPP_VERSION} VERSION_LESS ${SQLiteCpp_FIND_VERSION})
if(NOT SQLITECPP_VERSION_OK)
message(STATUS "SQLiteCpp version ${SQLITECPP_VERSION} found in ${SQLITECPP_INCLUDE_DIR}, "
"but at least version ${SQLiteCpp_FIND_VERSION} is required!")
endif(NOT SQLITECPP_VERSION_OK)
set(SQLITECPP_LIBRARY "SQLiteCpp")
link_directories(${SQLITECPP_LIBRARY_DIR})
endmacro(_sqlitecpp_check_version)
if(SQLITECPP_INCLUDE_DIR)
# Check if SQLiteCpp is already present in cache.
_sqlitecpp_check_version()
set(SQLITECPP_FOUND ${SQLITECPP_VERSION_OK})
else (SQLITECPP_INCLUDE_DIR)
find_path(SQLITECPP_BASE_PATH NAMES SQLiteCpp.h
PATHS
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/..
${PROJECT_SOURCE_DIR}/../..
${PROJECT_SOURCE_DIR}/../../..
${PROJECT_SOURCE_DIR}/../../../..
PATH_SUFFIXES SQLiteCpp/include/SQLiteCpp
)
set(SQLITECPP_INCLUDE_DIR ${SQLITECPP_BASE_PATH})
set(SQLITECPP_LIBRARY_DIR ${SQLITECPP_BASE_PATH}/../../build)
if(SQLITECPP_INCLUDE_DIR)
_sqlitecpp_check_version()
endif(SQLITECPP_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SQLITECPP DEFAULT_MSG SQLITECPP_INCLUDE_DIR SQLITECPP_VERSION_OK)
mark_as_advanced(SQLITECPP_INCLUDE_DIR)
endif(SQLITECPP_INCLUDE_DIR)

View File

@@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,303 +0,0 @@
SQLiteC++
---------
[![release](https://img.shields.io/github/release/SRombauts/SQLiteCpp.svg)](https://github.com/SRombauts/SQLiteCpp/releases)
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/SRombauts/SQLiteCpp/blob/master/LICENSE.txt)
[![Travis CI Linux Build Status](https://travis-ci.org/SRombauts/SQLiteCpp.svg)](https://travis-ci.org/SRombauts/SQLiteCpp "Travis CI Linux Build Status")
[![AppVeyor Windows Build status](https://ci.appveyor.com/api/projects/status/github/SRombauts/SQLiteCpp?svg=true)](https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp "AppVeyor Windows Build status")
[![Coveralls](https://img.shields.io/coveralls/SRombauts/SQLiteCpp.svg)](https://coveralls.io/github/SRombauts/SQLiteCpp "Coveralls test coverage")
[![Join the chat at https://gitter.im/SRombauts/SQLiteCpp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/SRombauts/SQLiteCpp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
SQLiteC++ (SQLiteCpp) is a smart and easy to use C++ SQLite3 wrapper.
See SQLiteC++ website http://srombauts.github.com/SQLiteCpp on GitHub.
Keywords: sqlite, sqlite3, C, library, wrapper C++
## About SQLiteC++:
SQLiteC++ offers an encapsulation around the native C APIs of SQLite,
with a few intuitive and well documented C++ classes.
### License:
Copyright (c) 2012-2016 Sébastien Rombauts (sebastien.rombauts@gmail.com)
Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
or copy at http://opensource.org/licenses/MIT)
#### Note on redistribution of SQLite source files
As stated by the MIT License, you are welcome to reuse, modify, and redistribute the SQLiteCpp source code
the way you want it to, be it a git submodule, a subdirectory, or a selection of some source files.
I would love a mention in your README, a web link to the SQLite repository, and a mention of the author,
but none of those are mandatory.
### About SQLite underlying library:
SQLite is a library that implements a serverless transactional SQL database engine.
It is the most widely deployed SQL database engine in the world.
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.
http://www.sqlite.org/about.html
### The goals of SQLiteC++ are:
- to offer the best of the existing simple C++ SQLite wrappers
- to be elegantly written with good C++ design, STL, exceptions and RAII idiom
- to keep dependencies to a minimum (STL and SQLite3)
- to be portable
- to be light and fast
- to be thread-safe only as much as SQLite "Multi-thread" mode (see below)
- to have a good unit test coverage
- to use API names sticking with those of the SQLite library
- to be well documented with Doxygen tags, and with some good examples
- to be well maintained
- to use a permissive MIT license, similar to BSD or Boost, for proprietary/commercial usage
It is designed using the Resource Acquisition Is Initialization (RAII) idiom
(see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization),
and throwing exceptions in case of SQLite errors (exept in destructors,
where assert() are used instead).
Each SQLiteC++ object must be constructed with a valid SQLite database connection,
and then is always valid until destroyed.
### Supported platforms:
Developements and tests are done under the following OSs:
- Ubuntu 14.04 (Travis CI)
- Windows XP/10
- OS X 10.11 (Travis CI)
And the following IDEs/Compilers
- GCC 4.8.4, 4.9.3, 5.3.0 and 6.1.1 (C++03, C++11, C++14, C++1z)
- Clang 3.5 and 3.8
- Xcode 8
- Visual Studio Community 2015
- Eclipse CDT under Linux
### Dependencies
- an STL implementation (even an old one, like the one provided with VC6 should work)
- exception support (the class Exception inherits from std::runtime_error)
- the SQLite library (3.7.15 minimum from 2012-12-12) either by linking to it dynamicaly or statically (install the libsqlite3-dev package under Debian/Ubuntu/Mint Linux),
or by adding its source file in your project code base (source code provided in src/sqlite3 for Windows),
with the SQLITE_ENABLE_COLUMN_METADATA macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata).
## Getting started
### Installation
To use this wrapper, you need to add the SQLiteC++ source files from the src/ directory
in your project code base, and compile/link against the sqlite library.
The easiest way to do this is to add the wrapper as a library.
The "CMakeLists.txt" file defining the static library is provided in the root directory,
so you simply have to add_subdirectory(SQLiteCpp) to you main CMakeLists.txt
and link to the "SQLiteCpp" wrapper library.
Thus this SQLiteCpp repository can be directly used as a Git submoldule.
See the [SQLiteCpp_Example](https://github.com/SRombauts/SQLiteCpp_Example) side repository for a standalone "from scratch" example.
Under Debian/Ubuntu/Mint Linux, you can install the libsqlite3-dev package if you don't want to use the embedded sqlite3 library.
### Building example and unit-tests:
Use git to clone the repository. Then init and update submodule "googletest".
```Shell
git clone https://github.com/SRombauts/SQLiteCpp.git
cd SQLiteCpp
git submodule init
git submodule update
```
#### CMake and tests
A CMake configuration file is also provided for multiplatform support and testing.
Typical generic build for MS Visual Studio under Windows (from [build.bat](build.bat)):
```Batchfile
mkdir build
cd build
cmake .. # cmake .. -G "Visual Studio 10" # for Visual Studio 2010
@REM Generate a Visual Studio solution for latest version found
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
@REM Build default configuration (ie 'Debug')
cmake --build .
@REM Build and run tests
ctest --output-on-failure
```
Generating the Linux Makefile, building in Debug and executing the tests (from [build.sh](build.sh)):
```Shell
mkdir Debug
cd Debug
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
# Build (ie 'make')
cmake --build .
# Build and run unit-tests (ie 'make test')
ctest --output-on-failure
```
#### CMake options
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/SRombauts/SQLiteCpp/blob/master/CMakeLists.txt) file.
#### Troubleshooting
Under Linux, if you get muliple linker errors like "undefined reference to sqlite3_xxx",
it's that you lack the "sqlite3" library: install the libsqlite3-dev package.
If you get a single linker error "Column.cpp: undefined reference to sqlite3_column_origin_name",
it's that your "sqlite3" library was not compiled with
the SQLITE_ENABLE_COLUMN_METADATA macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata).
You can either recompile it yourself (seek help online) or you can comment out the following line in src/Column.h:
```C++
#define SQLITE_ENABLE_COLUMN_METADATA
```
### Continuous Integration
This project is continuously tested under Ubuntu Linux with the gcc and clang compilers
using the Travis CI community service with the above CMake building and testing procedure.
It is also tested in the same way under Windows Server 2012 R2 with Visual Studio 2013 compiler
using the AppVeyor countinuous integration service.
Detailed results can be seen online:
- https://travis-ci.org/SRombauts/SQLiteCpp
- https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp
### Thread-safety
SQLite supports three modes of thread safety, as describe in "SQLite And Multiple Threads":
see http://www.sqlite.org/threadsafe.html
This SQLiteC++ wrapper does no add any locks (no mutexes) nor any other thread-safety mechanism
above the SQLite library itself, by design, for lightness and speed.
Thus, SQLiteC++ naturally supports the "Multi Thread" mode of SQLite:
"In this mode, SQLite can be safely used by multiple threads
provided that no single database connection is used simultaneously in two or more threads."
But SQLiteC++ does not support the fully thread-safe "Serialized" mode of SQLite,
because of the way it shares the underlying SQLite precompiled statement
in a custom shared pointer (See the inner class "Statement::Ptr").
## Examples
### The first sample demonstrates how to query a database and get results:
```C++
try
{
// Open a database file
SQLite::Database db("example.db3");
// Compile a SQL query, containing one parameter (index 1)
SQLite::Statement query(db, "SELECT * FROM test WHERE size > ?");
// Bind the integer value 6 to the first parameter of the SQL query
query.bind(1, 6);
// Loop to execute the query step by step, to get rows of result
while (query.executeStep())
{
// Demonstrate how to get some typed column value
int id = query.getColumn(0);
const char* value = query.getColumn(1);
int size = query.getColumn(2);
std::cout << "row: " << id << ", " << value << ", " << size << std::endl;
}
}
catch (std::exception& e)
{
std::cout << "exception: " << e.what() << std::endl;
}
```
### The second sample shows how to manage a transaction:
```C++
try
{
SQLite::Database db("transaction.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
db.exec("DROP TABLE IF EXISTS test");
// Begin transaction
SQLite::Transaction transaction(db);
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
// Commit transaction
transaction.commit();
}
catch (std::exception& e)
{
std::cout << "exception: " << e.what() << std::endl;
}
```
### How to handle assertion in SQLiteC++:
Exceptions shall not be used in destructors, so SQLiteC++ uses SQLITECPP_ASSERT() to check for errors in destructors.
If you don't want assert() to be called, you have to enable and define an assert handler as shown below,
and by setting the flag SQLITECPP_ENABLE_ASSERT_HANDLER when compiling the lib.
```C++
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
namespace SQLite
{
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
{
// Print a message to the standard error output stream, and abort the program.
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
std::abort();
}
}
#endif
```
## How to contribute
### GitHub website
The most efficient way to help and contribute to this wrapper project is to
use the tools provided by GitHub:
- please fill bug reports and feature requests here: https://github.com/SRombauts/SQLiteCpp/issues
- fork the repository, make some small changes and submit them with pull-request
### Contact
You can also email me directly, I will try to answer questions and requests whenever I get the time for it.
### Coding Style Guidelines
The source code use the CamelCase naming style variant where:
- type names (class, struct, typedef, enums...) begin with a capital letter
- files (.cpp/.h) are named like the class they contain
- function and variable names begin with a lower case letter
- member variables begin with a 'm', function arguments begin with a 'a', booleans with a 'b', pointers with a 'p'
- each file, class, method and member variable is documented using Doxygen tags
See also http://www.appinf.com/download/CppCodingStyleGuide.pdf for good guidelines
## See also - Some other simple C++ SQLite wrappers:
See bellow a short comparison of other wrappers done at the time of writing:
- [sqdbcpp](http://code.google.com/p/sqdbcpp/): RAII design, simple, no dependencies, UTF-8/UTF-16, new BSD license
- [sqlite3cc](http://ed.am/dev/sqlite3cc): uses boost, modern design, LPGPL
- [sqlite3pp](https://github.com/iwongu/sqlite3pp): modern design inspired by boost, MIT License
- [SQLite++](http://sqlitepp.berlios.de/): uses boost build system, Boost License 1.0
- [CppSQLite](http://www.codeproject.com/Articles/6343/CppSQLite-C-Wrapper-for-SQLite/): famous Code Project but old design, BSD License
- [easySQLite](http://code.google.com/p/easysqlite/): manages table as structured objects, complex
- [sqlite_modern_cpp](https://github.com/keramer/sqlite_modern_cpp): modern C++11, all in one file, MIT license

View File

@@ -1,30 +0,0 @@
Switch to C++11 for v2.0.0 with removal of include <sqlite.h> in headers
Add a Tutorial for SQLite newbies
Add a real example in the form of a small interactive console application
Improve Github Wiki pages with the FAQ: Installation, Examples, Tutorial, How to contribute
Publish the Doxygen Documentation in the Github Pages (gh-pages branch)
Missing features in v2.0.0:
- #24: executemany() like in Python https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.executemany
- #34: Better type for getColumn
Missing documentation in v2.0.0:
- explain the noncopyable property for RAII design
- comment on returning error code instead of exception that shall not be thrown when expected (!?)
Missing unit tests in v2.0.0:
- Load Extension (not practicable, and easy to verify by code review)
Advanced missing features:
- #39: SAVEPOINT https://www.sqlite.org/lang_savepoint.html
- Add optional usage of experimental sqlite3_trace() function to enable statistics
- Agregate ?
- support for different transaction mode ? NO: too specific
- operator<< binding ? NO: redundant with bind()
- ATTACH Database ? NO: can already be done by "ATTACH" Statement
Post an article to CodeProject: Is there a license issue ?

View File

@@ -1,26 +0,0 @@
# Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
# build format
version: "{build}"
# scripts that run after cloning repository
install:
- git submodule update --init googletest
# configurations to add to build matrix
# TODO: VS2010->VS2015 and Win32/Win64 (see https://github.com/google/googletest/blob/master/appveyor.yml)
# TODO: MinGW Makefiles and MSYS Makefiles
configuration:
- Debug
# - Release # CMake can only build the default configuration on Visual Studio
# scripts to run before build
before_build:
- mkdir build
- cd build
- cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_RUN_CPPCHECK=OFF ..
# build examples, and run tests (ie make & make test)
build_script:
- cmake --build .
- ctest --output-on-failure

View File

@@ -1,25 +0,0 @@
@REM Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
@REM
@REM Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
@REM or copy at http://opensource.org/licenses/MIT)
mkdir build
cd build
@REM Generate a Visual Studio solution for latest version found
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
if ERRORLEVEL 1 goto onError
@REM Build default configuration (ie 'Debug')
cmake --build .
if ERRORLEVEL 1 goto onError
@REM Build and run tests
ctest --output-on-failure
if ERRORLEVEL 1 goto onError
cd ..
exit
:onError
@echo An error occured!
cd ..

View File

@@ -1,20 +0,0 @@
#!/bin/sh
# Copyright (c) 2012-2016 Sébastien Rombauts (sebastien.rombauts@gmail.com)
#
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT)
# exit on firts error
set -e
mkdir -p build
cd build
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
cmake -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_USE_GCOV=OFF -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
# Build (ie 'make')
cmake --build .
# Build and run unit-tests (ie 'make test')
ctest --output-on-failure

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,464 +0,0 @@
/**
* @file main.cpp
* @brief A few short examples in a row.
*
* Demonstrates how-to use the SQLite++ wrapper
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <SQLiteCpp/SQLiteCpp.h>
#include <SQLiteCpp/VariadicBind.h>
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
namespace SQLite
{
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
{
// Print a message to the standard error output stream, and abort the program.
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
std::abort();
}
}
#endif
/// Get example path
static inline std::string getExamplePath()
{
std::string filePath(__FILE__);
return filePath.substr( 0, filePath.length() - std::string("main.cpp").length());
}
/// Example Database
static const std::string filename_example_db3 = getExamplePath() + "/example.db3";
/// Image
static const std::string filename_logo_png = getExamplePath() + "/logo.png";
/// Object Oriented Basic example
class Example
{
public:
// Constructor
Example() :
mDb(filename_example_db3), // Open a database file in readonly mode
mQuery(mDb, "SELECT * FROM test WHERE weight > :min_weight")// Compile a SQL query, containing one parameter (index 1)
{
}
virtual ~Example()
{
}
/// List the rows where the "weight" column is greater than the provided aParamValue
void ListGreaterThan (const int aParamValue)
{
std::cout << "ListGreaterThan (" << aParamValue << ")\n";
// Bind the integer value provided to the first parameter of the SQL query
mQuery.bind(":min_weight", aParamValue); // same as mQuery.bind(1, aParamValue);
// Loop to execute the query step by step, to get one a row of results at a time
while (mQuery.executeStep())
{
std::cout << "row (" << mQuery.getColumn(0) << ", \"" << mQuery.getColumn(1) << "\", " << mQuery.getColumn(2) << ")\n";
}
// Reset the query to be able to use it again later
mQuery.reset();
}
private:
SQLite::Database mDb; ///< Database connection
SQLite::Statement mQuery; ///< Database prepared SQL query
};
int main ()
{
// Using SQLITE_VERSION would require #include <sqlite3.h> which we want to avoid: use SQLite::VERSION if possible.
// std::cout << "SQlite3 version " << SQLITE_VERSION << std::endl;
std::cout << "SQlite3 version " << SQLite::VERSION << " (" << SQLite::getLibVersion() << ")" << std::endl;
std::cout << "SQliteC++ version " << SQLITECPP_VERSION << std::endl;
////////////////////////////////////////////////////////////////////////////
// Very basic first example (1/7) :
try
{
// Open a database file in readonly mode
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
// Test if the 'test' table exists
const bool bExists = db.tableExists("test");
std::cout << "SQLite table 'test' exists=" << bExists << "\n";
// Get a single value result with an easy to use shortcut
const std::string value = db.execAndGet("SELECT value FROM test WHERE id=2");
std::cout << "execAndGet=" << value.c_str() << std::endl;
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
////////////////////////////////////////////////////////////////////////////
// Simple select query - few variations (2/7) :
try
{
// Open a database file in readonly mode
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
///// a) Loop to get values of column by index, using auto cast to variable type
// Compile a SQL query, containing one parameter (index 1)
SQLite::Statement query(db, "SELECT id as test_id, value as test_val, weight as test_weight FROM test WHERE weight > ?");
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' compiled (" << query.getColumnCount () << " columns in the result)\n";
// Bind the integer value 2 to the first parameter of the SQL query
query.bind(1, 2);
std::cout << "binded with integer value '2' :\n";
// Loop to execute the query step by step, to get one a row of results at a time
while (query.executeStep())
{
// Demonstrates how to get some typed column value (and the equivalent explicit call)
const int id = query.getColumn(0); // = query.getColumn(0).getInt();
//const char* pvalue = query.getColumn(1); // = query.getColumn(1).getText();
const std::string value = query.getColumn(1); // = query.getColumn(1).getText();
const int bytes = query.getColumn(1).size(); // .getColumn(1).getBytes();
const double weight = query.getColumn(2); // = query.getColumn(2).getInt();
std::cout << "row (" << id << ", \"" << value.c_str() << "\"(" << bytes << ") " << weight << ")\n";
}
///// b) Get aliased column names (and original column names if possible)
// Reset the query to use it again
query.reset();
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount() << " columns in the result)\n";
// Show how to get the aliased names of the result columns.
const std::string name0 = query.getColumnName(0);
const std::string name1 = query.getColumnName(1);
const std::string name2 = query.getColumnName(2);
std::cout << "aliased result [\"" << name0.c_str() << "\", \"" << name1.c_str() << "\", \"" << name2.c_str() << "\"]\n";
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Show how to get origin names of the table columns from which theses result columns come from.
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
// also defined at compile times of the SQLite library itself.
const std::string oname0 = query.getColumnOriginName(0);
const std::string oname1 = query.getColumnOriginName(1);
const std::string oname2 = query.getColumnOriginName(2);
std::cout << "origin table 'test' [\"" << oname0.c_str() << "\", \"" << oname1.c_str() << "\", \"" << oname2.c_str() << "\"]\n";
#endif
// Loop to execute the query step by step, to get one a row of results at a time
while (query.executeStep())
{
// Demonstrates that inserting column value in a std:ostream is natural
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\", " << query.getColumn(2) << ")\n";
}
///// c) Get columns by name
// Reset the query to use it again
query.reset();
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount() << " columns in the result)\n";
// Loop to execute the query step by step, to get one a row of results at a time
while (query.executeStep())
{
// Demonstrates how to get column value by aliased name (not the original table names, see above)
const int id = query.getColumn("test_id");
const std::string value = query.getColumn("test_val");
const double weight = query.getColumn("test_weight");
std::cout << "row (" << id << ", \"" << value.c_str() << "\" " << weight << ")\n";
}
///// d) Uses explicit typed getters instead of auto cast operators
// Reset the query to use it again
query.reset();
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount () << " columns in the result)\n";
// Bind the string value "6" to the first parameter of the SQL query
query.bind(1, "6");
std::cout << "binded with string value \"6\" :\n";
// Reuses variables: uses assignement operator in the loop instead of constructor with initialization
int id = 0;
std::string value;
double weight = 0.0;
while (query.executeStep())
{
id = query.getColumn(0).getInt();
value = query.getColumn(1).getText();
weight = query.getColumn(2).getInt();
std::cout << "row (" << id << ", \"" << value << "\", " << weight << ")\n";
}
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
////////////////////////////////////////////////////////////////////////////
// Object Oriented Basic example (3/7) :
try
{
// Open the database and compile the query
Example example;
// Demonstrates the way to use the same query with different parameter values
example.ListGreaterThan(8);
example.ListGreaterThan(6);
example.ListGreaterThan(2);
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
// The execAndGet wrapper example (4/7) :
try
{
// Open a database file in readonly mode
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
// WARNING: Be very careful with this dangerous method: you have to
// make a COPY OF THE result, else it will be destroy before the next line
// (when the underlying temporary Statement and Column objects are destroyed)
std::string value = db.execAndGet("SELECT value FROM test WHERE id=2");
std::cout << "execAndGet=" << value.c_str() << std::endl;
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
////////////////////////////////////////////////////////////////////////////
// Simple batch queries example (5/7) :
try
{
// Open a database file in create/write mode
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
// Create a new table with an explicit "id" column aliasing the underlying rowid
db.exec("DROP TABLE IF EXISTS test");
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
// first row
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
// second row
nb = db.exec("INSERT INTO test VALUES (NULL, \"second\")");
std::cout << "INSERT INTO test VALUES (NULL, \"second\")\", returned " << nb << std::endl;
// update the second row
nb = db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'");
std::cout << "UPDATE test SET value=\"second-updated\" WHERE id='2', returned " << nb << std::endl;
// Check the results : expect two row of result
SQLite::Statement query(db, "SELECT * FROM test");
std::cout << "SELECT * FROM test :\n";
while (query.executeStep())
{
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\")\n";
}
db.exec("DROP TABLE test");
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
remove("test.db3");
////////////////////////////////////////////////////////////////////////////
// RAII transaction example (6/7) :
try
{
// Open a database file in create/write mode
SQLite::Database db("transaction.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
db.exec("DROP TABLE IF EXISTS test");
// Exemple of a successful transaction :
try
{
// Begin transaction
SQLite::Transaction transaction(db);
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
// Commit transaction
transaction.commit();
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
// Exemple of a rollbacked transaction :
try
{
// Begin transaction
SQLite::Transaction transaction(db);
int nb = db.exec("INSERT INTO test VALUES (NULL, \"second\")");
std::cout << "INSERT INTO test VALUES (NULL, \"second\")\", returned " << nb << std::endl;
nb = db.exec("INSERT INTO test ObviousError");
std::cout << "INSERT INTO test \"error\", returned " << nb << std::endl;
return EXIT_FAILURE; // we should never get there : exit the example program
// Commit transaction
transaction.commit();
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
// expected error, see above
}
// Check the results (expect only one row of result, as the second one has been rollbacked by the error)
SQLite::Statement query(db, "SELECT * FROM test");
std::cout << "SELECT * FROM test :\n";
while (query.executeStep())
{
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\")\n";
}
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
remove("transaction.db3");
////////////////////////////////////////////////////////////////////////////
// Binary blob and in-memory database example (7/7) :
try
{
// Open a database file in create/write mode
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
db.exec("DROP TABLE IF EXISTS test");
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value BLOB)");
FILE* fp = fopen(filename_logo_png.c_str(), "rb");
if (NULL != fp)
{
char buffer[16*1024];
void* blob = &buffer;
int size = static_cast<int>(fread(blob, 1, 16*1024, fp));
buffer[size] = '\0';
fclose (fp);
std::cout << "blob size=" << size << " :\n";
// Insert query
SQLite::Statement query(db, "INSERT INTO test VALUES (NULL, ?)");
// Bind the blob value to the first parameter of the SQL query
query.bind(1, blob, size);
std::cout << "blob binded successfully\n";
// Execute the one-step query to insert the blob
int nb = query.exec ();
std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb << std::endl;
}
else
{
std::cout << "file " << filename_logo_png << " not found !\n";
return EXIT_FAILURE; // unexpected error : exit the example program
}
fp = fopen("out.png", "wb");
if (NULL != fp)
{
const void* blob = NULL;
size_t size;
SQLite::Statement query(db, "SELECT * FROM test");
std::cout << "SELECT * FROM test :\n";
if (query.executeStep())
{
SQLite::Column colBlob = query.getColumn(1);
blob = colBlob.getBlob ();
size = colBlob.getBytes ();
std::cout << "row (" << query.getColumn(0) << ", size=" << size << ")\n";
size_t sizew = fwrite(blob, 1, size, fp);
SQLITECPP_ASSERT(sizew == size, "fwrite failed"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
fclose (fp);
}
}
else
{
std::cout << "file out.png not created !\n";
return EXIT_FAILURE; // unexpected error : exit the example program
}
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
remove("out.png");
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
// example with C++14 variadic bind
try
{
// Open a database file in create/write mode
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
db.exec("DROP TABLE IF EXISTS test");
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
{
SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)");
SQLite::bind(query, 42, "fortytwo");
// Execute the one-step query to insert the blob
int nb = query.exec();
std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb << std::endl;
}
SQLite::Statement query(db, "SELECT * FROM test");
std::cout << "SELECT * FROM test :\n";
if (query.executeStep())
{
std::cout << query.getColumn(0).getInt() << "\t\"" << query.getColumn(1).getText() << "\"\n";
}
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
return EXIT_FAILURE; // unexpected error : exit the example program
}
#endif
std::cout << "everything ok, quitting\n";
return EXIT_SUCCESS;
}

View File

@@ -1,46 +0,0 @@
/**
* @file Assertion.h
* @ingroup SQLiteCpp
* @brief Definition of the SQLITECPP_ASSERT() macro.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <cassert>
/**
* SQLITECPP_ASSERT SQLITECPP_ASSERT() is used in destructors, where exceptions shall not be thrown
*
* Define SQLITECPP_ENABLE_ASSERT_HANDLER at the project level
* and define a SQLite::assertion_failed() assertion handler
* to tell SQLiteC++ to use it instead of assert() when an assertion fail.
*/
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
// if an assert handler is provided by user code, use it instead of assert()
namespace SQLite
{
// declaration of the assert handler to define in user code
void assertion_failed(const char* apFile, const long apLine, const char* apFunc,
const char* apExpr, const char* apMsg);
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif
// call the assert handler provided by user code
#define SQLITECPP_ASSERT(expression, message) \
if (!(expression)) SQLite::assertion_failed(__FILE__, __LINE__, __func__, #expression, message)
} // namespace SQLite
#else
// if no assert handler provided by user code, use standard assert()
// (note: in release mode assert() does nothing)
#define SQLITECPP_ASSERT(expression, message) assert(expression && message)
#endif

View File

@@ -1,136 +0,0 @@
/**
* @file Backup.h
* @ingroup SQLiteCpp
* @brief Backup is used to backup a database file in a safe and online way.
*
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
* Copyright (c) 2015-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <SQLiteCpp/Database.h>
#include <string>
// Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3_backup;
namespace SQLite
{
/**
* @brief RAII encapsulation of a SQLite Database Backup process.
*
* A Backup object is used to backup a source database file to a destination database file
* in a safe and online way.
*
* Resource Acquisition Is Initialization (RAII) means that the Backup Resource
* is allocated in the constructor and released in the destructor, so that there is
* no need to worry about memory management or the validity of the underlying SQLite Backup.
*
* Thread-safety: a Backup object shall not be shared by multiple threads, because :
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
* provided that no single database connection is used simultaneously in two or more threads."
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
* because of the way it shares the underling SQLite precompiled statement
* in a custom shared pointer (See the inner class "Statement::Ptr").
*/
class Backup
{
public:
/**
* @brief Initialize a SQLite Backup object.
*
* Initialize a SQLite Backup object for the source database and destination database.
* The database name is "main" for the main database, "temp" for the temporary database,
* or the name specified after the AS keyword in an ATTACH statement for an attached database.
*
* Exception is thrown in case of error, then the Backup object is NOT constructed.
*
* @param[in] aDestDatabase Destination database connection
* @param[in] apDestDatabaseName Destination database name
* @param[in] aSrcDatabase Source database connection
* @param[in] apSrcDatabaseName Source database name
*
* @throw SQLite::Exception in case of error
*/
Backup(Database& aDestDatabase,
const char* apDestDatabaseName,
Database& aSrcDatabase,
const char* apSrcDatabaseName);
/**
* @brief Initialize a SQLite Backup object.
*
* Initialize a SQLite Backup object for source database and destination database.
* The database name is "main" for the main database, "temp" for the temporary database,
* or the name specified after the AS keyword in an ATTACH statement for an attached database.
*
* Exception is thrown in case of error, then the Backup object is NOT constructed.
*
* @param[in] aDestDatabase Destination database connection
* @param[in] aDestDatabaseName Destination database name
* @param[in] aSrcDatabase Source database connection
* @param[in] aSrcDatabaseName Source database name
*
* @throw SQLite::Exception in case of error
*/
Backup(Database& aDestDatabase,
const std::string& aDestDatabaseName,
Database& aSrcDatabase,
const std::string& aSrcDatabaseName);
/**
* @brief Initialize a SQLite Backup object for main databases.
*
* Initialize a SQLite Backup object for source database and destination database.
* Backup the main databases between the source and the destination.
*
* Exception is thrown in case of error, then the Backup object is NOT constructed.
*
* @param[in] aDestDatabase Destination database connection
* @param[in] aSrcDatabase Source database connection
*
* @throw SQLite::Exception in case of error
*/
Backup(Database& aDestDatabase,
Database& aSrcDatabase);
/// Release the SQLite Backup resource.
virtual ~Backup() noexcept;
/**
* @brief Execute a step of backup with a given number of source pages to be copied
*
* Exception is thrown when SQLITE_IOERR_XXX, SQLITE_NOMEM, or SQLITE_READONLY is returned
* in sqlite3_backup_step(). These errors are considered fatal, so there is no point
* in retrying the call to executeStep().
*
* @param[in] aNumPage The number of source pages to be copied, with a negative value meaning all remaining source pages
*
* @return SQLITE_OK/SQLITE_DONE/SQLITE_BUSY/SQLITE_LOCKED
*
* @throw SQLite::Exception in case of error
*/
int executeStep(const int aNumPage = -1);
/// Return the number of source pages still to be backed up as of the most recent call to executeStep().
int getRemainingPageCount();
/// Return the total number of pages in the source database as of the most recent call to executeStep().
int getTotalPageCount();
private:
/// @{ Backup must be non-copyable
Backup(const Backup&);
Backup& operator=(const Backup&);
/// @}
private:
sqlite3_backup* mpSQLiteBackup; ///< Pointer to SQLite Database Backup Handle
};
} // namespace SQLite

View File

@@ -1,281 +0,0 @@
/**
* @file Column.h
* @ingroup SQLiteCpp
* @brief Encapsulation of a Column in a row of the result pointed by the prepared SQLite::Statement.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Exception.h>
#include <string>
#include <limits.h>
namespace SQLite
{
extern const int INTEGER; ///< SQLITE_INTEGER
extern const int FLOAT; ///< SQLITE_FLOAT
extern const int TEXT; ///< SQLITE_TEXT
extern const int BLOB; ///< SQLITE_BLOB
extern const int Null; ///< SQLITE_NULL
/**
* @brief Encapsulation of a Column in a row of the result pointed by the prepared Statement.
*
* A Column is a particular field of SQLite data in the current row of result
* of the Statement : it points to a single cell.
*
* Its value can be expressed as a text, and, when applicable, as a numeric
* (integer or floating point) or a binary blob.
*
* Thread-safety: a Column object shall not be shared by multiple threads, because :
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
* provided that no single database connection is used simultaneously in two or more threads."
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
* because of the way it shares the underling SQLite precompiled statement
* in a custom shared pointer (See the inner class "Statement::Ptr").
*/
class Column
{
public:
/**
* @brief Encapsulation of a Column in a Row of the result.
*
* @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object.
* @param[in] aIndex Index of the column in the row of result, starting at 0
*/
Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept; // nothrow
/// Simple destructor
virtual ~Column() noexcept; // nothrow
// default copy constructor and assignment operator are perfectly suited :
// they copy the Statement::Ptr which in turn increments the reference counter.
/// Make clang happy by explicitly implementing the copy-constructor:
Column(const Column & aOther) :
mStmtPtr(aOther.mStmtPtr),
mIndex(aOther.mIndex)
{
}
/**
* @brief Return a pointer to the named assigned to this result column (potentially aliased)
*
* @see getOriginName() to get original column name (not aliased)
*/
const char* getName() const noexcept; // nothrow
#ifdef SQLITE_ENABLE_COLUMN_METADATA
/**
* @brief Return a pointer to the table column name that is the origin of this result column
*
* Require definition of the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro :
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
* - and also when compiling this wrapper.
*/
const char* getOriginName() const noexcept; // nothrow
#endif
/// Return the integer value of the column.
int getInt() const noexcept; // nothrow
/// Return the 32bits unsigned integer value of the column (note that SQLite3 does not support unsigned 64bits).
unsigned getUInt() const noexcept; // nothrow
/// Return the 64bits integer value of the column (note that SQLite3 does not support unsigned 64bits).
long long getInt64() const noexcept; // nothrow
/// Return the double (64bits float) value of the column
double getDouble() const noexcept; // nothrow
/**
* @brief Return a pointer to the text value (NULL terminated string) of the column.
*
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
* thus you must copy it before using it beyond its scope (to a std::string for instance).
*/
const char* getText(const char* apDefaultValue = "") const noexcept; // nothrow
/**
* @brief Return a pointer to the binary blob value of the column.
*
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
* thus you must copy it before using it beyond its scope (to a std::string for instance).
*/
const void* getBlob() const noexcept; // nothrow
/**
* @brief Return a std::string for a TEXT or BLOB column.
*
* Note this correctly handles strings that contain null bytes.
*/
std::string getString() const noexcept; // nothrow
/**
* @brief Return the type of the value of the column
*
* Return either SQLite::INTEGER, SQLite::FLOAT, SQLite::TEXT, SQLite::BLOB, or SQLite::Null.
*
* @warning After a type conversion (by a call to a getXxx on a Column of a Yyy type),
* the value returned by sqlite3_column_type() is undefined.
*/
int getType() const noexcept; // nothrow
/// Test if the column is an integer type value (meaningful only before any conversion)
inline bool isInteger() const noexcept // nothrow
{
return (SQLite::INTEGER == getType());
}
/// Test if the column is a floating point type value (meaningful only before any conversion)
inline bool isFloat() const noexcept // nothrow
{
return (SQLite::FLOAT == getType());
}
/// Test if the column is a text type value (meaningful only before any conversion)
inline bool isText() const noexcept // nothrow
{
return (SQLite::TEXT == getType());
}
/// Test if the column is a binary blob type value (meaningful only before any conversion)
inline bool isBlob() const noexcept // nothrow
{
return (SQLite::BLOB == getType());
}
/// Test if the column is NULL (meaningful only before any conversion)
inline bool isNull() const noexcept // nothrow
{
return (SQLite::Null == getType());
}
/**
* @brief Return the number of bytes used by the text (or blob) value of the column
*
* Return either :
* - size in bytes (not in characters) of the string returned by getText() without the '\0' terminator
* - size in bytes of the string representation of the numerical value (integer or double)
* - size in bytes of the binary blob returned by getBlob()
* - 0 for a NULL value
*/
int getBytes() const noexcept;
/// Alias returning the number of bytes used by the text (or blob) value of the column
inline int size() const noexcept
{
return getBytes ();
}
/// Inline cast operator to int
inline operator int() const
{
return getInt();
}
/// Inline cast operator to 32bits unsigned integer
inline operator unsigned int() const
{
return getUInt();
}
#if (LONG_MAX == INT_MAX) // sizeof(long)==4 means the data model of the system is ILP32 (32bits OS or Windows 64bits)
/// Inline cast operator to 32bits long
inline operator long() const
{
return getInt();
}
/// Inline cast operator to 32bits unsigned long
inline operator unsigned long() const
{
return getUInt();
}
#else
/// Inline cast operator to 64bits long when the data model of the system is ILP64 (Linux 64 bits...)
inline operator long() const
{
return getInt64();
}
#endif
/// Inline cast operator to 64bits integer
inline operator long long() const
{
return getInt64();
}
/// Inline cast operator to double
inline operator double() const
{
return getDouble();
}
/**
* @brief Inline cast operator to char*
*
* @see getText
*/
inline operator const char*() const
{
return getText();
}
/**
* @brief Inline cast operator to void*
*
* @see getBlob
*/
inline operator const void*() const
{
return getBlob();
}
#if !(defined(_MSC_VER) && _MSC_VER < 1900)
// NOTE : the following is required by GCC and Clang to cast a Column result in a std::string
// (error: conversion from SQLite::Column to non-scalar type std::string {aka std::basic_string<char>})
// but is not working under Microsoft Visual Studio 2010, 2012 and 2013
// (error C2440: 'initializing' : cannot convert from 'SQLite::Column' to 'std::basic_string<_Elem,_Traits,_Ax>'
// [...] constructor overload resolution was ambiguous)
/**
* @brief Inline cast operator to std::string
*
* Handles BLOB or TEXT, which may contain null bytes within
*
* @see getString
*/
inline operator std::string() const
{
return getString();
}
#endif
private:
Statement::Ptr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
int mIndex; ///< Index of the column in the row of result, starting at 0
};
/**
* @brief Standard std::ostream text inserter
*
* Insert the text value of the Column object, using getText(), into the provided stream.
*
* @param[in] aStream Stream to use
* @param[in] aColumn Column object to insert into the provided stream
*
* @return Reference to the stream used
*/
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn);
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900)
// Create an instance of T from the first N columns, see declaration in Statement.h for full details
template<typename T, int N>
T Statement::getColumns()
{
checkRow();
checkIndex(N - 1);
return getColumns<T>(std::make_integer_sequence<int, N>{});
}
// Helper function called by getColums<typename T, int N>
template<typename T, const int... Is>
T Statement::getColumns(const std::integer_sequence<int, Is...>)
{
return T(Column(mStmtPtr, Is)...);
}
#endif
} // namespace SQLite

View File

@@ -1,440 +0,0 @@
/**
* @file Database.h
* @ingroup SQLiteCpp
* @brief Management of a SQLite Database Connection.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <SQLiteCpp/Column.h>
#include <string.h>
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
struct sqlite3_context;
struct Mem;
typedef struct Mem sqlite3_value;
namespace SQLite
{
// Those public constants enable most usages of SQLiteCpp without including <sqlite3.h> in the client application.
/// The database is opened in read-only mode. If the database does not already exist, an error is returned.
extern const int OPEN_READONLY; // SQLITE_OPEN_READONLY
/// The database is opened for reading and writing if possible, or reading only if the file is write protected
/// by the operating system. In either case the database must already exist, otherwise an error is returned.
extern const int OPEN_READWRITE; // SQLITE_OPEN_READWRITE
/// With OPEN_READWRITE: The database is opened for reading and writing, and is created if it does not already exist.
extern const int OPEN_CREATE; // SQLITE_OPEN_CREATE
/// Enable URI filename interpretation, parsed according to RFC 3986 (ex. "file:data.db?mode=ro&cache=private")
extern const int OPEN_URI; // SQLITE_OPEN_URI
extern const int OK; ///< SQLITE_OK (used by inline check() bellow)
extern const char* VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time
extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time
/// Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept; // nothrow
/// Return SQLite version number using runtime call to the compiled library
int getLibVersionNumber() noexcept; // nothrow
/**
* @brief RAII management of a SQLite Database Connection.
*
* A Database object manage a list of all SQLite Statements associated with the
* underlying SQLite 3 database connection.
*
* Resource Acquisition Is Initialization (RAII) means that the Database Connection
* is opened in the constructor and closed in the destructor, so that there is
* no need to worry about memory management or the validity of the underlying SQLite Connection.
*
* Thread-safety: a Database object shall not be shared by multiple threads, because :
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
* provided that no single database connection is used simultaneously in two or more threads."
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
* because of the way it shares the underling SQLite precompiled statement
* in a custom shared pointer (See the inner class "Statement::Ptr").
*/
class Database
{
friend class Statement; // Give Statement constructor access to the mpSQLite Connection Handle
public:
/**
* @brief Open the provided database UTF-8 filename.
*
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
* of the old sqlite3_open() function (READWRITE+CREATE).
* This makes sense if you want to use it on a readonly filesystem
* or to prevent creation of a void file when a required file is missing.
*
* Exception is thrown in case of error, then the Database object is NOT constructed.
*
* @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
* @param[in] aFlags SQLite::OPEN_READONLY/SQLite::OPEN_READWRITE/SQLite::OPEN_CREATE...
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
* @param[in] apVfs UTF-8 name of custom VFS to use, or nullptr for sqlite3 default
*
* @throw SQLite::Exception in case of error
*/
Database(const char* apFilename,
const int aFlags = SQLite::OPEN_READONLY,
const int aBusyTimeoutMs = 0,
const char* apVfs = NULL);
/**
* @brief Open the provided database UTF-8 filename.
*
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
* of the old sqlite3_open() function (READWRITE+CREATE).
* This makes sense if you want to use it on a readonly filesystem
* or to prevent creation of a void file when a required file is missing.
*
* Exception is thrown in case of error, then the Database object is NOT constructed.
*
* @param[in] aFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
* @param[in] aFlags SQLite::OPEN_READONLY/SQLite::OPEN_READWRITE/SQLite::OPEN_CREATE...
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
* @param[in] aVfs UTF-8 name of custom VFS to use, or empty string for sqlite3 default
*
* @throw SQLite::Exception in case of error
*/
Database(const std::string& aFilename,
const int aFlags = SQLite::OPEN_READONLY,
const int aBusyTimeoutMs = 0,
const std::string& aVfs = "");
/**
* @brief Close the SQLite database connection.
*
* All SQLite statements must have been finalized before,
* so all Statement objects must have been unregistered.
*
* @warning assert in case of error
*/
virtual ~Database() noexcept; // nothrow
/**
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
*
* This is useful in multithreaded program to handle case where a table is locked for writing by a thread.
* Any other thread cannot access the table and will receive a SQLITE_BUSY error:
* setting a timeout will wait and retry up to the time specified before returning this SQLITE_BUSY error.
* Reading the value of timeout for current connection can be done with SQL query "PRAGMA busy_timeout;".
* Default busy timeout is 0ms.
*
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
*
* @throw SQLite::Exception in case of error
*/
void setBusyTimeout(const int aBusyTimeoutMs) noexcept; // nothrow
/**
* @brief Shortcut to execute one or multiple statements without results.
*
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
*
* @see Statement::exec() to handle precompiled statements (for better performances) without results
* @see Statement::executeStep() to handle "SELECT" queries with results
*
* @param[in] apQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
*
* @return number of rows modified by the *last* INSERT, UPDATE or DELETE statement (beware of multiple statements)
* @warning undefined for CREATE or DROP table: returns the value of a previous INSERT, UPDATE or DELETE statement.
*
* @throw SQLite::Exception in case of error
*/
int exec(const char* apQueries);
/**
* @brief Shortcut to execute one or multiple statements without results.
*
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
*
* @see Statement::exec() to handle precompiled statements (for better performances) without results
* @see Statement::executeStep() to handle "SELECT" queries with results
*
* @param[in] aQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
*
* @return number of rows modified by the *last* INSERT, UPDATE or DELETE statement (beware of multiple statements)
* @warning undefined for CREATE or DROP table: returns the value of a previous INSERT, UPDATE or DELETE statement.
*
* @throw SQLite::Exception in case of error
*/
inline int exec(const std::string& aQueries)
{
return exec(aQueries.c_str());
}
/**
* @brief Shortcut to execute a one step query and fetch the first column of the result.
*
* This is a shortcut to execute a simple statement with a single result.
* This should be used only for non reusable queries (else you should use a Statement with bind()).
* This should be used only for queries with expected results (else an exception is fired).
*
* @warning WARNING: Be very careful with this dangerous method: you have to
* make a COPY OF THE result, else it will be destroy before the next line
* (when the underlying temporary Statement and Column objects are destroyed)
*
* @see also Statement class for handling queries with multiple results
*
* @param[in] apQuery an UTF-8 encoded SQL query
*
* @return a temporary Column object with the first column of result.
*
* @throw SQLite::Exception in case of error
*/
Column execAndGet(const char* apQuery);
/**
* @brief Shortcut to execute a one step query and fetch the first column of the result.
*
* This is a shortcut to execute a simple statement with a single result.
* This should be used only for non reusable queries (else you should use a Statement with bind()).
* This should be used only for queries with expected results (else an exception is fired).
*
* @warning WARNING: Be very careful with this dangerous method: you have to
* make a COPY OF THE result, else it will be destroy before the next line
* (when the underlying temporary Statement and Column objects are destroyed)
*
* @see also Statement class for handling queries with multiple results
*
* @param[in] aQuery an UTF-8 encoded SQL query
*
* @return a temporary Column object with the first column of result.
*
* @throw SQLite::Exception in case of error
*/
inline Column execAndGet(const std::string& aQuery)
{
return execAndGet(aQuery.c_str());
}
/**
* @brief Shortcut to test if a table exists.
*
* Table names are case sensitive.
*
* @param[in] apTableName an UTF-8 encoded case sensitive Table name
*
* @return true if the table exists.
*
* @throw SQLite::Exception in case of error
*/
bool tableExists(const char* apTableName);
/**
* @brief Shortcut to test if a table exists.
*
* Table names are case sensitive.
*
* @param[in] aTableName an UTF-8 encoded case sensitive Table name
*
* @return true if the table exists.
*
* @throw SQLite::Exception in case of error
*/
inline bool tableExists(const std::string& aTableName)
{
return tableExists(aTableName.c_str());
}
/**
* @brief Get the rowid of the most recent successful INSERT into the database from the current connection.
*
* Each entry in an SQLite table always has a unique 64-bit signed integer key called the rowid.
* If the table has a column of type INTEGER PRIMARY KEY, then it is an alias for the rowid.
*
* @return Rowid of the most recent successful INSERT into the database, or 0 if there was none.
*/
long long getLastInsertRowid() const noexcept; // nothrow
/// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection (not DROP table).
int getTotalChanges() const noexcept; // nothrow
/// Return the numeric result code for the most recent failed API call (if any).
int getErrorCode() const noexcept; // nothrow
/// Return the extended numeric result code for the most recent failed API call (if any).
int getExtendedErrorCode() const noexcept; // nothrow
/// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* getErrorMsg() const noexcept; // nothrow
/// Return the filename used to open the database.
const std::string& getFilename() const noexcept // nothrow
{
return mFilename;
}
/**
* @brief Return raw pointer to SQLite Database Connection Handle.
*
* This is often needed to mix this wrapper with other libraries or for advance usage not supported by SQLiteCpp.
*/
inline sqlite3* getHandle() const noexcept // nothrow
{
return mpSQLite;
}
/**
* @brief Create or redefine a SQL function or aggregate in the sqlite database.
*
* This is the equivalent of the sqlite3_create_function_v2 command.
* @see http://www.sqlite.org/c3ref/create_function.html
*
* @note UTF-8 text encoding assumed.
*
* @param[in] apFuncName Name of the SQL function to be created or redefined
* @param[in] aNbArg Number of arguments in the function
* @param[in] abDeterministic Optimize for deterministic functions (most are). A random number generator is not.
* @param[in] apApp Arbitrary pointer of user data, accessible with sqlite3_user_data().
* @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal NULL)
* @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc NULL)
* @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc NULL)
* @param[in] apDestroy If not NULL, then it is the destructor for the application data pointer.
*
* @throw SQLite::Exception in case of error
*/
void createFunction(const char* apFuncName,
int aNbArg,
bool abDeterministic,
void* apApp,
void (*apFunc)(sqlite3_context *, int, sqlite3_value **),
void (*apStep)(sqlite3_context *, int, sqlite3_value **),
void (*apFinal)(sqlite3_context *), // NOLINT(readability/casting)
void (*apDestroy)(void *));
/**
* @brief Create or redefine a SQL function or aggregate in the sqlite database.
*
* This is the equivalent of the sqlite3_create_function_v2 command.
* @see http://www.sqlite.org/c3ref/create_function.html
*
* @note UTF-8 text encoding assumed.
*
* @param[in] aFuncName Name of the SQL function to be created or redefined
* @param[in] aNbArg Number of arguments in the function
* @param[in] abDeterministic Optimize for deterministic functions (most are). A random number generator is not.
* @param[in] apApp Arbitrary pointer of user data, accessible with sqlite3_user_data().
* @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal NULL)
* @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc NULL)
* @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc NULL)
* @param[in] apDestroy If not NULL, then it is the destructor for the application data pointer.
*
* @throw SQLite::Exception in case of error
*/
inline void createFunction(const std::string& aFuncName,
int aNbArg,
bool abDeterministic,
void* apApp,
void (*apFunc)(sqlite3_context *, int, sqlite3_value **),
void (*apStep)(sqlite3_context *, int, sqlite3_value **),
void (*apFinal)(sqlite3_context *), // NOLINT(readability/casting)
void (*apDestroy)(void *))
{
return createFunction(aFuncName.c_str(), aNbArg, abDeterministic,
apApp, apFunc, apStep, apFinal, apDestroy);
}
/**
* @brief Load a module into the current sqlite database instance.
*
* This is the equivalent of the sqlite3_load_extension call, but additionally enables
* module loading support prior to loading the requested module.
*
* @see http://www.sqlite.org/c3ref/load_extension.html
*
* @note UTF-8 text encoding assumed.
*
* @param[in] apExtensionName Name of the shared library containing extension
* @param[in] apEntryPointName Name of the entry point (NULL to let sqlite work it out)
*
* @throw SQLite::Exception in case of error
*/
void loadExtension(const char* apExtensionName, const char* apEntryPointName);
/**
* @brief Set the key for the current sqlite database instance.
*
* This is the equivalent of the sqlite3_key call and should thus be called
* directly after opening the database.
* Open encrypted database -> call db.key("secret") -> database ready
*
* @param[in] aKey Key to decode/encode the database
*
* @throw SQLite::Exception in case of error
*/
void key(const std::string& aKey) const;
/**
* @brief Reset the key for the current sqlite database instance.
*
* This is the equivalent of the sqlite3_rekey call and should thus be called
* after the database has been opened with a valid key. To decrypt a
* database, call this method with an empty string.
* Open normal database -> call db.rekey("secret") -> encrypted database, database ready
* Open encrypted database -> call db.key("secret") -> call db.rekey("newsecret") -> change key, database ready
* Open encrypted database -> call db.key("secret") -> call db.rekey("") -> decrypted database, database ready
*
* @param[in] aNewKey New key to encode the database
*
* @throw SQLite::Exception in case of error
*/
void rekey(const std::string& aNewKey) const;
/**
* @brief Test if a file contains an unencrypted database.
*
* This is a simple test that reads the first bytes of a database file and
* compares them to the standard header for unencrypted databases. If the
* header does not match the standard string, we assume that we have an
* encrypted file.
*
* @param[in] aFilename path/uri to a file
*
* @return true if the database has the standard header.
*
* @throw SQLite::Exception in case of error
*/
static const bool isUnencrypted(const std::string& aFilename);
private:
/// @{ Database must be non-copyable
Database(const Database&);
Database& operator=(const Database&);
/// @}
/**
* @brief Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
*/
inline void check(const int aRet) const
{
if (SQLite::OK != aRet)
{
throw SQLite::Exception(mpSQLite, aRet);
}
}
private:
sqlite3* mpSQLite; ///< Pointer to SQLite Database Connection Handle
std::string mFilename; ///< UTF-8 filename used to open the database
};
} // namespace SQLite

View File

@@ -1,99 +0,0 @@
/**
* @file Exception.h
* @ingroup SQLiteCpp
* @brief Encapsulation of the error message from SQLite3 on a std::runtime_error.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <stdexcept>
#include <string>
// Forward declaration to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
/// Compatibility with non-clang compilers.
#ifndef __has_feature
#define __has_feature(x) 0
#endif
// Detect whether the compiler supports C++11 noexcept exception specifications.
#if ( defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 7) || (__GNUC__ > 4)) \
&& defined(__GXX_EXPERIMENTAL_CXX0X__))
// GCC 4.7 and following have noexcept
#elif defined(__clang__) && __has_feature(cxx_noexcept)
// Clang 3.0 and above have noexcept
#elif defined(_MSC_VER) && _MSC_VER > 1800
// Visual Studio 2015 and above have noexcept
#else
// Visual Studio 2013 does not support noexcept, and "throw()" is deprecated by C++11
#define noexcept
#endif
namespace SQLite
{
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*/
class Exception : public std::runtime_error
{
public:
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] aErrorMessage The string message describing the SQLite error
*/
explicit Exception(const std::string& aErrorMessage);
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] aErrorMessage The string message describing the SQLite error
* @param[in] ret Return value from function call that failed.
*/
Exception(const std::string& aErrorMessage, int ret);
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
*/
explicit Exception(sqlite3* apSQLite);
/**
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
*
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
* @param[in] ret Return value from function call that failed.
*/
Exception(sqlite3* apSQLite, int ret);
/// Return the result code (if any, otherwise -1).
inline int getErrorCode() const noexcept // nothrow
{
return mErrcode;
}
/// Return the extended numeric result code (if any, otherwise -1).
inline int getExtendedErrorCode() const noexcept // nothrow
{
return mExtendedErrcode;
}
/// Return a string, solely based on the error code
const char* getErrorStr() const noexcept; // nothrow
private:
const int mErrcode; ///< Error code value
const int mExtendedErrcode; ///< Detailed error code if any
};
} // namespace SQLite

View File

@@ -1,42 +0,0 @@
/**
* @file SQLiteCpp.h
* @ingroup SQLiteCpp
* @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
*
* Include this main header file in your project to gain access to all functionality provided by the wrapper.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
/**
* @defgroup SQLiteCpp SQLiteC++
* @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
*/
#pragma once
// Include useful headers of SQLiteC++
#include <SQLiteCpp/Assertion.h>
#include <SQLiteCpp/Exception.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Column.h>
#include <SQLiteCpp/Transaction.h>
/**
* @brief Version numbers for SQLiteC++ are provided in the same way as sqlite3.h
*
* The [SQLITECPP_VERSION] C preprocessor macro in the SQLiteC++.h header
* evaluates to a string literal that is the SQLite version in the
* format "X.Y.Z" where X is the major version number
* and Y is the minor version number and Z is the release number.
*
* The [SQLITECPP_VERSION_NUMBER] C preprocessor macro resolves to an integer
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
* numbers used in [SQLITECPP_VERSION].
*/
#define SQLITECPP_VERSION "2.00.00" // 2.0.0
#define SQLITECPP_VERSION_NUMBER 2000000 // 2.0.0

View File

@@ -1,648 +0,0 @@
/**
* @file Statement.h
* @ingroup SQLiteCpp
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <SQLiteCpp/Exception.h>
#include <string>
#include <map>
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
struct sqlite3;
struct sqlite3_stmt;
namespace SQLite
{
// Forward declaration
class Database;
class Column;
extern const int OK; ///< SQLITE_OK
/**
* @brief RAII encapsulation of a prepared SQLite Statement.
*
* A Statement is a compiled SQL query ready to be executed step by step
* to provide results one row at a time.
*
* Resource Acquisition Is Initialization (RAII) means that the Statement
* is compiled in the constructor and finalized in the destructor, so that there is
* no need to worry about memory management or the validity of the underlying SQLite Statement.
*
* Thread-safety: a Statement object shall not be shared by multiple threads, because :
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
* provided that no single database connection is used simultaneously in two or more threads."
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
* because of the way it shares the underling SQLite precompiled statement
* in a custom shared pointer (See the inner class "Statement::Ptr").
*/
class Statement
{
friend class Column; // For access to Statement::Ptr inner class
public:
/**
* @brief Compile and register the SQL query for the provided SQLite Database Connection
*
* @param[in] aDatabase the SQLite Database Connection
* @param[in] apQuery an UTF-8 encoded query string
*
* Exception is thrown in case of error, then the Statement object is NOT constructed.
*/
Statement(Database& aDatabase, const char* apQuery);
/**
* @brief Compile and register the SQL query for the provided SQLite Database Connection
*
* @param[in] aDatabase the SQLite Database Connection
* @param[in] aQuery an UTF-8 encoded query string
*
* Exception is thrown in case of error, then the Statement object is NOT constructed.
*/
Statement(Database& aDatabase, const std::string& aQuery);
/// Finalize and unregister the SQL query from the SQLite Database Connection.
virtual ~Statement() noexcept; // nothrow
/// Reset the statement to make it ready for a new execution.
void reset();
/**
* @brief Clears away all the bindings of a prepared statement.
*
* Contrary to the intuition of many, reset() does not reset the bindings on a prepared statement.
* Use this routine to reset all parameters to NULL.
*/
void clearBindings(); // throw(SQLite::Exception)
////////////////////////////////////////////////////////////////////////////
// Bind a value to a parameter of the SQL statement,
// in the form "?" (unnamed), "?NNN", ":VVV", "@VVV" or "$VVV".
//
// Can use the parameter index, starting from "1", to the higher NNN value,
// or the complete parameter name "?NNN", ":VVV", "@VVV" or "$VVV"
// (prefixed with the corresponding sign "?", ":", "@" or "$")
//
// Note that for text and blob values, the SQLITE_TRANSIENT flag is used,
// which tell the sqlite library to make its own copy of the data before the bind() call returns.
// This choice is done to prevent any common misuses, like passing a pointer to a
// dynamic allocated and temporary variable (a std::string for instance).
// This is under-optimized for static data (a static text define in code)
// as well as for dynamic allocated buffer which could be transfer to sqlite
// instead of being copied.
// => if you know what you are doing, use bindNoCopy() instead of bind()
/**
* @brief Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const int aValue);
/**
* @brief Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const unsigned aValue);
/**
* @brief Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const long long aValue);
/**
* @brief Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const int aIndex, const double aValue);
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const int aIndex, const std::string& aValue);
/**
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const int aIndex, const char* apValue);
/**
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const int aIndex, const void* apValue, const int aSize);
/**
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1).
*
* The string can contain null characters as it is binded using its size.
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const int aIndex, const std::string& aValue);
/**
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* Main usage is with null-terminated literal text (aka in code static strings)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const int aIndex, const char* apValue);
/**
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const int aIndex, const void* apValue, const int aSize);
/**
* @brief Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @see clearBindings() to set all bound parameters to NULL.
*/
void bind(const int aIndex);
/**
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const int aValue);
/**
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const unsigned aValue);
/**
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const long long aValue);
/**
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
void bind(const char* apName, const double aValue);
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const char* apName, const std::string& aValue);
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const char* apName, const char* apValue);
/**
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
void bind(const char* apName, const void* apValue, const int aSize);
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* The string can contain null characters as it is binded using its size.
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const char* apName, const std::string& aValue);
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* Main usage is with null-terminated literal text (aka in code static strings)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const char* apName, const char* apValue);
/**
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
void bindNoCopy(const char* apName, const void* apValue, const int aSize);
/**
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @see clearBindings() to set all bound parameters to NULL.
*/
void bind(const char* apName); // bind NULL value
/**
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const int aValue)
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const unsigned aValue)
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const long long aValue)
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*/
inline void bind(const std::string& aName, const double aValue)
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const std::string& aValue)
{
bind(aName.c_str(), aValue);
}
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const char* apValue)
{
bind(aName.c_str(), apValue);
}
/**
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
*/
inline void bind(const std::string& aName, const void* apValue, const int aSize)
{
bind(aName.c_str(), apValue, aSize);
}
/**
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* The string can contain null characters as it is binded using its size.
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
inline void bindNoCopy(const std::string& aName, const std::string& aValue)
{
bindNoCopy(aName.c_str(), aValue);
}
/**
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* Main usage is with null-terminated literal text (aka in code static strings)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
inline void bindNoCopy(const std::string& aName, const char* apValue)
{
bindNoCopy(aName.c_str(), apValue);
}
/**
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
*/
inline void bindNoCopy(const std::string& aName, const void* apValue, const int aSize)
{
bindNoCopy(aName.c_str(), apValue, aSize);
}
/**
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
*
* @see clearBindings() to set all bound parameters to NULL.
*/
inline void bind(const std::string& aName) // bind NULL value
{
bind(aName.c_str());
}
////////////////////////////////////////////////////////////////////////////
/**
* @brief Execute a step of the prepared query to fetch one row of results.
*
* While true is returned, a row of results is available, and can be accessed
* thru the getColumn() method
*
* @see exec() execute a one-step prepared statement with no expected result
* @see Database::exec() is a shortcut to execute one or multiple statements without results
*
* @return - true (SQLITE_ROW) if there is another row ready : you can call getColumn(N) to get it
* then you have to call executeStep() again to fetch more rows until the query is finished
* - false (SQLITE_DONE) if the query has finished executing : there is no (more) row of result
* (case of a query with no result, or after N rows fetched successfully)
*
* @throw SQLite::Exception in case of error
*/
bool executeStep();
/**
* @brief Execute a one-step query with no expected result.
*
* This method is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
*
* It is similar to Database::exec(), but using a precompiled statement, it adds :
* - the ability to bind() arguments to it (best way to insert data),
* - reusing it allows for better performances (efficient for multiple insertion).
*
* @see executeStep() execute a step of the prepared query to fetch one row of results
* @see Database::exec() is a shortcut to execute one or multiple statements without results
*
* @return number of row modified by this SQL statement (INSERT, UPDATE or DELETE)
*
* @throw SQLite::Exception in case of error, or if row of results are returned !
*/
int exec();
////////////////////////////////////////////////////////////////////////////
/**
* @brief Return a copy of the column data specified by its index
*
* Can be used to access the data of the current row of result when applicable,
* while the executeStep() method returns true.
*
* Throw an exception if there is no row to return a Column from:
* - if provided index is out of bound
* - before any executeStep() call
* - after the last executeStep() returned false
* - after a reset() call
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*
* @param[in] aIndex Index of the column, starting at 0
*
* @note This method is not const, reflecting the fact that the returned Column object will
* share the ownership of the underlying sqlite3_stmt.
*
* @warning The resulting Column object must not be memorized "as-is".
* Is is only a wrapper around the current result row, so it is only valid
* while the row from the Statement remains valid, that is only until next executeStep() call.
* Thus, you should instead extract immediately its data (getInt(), getText()...)
* and use or copy this data for any later usage.
*/
Column getColumn(const int aIndex);
/**
* @brief Return a copy of the column data specified by its column name (less efficient than using an index)
*
* Can be used to access the data of the current row of result when applicable,
* while the executeStep() method returns true.
*
* Throw an exception if there is no row to return a Column from :
* - if provided name is not one of the aliased column names
* - before any executeStep() call
* - after the last executeStep() returned false
* - after a reset() call
*
* Throw an exception if the specified name is not an on of the aliased name of the columns in the result.
*
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
*
* @note Uses a map of column names to indexes, build on first call.
*
* @note This method is not const, reflecting the fact that the returned Column object will
* share the ownership of the underlying sqlite3_stmt.
*
* @warning The resulting Column object must not be memorized "as-is".
* Is is only a wrapper around the current result row, so it is only valid
* while the row from the Statement remains valid, that is only until next executeStep() call.
* Thus, you should instead extract immediately its data (getInt(), getText()...)
* and use or copy this data for any later usage.
*
* Throw an exception if the specified name is not one of the aliased name of the columns in the result.
*/
Column getColumn(const char* apName);
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900)
/**
* @brief Return an instance of T constructed from copies of the first N columns
*
* Can be used to access the data of the current row of result when applicable,
* while the executeStep() method returns true.
*
* Throw an exception if there is no row to return a Column from:
* - if provided column count is out of bound
* - before any executeStep() call
* - after the last executeStep() returned false
* - after a reset() call
*
* Throw an exception if the specified column count is out of the [0, getColumnCount()) range.
*
* @tparam T Object type to construct
* @tparam N Number of columns
*
* @note Requires std=C++14
*/
template<typename T, int N>
T getColumns();
private:
/**
* @brief Helper function used by getColumns<typename T, int N> to expand an integer_sequence used to generate
* the required Column objects
*/
template<typename T, const int... Is>
T getColumns(const std::integer_sequence<int, Is...>);
public:
#endif
/**
* @brief Test if the column value is NULL
*
* @param[in] aIndex Index of the column, starting at 0
*
* @return true if the column value is NULL
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*/
bool isColumnNull(const int aIndex) const;
/**
* @brief Test if the column value is NULL
*
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
*
* @return true if the column value is NULL
*
* Throw an exception if the specified name is not one of the aliased name of the columns in the result.
*/
bool isColumnNull(const char* apName) const;
/**
* @brief Return a pointer to the named assigned to the specified result column (potentially aliased)
*
* @param[in] aIndex Index of the column in the range [0, getColumnCount()).
*
* @see getColumnOriginName() to get original column name (not aliased)
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*/
const char* getColumnName(const int aIndex) const;
#ifdef SQLITE_ENABLE_COLUMN_METADATA
/**
* @brief Return a pointer to the table column name that is the origin of the specified result column
*
* Require definition of the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro :
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
* - and also when compiling this wrapper.
*
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
*/
const char* getColumnOriginName(const int aIndex) const;
#endif
/**
* @brief Return the index of the specified (potentially aliased) column name
*
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
*
* @note Uses a map of column names to indexes, build on first call.
*
* Throw an exception if the specified name is not known.
*/
int getColumnIndex(const char* apName) const;
////////////////////////////////////////////////////////////////////////////
/// Return the UTF-8 SQL Query.
inline const std::string& getQuery() const
{
return mQuery;
}
/// Return the number of columns in the result set returned by the prepared statement
inline int getColumnCount() const
{
return mColumnCount;
}
/// true when a row has been fetched with executeStep()
inline bool isOk() const
{
return mbOk;
}
/// true when the last executeStep() had no more row to fetch
inline bool isDone() const
{
return mbDone;
}
/// Return the numeric result code for the most recent failed API call (if any).
int getErrorCode() const noexcept; // nothrow
/// Return the extended numeric result code for the most recent failed API call (if any).
int getExtendedErrorCode() const noexcept; // nothrow
/// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* getErrorMsg() const noexcept; // nothrow
private:
/**
* @brief Shared pointer to the sqlite3_stmt SQLite Statement Object.
*
* Manage the finalization of the sqlite3_stmt with a reference counter.
*
* This is a internal class, not part of the API (hence full documentation is in the cpp).
*/
class Ptr
{
public:
// Prepare the statement and initialize its reference counter
Ptr(sqlite3* apSQLite, std::string& aQuery);
// Copy constructor increments the ref counter
Ptr(const Ptr& aPtr);
// Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
~Ptr() noexcept; // nothrow (no virtual destructor needed here)
/// Inline cast operator returning the pointer to SQLite Database Connection Handle
inline operator sqlite3*() const
{
return mpSQLite;
}
/// Inline cast operator returning the pointer to SQLite Statement Object
inline operator sqlite3_stmt*() const
{
return mpStmt;
}
private:
/// @{ Unused/forbidden copy/assignment operator
Ptr& operator=(const Ptr& aPtr);
/// @}
private:
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
sqlite3_stmt* mpStmt; //!< Pointer to SQLite Statement Object
unsigned int* mpRefCount; //!< Pointer to the heap allocated reference counter of the sqlite3_stmt
//!< (to share it with Column objects)
};
private:
/// @{ Statement must be non-copyable
Statement(const Statement&);
Statement& operator=(const Statement&);
/// @}
/**
* @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
*
* @param[in] SQLite return code to test against the SQLITE_OK expected value
*/
inline void check(const int aRet) const
{
if (SQLite::OK != aRet)
{
throw SQLite::Exception(mStmtPtr, aRet);
}
}
/**
* @brief Check if there is a row of result returnes by executeStep(), else throw a SQLite::Exception.
*/
inline void checkRow() const
{
if (false == mbOk)
{
throw SQLite::Exception("No row to get a column from. executeStep() was not called, or returned false.");
}
}
/**
* @brief Check if there is a Column index is in the range of columns in the result.
*/
inline void checkIndex(const int aIndex) const
{
if ((aIndex < 0) || (aIndex >= mColumnCount))
{
throw SQLite::Exception("Column index out of range.");
}
}
private:
/// Map of columns index by name (mutable so getColumnIndex can be const)
typedef std::map<std::string, int> TColumnNames;
private:
std::string mQuery; //!< UTF-8 SQL Query
Ptr mStmtPtr; //!< Shared Pointer to the prepared SQLite Statement Object
int mColumnCount; //!< Number of columns in the result of the prepared statement
mutable TColumnNames mColumnNames; //!< Map of columns index by name (mutable so getColumnIndex can be const)
bool mbOk; //!< true when a row has been fetched with executeStep()
bool mbDone; //!< true when the last executeStep() had no more row to fetch
};
} // namespace SQLite

View File

@@ -1,77 +0,0 @@
/**
* @file Transaction.h
* @ingroup SQLiteCpp
* @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#include <SQLiteCpp/Exception.h>
namespace SQLite
{
// Forward declaration
class Database;
/**
* @brief RAII encapsulation of a SQLite Transaction.
*
* A Transaction is a way to group multiple SQL statements into an atomic secured operation;
* either it succeeds, with all the changes committed to the database file,
* or if it fails, all the changes are rolled back to the initial state.
*
* Resource Acquisition Is Initialization (RAII) means that the Transaction
* begins in the constructor and is rollbacked in the destructor, so that there is
* no need to worry about memory management or the validity of the underlying SQLite Connection.
*
* This method also offers big performances improvements compared to individually executed statements.
*
* Thread-safety: a Transaction object shall not be shared by multiple threads, because :
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
* provided that no single database connection is used simultaneously in two or more threads."
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
* because of the way it shares the underling SQLite precompiled statement
* in a custom shared pointer (See the inner class "Statement::Ptr").
*/
class Transaction
{
public:
/**
* @brief Begins the SQLite transaction
*
* @param[in] aDatabase the SQLite Database Connection
*
* Exception is thrown in case of error, then the Transaction is NOT initiated.
*/
explicit Transaction(Database& aDatabase);
/**
* @brief Safely rollback the transaction if it has not been committed.
*/
virtual ~Transaction() noexcept; // nothrow
/**
* @brief Commit the transaction.
*/
void commit();
private:
// Transaction must be non-copyable
Transaction(const Transaction&);
Transaction& operator=(const Transaction&);
/// @}
private:
Database& mDatabase; ///< Reference to the SQLite Database Connection
bool mbCommited; ///< True when commit has been called
};
} // namespace SQLite

View File

@@ -1,76 +0,0 @@
/**
* @file VariadicBind.h
* @ingroup SQLiteCpp
* @brief Convenience function for Statement::bind(...)
*
* Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
* Copyright (c) 2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#pragma once
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
#include <SQLiteCpp/Statement.h>
/// @cond
#include <utility>
#include <initializer_list>
namespace SQLite
{
/// implementation detail for variadic bind.
namespace detail {
template<class F, class ...Args, std::size_t ... I>
inline void invoke_with_index(F&& f, std::integer_sequence<std::size_t, I...>, const Args& ...args)
{
std::initializer_list<int> { (f(I+1, args), 0)... };
}
/// implementation detail for variadic bind.
template<class F, class ...Args>
inline void invoke_with_index(F&& f, const Args& ... args)
{
invoke_with_index(std::forward<F>(f), std::index_sequence_for<Args...>(), args...);
}
} // namespace detail
/// @endcond
/**
* \brief Convenience function for calling Statement::bind(...) once for each argument given.
*
* This takes care of incrementing the index between each calls to bind.
*
* This feature requires a c++14 capable compiler.
*
* \code{.cpp}
* SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC<?");
* bind(stm,a,b,c);
* //...is equivalent to
* stm.bind(1,a);
* stm.bind(2,b);
* stm.bind(3,c);
* \endcode
* @param s statement
* @param args one or more args to bind.
*/
template<class ...Args>
void bind(SQLite::Statement& s, const Args& ... args)
{
static_assert(sizeof...(args) > 0, "please invoke bind with one or more args");
auto f=[&s](std::size_t index, const auto& value)
{
s.bind(index, value);
};
detail::invoke_with_index(f, args...);
}
} // namespace SQLite
#endif // c++14

View File

@@ -1,12 +0,0 @@
# CMake file for compiling the sqlite3 static library under Windows (for ease of use)
#
# Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
#
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
# or copy at http://opensource.org/licenses/MIT)
# add sources of the "sqlite3" static library
add_library(sqlite3
sqlite3.c
sqlite3.h
)

View File

@@ -1,14 +0,0 @@
sqlite3
-------
"sqlite3.c" and "sqlite3.h" files from sqlite-amalgamation-3120200.zip (SQLite 3.12.2 2016-04-18)
Those files are provided for easy setup and compatibility under Windows/Linux/MacOS.
They are used by default by the CMake build.
Use -DSQLITECPP_INTERNAL_SQLITE=OFF to link against the Linux "libsqlite3-dev" package instead.
### License:
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,104 +0,0 @@
/**
* @file Backup.cpp
* @ingroup SQLiteCpp
* @brief Backup is used to backup a database file in a safe and online way.
*
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
* Copyright (c) 2015-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Backup.h>
#include <SQLiteCpp/Exception.h>
#include <sqlite3.h>
namespace SQLite
{
// Initialize resource for SQLite database backup
Backup::Backup(Database& aDestDatabase,
const char* apDestDatabaseName,
Database& aSrcDatabase,
const char* apSrcDatabaseName) :
mpSQLiteBackup(NULL)
{
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
apDestDatabaseName,
aSrcDatabase.getHandle(),
apSrcDatabaseName);
if (NULL == mpSQLiteBackup)
{
// If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle());
}
}
// Initialize resource for SQLite database backup
Backup::Backup(Database& aDestDatabase,
const std::string& aDestDatabaseName,
Database& aSrcDatabase,
const std::string& aSrcDatabaseName) :
mpSQLiteBackup(NULL)
{
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
aDestDatabaseName.c_str(),
aSrcDatabase.getHandle(),
aSrcDatabaseName.c_str());
if (NULL == mpSQLiteBackup)
{
// If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle());
}
}
// Initialize resource for SQLite database backup
Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
mpSQLiteBackup(NULL)
{
mpSQLiteBackup = sqlite3_backup_init(aDestDatabase.getHandle(),
"main",
aSrcDatabase.getHandle(),
"main");
if (NULL == mpSQLiteBackup)
{
// If an error occurs, the error code and message are attached to the destination database connection.
throw SQLite::Exception(aDestDatabase.getHandle());
}
}
// Release resource for SQLite database backup
Backup::~Backup() noexcept
{
if (NULL != mpSQLiteBackup)
{
sqlite3_backup_finish(mpSQLiteBackup);
}
}
// Execute backup step with a given number of source pages to be copied
int Backup::executeStep(const int aNumPage /* = -1 */)
{
const int res = sqlite3_backup_step(mpSQLiteBackup, aNumPage);
if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res)
{
throw SQLite::Exception(sqlite3_errstr(res), res);
}
return res;
}
// Get the number of remaining source pages to be copied in this backup process
int Backup::getRemainingPageCount()
{
return sqlite3_backup_remaining(mpSQLiteBackup);
}
// Get the number of total source pages to be copied in this backup process
int Backup::getTotalPageCount()
{
return sqlite3_backup_pagecount(mpSQLiteBackup);
}
} // namespace SQLite

View File

@@ -1,124 +0,0 @@
/**
* @file Column.cpp
* @ingroup SQLiteCpp
* @brief Encapsulation of a Column in a row of the result pointed by the prepared SQLite::Statement.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Column.h>
#include <sqlite3.h>
#include <iostream>
namespace SQLite
{
const int INTEGER = SQLITE_INTEGER;
const int FLOAT = SQLITE_FLOAT;
const int TEXT = SQLITE_TEXT;
const int BLOB = SQLITE_BLOB;
const int Null = SQLITE_NULL;
// Encapsulation of a Column in a row of the result pointed by the prepared Statement.
Column::Column(Statement::Ptr& aStmtPtr, int aIndex) noexcept : // nothrow
mStmtPtr(aStmtPtr),
mIndex(aIndex)
{
}
// Finalize and unregister the SQL query from the SQLite Database Connection.
Column::~Column() noexcept // nothrow
{
// the finalization will be done by the destructor of the last shared pointer
}
// Return the named assigned to this result column (potentially aliased)
const char* Column::getName() const noexcept // nothrow
{
return sqlite3_column_name(mStmtPtr, mIndex);
}
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Return the name of the table column that is the origin of this result column
const char* Column::getOriginName() const noexcept // nothrow
{
return sqlite3_column_origin_name(mStmtPtr, mIndex);
}
#endif
// Return the integer value of the column specified by its index starting at 0
int Column::getInt() const noexcept // nothrow
{
return sqlite3_column_int(mStmtPtr, mIndex);
}
// Return the unsigned integer value of the column specified by its index starting at 0
unsigned Column::getUInt() const noexcept // nothrow
{
return static_cast<unsigned>(getInt64());
}
// Return the 64bits integer value of the column specified by its index starting at 0
long long Column::getInt64() const noexcept // nothrow
{
return sqlite3_column_int64(mStmtPtr, mIndex);
}
// Return the double value of the column specified by its index starting at 0
double Column::getDouble() const noexcept // nothrow
{
return sqlite3_column_double(mStmtPtr, mIndex);
}
// Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept // nothrow
{
const char* pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr, mIndex));
return (pText?pText:apDefaultValue);
}
// Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0
const void* Column::getBlob() const noexcept // nothrow
{
return sqlite3_column_blob(mStmtPtr, mIndex);
}
// Return a std::string to a TEXT or BLOB column
std::string Column::getString() const noexcept // nothrow
{
// Note: using sqlite3_column_blob and not sqlite3_column_text
// - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly
const char *data = static_cast<const char *>(sqlite3_column_blob(mStmtPtr, mIndex));
// SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()"
// Note: std::string is ok to pass nullptr as first arg, if length is 0
return std::string(data, sqlite3_column_bytes(mStmtPtr, mIndex));
}
// Return the type of the value of the column
int Column::getType() const noexcept // nothrow
{
return sqlite3_column_type(mStmtPtr, mIndex);
}
// Return the number of bytes used by the text value of the column
int Column::getBytes() const noexcept // nothrow
{
return sqlite3_column_bytes(mStmtPtr, mIndex);
}
// Standard std::ostream inserter
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn)
{
aStream << aColumn.getText();
return aStream;
}
} // namespace SQLite

View File

@@ -1,287 +0,0 @@
/**
* @file Database.cpp
* @ingroup SQLiteCpp
* @brief Management of a SQLite Database Connection.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Assertion.h>
#include <SQLiteCpp/Exception.h>
#include <sqlite3.h>
#include <fstream>
#include <string.h>
#ifndef SQLITE_DETERMINISTIC
#define SQLITE_DETERMINISTIC 0x800
#endif // SQLITE_DETERMINISTIC
namespace SQLite
{
const int OPEN_READONLY = SQLITE_OPEN_READONLY;
const int OPEN_READWRITE = SQLITE_OPEN_READWRITE;
const int OPEN_CREATE = SQLITE_OPEN_CREATE;
const int OPEN_URI = SQLITE_OPEN_URI;
const int OK = SQLITE_OK;
const char* VERSION = SQLITE_VERSION;
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
// Return SQLite version string using runtime call to the compiled library
const char* getLibVersion() noexcept // nothrow
{
return sqlite3_libversion();
}
// Return SQLite version number using runtime call to the compiled library
int getLibVersionNumber() noexcept // nothrow
{
return sqlite3_libversion_number();
}
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
Database::Database(const char* apFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */,
const char* apVfs /* = NULL*/) :
mpSQLite(NULL),
mFilename(apFilename)
{
const int ret = sqlite3_open_v2(apFilename, &mpSQLite, aFlags, apVfs);
if (SQLITE_OK != ret)
{
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw exception;
}
if (aBusyTimeoutMs > 0)
{
setBusyTimeout(aBusyTimeoutMs);
}
}
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
Database::Database(const std::string& aFilename,
const int aFlags /* = SQLite::OPEN_READONLY*/,
const int aBusyTimeoutMs /* = 0 */,
const std::string& aVfs /* = "" */) :
mpSQLite(NULL),
mFilename(aFilename)
{
const int ret = sqlite3_open_v2(aFilename.c_str(), &mpSQLite, aFlags, aVfs.empty() ? NULL : aVfs.c_str());
if (SQLITE_OK != ret)
{
const SQLite::Exception exception(mpSQLite, ret); // must create before closing
sqlite3_close(mpSQLite); // close is required even in case of error on opening
throw exception;
}
if (aBusyTimeoutMs > 0)
{
setBusyTimeout(aBusyTimeoutMs);
}
}
// Close the SQLite database connection.
Database::~Database() noexcept // nothrow
{
const int ret = sqlite3_close(mpSQLite);
// Avoid unreferenced variable warning when build in release mode
(void) ret;
// Only case of error is SQLITE_BUSY: "database is locked" (some statements are not finalized)
// Never throw an exception in a destructor :
SQLITECPP_ASSERT(SQLITE_OK == ret, "database is locked"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
}
/**
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
*
* This is useful in multithreaded program to handle case where a table is locked for writting by a thread.
* Any other thread cannot access the table and will receive a SQLITE_BUSY error:
* setting a timeout will wait and retry up to the time specified before returning this SQLITE_BUSY error.
* Reading the value of timeout for current connection can be done with SQL query "PRAGMA busy_timeout;".
* Default busy timeout is 0ms.
*
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
*
* @throw SQLite::Exception in case of error
*/
void Database::setBusyTimeout(const int aBusyTimeoutMs) noexcept // nothrow
{
const int ret = sqlite3_busy_timeout(mpSQLite, aBusyTimeoutMs);
check(ret);
}
// Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...).
int Database::exec(const char* apQueries)
{
const int ret = sqlite3_exec(mpSQLite, apQueries, NULL, NULL, NULL);
check(ret);
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only)
return sqlite3_changes(mpSQLite);
}
// Shortcut to execute a one step query and fetch the first column of the result.
// WARNING: Be very careful with this dangerous method: you have to
// make a COPY OF THE result, else it will be destroy before the next line
// (when the underlying temporary Statement and Column objects are destroyed)
// this is an issue only for pointer type result (ie. char* and blob)
// (use the Column copy-constructor)
Column Database::execAndGet(const char* apQuery)
{
Statement query(*this, apQuery);
(void)query.executeStep(); // Can return false if no result, which will throw next line in getColumn()
return query.getColumn(0);
}
// Shortcut to test if a table exists.
bool Database::tableExists(const char* apTableName)
{
Statement query(*this, "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?");
query.bind(1, apTableName);
(void)query.executeStep(); // Cannot return false, as the above query always return a result
return (1 == query.getColumn(0).getInt());
}
// Get the rowid of the most recent successful INSERT into the database from the current connection.
long long Database::getLastInsertRowid() const noexcept // nothrow
{
return sqlite3_last_insert_rowid(mpSQLite);
}
// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection.
int Database::getTotalChanges() const noexcept // nothrow
{
return sqlite3_total_changes(mpSQLite);
}
// Return the numeric result code for the most recent failed API call (if any).
int Database::getErrorCode() const noexcept // nothrow
{
return sqlite3_errcode(mpSQLite);
}
// Return the extended numeric result code for the most recent failed API call (if any).
int Database::getExtendedErrorCode() const noexcept // nothrow
{
return sqlite3_extended_errcode(mpSQLite);
}
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* Database::getErrorMsg() const noexcept // nothrow
{
return sqlite3_errmsg(mpSQLite);
}
// Attach a custom function to your sqlite database. Assumes UTF8 text representation.
// Parameter details can be found here: http://www.sqlite.org/c3ref/create_function.html
void Database::createFunction(const char* apFuncName,
int aNbArg,
bool abDeterministic,
void* apApp,
void (*apFunc)(sqlite3_context *, int, sqlite3_value **),
void (*apStep)(sqlite3_context *, int, sqlite3_value **),
void (*apFinal)(sqlite3_context *), // NOLINT(readability/casting)
void (*apDestroy)(void *))
{
int TextRep = SQLITE_UTF8;
// optimization if deterministic function (e.g. of nondeterministic function random())
if (abDeterministic) {
TextRep = TextRep|SQLITE_DETERMINISTIC;
}
const int ret = sqlite3_create_function_v2(mpSQLite, apFuncName, aNbArg, TextRep,
apApp, apFunc, apStep, apFinal, apDestroy);
check(ret);
}
// Load an extension into the sqlite database. Only affects the current connection.
// Parameter details can be found here: http://www.sqlite.org/c3ref/load_extension.html
void Database::loadExtension(const char* apExtensionName, const char *apEntryPointName)
{
#ifdef SQLITE_OMIT_LOAD_EXTENSION
throw std::runtime_error("sqlite extensions are disabled");
#else
#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18):
// Security warning:
// It is recommended that the SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION method be used to enable only this interface.
// The use of the sqlite3_enable_load_extension() interface should be avoided to keep the SQL load_extension()
// disabled and prevent SQL injections from giving attackers access to extension loading capabilities.
int ret = sqlite3_db_config(mpSQLite, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL);
#else
int ret = sqlite3_enable_load_extension(mpSQLite, 1);
#endif
check(ret);
ret = sqlite3_load_extension(mpSQLite, apExtensionName, apEntryPointName, 0);
check(ret);
#endif
}
// Set the key for the current sqlite database instance.
void Database::key(const std::string& aKey) const
{
int pass_len = aKey.length();
#ifdef SQLITE_HAS_CODEC
if (pass_len > 0) {
const int ret = sqlite3_key(mpSQLite, aKey.c_str(), pass_len);
check(ret);
}
#else // SQLITE_HAS_CODEC
if (pass_len > 0) {
const SQLite::Exception exception("No encryption support, recompile with SQLITE_HAS_CODEC to enable.");
throw exception;
}
#endif // SQLITE_HAS_CODEC
}
// Reset the key for the current sqlite database instance.
void Database::rekey(const std::string& aNewKey) const
{
#ifdef SQLITE_HAS_CODEC
int pass_len = aNewKey.length();
if (pass_len > 0) {
const int ret = sqlite3_rekey(mpSQLite, aNewKey.c_str(), pass_len);
check(ret);
} else {
const int ret = sqlite3_rekey(mpSQLite, nullptr, 0);
check(ret);
}
#else // SQLITE_HAS_CODEC
const SQLite::Exception exception("No encryption support, recompile with SQLITE_HAS_CODEC to enable.");
throw exception;
#endif // SQLITE_HAS_CODEC
}
// Test if a file contains an unencrypted database.
const bool Database::isUnencrypted(const std::string& aFilename)
{
if (aFilename.length() > 0) {
std::ifstream fileBuffer(aFilename.c_str(), std::ios::in | std::ios::binary);
char header[16];
if (fileBuffer.is_open()) {
fileBuffer.seekg(0, std::ios::beg);
fileBuffer.getline(header, 16);
fileBuffer.close();
} else {
const SQLite::Exception exception("Error opening file: " + aFilename);
throw exception;
}
return strncmp(header, "SQLite format 3\000", 16) == 0;
}
const SQLite::Exception exception("Could not open database, the aFilename parameter was empty.");
throw exception;
}
} // namespace SQLite

View File

@@ -1,54 +0,0 @@
/**
* @file Exception.cpp
* @ingroup SQLiteCpp
* @brief Encapsulation of the error message from SQLite3 on a std::runtime_error.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Exception.h>
#include <sqlite3.h>
namespace SQLite
{
Exception::Exception(const std::string& aErrorMessage) :
std::runtime_error(aErrorMessage),
mErrcode(-1), // 0 would be SQLITE_OK, which doesn't make sense
mExtendedErrcode(-1)
{
}
Exception::Exception(const std::string& aErrorMessage, int ret) :
std::runtime_error(aErrorMessage),
mErrcode(ret),
mExtendedErrcode(-1)
{
}
Exception::Exception(sqlite3* apSQLite) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(sqlite3_errcode(apSQLite)),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}
Exception::Exception(sqlite3* apSQLite, int ret) :
std::runtime_error(sqlite3_errmsg(apSQLite)),
mErrcode(ret),
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
{
}
// Return a string, solely based on the error code
const char* Exception::getErrorStr() const noexcept // nothrow
{
return sqlite3_errstr(mErrcode);
}
} // namespace SQLite

View File

@@ -1,462 +0,0 @@
/**
* @file Statement.cpp
* @ingroup SQLiteCpp
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Column.h>
#include <SQLiteCpp/Assertion.h>
#include <SQLiteCpp/Exception.h>
#include <sqlite3.h>
namespace SQLite
{
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const char* apQuery) :
mQuery(apQuery),
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0),
mbOk(false),
mbDone(false)
{
mColumnCount = sqlite3_column_count(mStmtPtr);
}
// Compile and register the SQL query for the provided SQLite Database Connection
Statement::Statement(Database &aDatabase, const std::string& aQuery) :
mQuery(aQuery),
mStmtPtr(aDatabase.mpSQLite, mQuery), // prepare the SQL query, and ref count (needs Database friendship)
mColumnCount(0),
mbOk(false),
mbDone(false)
{
mColumnCount = sqlite3_column_count(mStmtPtr);
}
// Finalize and unregister the SQL query from the SQLite Database Connection.
Statement::~Statement() noexcept // nothrow
{
// the finalization will be done by the destructor of the last shared pointer
}
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
void Statement::reset()
{
mbOk = false;
mbDone = false;
const int ret = sqlite3_reset(mStmtPtr);
check(ret);
}
// Clears away all the bindings of a prepared statement (can be associated with #reset() above).
void Statement::clearBindings()
{
const int ret = sqlite3_clear_bindings(mStmtPtr);
check(ret);
}
// Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const int aValue)
{
const int ret = sqlite3_bind_int(mStmtPtr, aIndex, aValue);
check(ret);
}
// Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const unsigned aValue)
{
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue);
check(ret);
}
// Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const long long aValue)
{
const int ret = sqlite3_bind_int64(mStmtPtr, aIndex, aValue);
check(ret);
}
// Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const double aValue)
{
const int ret = sqlite3_bind_double(mStmtPtr, aIndex, aValue);
check(ret);
}
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const std::string& aValue)
{
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
check(ret);
}
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const char* apValue)
{
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_TRANSIENT);
check(ret);
}
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex, const void* apValue, const int aSize)
{
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_TRANSIENT);
check(ret);
}
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
{
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_STATIC);
check(ret);
}
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const char* apValue)
{
const int ret = sqlite3_bind_text(mStmtPtr, aIndex, apValue, -1, SQLITE_STATIC);
check(ret);
}
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const int aIndex, const void* apValue, const int aSize)
{
const int ret = sqlite3_bind_blob(mStmtPtr, aIndex, apValue, aSize, SQLITE_STATIC);
check(ret);
}
// Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const int aIndex)
{
const int ret = sqlite3_bind_null(mStmtPtr, aIndex);
check(ret);
}
// Bind an int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const int aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_int(mStmtPtr, index, aValue);
check(ret);
}
// Bind a 32bits unsigned int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const unsigned aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue);
check(ret);
}
// Bind a 64bits int value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const long long aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_int64(mStmtPtr, index, aValue);
check(ret);
}
// Bind a double (64bits float) value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const double aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_double(mStmtPtr, index, aValue);
check(ret);
}
// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const std::string& aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
check(ret);
}
// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const char* apValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_TRANSIENT);
check(ret);
}
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName, const void* apValue, const int aSize)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_TRANSIENT);
check(ret);
}
// Bind a string value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const std::string& aValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, aValue.c_str(),
static_cast<int>(aValue.size()), SQLITE_STATIC);
check(ret);
}
// Bind a text value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const char* apValue)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_text(mStmtPtr, index, apValue, -1, SQLITE_STATIC);
check(ret);
}
// Bind a binary blob value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bindNoCopy(const char* apName, const void* apValue, const int aSize)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_blob(mStmtPtr, index, apValue, aSize, SQLITE_STATIC);
check(ret);
}
// Bind a NULL value to a parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
void Statement::bind(const char* apName)
{
const int index = sqlite3_bind_parameter_index(mStmtPtr, apName);
const int ret = sqlite3_bind_null(mStmtPtr, index);
check(ret);
}
// Execute a step of the query to fetch one row of results
bool Statement::executeStep()
{
if (false == mbDone)
{
const int ret = sqlite3_step(mStmtPtr);
if (SQLITE_ROW == ret) // one row is ready : call getColumn(N) to access it
{
mbOk = true;
}
else if (SQLITE_DONE == ret) // no (more) row ready : the query has finished executing
{
mbOk = false;
mbDone = true;
}
else
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(mStmtPtr, ret);
}
}
else
{
throw SQLite::Exception("Statement needs to be reseted.");
}
return mbOk; // true only if one row is accessible by getColumn(N)
}
// Execute a one-step query with no expected result
int Statement::exec()
{
if (false == mbDone)
{
const int ret = sqlite3_step(mStmtPtr);
if (SQLITE_DONE == ret) // the statement has finished executing successfully
{
mbOk = false;
mbDone = true;
}
else if (SQLITE_ROW == ret)
{
mbOk = false;
mbDone = false;
throw SQLite::Exception("exec() does not expect results. Use executeStep.");
}
else
{
mbOk = false;
mbDone = false;
throw SQLite::Exception(mStmtPtr, ret);
}
}
else
{
throw SQLite::Exception("Statement need to be reseted.");
}
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
return sqlite3_changes(mStmtPtr);
}
// Return a copy of the column data specified by its index starting at 0
// (use the Column copy-constructor)
Column Statement::getColumn(const int aIndex)
{
checkRow();
checkIndex(aIndex);
// Share the Statement Object handle with the new Column created
return Column(mStmtPtr, aIndex);
}
// Return a copy of the column data specified by its column name starting at 0
// (use the Column copy-constructor)
Column Statement::getColumn(const char* apName)
{
checkRow();
const int index = getColumnIndex(apName);
// Share the Statement Object handle with the new Column created
return Column(mStmtPtr, index);
}
// Test if the column is NULL
bool Statement::isColumnNull(const int aIndex) const
{
checkRow();
checkIndex(aIndex);
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, aIndex));
}
bool Statement::isColumnNull(const char* apName) const
{
checkRow();
const int index = getColumnIndex(apName);
return (SQLITE_NULL == sqlite3_column_type(mStmtPtr, index));
}
// Return the named assigned to the specified result column (potentially aliased)
const char* Statement::getColumnName(const int aIndex) const
{
checkIndex(aIndex);
return sqlite3_column_name(mStmtPtr, aIndex);
}
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Return the named assigned to the specified result column (potentially aliased)
const char* Statement::getColumnOriginName(const int aIndex) const
{
checkIndex(aIndex);
return sqlite3_column_origin_name(mStmtPtr, aIndex);
}
#endif
// Return the index of the specified (potentially aliased) column name
int Statement::getColumnIndex(const char* apName) const
{
// Build the map of column index by name on first call
if (mColumnNames.empty())
{
for (int i = 0; i < mColumnCount; ++i)
{
const char* pName = sqlite3_column_name(mStmtPtr, i);
mColumnNames[pName] = i;
}
}
const TColumnNames::const_iterator iIndex = mColumnNames.find(apName);
if (iIndex == mColumnNames.end())
{
throw SQLite::Exception("Unknown column name.");
}
return (*iIndex).second;
}
// Return the numeric result code for the most recent failed API call (if any).
int Statement::getErrorCode() const noexcept // nothrow
{
return sqlite3_errcode(mStmtPtr);
}
// Return the extended numeric result code for the most recent failed API call (if any).
int Statement::getExtendedErrorCode() const noexcept // nothrow
{
return sqlite3_extended_errcode(mStmtPtr);
}
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
const char* Statement::getErrorMsg() const noexcept // nothrow
{
return sqlite3_errmsg(mStmtPtr);
}
////////////////////////////////////////////////////////////////////////////////
// Internal class : shared pointer to the sqlite3_stmt SQLite Statement Object
////////////////////////////////////////////////////////////////////////////////
/**
* @brief Prepare the statement and initialize its reference counter
*
* @param[in] apSQLite The sqlite3 database connexion
* @param[in] aQuery The SQL query string to prepare
*/
Statement::Ptr::Ptr(sqlite3* apSQLite, std::string& aQuery) :
mpSQLite(apSQLite),
mpStmt(NULL),
mpRefCount(NULL)
{
const int ret = sqlite3_prepare_v2(apSQLite, aQuery.c_str(), static_cast<int>(aQuery.size()), &mpStmt, NULL);
if (SQLITE_OK != ret)
{
throw SQLite::Exception(apSQLite, ret);
}
// Initialize the reference counter of the sqlite3_stmt :
// used to share the mStmtPtr between Statement and Column objects;
// This is needed to enable Column objects to live longer than the Statement objet it refers to.
mpRefCount = new unsigned int(1); // NOLINT(readability/casting)
}
/**
* @brief Copy constructor increments the ref counter
*
* @param[in] aPtr Pointer to copy
*/
Statement::Ptr::Ptr(const Statement::Ptr& aPtr) :
mpSQLite(aPtr.mpSQLite),
mpStmt(aPtr.mpStmt),
mpRefCount(aPtr.mpRefCount)
{
assert(NULL != mpRefCount);
assert(0 != *mpRefCount);
// Increment the reference counter of the sqlite3_stmt,
// asking not to finalize the sqlite3_stmt during the lifetime of the new objet
++(*mpRefCount);
}
/**
* @brief Decrement the ref counter and finalize the sqlite3_stmt when it reaches 0
*/
Statement::Ptr::~Ptr() noexcept // nothrow
{
assert(NULL != mpRefCount);
assert(0 != *mpRefCount);
// Decrement and check the reference counter of the sqlite3_stmt
--(*mpRefCount);
if (0 == *mpRefCount)
{
// If count reaches zero, finalize the sqlite3_stmt, as no Statement nor Column objet use it anymore.
// No need to check the return code, as it is the same as the last statement evaluation.
sqlite3_finalize(mpStmt);
// and delete the reference counter
delete mpRefCount;
mpRefCount = NULL;
mpStmt = NULL;
}
// else, the finalization will be done later, by the last object
}
} // namespace SQLite

View File

@@ -1,60 +0,0 @@
/**
* @file Transaction.cpp
* @ingroup SQLiteCpp
* @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
*
* Copyright (c) 2012-2013 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Transaction.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Assertion.h>
namespace SQLite
{
// Begins the SQLite transaction
Transaction::Transaction(Database& aDatabase) :
mDatabase(aDatabase),
mbCommited(false)
{
mDatabase.exec("BEGIN");
}
// Safely rollback the transaction if it has not been committed.
Transaction::~Transaction() noexcept // nothrow
{
if (false == mbCommited)
{
try
{
mDatabase.exec("ROLLBACK");
}
catch (SQLite::Exception&)
{
// Never throw an exception in a destructor: error if already rollbacked, but no harm is caused by this.
}
}
}
// Commit the transaction.
void Transaction::commit()
{
if (false == mbCommited)
{
mDatabase.exec("COMMIT");
mbCommited = true;
}
else
{
throw SQLite::Exception("Transaction already commited.");
}
}
} // namespace SQLite

View File

@@ -1,115 +0,0 @@
/**
* @file Backup_test.cpp
* @ingroup tests
* @brief Test of a SQLite Backup.
*
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
* Copyright (c) 2015-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Backup.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Exception.h>
#include <sqlite3.h> // for SQLITE_ERROR, SQLITE_RANGE and SQLITE_DONE
#include <gtest/gtest.h>
#include <cstdio>
TEST(Backup, initException) {
remove("backup_test.db3");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
const std::string name("main");
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
remove("backup_test.db3");
}
TEST(Backup, executeStepOne) {
remove("backup_test.db3");
remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
SQLite::Backup backup(destDB, "main", srcDB, "main");
int res = backup.executeStep(1); // backup only one page at a time
ASSERT_EQ(SQLite::OK, res);
const int total = backup.getTotalPageCount();
ASSERT_EQ(2, total);
int remaining = backup.getRemainingPageCount();
ASSERT_EQ(1, remaining);
res = backup.executeStep(1); // backup the second and last page
ASSERT_EQ(SQLITE_DONE, res);
remaining = backup.getRemainingPageCount();
ASSERT_EQ(0, remaining);
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
ASSERT_TRUE(query.executeStep());
EXPECT_EQ(1, query.getColumn(0).getInt());
EXPECT_STREQ("first", query.getColumn(1));
ASSERT_TRUE(query.executeStep());
EXPECT_EQ(2, query.getColumn(0).getInt());
EXPECT_STREQ("second", query.getColumn(1));
remove("backup_test.db3");
remove("backup_test.db3.backup");
}
TEST(Backup, executeStepAll) {
remove("backup_test.db3");
remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
SQLite::Backup backup(destDB, srcDB);
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
ASSERT_EQ(res, SQLITE_DONE);
const int total = backup.getTotalPageCount();
ASSERT_EQ(2, total);
const int remaining = backup.getRemainingPageCount();
ASSERT_EQ(0, remaining);
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
ASSERT_TRUE(query.executeStep());
EXPECT_EQ(1, query.getColumn(0).getInt());
EXPECT_STREQ("first", query.getColumn(1));
ASSERT_TRUE(query.executeStep());
EXPECT_EQ(2, query.getColumn(0).getInt());
EXPECT_STREQ("second", query.getColumn(1));
remove("backup_test.db3");
remove("backup_test.db3.backup");
}
TEST(Backup, executeStepException) {
remove("backup_test.db3");
remove("backup_test.db3.backup");
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
{
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
(void)destDB;
}
{
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
SQLite::Backup backup(destDB, srcDB);
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
}
remove("backup_test.db3");
remove("backup_test.db3.backup");
}

View File

@@ -1,201 +0,0 @@
/**
* @file Column_test.cpp
* @ingroup tests
* @brief Test of a SQLiteCpp Column.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Column.h>
#include <sqlite3.h> // for sqlite3_int64
#include <gtest/gtest.h>
#include <cstdio>
#include <stdint.h>
TEST(Column, basis) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL, binary BLOB, empty TEXT)"));
EXPECT_TRUE(db.tableExists("test"));
EXPECT_TRUE(db.tableExists(std::string("test")));
EXPECT_EQ(0, db.getLastInsertRowid());
// Create a first row (autoid: 1) with all kind of data and a null value
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, \"first\", -123, 0.123, ?, NULL)");
// Bind the blob value to the first parameter of the SQL query
const char buffer[] = {'b', 'l', '\0', 'b'}; // "bl\0b" : 4 char, with a null byte inside
const int size = sizeof(buffer); // size = 4
const void* blob = &buffer;
insert.bind(1, blob, size);
// Execute the one-step query to insert the row
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(1, db.getLastInsertRowid());
EXPECT_EQ(1, db.getTotalChanges());
EXPECT_THROW(insert.exec(), SQLite::Exception); // exec() shall throw as it needs to be reseted
// Compile a SQL query
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(6, query.getColumnCount ());
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
// validates every variant of cast operators, and conversions of types
{
const sqlite3_int64 id1 = query.getColumn(0); // operator int64_t()
const int64_t id2 = query.getColumn(0); // operator int64_t()
const long long id3 = query.getColumn(0); // operator int64_t()
const long id4 = query.getColumn(0); // operator int64_t() or long() depending on compiler/architecture
const unsigned int uint1 = query.getColumn(0); // operator uint32_t()
const uint32_t uint2 = query.getColumn(0); // operator uint32_t()
const char* ptxt = query.getColumn(1); // operator const char*()
const std::string msg = query.getColumn(1); // operator std::string() (or const char* with MSVC)
const int integer = query.getColumn(2); // operator int()
const double real = query.getColumn(3); // operator double()
const void* pblob = query.getColumn(4); // operator void*()
const std::string sblob = query.getColumn(4); // operator std::string() (or const char* with MSVC)
const void* pempty = query.getColumn(5); // operator void*()
EXPECT_EQ(1, id1);
EXPECT_EQ(1, id2);
EXPECT_EQ(1, id3);
EXPECT_EQ(1, id4);
EXPECT_EQ(1, uint1);
EXPECT_EQ(1, uint2);
EXPECT_STREQ("first", ptxt);
EXPECT_EQ("first", msg);
EXPECT_EQ(-123, integer);
EXPECT_EQ(0.123, real);
EXPECT_EQ(0, memcmp("bl\0b", pblob, size));
EXPECT_EQ(size, sblob.size());
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], size));
EXPECT_EQ(NULL, pempty);
}
// validates every variant of explicit getters
{
int64_t id = query.getColumn(0).getInt64();
const unsigned int uint1 = query.getColumn(0).getUInt();
const uint32_t uint2 = query.getColumn(0).getUInt();
const char* ptxt = query.getColumn(1).getText();
const std::string msg1 = query.getColumn(1).getText();
const std::string msg2 = query.getColumn(1).getString();
const int integer = query.getColumn(2).getInt();
const double real = query.getColumn(3).getDouble();
const void* pblob = query.getColumn(4).getBlob();
const std::string sblob = query.getColumn(4).getString();
EXPECT_EQ(1, id);
EXPECT_EQ(1, uint1);
EXPECT_EQ(1, uint2);
EXPECT_STREQ("first", ptxt);
EXPECT_EQ("first", msg1);
EXPECT_EQ("first", msg2);
EXPECT_EQ(-123, integer);
EXPECT_EQ(0.123, real);
EXPECT_EQ(0, memcmp("bl\0b", pblob, 4));
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], 4));
}
// Validate getBytes(), getType(), isInteger(), isNull()...
EXPECT_EQ(SQLite::INTEGER, query.getColumn(0).getType());
EXPECT_EQ(true, query.getColumn(0).isInteger());
EXPECT_EQ(false, query.getColumn(0).isFloat());
EXPECT_EQ(false, query.getColumn(0).isText());
EXPECT_EQ(false, query.getColumn(0).isBlob());
EXPECT_EQ(false, query.getColumn(0).isNull());
EXPECT_STREQ("1", query.getColumn(0).getText()); // convert to string
EXPECT_EQ(1, query.getColumn(0).getBytes()); // size of the string "1" without the null terminator
EXPECT_EQ(SQLite::TEXT, query.getColumn(1).getType());
EXPECT_EQ(false, query.getColumn(1).isInteger());
EXPECT_EQ(false, query.getColumn(1).isFloat());
EXPECT_EQ(true, query.getColumn(1).isText());
EXPECT_EQ(false, query.getColumn(1).isBlob());
EXPECT_EQ(false, query.getColumn(1).isNull());
EXPECT_STREQ("first", query.getColumn(1).getText()); // convert to string
EXPECT_EQ(5, query.getColumn(1).getBytes()); // size of the string "first"
EXPECT_EQ(SQLite::INTEGER, query.getColumn(2).getType());
EXPECT_EQ(true, query.getColumn(2).isInteger());
EXPECT_EQ(false, query.getColumn(2).isFloat());
EXPECT_EQ(false, query.getColumn(2).isText());
EXPECT_EQ(false, query.getColumn(2).isBlob());
EXPECT_EQ(false, query.getColumn(2).isNull());
EXPECT_STREQ("-123", query.getColumn(2).getText()); // convert to string
EXPECT_EQ(4, query.getColumn(2).getBytes()); // size of the string "-123"
EXPECT_EQ(SQLite::FLOAT, query.getColumn(3).getType());
EXPECT_EQ(false, query.getColumn(3).isInteger());
EXPECT_EQ(true, query.getColumn(3).isFloat());
EXPECT_EQ(false, query.getColumn(3).isText());
EXPECT_EQ(false, query.getColumn(3).isBlob());
EXPECT_EQ(false, query.getColumn(3).isNull());
EXPECT_STREQ("0.123", query.getColumn(3).getText()); // convert to string
EXPECT_EQ(5, query.getColumn(3).getBytes()); // size of the string "0.123"
EXPECT_EQ(SQLite::BLOB, query.getColumn(4).getType());
EXPECT_EQ(false, query.getColumn(4).isInteger());
EXPECT_EQ(false, query.getColumn(4).isFloat());
EXPECT_EQ(false, query.getColumn(4).isText());
EXPECT_EQ(true, query.getColumn(4).isBlob());
EXPECT_EQ(false, query.getColumn(4).isNull());
EXPECT_STREQ("bl\0b", query.getColumn(4).getText()); // convert to string
EXPECT_EQ(4, query.getColumn(4).getBytes()); // size of the blob "bl\0b" with the null char
EXPECT_EQ(SQLite::Null, query.getColumn(5).getType());
EXPECT_EQ(false, query.getColumn(5).isInteger());
EXPECT_EQ(false, query.getColumn(5).isFloat());
EXPECT_EQ(false, query.getColumn(5).isText());
EXPECT_EQ(false, query.getColumn(5).isBlob());
EXPECT_EQ(true, query.getColumn(5).isNull());
EXPECT_STREQ("", query.getColumn(5).getText()); // convert to string
EXPECT_EQ(0, query.getColumn(5).getBytes()); // size of the string "" without the null terminator
// Use intermediate Column objects (this is not the recommended way to use the API)
{
const SQLite::Column id = query.getColumn(0);
EXPECT_EQ(1, id.getInt64());
const SQLite::Column msg = query.getColumn(1);
EXPECT_EQ("first", msg.getString());
const SQLite::Column integer = query.getColumn(2);
EXPECT_EQ(-123, integer.getInt());
const SQLite::Column dbl = query.getColumn(3);
EXPECT_EQ(0.123, dbl.getDouble());
}
}
TEST(Column, getName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
// Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value"
SQLite::Statement query(db, "SELECT id, msg as value FROM test");
query.executeStep();
// Show how to get the aliased names of the result columns.
const std::string name0 = query.getColumn(0).getName();
const std::string name1 = query.getColumn(1).getName();
EXPECT_EQ("id", name0);
EXPECT_EQ("value", name1);
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Show how to get origin names of the table columns from which theses result columns come from.
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
// also defined at compile times of the SQLite library itself.
const std::string oname0 = query.getColumn(0).getOriginName();
const std::string oname1 = query.getColumn(1).getOriginName();
EXPECT_EQ("id", oname0);
EXPECT_EQ("msg", oname1);
#endif
}

View File

@@ -1,329 +0,0 @@
/**
* @file Database_test.cpp
* @ingroup tests
* @brief Test of a SQLiteCpp Database.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Database.h>
#include <sqlite3.h> // for SQLITE_ERROR and SQLITE_VERSION_NUMBER
#include <gtest/gtest.h>
#include <cstdio>
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
namespace SQLite
{
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
{
// TODO: unit test that this assertion callback get called (already tested manually)
std::cout << "assertion_failed(" << apFile << ", " << apLine << ", " << apFunc << ", " << apExpr << ", " << apMsg << ")\n";
}
}
#endif
TEST(SQLiteCpp, version) {
EXPECT_STREQ(SQLITE_VERSION, SQLite::VERSION);
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::VERSION_NUMBER);
EXPECT_STREQ(SQLITE_VERSION, SQLite::getLibVersion());
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::getLibVersionNumber());
}
TEST(Database, ctorExecCreateDropExist) {
remove("test.db3");
{
// Try to open a non-existing database
std::string filename = "test.db3";
EXPECT_THROW(SQLite::Database not_found(filename), SQLite::Exception);
// Create a new database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_STREQ("test.db3", db.getFilename().c_str());
EXPECT_FALSE(db.tableExists("test"));
EXPECT_FALSE(db.tableExists(std::string("test")));
EXPECT_EQ(0, db.getLastInsertRowid());
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
EXPECT_TRUE(db.tableExists("test"));
EXPECT_TRUE(db.tableExists(std::string("test")));
EXPECT_EQ(0, db.getLastInsertRowid());
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
EXPECT_FALSE(db.tableExists("test"));
EXPECT_FALSE(db.tableExists(std::string("test")));
EXPECT_EQ(0, db.getLastInsertRowid());
} // Close DB test.db3
remove("test.db3");
}
TEST(Database, createCloseReopen) {
remove("test.db3");
{
// Try to open the non-existing database
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
// Create a new database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_FALSE(db.tableExists("test"));
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
{
// Reopen the database file
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
remove("test.db3");
}
TEST(Database, inMemory) {
{
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
EXPECT_FALSE(db.tableExists("test"));
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_TRUE(db.tableExists("test"));
// Create a new database: not shared with the above db
SQLite::Database db2(":memory:");
EXPECT_FALSE(db2.tableExists("test"));
} // Close an destroy DBs
{
// Create a new database: no more "test" table
SQLite::Database db(":memory:");
EXPECT_FALSE(db.tableExists("test"));
} // Close an destroy DB
}
#if SQLITE_VERSION_NUMBER >= 3007015 // SQLite v3.7.15 is first version with PRAGMA busy_timeout
TEST(Database, busyTimeout) {
{
// Create a new database with default timeout of 0ms
SQLite::Database db(":memory:");
// Busy timeout default to 0ms: any contention between threads or process leads to SQLITE_BUSY error
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
// Set a non null busy timeout: any contention between threads will leads to as much retry as possible during the time
db.setBusyTimeout(5000);
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
// Reset timeout to 0
db.setBusyTimeout(0);
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
}
{
// Create a new database with a non null busy timeout
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE, 5000);
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
// Reset timeout to null
db.setBusyTimeout(0);
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
}
{
// Create a new database with a non null busy timeout
const std::string memory = ":memory:";
SQLite::Database db(memory, SQLite::OPEN_READWRITE, 5000);
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
// Reset timeout to null
db.setBusyTimeout(0);
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
}
}
#endif // SQLITE_VERSION_NUMBER >= 3007015
TEST(Database, exec) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
// Create a new table with an explicit "id" column aliasing the underlying rowid
// NOTE: here exec() returns 0 only because it is the first statements since database connexion,
// but its return is an undefined value for "CREATE TABLE" statements.
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_EQ(0, db.getLastInsertRowid());
EXPECT_EQ(0, db.getTotalChanges());
// first row : insert the "first" text value into new row of id 1
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
EXPECT_EQ(1, db.getLastInsertRowid());
EXPECT_EQ(1, db.getTotalChanges());
// second row : insert the "second" text value into new row of id 2
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
EXPECT_EQ(2, db.getLastInsertRowid());
EXPECT_EQ(2, db.getTotalChanges());
// third row : insert the "third" text value into new row of id 3
const std::string insert("INSERT INTO test VALUES (NULL, \"third\")");
EXPECT_EQ(1, db.exec(insert));
EXPECT_EQ(3, db.getLastInsertRowid());
EXPECT_EQ(3, db.getTotalChanges());
// update the second row : update text value to "second_updated"
EXPECT_EQ(1, db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'"));
EXPECT_EQ(3, db.getLastInsertRowid()); // last inserted row ID is still 3
EXPECT_EQ(4, db.getTotalChanges());
// delete the third row
EXPECT_EQ(1, db.exec("DELETE FROM test WHERE id='3'"));
EXPECT_EQ(3, db.getLastInsertRowid());
EXPECT_EQ(5, db.getTotalChanges());
// drop the whole table, ie the two remaining columns
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "DROP TABLE" statements
db.exec("DROP TABLE IF EXISTS test");
EXPECT_FALSE(db.tableExists("test"));
EXPECT_EQ(5, db.getTotalChanges());
// Re-Create the same table
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "CREATE TABLE" statements
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_EQ(5, db.getTotalChanges());
// insert two rows with two *different* statements => returns only 1, ie. for the second INSERT statement
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\");INSERT INTO test VALUES (NULL, \"second\");"));
EXPECT_EQ(2, db.getLastInsertRowid());
EXPECT_EQ(7, db.getTotalChanges());
#if (SQLITE_VERSION_NUMBER >= 3007011)
// insert two rows with only one statement (starting with SQLite 3.7.11) => returns 2
EXPECT_EQ(2, db.exec("INSERT INTO test VALUES (NULL, \"third\"), (NULL, \"fourth\");"));
EXPECT_EQ(4, db.getLastInsertRowid());
EXPECT_EQ(9, db.getTotalChanges());
#endif
}
TEST(Database, execAndGet) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
// Create a new table with an explicit "id" column aliasing the underlying rowid
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
// insert a few rows
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\", 5)"));
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\", 7)"));
// Get a single value result with an easy to use shortcut
EXPECT_STREQ("second", db.execAndGet("SELECT value FROM test WHERE id=2"));
EXPECT_STREQ("third", db.execAndGet("SELECT value FROM test WHERE weight=7"));
EXPECT_EQ(3, db.execAndGet("SELECT weight FROM test WHERE value=\"first\"").getInt());
}
TEST(Database, execException) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// exception with SQL error: "no such table"
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"), SQLite::Exception);
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
EXPECT_STREQ("no such table: test", db.getErrorMsg());
// Create a new table
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
EXPECT_STREQ("not an error", db.getErrorMsg());
// exception with SQL error: "table test has 3 columns but 2 values were supplied"
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, 3)"), SQLite::Exception);
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
EXPECT_STREQ("table test has 3 columns but 2 values were supplied", db.getErrorMsg());
// exception with SQL error: "No row to get a column from"
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"first\""), SQLite::Exception);
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
// exception with SQL error: "No row to get a column from"
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"second\""), SQLite::Exception);
// Add a row with more values than columns in the table: "table test has 3 columns but 4 values were supplied"
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"), SQLite::Exception);
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
EXPECT_STREQ("table test has 3 columns but 4 values were supplied", db.getErrorMsg());
}
// TODO: test Database::createFunction()
// TODO: test Database::loadExtension()
#ifdef SQLITE_HAS_CODEC
TEST(Database, encryptAndDecrypt) {
remove("test.db3");
{
// Try to open the non-existing database
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
// Create a new database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
EXPECT_FALSE(db.tableExists("test"));
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
{
// Reopen the database file and encrypt it
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
// Encrypt the database
db.rekey("123secret");
} // Close DB test.db3
{
// Reopen the database file and try to use it
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
SQLite::Database db("test.db3", SQLite::OPEN_READONLY);
EXPECT_THROW(db.tableExists("test"), SQLite::Exception);
db.key("123secret");
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
{
// Reopen the database file and decrypt it
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
// Decrypt the database
db.key("123secret");
db.rekey("");
} // Close DB test.db3
{
// Reopen the database file and use it
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
remove("test.db3");
}
#else // SQLITE_HAS_CODEC
TEST(Database, encryptAndDecrypt) {
remove("test.db3");
{
// Try to open the non-existing database
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
// Create a new database
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
EXPECT_FALSE(db.tableExists("test"));
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
EXPECT_TRUE(db.tableExists("test"));
} // Close DB test.db3
{
// Reopen the database file and encrypt it
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
// Encrypt the database
EXPECT_THROW(db.key("123secret"), SQLite::Exception);
EXPECT_THROW(db.rekey("123secret"), SQLite::Exception);
} // Close DB test.db3
remove("test.db3");
}
#endif // SQLITE_HAS_CODEC

View File

@@ -1,710 +0,0 @@
/**
* @file Statement_test.cpp
* @ingroup tests
* @brief Test of a SQLiteCpp Statement.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <sqlite3.h> // for SQLITE_DONE
#include <gtest/gtest.h>
#include <cstdio>
#include <stdint.h>
TEST(Statement, invalid) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Compile a SQL query, but without any table in the database
EXPECT_THROW(SQLite::Statement query(db, "SELECT * FROM test"), SQLite::Exception);
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Compile a SQL query with no parameter
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(2, query.getColumnCount ());
EXPECT_FALSE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(SQLite::OK, query.getErrorCode());
EXPECT_EQ(SQLite::OK, query.getExtendedErrorCode());
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
EXPECT_THROW(query.isColumnNull(0), SQLite::Exception);
EXPECT_THROW(query.isColumnNull(1), SQLite::Exception);
EXPECT_THROW(query.isColumnNull(2), SQLite::Exception);
EXPECT_THROW(query.getColumn(-1), SQLite::Exception);
EXPECT_THROW(query.getColumn(0), SQLite::Exception);
EXPECT_THROW(query.getColumn(1), SQLite::Exception);
EXPECT_THROW(query.getColumn(2), SQLite::Exception);
query.reset();
EXPECT_FALSE(query.isOk());
EXPECT_FALSE(query.isDone());
query.executeStep();
EXPECT_FALSE(query.isOk());
EXPECT_TRUE( query.isDone());
query.reset();
EXPECT_FALSE(query.isOk());
EXPECT_FALSE(query.isDone());
query.reset();
EXPECT_THROW(query.bind(-1, 123), SQLite::Exception);
EXPECT_THROW(query.bind(0, 123), SQLite::Exception);
EXPECT_THROW(query.bind(1, 123), SQLite::Exception);
EXPECT_THROW(query.bind(2, 123), SQLite::Exception);
EXPECT_THROW(query.bind(0, "abc"), SQLite::Exception);
EXPECT_THROW(query.bind(0), SQLite::Exception);
EXPECT_EQ(SQLITE_RANGE, db.getErrorCode());
EXPECT_EQ(SQLITE_RANGE, db.getExtendedErrorCode());
EXPECT_STREQ("bind or column index out of range", db.getErrorMsg());
EXPECT_EQ(SQLITE_RANGE, query.getErrorCode());
EXPECT_EQ(SQLITE_RANGE, query.getExtendedErrorCode());
EXPECT_STREQ("bind or column index out of range", query.getErrorMsg());
query.exec(); // exec() instead of executeStep() as there is no result
EXPECT_THROW(query.isColumnNull(0), SQLite::Exception);
EXPECT_THROW(query.getColumn(0), SQLite::Exception);
EXPECT_THROW(query.exec(), SQLite::Exception); // exec() shall throw as it needs to be reseted
// Add a first row
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
EXPECT_EQ(1, db.getLastInsertRowid());
EXPECT_EQ(1, db.getTotalChanges());
query.reset();
EXPECT_FALSE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.exec(), SQLite::Exception); // exec() shall throw as it does not expect a result
}
TEST(Statement, executeStep) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a first row
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
EXPECT_EQ(1, db.getLastInsertRowid());
// Compile a SQL query
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
// Get the first row
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
const int64_t id = query.getColumn(0);
const std::string msg = query.getColumn(1);
const int integer = query.getColumn(2);
const long integer2= query.getColumn(2);
const double real = query.getColumn(3);
EXPECT_EQ(1, id);
EXPECT_EQ("first", msg);
EXPECT_EQ(123, integer);
EXPECT_EQ(123, integer2);
EXPECT_EQ(0.123, real);
// Step one more time to discover there is nothing more
query.executeStep();
EXPECT_FALSE(query.isOk());
EXPECT_TRUE (query.isDone()); // "done" is "the end"
// Step after "the end" throw an exception
EXPECT_THROW(query.executeStep(), SQLite::Exception);
// Try to insert a new row with the same PRIMARY KEY: "UNIQUE constraint failed: test.id"
SQLite::Statement insert(db, "INSERT INTO test VALUES (1, \"impossible\", 456, 0.456)");
EXPECT_THROW(insert.executeStep(), SQLite::Exception);
// in this case, reset() do throw again the same error
EXPECT_THROW(insert.reset(), SQLite::Exception);
// Try again to insert a new row with the same PRIMARY KEY (with an alternative method): "UNIQUE constraint failed: test.id"
SQLite::Statement insert2(db, "INSERT INTO test VALUES (1, \"impossible\", 456, 0.456)");
EXPECT_THROW(insert2.exec(), SQLite::Exception);
}
TEST(Statement, bindings) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Insertion with bindable parameters
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?)");
// Compile a SQL query to check the results
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
// First row with text/int/double
{
const char* text = "first";
const int integer = -123;
const double dbl = 0.123;
insert.bind(1, text);
insert.bind(2, integer);
insert.bind(3, dbl);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ (1, query.getColumn(0).getInt64());
EXPECT_STREQ("first", query.getColumn(1).getText());
EXPECT_EQ (-123, query.getColumn(2).getInt());
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
}
// reset() without clearbindings()
insert.reset();
// Second row with the same exact values because clearbindings() was not called
{
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ (2, query.getColumn(0).getInt64());
EXPECT_STREQ("first", query.getColumn(1).getText());
EXPECT_EQ (-123, query.getColumn(2).getInt());
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
}
// reset() with clearbindings() and no more bindings
insert.reset();
insert.clearBindings();
// Third row with the all null values because clearbindings() was called
{
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the resultw
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ (3, query.getColumn(0).getInt64());
EXPECT_TRUE (query.isColumnNull(1));
EXPECT_STREQ("", query.getColumn(1).getText());
EXPECT_TRUE (query.isColumnNull(2));
EXPECT_EQ (0, query.getColumn(2).getInt());
EXPECT_TRUE (query.isColumnNull(3));
EXPECT_EQ (0.0, query.getColumn(3).getDouble());
}
// reset() with clearbindings() and new bindings
insert.reset();
insert.clearBindings();
// Fourth row with string/int64/float
{
const std::string fourth("fourth");
const long long int64 = 12345678900000LL;
const float float32 = 0.234f;
insert.bind(1, fourth);
insert.bind(2, int64);
insert.bind(3, float32);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(4, query.getColumn(0).getInt64());
EXPECT_EQ(fourth, query.getColumn(1).getText());
EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64());
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
}
// reset() without clearbindings()
insert.reset();
// Fifth row with binary buffer and a null parameter
{
const char buffer[] = "binary";
insert.bind(1, buffer, sizeof(buffer));
insert.bind(2);
EXPECT_EQ(1, insert.exec());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(5, query.getColumn(0).getInt64());
EXPECT_STREQ(buffer, query.getColumn(1).getText());
EXPECT_TRUE (query.isColumnNull(2));
EXPECT_EQ(0, query.getColumn(2).getInt());
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
}
// reset() without clearbindings()
insert.reset();
// Sixth row with uint32_t unsigned value
{
const uint32_t uint32 = 4294967295U;
insert.bind(2, uint32);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(6, query.getColumn(0).getInt64());
EXPECT_EQ(4294967295U, query.getColumn(2).getUInt());
}
}
TEST(Statement, bindNoCopy) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, txt1 TEXT, txt2 TEXT, binary BLOB)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Insertion with bindable parameters
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, ?, ?, ?)");
// Compile a SQL query to check the results
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
// Insert one row with all variants of bindNoCopy()
{
const char* txt1 = "first";
const std::string txt2 = "sec\0nd";
const char blob[] = {'b','l','\0','b'};
insert.bindNoCopy(1, txt1);
insert.bindNoCopy(2, txt2);
insert.bindNoCopy(3, blob, sizeof(blob));
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(1, query.getColumn(0).getInt64());
EXPECT_STREQ(txt1, query.getColumn(1).getText());
EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size()));
EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob)));
}
}
TEST(Statement, bindByName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Insertion with bindable parameters
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, @msg, @int, @double)");
// First row with text/int/double
insert.bind("@msg", "first");
insert.bind("@int", 123);
insert.bind("@double", 0.123);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Compile a SQL query to check the result
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ (1, query.getColumn(0).getInt64());
EXPECT_STREQ("first", query.getColumn(1).getText());
EXPECT_EQ (123, query.getColumn(2).getInt());
EXPECT_EQ (0.123, query.getColumn(3).getDouble());
// reset() with clearbindings() and new bindings
insert.reset();
insert.clearBindings();
// Second row with string/int64/float
{
const std::string second("second");
const long long int64 = 12345678900000LL;
const float float32 = 0.234f;
insert.bind("@msg", second);
insert.bind("@int", int64);
insert.bind("@double", float32);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(2, query.getColumn(0).getInt64());
EXPECT_EQ(second, query.getColumn(1).getText());
EXPECT_EQ(12345678900000LL, query.getColumn(2).getInt64());
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
}
// reset() without clearbindings()
insert.reset();
// Third row with binary buffer and a null parameter
{
const char buffer[] = "binary";
insert.bind("@msg", buffer, sizeof(buffer));
insert.bind("@int");
EXPECT_EQ(1, insert.exec());
// Check the result
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(3, query.getColumn(0).getInt64());
EXPECT_STREQ(buffer, query.getColumn(1).getText());
EXPECT_TRUE (query.isColumnNull(2));
EXPECT_EQ(0, query.getColumn(2).getInt());
EXPECT_EQ(0.234f, query.getColumn(3).getDouble());
}
// reset() without clearbindings()
insert.reset();
// Fourth row with uint32_t unsigned value
{
const uint32_t uint32 = 4294967295U;
insert.bind("@int", uint32);
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(4, query.getColumn(0).getInt64());
EXPECT_EQ(4294967295U, query.getColumn(2).getUInt());
}
}
TEST(Statement, bindNoCopyByName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, txt1 TEXT, txt2 TEXT, binary BLOB)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Insertion with bindable parameters
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, @txt1, @txt2, @blob)");
// Compile a SQL query to check the results
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
// Insert one row with all variants of bindNoCopy()
{
const char* txt1 = "first";
const std::string txt2 = "sec\0nd";
const char blob[] = { 'b','l','\0','b' };
insert.bindNoCopy("@txt1", txt1);
insert.bindNoCopy("@txt2", txt2);
insert.bindNoCopy("@blob", blob, sizeof(blob));
EXPECT_EQ(1, insert.exec());
EXPECT_EQ(SQLITE_DONE, db.getErrorCode());
// Check the result
query.executeStep();
EXPECT_TRUE(query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_EQ(1, query.getColumn(0).getInt64());
EXPECT_STREQ(txt1, query.getColumn(1).getText());
EXPECT_EQ(0, memcmp(&txt2[0], &query.getColumn(2).getString()[0], txt2.size()));
EXPECT_EQ(0, memcmp(blob, &query.getColumn(3).getString()[0], sizeof(blob)));
}
}
TEST(Statement, isColumnNull) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
ASSERT_EQ(SQLite::OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)"));
ASSERT_EQ(SQLite::OK, db.getErrorCode());
// Create a first row with no null values, then other rows with each time a NULL value
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)"));
// Compile a SQL query
const std::string select("SELECT * FROM test");
SQLite::Statement query(db, select);
EXPECT_EQ(select, query.getQuery());
EXPECT_EQ(3, query.getColumnCount());
// Get the first non-null row
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull(0));
EXPECT_EQ(false, query.isColumnNull(1));
EXPECT_EQ(false, query.isColumnNull(2));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the second row with null text
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
EXPECT_EQ(true, query.isColumnNull(0));
EXPECT_EQ(false, query.isColumnNull(1));
EXPECT_EQ(false, query.isColumnNull(2));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the second row with null integer
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull(0));
EXPECT_EQ(true, query.isColumnNull(1));
EXPECT_EQ(false, query.isColumnNull(2));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the third row with null float
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(-1), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull(0));
EXPECT_EQ(false, query.isColumnNull(1));
EXPECT_EQ(true, query.isColumnNull(2));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
}
TEST(Statement, isColumnNullByName) {
// Create a new database
SQLite::Database db(":memory:", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
ASSERT_EQ(SQLITE_OK, db.getErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT, int INTEGER, double REAL)"));
ASSERT_EQ(SQLITE_OK, db.getErrorCode());
// Create a first row with no null values, then other rows with each time a NULL value
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 123, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", NULL, 0.123)"));
ASSERT_EQ(1, db.exec("INSERT INTO test VALUES (\"first\", 123, NULL)"));
// Compile a SQL query
const std::string select("SELECT * FROM test");
SQLite::Statement query(db, select);
EXPECT_EQ(select, query.getQuery());
EXPECT_EQ(3, query.getColumnCount());
// Get the first non-null row
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull("int"));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the second row with null text
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(true, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull(1));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the second row with null integer
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(true, query.isColumnNull("int"));
EXPECT_EQ(false, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
// Get the third row with null float
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
EXPECT_THROW(query.isColumnNull(""), SQLite::Exception);
EXPECT_EQ(false, query.isColumnNull("msg"));
EXPECT_EQ(false, query.isColumnNull("int"));
EXPECT_EQ(true, query.isColumnNull("double"));
EXPECT_THROW(query.isColumnNull(3), SQLite::Exception);
}
TEST(Statement, getColumnByName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Create a first row
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
EXPECT_EQ(1, db.getLastInsertRowid());
EXPECT_EQ(1, db.getTotalChanges());
// Compile a SQL query
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
query.executeStep();
EXPECT_TRUE (query.isOk());
EXPECT_FALSE(query.isDone());
// Look for non-existing columns
EXPECT_THROW(query.getColumn("unknown"), SQLite::Exception);
EXPECT_THROW(query.getColumn(""), SQLite::Exception);
const std::string msg = query.getColumn("msg");
const int integer = query.getColumn("int");
const double real = query.getColumn("double");
EXPECT_EQ("first", msg);
EXPECT_EQ(123, integer);
EXPECT_EQ(0.123, real);
}
TEST(Statement, getName) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
// Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value"
SQLite::Statement query(db, "SELECT id, msg as value FROM test");
query.executeStep();
const std::string name0 = query.getColumnName(0);
const std::string name1 = query.getColumnName(1);
EXPECT_EQ("id", name0);
EXPECT_EQ("value", name1);
#ifdef SQLITE_ENABLE_COLUMN_METADATA
// Show how to get origin names of the table columns from which theses result columns come from.
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
// also defined at compile times of the SQLite library itself.
const std::string oname0 = query.getColumnOriginName(0);
const std::string oname1 = query.getColumnOriginName(1);
EXPECT_EQ("id", oname0);
EXPECT_EQ("msg", oname1);
#endif
}
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900)
TEST(Statement, getColumns) {
struct GetRowTestStruct
{
int id;
std::string msg;
int integer;
double real;
GetRowTestStruct(int _id, std::string _msg, int _integer, double _real)
: id(_id), msg(_msg), integer(_integer), real(_real)
{}
GetRowTestStruct(int _id, const std::string& _msg)
: id(_id), msg(_msg), integer(-1), real(0.0)
{}
};
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Create a new table
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
// Create a first row
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
EXPECT_EQ(1, db.getLastInsertRowid());
EXPECT_EQ(1, db.getTotalChanges());
// Compile a SQL query
SQLite::Statement query(db, "SELECT * FROM test");
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
EXPECT_EQ(4, query.getColumnCount());
query.executeStep();
EXPECT_TRUE(query.isOk());
EXPECT_FALSE(query.isDone());
// Get all columns
auto testStruct = query.getColumns<GetRowTestStruct, 4>();
EXPECT_EQ(1, testStruct.id);
EXPECT_EQ("first", testStruct.msg);
EXPECT_EQ(123, testStruct.integer);
EXPECT_EQ(0.123, testStruct.real);
// Get only the first 2 columns
auto testStruct2 = query.getColumns<GetRowTestStruct, 2>();
EXPECT_EQ(1, testStruct2.id);
EXPECT_EQ("first", testStruct2.msg);
EXPECT_EQ(-1, testStruct2.integer);
EXPECT_EQ(0.0, testStruct2.real);
}
#endif

View File

@@ -1,103 +0,0 @@
/**
* @file Transaction_test.cpp
* @ingroup tests
* @brief Test of a SQLite Transaction.
*
* Copyright (c) 2012-2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Transaction.h>
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/Exception.h>
#include <gtest/gtest.h>
#include <cstdio>
TEST(Transaction, commitRollback) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(SQLite::OK, db.getErrorCode());
{
// Begin transaction
SQLite::Transaction transaction(db);
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
EXPECT_EQ(SQLite::OK, db.getErrorCode());
// Insert a first value
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
EXPECT_EQ(1, db.getLastInsertRowid());
// Commit transaction
transaction.commit();
// Commit again throw an exception
EXPECT_THROW(transaction.commit(), SQLite::Exception);
}
// Auto rollback if no commit() before the end of scope
{
// Begin transaction
SQLite::Transaction transaction(db);
// Insert a second value (that will be rollbacked)
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
EXPECT_EQ(2, db.getLastInsertRowid());
// end of scope: automatic rollback
}
// Auto rollback of a transaction on error/exception
try
{
// Begin transaction
SQLite::Transaction transaction(db);
// Insert a second value (that will be rollbacked)
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
EXPECT_EQ(2, db.getLastInsertRowid());
// Execute with an error => exception with auto-rollback
db.exec("DesiredSyntaxError to raise an exception to rollback the transaction");
GTEST_FATAL_FAILURE_("we should never get there");
transaction.commit(); // We should never get there
}
catch (std::exception& e)
{
std::cout << "SQLite exception: " << e.what() << std::endl;
// expected error, see above
}
// Double rollback with a manual command before the end of scope
{
// Begin transaction
SQLite::Transaction transaction(db);
// Insert a second value (that will be rollbacked)
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
EXPECT_EQ(2, db.getLastInsertRowid());
// Execute a manual rollback (no real use case I can think of, so no rollback() method)
db.exec("ROLLBACK");
// end of scope: the automatic rollback should not raise an error because it is harmless
}
// Check the results (expect only one row of result, as all other one have been rollbacked)
SQLite::Statement query(db, "SELECT * FROM test");
int nbRows = 0;
while (query.executeStep())
{
nbRows++;
EXPECT_EQ(1, query.getColumn(0).getInt());
EXPECT_STREQ("first", query.getColumn(1).getText());
}
EXPECT_EQ(1, nbRows);
}

View File

@@ -1,72 +0,0 @@
/**
* @file VariadicBind_test.cpp
* @ingroup tests
* @brief Test of variadic bind
*
* Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
* Copyright (c) 2016 Sebastien Rombauts (sebastien.rombauts@gmail.com)
*
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
* or copy at http://opensource.org/licenses/MIT)
*/
#include <SQLiteCpp/Database.h>
#include <SQLiteCpp/Statement.h>
#include <SQLiteCpp/VariadicBind.h>
#include <gtest/gtest.h>
#include <cstdio>
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
TEST(VariadicBind, invalid) {
// Create a new database
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
EXPECT_EQ(0,
db.exec(
"CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default') "));
EXPECT_TRUE(db.tableExists("test"));
{
SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)");
// zero arguments - should give compile time error through a static assert
// SQLite::bind(query);
// bind one argument less than expected - should be fine.
// the unspecified argument should be set to null, not the default.
SQLite::bind(query, 1);
EXPECT_EQ(1, query.exec());
query.reset();
// bind all arguments - should work just fine
SQLite::bind(query, 2, "two");
EXPECT_EQ(1, query.exec());
query.reset();
// bind too many arguments - should throw.
EXPECT_THROW(SQLite::bind(query, 3, "three", 0), SQLite::Exception);
EXPECT_EQ(1, query.exec());
}
// make sure the content is as expected
{
using namespace std::string_literals;
SQLite::Statement query(db, "SELECT id, value FROM test ORDER BY id"s);
std::vector<std::pair<int, std::string> > results;
while (query.executeStep()) {
const int id = query.getColumn(0);
std::string value = query.getColumn(1);
results.emplace_back( id, std::move(value) );
}
EXPECT_EQ(std::size_t(3), results.size());
EXPECT_EQ(std::make_pair(1,""s), results.at(0));
EXPECT_EQ(std::make_pair(2,"two"s), results.at(1));
EXPECT_EQ(std::make_pair(3,"three"s), results.at(2));
}
}
#endif // c++14

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
@CMAKE_CONFIGURABLE_FILE_CONTENT@

View File

@@ -1,61 +0,0 @@
include(CheckCSourceCompiles)
option(CURL_HIDDEN_SYMBOLS "Set to ON to hide libcurl internal symbols (=hide all symbols that aren't officially external)." ON)
mark_as_advanced(CURL_HIDDEN_SYMBOLS)
if(CURL_HIDDEN_SYMBOLS)
set(SUPPORTS_SYMBOL_HIDING FALSE)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
elseif(CMAKE_COMPILER_IS_GNUCC)
if(NOT CMAKE_VERSION VERSION_LESS 2.8.10)
set(GCC_VERSION ${CMAKE_C_COMPILER_VERSION})
else()
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion
OUTPUT_VARIABLE GCC_VERSION)
endif()
if(NOT GCC_VERSION VERSION_LESS 3.4)
# note: this is considered buggy prior to 4.0 but the autotools don't care, so let's ignore that fact
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "SunPro" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 8.0)
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__global")
set(_CFLAG_SYMBOLS_HIDE "-xldscope=hidden")
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 9.0)
# note: this should probably just check for version 9.1.045 but I'm not 100% sure
# so let's to it the same way autotools do.
set(SUPPORTS_SYMBOL_HIDING TRUE)
set(_SYMBOL_EXTERN "__attribute__ ((__visibility__ (\"default\")))")
set(_CFLAG_SYMBOLS_HIDE "-fvisibility=hidden")
check_c_source_compiles("#include <stdio.h>
int main (void) { printf(\"icc fvisibility bug test\"); return 0; }" _no_bug)
if(NOT _no_bug)
set(SUPPORTS_SYMBOL_HIDING FALSE)
set(_SYMBOL_EXTERN "")
set(_CFLAG_SYMBOLS_HIDE "")
endif()
elseif(MSVC)
set(SUPPORTS_SYMBOL_HIDING TRUE)
endif()
set(HIDES_CURL_PRIVATE_SYMBOLS ${SUPPORTS_SYMBOL_HIDING})
elseif(MSVC)
if(NOT CMAKE_VERSION VERSION_LESS 3.7)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) #present since 3.4.3 but broken
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
else()
message(WARNING "Hiding private symbols regardless CURL_HIDDEN_SYMBOLS being disabled.")
set(HIDES_CURL_PRIVATE_SYMBOLS TRUE)
endif()
elseif()
set(HIDES_CURL_PRIVATE_SYMBOLS FALSE)
endif()
set(CURL_CFLAG_SYMBOLS_HIDE ${_CFLAG_SYMBOLS_HIDE})
set(CURL_EXTERN_SYMBOL ${_SYMBOL_EXTERN})

View File

@@ -1,535 +0,0 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
#ifdef TIME_WITH_SYS_TIME
/* Time with sys/time test */
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
int
main ()
{
if ((struct tm *) 0)
return 0;
;
return 0;
}
#endif
#ifdef HAVE_FCNTL_O_NONBLOCK
/* headers for FCNTL_O_NONBLOCK test */
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
/* */
#if defined(sun) || defined(__sun__) || \
defined(__SUNPRO_C) || defined(__SUNPRO_CC)
# if defined(__SVR4) || defined(__srv4__)
# define PLATFORM_SOLARIS
# else
# define PLATFORM_SUNOS4
# endif
#endif
#if (defined(_AIX) || defined(__xlC__)) && !defined(_AIX41)
# define PLATFORM_AIX_V3
#endif
/* */
#if defined(PLATFORM_SUNOS4) || defined(PLATFORM_AIX_V3) || defined(__BEOS__)
#error "O_NONBLOCK does not work on this platform"
#endif
int
main ()
{
/* O_NONBLOCK source test */
int flags = 0;
if(0 != fcntl(0, F_SETFL, flags | O_NONBLOCK))
return 1;
return 0;
}
#endif
/* tests for gethostbyaddr_r or gethostbyname_r */
#if defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT) || \
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
# define _REENTRANT
/* no idea whether _REENTRANT is always set, just invent a new flag */
# define TEST_GETHOSTBYFOO_REENTRANT
#endif
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
defined(HAVE_GETHOSTBYADDR_R_7) || \
defined(HAVE_GETHOSTBYADDR_R_8) || \
defined(HAVE_GETHOSTBYNAME_R_3) || \
defined(HAVE_GETHOSTBYNAME_R_5) || \
defined(HAVE_GETHOSTBYNAME_R_6) || \
defined(TEST_GETHOSTBYFOO_REENTRANT)
#include <sys/types.h>
#include <netdb.h>
int main(void)
{
char *address = "example.com";
int length = 0;
int type = 0;
struct hostent h;
int rc = 0;
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT) || \
\
defined(HAVE_GETHOSTBYNAME_R_3) || \
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
struct hostent_data hdata;
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT) || \
defined(HAVE_GETHOSTBYADDR_R_8) || \
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT) || \
\
defined(HAVE_GETHOSTBYNAME_R_5) || \
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT) || \
defined(HAVE_GETHOSTBYNAME_R_6) || \
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
char buffer[8192];
int h_errnop;
struct hostent *hp;
#endif
#ifndef gethostbyaddr_r
(void)gethostbyaddr_r;
#endif
#if defined(HAVE_GETHOSTBYADDR_R_5) || \
defined(HAVE_GETHOSTBYADDR_R_5_REENTRANT)
rc = gethostbyaddr_r(address, length, type, &h, &hdata);
#elif defined(HAVE_GETHOSTBYADDR_R_7) || \
defined(HAVE_GETHOSTBYADDR_R_7_REENTRANT)
hp = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &h_errnop);
(void)hp;
#elif defined(HAVE_GETHOSTBYADDR_R_8) || \
defined(HAVE_GETHOSTBYADDR_R_8_REENTRANT)
rc = gethostbyaddr_r(address, length, type, &h, buffer, 8192, &hp, &h_errnop);
#endif
#if defined(HAVE_GETHOSTBYNAME_R_3) || \
defined(HAVE_GETHOSTBYNAME_R_3_REENTRANT)
rc = gethostbyname_r(address, &h, &hdata);
#elif defined(HAVE_GETHOSTBYNAME_R_5) || \
defined(HAVE_GETHOSTBYNAME_R_5_REENTRANT)
rc = gethostbyname_r(address, &h, buffer, 8192, &h_errnop);
(void)hp; /* not used for test */
#elif defined(HAVE_GETHOSTBYNAME_R_6) || \
defined(HAVE_GETHOSTBYNAME_R_6_REENTRANT)
rc = gethostbyname_r(address, &h, buffer, 8192, &hp, &h_errnop);
#endif
(void)length;
(void)type;
(void)rc;
return 0;
}
#endif
#ifdef HAVE_SOCKLEN_T
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#endif
int
main ()
{
if ((socklen_t *) 0)
return 0;
if (sizeof (socklen_t))
return 0;
;
return 0;
}
#endif
#ifdef HAVE_IN_ADDR_T
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int
main ()
{
if ((in_addr_t *) 0)
return 0;
if (sizeof (in_addr_t))
return 0;
;
return 0;
}
#endif
#ifdef HAVE_BOOL_T
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#endif
int
main ()
{
if (sizeof (bool *) )
return 0;
;
return 0;
}
#endif
#ifdef STDC_HEADERS
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
int main() { return 0; }
#endif
#ifdef RETSIGTYPE_TEST
#include <sys/types.h>
#include <signal.h>
#ifdef signal
# undef signal
#endif
#ifdef __cplusplus
extern "C" void (*signal (int, void (*)(int)))(int);
#else
void (*signal ()) ();
#endif
int
main ()
{
return 0;
}
#endif
#ifdef HAVE_INET_NTOA_R_DECL
#include <arpa/inet.h>
typedef void (*func_type)();
int main()
{
#ifndef inet_ntoa_r
func_type func;
func = (func_type)inet_ntoa_r;
#endif
return 0;
}
#endif
#ifdef HAVE_INET_NTOA_R_DECL_REENTRANT
#define _REENTRANT
#include <arpa/inet.h>
typedef void (*func_type)();
int main()
{
#ifndef inet_ntoa_r
func_type func;
func = (func_type)&inet_ntoa_r;
#endif
return 0;
}
#endif
#ifdef HAVE_GETADDRINFO
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
int main(void) {
struct addrinfo hints, *ai;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
#ifndef getaddrinfo
(void)getaddrinfo;
#endif
error = getaddrinfo("127.0.0.1", "8080", &hints, &ai);
if (error) {
return 1;
}
return 0;
}
#endif
#ifdef HAVE_FILE_OFFSET_BITS
#ifdef _FILE_OFFSET_BITS
#undef _FILE_OFFSET_BITS
#endif
#define _FILE_OFFSET_BITS 64
#include <sys/types.h>
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int main () { ; return 0; }
#endif
#ifdef HAVE_IOCTLSOCKET
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
/* ioctlsocket source code */
int socket;
unsigned long flags = ioctlsocket(socket, FIONBIO, &flags);
;
return 0;
}
#endif
#ifdef HAVE_IOCTLSOCKET_CAMEL
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
/* IoctlSocket source code */
if(0 != IoctlSocket(0, 0, 0))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTLSOCKET_CAMEL_FIONBIO
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
/* IoctlSocket source code */
long flags = 0;
if(0 != ioctlsocket(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTLSOCKET_FIONBIO
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
int
main ()
{
int flags = 0;
if(0 != ioctlsocket(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTL_FIONBIO
/* headers for FIONBIO test */
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
int
main ()
{
int flags = 0;
if(0 != ioctl(0, FIONBIO, &flags))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_IOCTL_SIOCGIFADDR
/* headers for FIONBIO test */
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_STROPTS_H
# include <stropts.h>
#endif
#include <net/if.h>
int
main ()
{
struct ifreq ifr;
if(0 != ioctl(0, SIOCGIFADDR, &ifr))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_SETSOCKOPT_SO_NONBLOCK
/* includes start */
#ifdef HAVE_WINDOWS_H
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
# ifdef HAVE_WINSOCK2_H
# include <winsock2.h>
# else
# ifdef HAVE_WINSOCK_H
# include <winsock.h>
# endif
# endif
#endif
/* includes start */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
/* includes end */
int
main ()
{
if(0 != setsockopt(0, SOL_SOCKET, SO_NONBLOCK, 0, 0))
return 1;
;
return 0;
}
#endif
#ifdef HAVE_GLIBC_STRERROR_R
#include <string.h>
#include <errno.h>
int
main () {
char buffer[1024]; /* big enough to play with */
char *string =
strerror_r(EACCES, buffer, sizeof(buffer));
/* this should've returned a string */
if(!string || !string[0])
return 99;
return 0;
}
#endif
#ifdef HAVE_POSIX_STRERROR_R
#include <string.h>
#include <errno.h>
int
main () {
char buffer[1024]; /* big enough to play with */
int error =
strerror_r(EACCES, buffer, sizeof(buffer));
/* This should've returned zero, and written an error string in the
buffer.*/
if(!buffer[0] || error)
return 99;
return 0;
}
#endif

View File

@@ -1,42 +0,0 @@
# - Find c-ares
# Find the c-ares includes and library
# This module defines
# CARES_INCLUDE_DIR, where to find ares.h, etc.
# CARES_LIBRARIES, the libraries needed to use c-ares.
# CARES_FOUND, If false, do not try to use c-ares.
# also defined, but not for general use are
# CARES_LIBRARY, where to find the c-ares library.
FIND_PATH(CARES_INCLUDE_DIR ares.h
/usr/local/include
/usr/include
)
SET(CARES_NAMES ${CARES_NAMES} cares)
FIND_LIBRARY(CARES_LIBRARY
NAMES ${CARES_NAMES}
PATHS /usr/lib /usr/local/lib
)
IF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_LIBRARIES ${CARES_LIBRARY})
SET(CARES_FOUND "YES")
ELSE (CARES_LIBRARY AND CARES_INCLUDE_DIR)
SET(CARES_FOUND "NO")
ENDIF (CARES_LIBRARY AND CARES_INCLUDE_DIR)
IF (CARES_FOUND)
IF (NOT CARES_FIND_QUIETLY)
MESSAGE(STATUS "Found c-ares: ${CARES_LIBRARIES}")
ENDIF (NOT CARES_FIND_QUIETLY)
ELSE (CARES_FOUND)
IF (CARES_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find c-ares library")
ENDIF (CARES_FIND_REQUIRED)
ENDIF (CARES_FOUND)
MARK_AS_ADVANCED(
CARES_LIBRARY
CARES_INCLUDE_DIR
)

View File

@@ -1,289 +0,0 @@
# - Try to find the GSS Kerberos library
# Once done this will define
#
# GSS_ROOT_DIR - Set this variable to the root installation of GSS
#
# Read-Only variables:
# GSS_FOUND - system has the Heimdal library
# GSS_FLAVOUR - "MIT" or "Heimdal" if anything found.
# GSS_INCLUDE_DIR - the Heimdal include directory
# GSS_LIBRARIES - The libraries needed to use GSS
# GSS_LINK_DIRECTORIES - Directories to add to linker search path
# GSS_LINKER_FLAGS - Additional linker flags
# GSS_COMPILER_FLAGS - Additional compiler flags
# GSS_VERSION - This is set to version advertised by pkg-config or read from manifest.
# In case the library is found but no version info availabe it'll be set to "unknown"
set(_MIT_MODNAME mit-krb5-gssapi)
set(_HEIMDAL_MODNAME heimdal-gssapi)
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckTypeSize)
set(_GSS_ROOT_HINTS
"${GSS_ROOT_DIR}"
"$ENV{GSS_ROOT_DIR}"
)
# try to find library using system pkg-config if user didn't specify root dir
if(NOT GSS_ROOT_DIR AND NOT "$ENV{GSS_ROOT_DIR}")
if(UNIX)
find_package(PkgConfig QUIET)
pkg_search_module(_GSS_PKG ${_MIT_MODNAME} ${_HEIMDAL_MODNAME})
list(APPEND _GSS_ROOT_HINTS "${_GSS_PKG_PREFIX}")
elseif(WIN32)
list(APPEND _GSS_ROOT_HINTS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos;InstallDir]")
endif()
endif()
if(NOT _GSS_FOUND) #not found by pkg-config. Let's take more traditional approach.
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
bin
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
)
# if not found in user-supplied directories, maybe system knows better
find_file(_GSS_CONFIGURE_SCRIPT
NAMES
"krb5-config"
PATH_SUFFIXES
bin
)
if(_GSS_CONFIGURE_SCRIPT)
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--cflags" "gssapi"
OUTPUT_VARIABLE _GSS_CFLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "CFLAGS: ${_GSS_CFLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# should also work in an odd case when multiple directories are given
string(STRIP "${_GSS_CFLAGS}" _GSS_CFLAGS)
string(REGEX REPLACE " +-I" ";" _GSS_CFLAGS "${_GSS_CFLAGS}")
string(REGEX REPLACE " +-([^I][^ \\t;]*)" ";-\\1"_GSS_CFLAGS "${_GSS_CFLAGS}")
foreach(_flag ${_GSS_CFLAGS})
if(_flag MATCHES "^-I.*")
string(REGEX REPLACE "^-I" "" _val "${_flag}")
list(APPEND _GSS_INCLUDE_DIR "${_val}")
else()
list(APPEND _GSS_COMPILER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--libs" "gssapi"
OUTPUT_VARIABLE _GSS_LIB_FLAGS
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
message(STATUS "LDFLAGS: ${_GSS_LIB_FLAGS}")
if(NOT _GSS_CONFIGURE_FAILED) # 0 means success
# this script gives us libraries and link directories. Blah. We have to deal with it.
string(STRIP "${_GSS_LIB_FLAGS}" _GSS_LIB_FLAGS)
string(REGEX REPLACE " +-(L|l)" ";-\\1" _GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
string(REGEX REPLACE " +-([^Ll][^ \\t;]*)" ";-\\1"_GSS_LIB_FLAGS "${_GSS_LIB_FLAGS}")
foreach(_flag ${_GSS_LIB_FLAGS})
if(_flag MATCHES "^-l.*")
string(REGEX REPLACE "^-l" "" _val "${_flag}")
list(APPEND _GSS_LIBRARIES "${_val}")
elseif(_flag MATCHES "^-L.*")
string(REGEX REPLACE "^-L" "" _val "${_flag}")
list(APPEND _GSS_LINK_DIRECTORIES "${_val}")
else()
list(APPEND _GSS_LINKER_FLAGS "${_flag}")
endif()
endforeach()
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--version"
OUTPUT_VARIABLE _GSS_VERSION
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--version" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(_GSS_VERSION 0)
endif()
execute_process(
COMMAND ${_GSS_CONFIGURE_SCRIPT} "--vendor"
OUTPUT_VARIABLE _GSS_VENDOR
RESULT_VARIABLE _GSS_CONFIGURE_FAILED
)
# older versions may not have the "--vendor" parameter. In this case we just don't care.
if(_GSS_CONFIGURE_FAILED)
set(GSS_FLAVOUR "Heimdal") # most probably, shouldn't really matter
else()
if(_GSS_VENDOR MATCHES ".*H|heimdal.*")
set(GSS_FLAVOUR "Heimdal")
else()
set(GSS_FLAVOUR "MIT")
endif()
endif()
else() # either there is no config script or we are on platform that doesn't provide one (Windows?)
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi/gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR) #jay, we've found something
set(CMAKE_REQUIRED_INCLUDES "${_GSS_INCLUDE_DIR}")
check_include_files( "gssapi/gssapi_generic.h;gssapi/gssapi_krb5.h" _GSS_HAVE_MIT_HEADERS)
if(_GSS_HAVE_MIT_HEADERS)
set(GSS_FLAVOUR "MIT")
else()
# prevent compiling the header - just check if we can include it
set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D__ROKEN_H__")
check_include_file( "roken.h" _GSS_HAVE_ROKEN_H)
check_include_file( "heimdal/roken.h" _GSS_HAVE_HEIMDAL_ROKEN_H)
if(_GSS_HAVE_ROKEN_H OR _GSS_HAVE_HEIMDAL_ROKEN_H)
set(GSS_FLAVOUR "Heimdal")
endif()
set(CMAKE_REQUIRED_DEFINITIONS "")
endif()
else()
# I'm not convienced if this is the right way but this is what autotools do at the moment
find_path(_GSS_INCLUDE_DIR
NAMES
"gssapi.h"
HINTS
${_GSS_ROOT_HINTS}
PATH_SUFFIXES
include
inc
)
if(_GSS_INCLUDE_DIR)
set(GSS_FLAVOUR "Heimdal")
endif()
endif()
# if we have headers, check if we can link libraries
if(GSS_FLAVOUR)
set(_GSS_LIBDIR_SUFFIXES "")
set(_GSS_LIBDIR_HINTS ${_GSS_ROOT_HINTS})
get_filename_component(_GSS_CALCULATED_POTENTIAL_ROOT "${_GSS_INCLUDE_DIR}" PATH)
list(APPEND _GSS_LIBDIR_HINTS ${_GSS_CALCULATED_POTENTIAL_ROOT})
if(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/AMD64")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi64")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib/i386")
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi32")
else()
set(_GSS_LIBNAME "libgssapi")
endif()
endif()
else()
list(APPEND _GSS_LIBDIR_SUFFIXES "lib;lib64") # those suffixes are not checked for HINTS
if(GSS_FLAVOUR STREQUAL "MIT")
set(_GSS_LIBNAME "gssapi_krb5")
else()
set(_GSS_LIBNAME "gssapi")
endif()
endif()
find_library(_GSS_LIBRARIES
NAMES
${_GSS_LIBNAME}
HINTS
${_GSS_LIBDIR_HINTS}
PATH_SUFFIXES
${_GSS_LIBDIR_SUFFIXES}
)
endif()
endif()
else()
if(_GSS_PKG_${_MIT_MODNAME}_VERSION)
set(GSS_FLAVOUR "MIT")
set(_GSS_VERSION _GSS_PKG_${_MIT_MODNAME}_VERSION)
else()
set(GSS_FLAVOUR "Heimdal")
set(_GSS_VERSION _GSS_PKG_${_MIT_HEIMDAL}_VERSION)
endif()
endif()
set(GSS_INCLUDE_DIR ${_GSS_INCLUDE_DIR})
set(GSS_LIBRARIES ${_GSS_LIBRARIES})
set(GSS_LINK_DIRECTORIES ${_GSS_LINK_DIRECTORIES})
set(GSS_LINKER_FLAGS ${_GSS_LINKER_FLAGS})
set(GSS_COMPILER_FLAGS ${_GSS_COMPILER_FLAGS})
set(GSS_VERSION ${_GSS_VERSION})
if(GSS_FLAVOUR)
if(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "Heimdal")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.amd64.manifest")
else()
set(HEIMDAL_MANIFEST_FILE "Heimdal.Application.x86.manifest")
endif()
if(EXISTS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}")
file(STRINGS "${GSS_INCLUDE_DIR}/${HEIMDAL_MANIFEST_FILE}" heimdal_version_str
REGEX "^.*version=\"[0-9]\\.[^\"]+\".*$")
string(REGEX MATCH "[0-9]\\.[^\"]+"
GSS_VERSION "${heimdal_version_str}")
endif()
if(NOT GSS_VERSION)
set(GSS_VERSION "Heimdal Unknown")
endif()
elseif(NOT GSS_VERSION AND GSS_FLAVOUR STREQUAL "MIT")
get_filename_component(_MIT_VERSION "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MIT\\Kerberos\\SDK\\CurrentVersion;VersionString]" NAME CACHE)
if(WIN32 AND _MIT_VERSION)
set(GSS_VERSION "${_MIT_VERSION}")
else()
set(GSS_VERSION "MIT Unknown")
endif()
endif()
endif()
include(FindPackageHandleStandardArgs)
set(_GSS_REQUIRED_VARS GSS_LIBRARIES GSS_FLAVOUR)
find_package_handle_standard_args(GSS
REQUIRED_VARS
${_GSS_REQUIRED_VARS}
VERSION_VAR
GSS_VERSION
FAIL_MESSAGE
"Could NOT find GSS, try to set the path to GSS root folder in the system variable GSS_ROOT_DIR"
)
mark_as_advanced(GSS_INCLUDE_DIR GSS_LIBRARIES)

View File

@@ -1,35 +0,0 @@
# - Try to find the libssh2 library
# Once done this will define
#
# LIBSSH2_FOUND - system has the libssh2 library
# LIBSSH2_INCLUDE_DIR - the libssh2 include directory
# LIBSSH2_LIBRARY - the libssh2 library name
if (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
set(LibSSH2_FIND_QUIETLY TRUE)
endif (LIBSSH2_INCLUDE_DIR AND LIBSSH2_LIBRARY)
FIND_PATH(LIBSSH2_INCLUDE_DIR libssh2.h
)
FIND_LIBRARY(LIBSSH2_LIBRARY NAMES ssh2
)
if(LIBSSH2_INCLUDE_DIR)
file(STRINGS "${LIBSSH2_INCLUDE_DIR}/libssh2.h" libssh2_version_str REGEX "^#define[\t ]+LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9][0-9][0-9].*")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MAJOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_MINOR "${libssh2_version_str}")
string(REGEX REPLACE "^.*LIBSSH2_VERSION_NUM[\t ]+0x[0-9][0-9][0-9][0-9]([0-9][0-9]).*$" "\\1" LIBSSH2_VERSION_PATCH "${libssh2_version_str}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MAJOR "${LIBSSH2_VERSION_MAJOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_MINOR "${LIBSSH2_VERSION_MINOR}")
string(REGEX REPLACE "^0(.+)" "\\1" LIBSSH2_VERSION_PATCH "${LIBSSH2_VERSION_PATCH}")
set(LIBSSH2_VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}")
endif(LIBSSH2_INCLUDE_DIR)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibSSH2 DEFAULT_MSG LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY )
MARK_AS_ADVANCED(LIBSSH2_INCLUDE_DIR LIBSSH2_LIBRARY LIBSSH2_VERSION_MAJOR LIBSSH2_VERSION_MINOR LIBSSH2_VERSION_PATCH LIBSSH2_VERSION)

View File

@@ -1,18 +0,0 @@
include(FindPackageHandleStandardArgs)
find_path(NGHTTP2_INCLUDE_DIR "nghttp2/nghttp2.h")
find_library(NGHTTP2_LIBRARY NAMES nghttp2)
find_package_handle_standard_args(NGHTTP2
FOUND_VAR
NGHTTP2_FOUND
REQUIRED_VARS
NGHTTP2_LIBRARY
NGHTTP2_INCLUDE_DIR
FAIL_MESSAGE
"Could NOT find NGHTTP2"
)
set(NGHTTP2_INCLUDE_DIRS ${NGHTTP2_INCLUDE_DIR} )
set(NGHTTP2_LIBRARIES ${NGHTTP2_LIBRARY})

View File

@@ -1,95 +0,0 @@
#File defines convenience macros for available feature testing
# This macro checks if the symbol exists in the library and if it
# does, it prepends library to the list. It is intended to be called
# multiple times with a sequence of possibly dependent libraries in
# order of least-to-most-dependent. Some libraries depend on others
# to link correctly.
macro(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE)
check_library_exists("${LIBRARY};${CURL_LIBS}" ${SYMBOL} "${CMAKE_LIBRARY_PATH}"
${VARIABLE})
if(${VARIABLE})
set(CURL_LIBS ${LIBRARY} ${CURL_LIBS})
endif(${VARIABLE})
endmacro(CHECK_LIBRARY_EXISTS_CONCAT)
# Check if header file exists and add it to the list.
# This macro is intended to be called multiple times with a sequence of
# possibly dependent header files. Some headers depend on others to be
# compiled correctly.
macro(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE)
check_include_files("${CURL_INCLUDES};${FILE}" ${VARIABLE})
if(${VARIABLE})
set(CURL_INCLUDES ${CURL_INCLUDES} ${FILE})
set(CURL_TEST_DEFINES "${CURL_TEST_DEFINES} -D${VARIABLE}")
endif(${VARIABLE})
endmacro(CHECK_INCLUDE_FILE_CONCAT)
# For other curl specific tests, use this macro.
macro(CURL_INTERNAL_TEST CURL_TEST)
if(NOT DEFINED "${CURL_TEST}")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CURL_TEST_DEFINES} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_compile(${CURL_TEST}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Curl Test ${CURL_TEST} passed with the following output:\n"
"${OUTPUT}\n")
else(${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}\n")
endif(${CURL_TEST})
endif()
endmacro(CURL_INTERNAL_TEST)
macro(CURL_INTERNAL_TEST_RUN CURL_TEST)
if(NOT DEFINED "${CURL_TEST}_COMPILE")
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-D${CURL_TEST} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LIBRARIES)
set(CURL_TEST_ADD_LIBRARIES
"-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}")
endif(CMAKE_REQUIRED_LIBRARIES)
message(STATUS "Performing Curl Test ${CURL_TEST}")
try_run(${CURL_TEST} ${CURL_TEST}_COMPILE
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/CMake/CurlTests.c
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
"${CURL_TEST_ADD_LIBRARIES}"
OUTPUT_VARIABLE OUTPUT)
if(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
set(${CURL_TEST} 1 CACHE INTERNAL "Curl test ${FUNCTION}")
message(STATUS "Performing Curl Test ${CURL_TEST} - Success")
else(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
message(STATUS "Performing Curl Test ${CURL_TEST} - Failed")
set(${CURL_TEST} "" CACHE INTERNAL "Curl test ${FUNCTION}")
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"Performing Curl Test ${CURL_TEST} failed with the following output:\n"
"${OUTPUT}")
if(${CURL_TEST}_COMPILE)
file(APPEND
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"There was a problem running this test\n")
endif(${CURL_TEST}_COMPILE)
file(APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log"
"\n\n")
endif(${CURL_TEST}_COMPILE AND NOT ${CURL_TEST})
endif()
endmacro(CURL_INTERNAL_TEST_RUN)

View File

@@ -1,232 +0,0 @@
include(CheckCSourceCompiles)
# The begin of the sources (macros and includes)
set(_source_epilogue "#undef inline")
macro(add_header_include check header)
if(${check})
set(_source_epilogue "${_source_epilogue}\n#include <${header}>")
endif(${check})
endmacro(add_header_include)
set(signature_call_conv)
if(HAVE_WINDOWS_H)
add_header_include(HAVE_WINSOCK2_H "winsock2.h")
add_header_include(HAVE_WINDOWS_H "windows.h")
add_header_include(HAVE_WINSOCK_H "winsock.h")
set(_source_epilogue
"${_source_epilogue}\n#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif")
set(signature_call_conv "PASCAL")
if(HAVE_LIBWS2_32)
set(CMAKE_REQUIRED_LIBRARIES ws2_32)
endif()
else(HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TYPES_H "sys/types.h")
add_header_include(HAVE_SYS_SOCKET_H "sys/socket.h")
endif(HAVE_WINDOWS_H)
check_c_source_compiles("${_source_epilogue}
int main(void) {
recv(0, 0, 0, 0);
return 0;
}" curl_cv_recv)
if(curl_cv_recv)
if(NOT DEFINED curl_cv_func_recv_args OR "${curl_cv_func_recv_args}" STREQUAL "unknown")
foreach(recv_retv "int" "ssize_t" )
foreach(recv_arg1 "int" "ssize_t" "SOCKET")
foreach(recv_arg2 "void *" "char *")
foreach(recv_arg3 "size_t" "int" "socklen_t" "unsigned int")
foreach(recv_arg4 "int" "unsigned int")
if(NOT curl_cv_func_recv_done)
unset(curl_cv_func_recv_test CACHE)
check_c_source_compiles("
${_source_epilogue}
extern ${recv_retv} ${signature_call_conv}
recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4});
int main(void) {
${recv_arg1} s=0;
${recv_arg2} buf=0;
${recv_arg3} len=0;
${recv_arg4} flags=0;
${recv_retv} res = recv(s, buf, len, flags);
(void) res;
return 0;
}"
curl_cv_func_recv_test)
message(STATUS
"Tested: ${recv_retv} recv(${recv_arg1}, ${recv_arg2}, ${recv_arg3}, ${recv_arg4})")
if(curl_cv_func_recv_test)
set(curl_cv_func_recv_args
"${recv_arg1},${recv_arg2},${recv_arg3},${recv_arg4},${recv_retv}")
set(RECV_TYPE_ARG1 "${recv_arg1}")
set(RECV_TYPE_ARG2 "${recv_arg2}")
set(RECV_TYPE_ARG3 "${recv_arg3}")
set(RECV_TYPE_ARG4 "${recv_arg4}")
set(RECV_TYPE_RETV "${recv_retv}")
set(HAVE_RECV 1)
set(curl_cv_func_recv_done 1)
endif(curl_cv_func_recv_test)
endif(NOT curl_cv_func_recv_done)
endforeach(recv_arg4)
endforeach(recv_arg3)
endforeach(recv_arg2)
endforeach(recv_arg1)
endforeach(recv_retv)
else()
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG1 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG2 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" RECV_TYPE_ARG3 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" RECV_TYPE_ARG4 "${curl_cv_func_recv_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" RECV_TYPE_RETV "${curl_cv_func_recv_args}")
endif()
if("${curl_cv_func_recv_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for recv args")
endif("${curl_cv_func_recv_args}" STREQUAL "unknown")
else(curl_cv_recv)
message(FATAL_ERROR "Unable to link function recv")
endif(curl_cv_recv)
set(curl_cv_func_recv_args "${curl_cv_func_recv_args}" CACHE INTERNAL "Arguments for recv")
set(HAVE_RECV 1)
check_c_source_compiles("${_source_epilogue}
int main(void) {
send(0, 0, 0, 0);
return 0;
}" curl_cv_send)
if(curl_cv_send)
if(NOT DEFINED curl_cv_func_send_args OR "${curl_cv_func_send_args}" STREQUAL "unknown")
foreach(send_retv "int" "ssize_t" )
foreach(send_arg1 "int" "ssize_t" "SOCKET")
foreach(send_arg2 "const void *" "void *" "char *" "const char *")
foreach(send_arg3 "size_t" "int" "socklen_t" "unsigned int")
foreach(send_arg4 "int" "unsigned int")
if(NOT curl_cv_func_send_done)
unset(curl_cv_func_send_test CACHE)
check_c_source_compiles("
${_source_epilogue}
extern ${send_retv} ${signature_call_conv}
send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4});
int main(void) {
${send_arg1} s=0;
${send_arg2} buf=0;
${send_arg3} len=0;
${send_arg4} flags=0;
${send_retv} res = send(s, buf, len, flags);
(void) res;
return 0;
}"
curl_cv_func_send_test)
message(STATUS
"Tested: ${send_retv} send(${send_arg1}, ${send_arg2}, ${send_arg3}, ${send_arg4})")
if(curl_cv_func_send_test)
string(REGEX REPLACE "(const) .*" "\\1" send_qual_arg2 "${send_arg2}")
string(REGEX REPLACE "const (.*)" "\\1" send_arg2 "${send_arg2}")
set(curl_cv_func_send_args
"${send_arg1},${send_arg2},${send_arg3},${send_arg4},${send_retv},${send_qual_arg2}")
set(SEND_TYPE_ARG1 "${send_arg1}")
set(SEND_TYPE_ARG2 "${send_arg2}")
set(SEND_TYPE_ARG3 "${send_arg3}")
set(SEND_TYPE_ARG4 "${send_arg4}")
set(SEND_TYPE_RETV "${send_retv}")
set(HAVE_SEND 1)
set(curl_cv_func_send_done 1)
endif(curl_cv_func_send_test)
endif(NOT curl_cv_func_send_done)
endforeach(send_arg4)
endforeach(send_arg3)
endforeach(send_arg2)
endforeach(send_arg1)
endforeach(send_retv)
else()
string(REGEX REPLACE "^([^,]*),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG1 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,([^,]*),[^,]*,[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG2 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,([^,]*),[^,]*,[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG3 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,([^,]*),[^,]*,[^,]*$" "\\1" SEND_TYPE_ARG4 "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$" "\\1" SEND_TYPE_RETV "${curl_cv_func_send_args}")
string(REGEX REPLACE "^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,([^,]*)$" "\\1" SEND_QUAL_ARG2 "${curl_cv_func_send_args}")
endif()
if("${curl_cv_func_send_args}" STREQUAL "unknown")
message(FATAL_ERROR "Cannot find proper types to use for send args")
endif("${curl_cv_func_send_args}" STREQUAL "unknown")
set(SEND_QUAL_ARG2 "const")
else(curl_cv_send)
message(FATAL_ERROR "Unable to link function send")
endif(curl_cv_send)
set(curl_cv_func_send_args "${curl_cv_func_send_args}" CACHE INTERNAL "Arguments for send")
set(HAVE_SEND 1)
check_c_source_compiles("${_source_epilogue}
int main(void) {
int flag = MSG_NOSIGNAL;
(void)flag;
return 0;
}" HAVE_MSG_NOSIGNAL)
if(NOT HAVE_WINDOWS_H)
add_header_include(HAVE_SYS_TIME_H "sys/time.h")
add_header_include(TIME_WITH_SYS_TIME "time.h")
add_header_include(HAVE_TIME_H "time.h")
endif()
check_c_source_compiles("${_source_epilogue}
int main(void) {
struct timeval ts;
ts.tv_sec = 0;
ts.tv_usec = 0;
(void)ts;
return 0;
}" HAVE_STRUCT_TIMEVAL)
include(CheckCSourceRuns)
# See HAVE_POLL in CMakeLists.txt for why poll is disabled on macOS
if(NOT APPLE)
set(CMAKE_REQUIRED_FLAGS)
if(HAVE_SYS_POLL_H)
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SYS_POLL_H")
endif(HAVE_SYS_POLL_H)
check_c_source_runs("
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
int main(void) {
return poll((void *)0, 0, 10 /*ms*/);
}" HAVE_POLL_FINE)
endif()
set(HAVE_SIG_ATOMIC_T 1)
set(CMAKE_REQUIRED_FLAGS)
if(HAVE_SIGNAL_H)
set(CMAKE_REQUIRED_FLAGS "-DHAVE_SIGNAL_H")
set(CMAKE_EXTRA_INCLUDE_FILES "signal.h")
endif(HAVE_SIGNAL_H)
check_type_size("sig_atomic_t" SIZEOF_SIG_ATOMIC_T)
if(HAVE_SIZEOF_SIG_ATOMIC_T)
check_c_source_compiles("
#ifdef HAVE_SIGNAL_H
# include <signal.h>
#endif
int main(void) {
static volatile sig_atomic_t dummy = 0;
(void)dummy;
return 0;
}" HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
if(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
set(HAVE_SIG_ATOMIC_T_VOLATILE 1)
endif(NOT HAVE_SIG_ATOMIC_T_NOT_VOLATILE)
endif(HAVE_SIZEOF_SIG_ATOMIC_T)
if(HAVE_WINDOWS_H)
set(CMAKE_EXTRA_INCLUDE_FILES winsock2.h)
else()
set(CMAKE_EXTRA_INCLUDE_FILES)
if(HAVE_SYS_SOCKET_H)
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
endif(HAVE_SYS_SOCKET_H)
endif()
check_type_size("struct sockaddr_storage" SIZEOF_STRUCT_SOCKADDR_STORAGE)
if(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)
set(HAVE_STRUCT_SOCKADDR_STORAGE 1)
endif(HAVE_SIZEOF_STRUCT_SOCKADDR_STORAGE)

View File

@@ -1,125 +0,0 @@
if(NOT UNIX)
if(WIN32)
set(HAVE_LIBDL 0)
set(HAVE_LIBUCB 0)
set(HAVE_LIBSOCKET 0)
set(NOT_NEED_LIBNSL 0)
set(HAVE_LIBNSL 0)
set(HAVE_GETHOSTNAME 1)
set(HAVE_LIBZ 0)
set(HAVE_LIBCRYPTO 0)
set(HAVE_DLOPEN 0)
set(HAVE_ALLOCA_H 0)
set(HAVE_ARPA_INET_H 0)
set(HAVE_DLFCN_H 0)
set(HAVE_FCNTL_H 1)
set(HAVE_INTTYPES_H 0)
set(HAVE_IO_H 1)
set(HAVE_MALLOC_H 1)
set(HAVE_MEMORY_H 1)
set(HAVE_NETDB_H 0)
set(HAVE_NETINET_IF_ETHER_H 0)
set(HAVE_NETINET_IN_H 0)
set(HAVE_NET_IF_H 0)
set(HAVE_PROCESS_H 1)
set(HAVE_PWD_H 0)
set(HAVE_SETJMP_H 1)
set(HAVE_SGTTY_H 0)
set(HAVE_SIGNAL_H 1)
set(HAVE_SOCKIO_H 0)
set(HAVE_STDINT_H 0)
set(HAVE_STDLIB_H 1)
set(HAVE_STRINGS_H 0)
set(HAVE_STRING_H 1)
set(HAVE_SYS_PARAM_H 0)
set(HAVE_SYS_POLL_H 0)
set(HAVE_SYS_SELECT_H 0)
set(HAVE_SYS_SOCKET_H 0)
set(HAVE_SYS_SOCKIO_H 0)
set(HAVE_SYS_STAT_H 1)
set(HAVE_SYS_TIME_H 0)
set(HAVE_SYS_TYPES_H 1)
set(HAVE_SYS_UTIME_H 1)
set(HAVE_TERMIOS_H 0)
set(HAVE_TERMIO_H 0)
set(HAVE_TIME_H 1)
set(HAVE_UNISTD_H 0)
set(HAVE_UTIME_H 0)
set(HAVE_X509_H 0)
set(HAVE_ZLIB_H 0)
set(HAVE_SIZEOF_LONG_DOUBLE 1)
set(SIZEOF_LONG_DOUBLE 8)
set(HAVE_SOCKET 1)
set(HAVE_POLL 0)
set(HAVE_SELECT 1)
set(HAVE_STRDUP 1)
set(HAVE_STRSTR 1)
set(HAVE_STRTOK_R 0)
set(HAVE_STRFTIME 1)
set(HAVE_UNAME 0)
set(HAVE_STRCASECMP 0)
set(HAVE_STRICMP 1)
set(HAVE_STRCMPI 1)
set(HAVE_GETHOSTBYADDR 1)
set(HAVE_GETTIMEOFDAY 0)
set(HAVE_INET_ADDR 1)
set(HAVE_INET_NTOA 1)
set(HAVE_INET_NTOA_R 0)
set(HAVE_TCGETATTR 0)
set(HAVE_TCSETATTR 0)
set(HAVE_PERROR 1)
set(HAVE_CLOSESOCKET 1)
set(HAVE_SETVBUF 0)
set(HAVE_SIGSETJMP 0)
set(HAVE_GETPASS_R 0)
set(HAVE_STRLCAT 0)
set(HAVE_GETPWUID 0)
set(HAVE_GETEUID 0)
set(HAVE_UTIME 1)
set(HAVE_RAND_EGD 0)
set(HAVE_RAND_SCREEN 0)
set(HAVE_RAND_STATUS 0)
set(HAVE_GMTIME_R 0)
set(HAVE_LOCALTIME_R 0)
set(HAVE_GETHOSTBYADDR_R 0)
set(HAVE_GETHOSTBYNAME_R 0)
set(HAVE_SIGNAL_FUNC 1)
set(HAVE_SIGNAL_MACRO 0)
set(HAVE_GETHOSTBYADDR_R_5 0)
set(HAVE_GETHOSTBYADDR_R_5_REENTRANT 0)
set(HAVE_GETHOSTBYADDR_R_7 0)
set(HAVE_GETHOSTBYADDR_R_7_REENTRANT 0)
set(HAVE_GETHOSTBYADDR_R_8 0)
set(HAVE_GETHOSTBYADDR_R_8_REENTRANT 0)
set(HAVE_GETHOSTBYNAME_R_3 0)
set(HAVE_GETHOSTBYNAME_R_3_REENTRANT 0)
set(HAVE_GETHOSTBYNAME_R_5 0)
set(HAVE_GETHOSTBYNAME_R_5_REENTRANT 0)
set(HAVE_GETHOSTBYNAME_R_6 0)
set(HAVE_GETHOSTBYNAME_R_6_REENTRANT 0)
set(TIME_WITH_SYS_TIME 0)
set(HAVE_O_NONBLOCK 0)
set(HAVE_IN_ADDR_T 0)
set(HAVE_INET_NTOA_R_DECL 0)
set(HAVE_INET_NTOA_R_DECL_REENTRANT 0)
if(ENABLE_IPV6)
set(HAVE_GETADDRINFO 1)
else()
set(HAVE_GETADDRINFO 0)
endif()
set(STDC_HEADERS 1)
set(RETSIGTYPE_TEST 1)
set(HAVE_SIGACTION 0)
set(HAVE_MACRO_SIGSETJMP 0)
else(WIN32)
message("This file should be included on Windows platform only")
endif(WIN32)
endif(NOT UNIX)

View File

@@ -1,31 +0,0 @@
# File containing various utilities
# Converts a CMake list to a string containing elements separated by spaces
function(TO_LIST_SPACES _LIST_NAME OUTPUT_VAR)
set(NEW_LIST_SPACE)
foreach(ITEM ${${_LIST_NAME}})
set(NEW_LIST_SPACE "${NEW_LIST_SPACE} ${ITEM}")
endforeach()
string(STRIP ${NEW_LIST_SPACE} NEW_LIST_SPACE)
set(${OUTPUT_VAR} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Appends a lis of item to a string which is a space-separated list, if they don't already exist.
function(LIST_SPACES_APPEND_ONCE LIST_NAME)
string(REPLACE " " ";" _LIST ${${LIST_NAME}})
list(APPEND _LIST ${ARGN})
list(REMOVE_DUPLICATES _LIST)
to_list_spaces(_LIST NEW_LIST_SPACE)
set(${LIST_NAME} "${NEW_LIST_SPACE}" PARENT_SCOPE)
endfunction()
# Convinience function that does the same as LIST(FIND ...) but with a TRUE/FALSE return value.
# Ex: IN_STR_LIST(MY_LIST "Searched item" WAS_FOUND)
function(IN_STR_LIST LIST_NAME ITEM_SEARCHED RETVAL)
list(FIND ${LIST_NAME} ${ITEM_SEARCHED} FIND_POS)
if(${FIND_POS} EQUAL -1)
set(${RETVAL} FALSE PARENT_SCOPE)
else()
set(${RETVAL} TRUE PARENT_SCOPE)
endif()
endfunction()

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +0,0 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2016, Daniel Stenberg, <daniel@haxx.se>, and many
contributors, see the THANKS file.
All rights reserved.
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization of the copyright holder.

View File

@@ -1,146 +0,0 @@
#!/bin/bash
# This script performs all of the steps needed to build a
# universal binary libcurl.framework for Mac OS X 10.4 or greater.
#
# Hendrik Visage:
# Generalizations added since Snowleopard (10.6) do not include
# the 10.4u SDK.
#
# Also note:
# 10.5 is the *ONLY* SDK that support PPC64 :( -- 10.6 do not have ppc64 support
#If you need to have PPC64 support then change below to 1
PPC64_NEEDED=0
# Apple does not support building for PPC anymore in Xcode 4 and later.
# If you're using Xcode 3 or earlier and need PPC support, then change
# the setting below to 1
PPC_NEEDED=0
# For me the default is to develop for the platform I am on, and if you
#desire compatibility with older versions then change USE_OLD to 1 :)
USE_OLD=0
VERSION=`/usr/bin/sed -ne 's/^#define LIBCURL_VERSION "\(.*\)"/\1/p' include/curl/curlver.h`
FRAMEWORK_VERSION=Versions/Release-$VERSION
#I also wanted to "copy over" the system, and thus the reason I added the
# version to Versions/Release-7.20.1 etc.
# now a simple rsync -vaP libcurl.framework /Library/Frameworks will install it
# and setup the right paths to this version, leaving the system version
# "intact", so you can "fix" it later with the links to Versions/A/...
DEVELOPER_PATH=`xcode-select --print-path`
# Around Xcode 4.3, SDKs were moved from the Developer folder into the
# MacOSX.platform folder
if test -d "$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs"; then
SDK_PATH="$DEVELOPER_PATH/Platforms/MacOSX.platform/Developer/SDKs"
else
SDK_PATH="$DEVELOPER_PATH/SDKs";
fi
OLD_SDK=`ls $SDK_PATH|head -1`
NEW_SDK=`ls -r $SDK_PATH|head -1`
if test "0"$USE_OLD -gt 0
then
SDK32=$OLD_SDK
else
SDK32=$NEW_SDK
fi
MACVER=`echo $SDK32|sed -e s/[a-zA-Z]//g -e s/.\$//`
SDK32_DIR=$SDK_PATH/$SDK32
MINVER32='-mmacosx-version-min='$MACVER
if test $PPC_NEEDED -gt 0; then
ARCHES32='-arch i386 -arch ppc'
else
ARCHES32='-arch i386'
fi
if test $PPC64_NEEDED -gt 0
then
SDK64=10.5
ARCHES64='-arch x86_64 -arch ppc64'
SDK64=`ls $SDK_PATH|grep 10.5|head -1`
else
ARCHES64='-arch x86_64'
#We "know" that 10.4 and earlier do not support 64bit
OLD_SDK64=`ls $SDK_PATH|egrep -v "10.[0-4]"|head -1`
NEW_SDK64=`ls -r $SDK_PATH|egrep -v "10.[0-4][^0-9]" | head -1`
if test $USE_OLD -gt 0
then
SDK64=$OLD_SDK64
else
SDK64=$NEW_SDK64
fi
fi
SDK64_DIR=$SDK_PATH/$SDK64
MACVER64=`echo $SDK64|sed -e s/[a-zA-Z]//g -e s/.\$//`
MINVER64='-mmacosx-version-min='$MACVER64
if test ! -z $SDK32; then
echo "----Configuring libcurl for 32 bit universal framework..."
make clean
./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \
CFLAGS="-Os -isysroot $SDK32_DIR $ARCHES32" \
LDFLAGS="-Wl,-syslibroot,$SDK32_DIR $ARCHES32 -Wl,-headerpad_max_install_names" \
CC=$CC
echo "----Building 32 bit libcurl..."
make -j `sysctl -n hw.logicalcpu_max`
echo "----Creating 32 bit framework..."
rm -r libcurl.framework
mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Resources
cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl
install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl
/usr/bin/sed -e "s/7\.12\.3/$VERSION/" lib/libcurl.plist >libcurl.framework/${FRAMEWORK_VERSION}/Resources/Info.plist
mkdir -p libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl
cp include/curl/*.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl
pushd libcurl.framework
ln -fs ${FRAMEWORK_VERSION}/libcurl libcurl
ln -fs ${FRAMEWORK_VERSION}/Resources Resources
ln -fs ${FRAMEWORK_VERSION}/Headers Headers
cd Versions
ln -fs $(basename "${FRAMEWORK_VERSION}") Current
echo Testing for SDK64
if test -d $SDK64_DIR; then
echo entering...
popd
make clean
echo "----Configuring libcurl for 64 bit universal framework..."
./configure --disable-dependency-tracking --disable-static --with-gssapi --with-darwinssl \
CFLAGS="-Os -isysroot $SDK64_DIR $ARCHES64" \
LDFLAGS="-Wl,-syslibroot,$SDK64_DIR $ARCHES64 -Wl,-headerpad_max_install_names" \
CC=$CC
echo "----Building 64 bit libcurl..."
make -j `sysctl -n hw.logicalcpu_max`
echo "----Appending 64 bit framework to 32 bit framework..."
cp lib/.libs/libcurl.dylib libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
install_name_tool -id @rpath/libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
cp libcurl.framework/${FRAMEWORK_VERSION}/libcurl libcurl.framework/${FRAMEWORK_VERSION}/libcurl32
pwd
lipo libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64 -create -output libcurl.framework/${FRAMEWORK_VERSION}/libcurl
rm libcurl.framework/${FRAMEWORK_VERSION}/libcurl32 libcurl.framework/${FRAMEWORK_VERSION}/libcurl64
cp libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild32.h
cp include/curl/curlbuild.h libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild64.h
cat >libcurl.framework/${FRAMEWORK_VERSION}/Headers/curl/curlbuild.h <<EOF
#ifdef __LP64__
#include "curl/curlbuild64.h"
#else
#include "curl/curlbuild32.h"
#endif
EOF
fi
pwd
lipo -info libcurl.framework/${FRAMEWORK_VERSION}/libcurl
echo "libcurl.framework is built and can now be included in other projects."
echo "Copy libcurl.framework to your bundle's Contents/Frameworks folder, ~/Library/Frameworks or /Library/Frameworks."
else
echo "Building libcurl.framework requires Mac OS X 10.4 or later with the MacOSX10.4/5/6 SDK installed."
fi

View File

@@ -1,586 +0,0 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
VC=vc6
all:
./configure
make
ssl:
./configure --with-ssl
make
borland:
cd lib
$(MAKE) -f Makefile.b32
cd ..\src
$(MAKE) -f Makefile.b32
borland-ssl:
cd lib
$(MAKE) -f Makefile.b32 WITH_SSL=1
cd ..\src
$(MAKE) -f Makefile.b32 WITH_SSL=1
borland-ssl-zlib:
cd lib
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
cd ..\src
$(MAKE) -f Makefile.b32 WITH_SSL=1 WITH_ZLIB=1
borland-clean:
cd lib
$(MAKE) -f Makefile.b32 clean
cd ..\src
$(MAKE) -f Makefile.b32 clean
watcom: .SYMBOLIC
cd lib && $(MAKE) -u -f Makefile.Watcom
cd src && $(MAKE) -u -f Makefile.Watcom
watcom-clean: .SYMBOLIC
cd lib && $(MAKE) -u -f Makefile.Watcom clean
cd src && $(MAKE) -u -f Makefile.Watcom clean
watcom-vclean: .SYMBOLIC
cd lib && $(MAKE) -u -f Makefile.Watcom vclean
cd src && $(MAKE) -u -f Makefile.Watcom vclean
mingw32:
$(MAKE) -C lib -f Makefile.m32
$(MAKE) -C src -f Makefile.m32
mingw32-clean:
$(MAKE) -C lib -f Makefile.m32 clean
$(MAKE) -C src -f Makefile.m32 clean
$(MAKE) -C docs/examples -f Makefile.m32 clean
mingw32-vclean mingw32-distclean:
$(MAKE) -C lib -f Makefile.m32 vclean
$(MAKE) -C src -f Makefile.m32 vclean
$(MAKE) -C docs/examples -f Makefile.m32 vclean
mingw32-examples%:
$(MAKE) -C docs/examples -f Makefile.m32 CFG=$@
mingw32%:
$(MAKE) -C lib -f Makefile.m32 CFG=$@
$(MAKE) -C src -f Makefile.m32 CFG=$@
vc-clean: $(VC)
cd lib
nmake -f Makefile.$(VC) clean
cd ..\src
nmake -f Makefile.$(VC) clean
vc-all: $(VC)
cd lib
nmake -f Makefile.$(VC) cfg=release
nmake -f Makefile.$(VC) cfg=release-ssl
nmake -f Makefile.$(VC) cfg=release-zlib
nmake -f Makefile.$(VC) cfg=release-ssl-zlib
nmake -f Makefile.$(VC) cfg=release-ssl-dll
nmake -f Makefile.$(VC) cfg=release-zlib-dll
nmake -f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
nmake -f Makefile.$(VC) cfg=release-dll
nmake -f Makefile.$(VC) cfg=release-dll-ssl-dll
nmake -f Makefile.$(VC) cfg=release-dll-zlib-dll
nmake -f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
nmake -f Makefile.$(VC) cfg=debug
nmake -f Makefile.$(VC) cfg=debug-ssl
nmake -f Makefile.$(VC) cfg=debug-zlib
nmake -f Makefile.$(VC) cfg=debug-ssl-zlib
nmake -f Makefile.$(VC) cfg=debug-ssl-dll
nmake -f Makefile.$(VC) cfg=debug-zlib-dll
nmake -f Makefile.$(VC) cfg=debug-ssl-dll-zlib-dll
nmake -f Makefile.$(VC) cfg=debug-dll
nmake -f Makefile.$(VC) cfg=debug-dll-ssl-dll
nmake -f Makefile.$(VC) cfg=debug-dll-zlib-dll
nmake -f Makefile.$(VC) cfg=debug-dll-ssl-dll-zlib-dll
vc: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release
cd ..\src
nmake /f Makefile.$(VC)
vc-x64: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release
vc-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release WINDOWS_SSPI=1
vc-x64-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release WINDOWS_SSPI=1
vc-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release USE_IDN=1
vc-x64-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1
vc-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release USE_IDN=1 WINDOWS_SSPI=1
vc-x64-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release USE_IDN=1 WINDOWS_SSPI=1
vc-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-zlib
vc-x64-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib
vc-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-zlib WINDOWS_SSPI=1
vc-x64-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib WINDOWS_SSPI=1
vc-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1
vc-x64-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1
vc-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-x64-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-ssl: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl
vc-x64-ssl: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl
vc-ssl-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl WINDOWS_SSPI=1
vc-x64-ssl-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl WINDOWS_SSPI=1
vc-ssl-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1
vc-x64-ssl-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1
vc-ssl-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
vc-x64-ssl-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl USE_IDN=1 WINDOWS_SSPI=1
vc-ssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib
vc-x64-ssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib
vc-ssl-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib WINDOWS_SSPI=1
vc-x64-ssl-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib WINDOWS_SSPI=1
vc-ssl-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1
vc-x64-ssl-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1
vc-ssl-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-x64-ssl-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-ssl-ssh2-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib
vc-x64-ssl-ssh2-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib
vc-ssl-ssh2-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
vc-x64-ssl-ssh2-zlib-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib WINDOWS_SSPI=1
vc-ssl-ssh2-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1
vc-x64-ssl-ssh2-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1
vc-ssl-ssh2-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-x64-ssl-ssh2-zlib-idn-sspi: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-ssl-ssh2-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-winssl: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl WINDOWS_SSPI=1
vc-x64-winssl: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl WINDOWS_SSPI=1
vc-winssl-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
vc-x64-winssl-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl USE_IDN=1 WINDOWS_SSPI=1
vc-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl-zlib WINDOWS_SSPI=1
vc-x64-winssl-zlib: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib WINDOWS_SSPI=1
vc-winssl-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-x64-winssl-zlib-idn: $(VC)
cd lib
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
cd ..\src
nmake /f Makefile.$(VC) MACHINE=x64 cfg=release-winssl-zlib USE_IDN=1 WINDOWS_SSPI=1
vc-ssl-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-dll
vc-dll-ssl-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll
vc-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-dll
vc-dll-zlib-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-dll-zlib-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-dll-zlib-dll
vc-dll-ssl-dll-zlib-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-dll-ssl-dll-zlib-dll
vc-ssl-dll-zlib-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-ssl-dll-zlib-dll
vc-zlib-dll: $(VC)
cd lib
nmake /f Makefile.$(VC) cfg=release-zlib-dll
cd ..\src
nmake /f Makefile.$(VC) cfg=release-zlib-dll
djgpp:
$(MAKE) -C lib -f Makefile.dj
$(MAKE) -C src -f Makefile.dj
cygwin:
./configure
make
cygwin-ssl:
./configure --with-ssl
make
amiga:
cd ./lib && make -f makefile.amiga
cd ./src && make -f makefile.amiga
netware:
$(MAKE) -C lib -f Makefile.netware
$(MAKE) -C src -f Makefile.netware
netware-clean:
$(MAKE) -C lib -f Makefile.netware clean
$(MAKE) -C src -f Makefile.netware clean
$(MAKE) -C docs/examples -f Makefile.netware clean
netware-vclean netware-distclean:
$(MAKE) -C lib -f Makefile.netware vclean
$(MAKE) -C src -f Makefile.netware vclean
$(MAKE) -C docs/examples -f Makefile.netware vclean
netware-install:
$(MAKE) -C lib -f Makefile.netware install
$(MAKE) -C src -f Makefile.netware install
netware-examples-%:
$(MAKE) -C docs/examples -f Makefile.netware CFG=$@
netware-%:
$(MAKE) -C lib -f Makefile.netware CFG=$@
$(MAKE) -C src -f Makefile.netware CFG=$@
unix: all
unix-ssl: ssl
linux: all
linux-ssl: ssl
# We don't need to do anything for vc6.
vc6:
# VC7 makefiles are for use with VS.NET and VS.NET 2003
vc7: lib/Makefile.vc7 src/Makefile.vc7
lib/Makefile.vc7: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s/VC6/VC7/g" lib/Makefile.vc6 > lib/Makefile.vc7
src/Makefile.vc7: src/Makefile.vc6
@echo "generate $@"
@sed -e "s/VC6/VC7/g" src/Makefile.vc6 > src/Makefile.vc7
# VC8 makefiles are for use with VS2005
vc8: lib/Makefile.vc8 src/Makefile.vc8
lib/Makefile.vc8: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" lib/Makefile.vc6 > lib/Makefile.vc8
src/Makefile.vc8: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib bufferoverflowu.lib/g" -e "s/VC6/VC8/g" src/Makefile.vc6 > src/Makefile.vc8
# VC9 makefiles are for use with VS2008
vc9: lib/Makefile.vc9 src/Makefile.vc9
lib/Makefile.vc9: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" lib/Makefile.vc6 > lib/Makefile.vc9
src/Makefile.vc9: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc9/g" -e "s/VC6/VC9/g" src/Makefile.vc6 > src/Makefile.vc9
# VC10 makefiles are for use with VS2010
vc10: lib/Makefile.vc10 src/Makefile.vc10
lib/Makefile.vc10: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc10/g" -e "s/VC6/VC10/g" lib/Makefile.vc6 > lib/Makefile.vc10
src/Makefile.vc10: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc10/g" -e "s/VC6/VC10/g" src/Makefile.vc6 > src/Makefile.vc10
# VC11 makefiles are for use with VS2012
vc11: lib/Makefile.vc11 src/Makefile.vc11
lib/Makefile.vc11: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc11/g" -e "s/VC6/VC11/g" lib/Makefile.vc6 > lib/Makefile.vc11
src/Makefile.vc11: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc11/g" -e "s/VC6/VC11/g" src/Makefile.vc6 > src/Makefile.vc11
# VC12 makefiles are for use with VS2013
vc12: lib/Makefile.vc12 src/Makefile.vc12
lib/Makefile.vc12: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc12/g" -e "s/VC6/VC12/g" lib/Makefile.vc6 > lib/Makefile.vc12
src/Makefile.vc12: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc12/g" -e "s/VC6/VC12/g" src/Makefile.vc6 > src/Makefile.vc12
# VC14 makefiles are for use with VS2015
vc14: lib/Makefile.vc14 src/Makefile.vc14
lib/Makefile.vc14: lib/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc14/g" -e "s/VC6/VC14/g" lib/Makefile.vc6 > lib/Makefile.vc14
src/Makefile.vc14: src/Makefile.vc6
@echo "generate $@"
@sed -e "s#/GX /DWIN32 /YX#/EHsc /DWIN32#" -e "s#/GZ#/RTC1#" -e "s/ws2_32.lib/ws2_32.lib/g" -e "s/vc6/vc14/g" -e "s/VC6/VC14/g" src/Makefile.vc6 > src/Makefile.vc14
ca-bundle: lib/mk-ca-bundle.pl
@echo "generate a fresh ca-bundle.crt"
@perl $< -b -l -u lib/ca-bundle.crt
ca-firefox: lib/firefox-db2pem.sh
@echo "generate a fresh ca-bundle.crt"
./lib/firefox-db2pem.sh lib/ca-bundle.crt

View File

@@ -1,609 +0,0 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
CMAKE_DIST = CMakeLists.txt CMake/CMakeConfigurableFile.in \
CMake/CurlTests.c CMake/FindGSS.cmake CMake/OtherTests.cmake \
CMake/Platforms/WindowsCache.cmake CMake/Utilities.cmake \
include/curl/curlbuild.h.cmake CMake/Macros.cmake \
CMake/CurlSymbolHiding.cmake CMake/FindCARES.cmake \
CMake/FindLibSSH2.cmake CMake/FindNGHTTP2.cmake
VC6_LIBTMPL = projects/Windows/VC6/lib/libcurl.tmpl
VC6_LIBDSP = projects/Windows/VC6/lib/libcurl.dsp.dist
VC6_LIBDSP_DEPS = $(VC6_LIBTMPL) Makefile.am lib/Makefile.inc
VC6_SRCTMPL = projects/Windows/VC6/src/curl.tmpl
VC6_SRCDSP = projects/Windows/VC6/src/curl.dsp.dist
VC6_SRCDSP_DEPS = $(VC6_SRCTMPL) Makefile.am src/Makefile.inc
VC7_LIBTMPL = projects/Windows/VC7/lib/libcurl.tmpl
VC7_LIBVCPROJ = projects/Windows/VC7/lib/libcurl.vcproj.dist
VC7_LIBVCPROJ_DEPS = $(VC7_LIBTMPL) Makefile.am lib/Makefile.inc
VC7_SRCTMPL = projects/Windows/VC7/src/curl.tmpl
VC7_SRCVCPROJ = projects/Windows/VC7/src/curl.vcproj.dist
VC7_SRCVCPROJ_DEPS = $(VC7_SRCTMPL) Makefile.am src/Makefile.inc
VC71_LIBTMPL = projects/Windows/VC7.1/lib/libcurl.tmpl
VC71_LIBVCPROJ = projects/Windows/VC7.1/lib/libcurl.vcproj.dist
VC71_LIBVCPROJ_DEPS = $(VC71_LIBTMPL) Makefile.am lib/Makefile.inc
VC71_SRCTMPL = projects/Windows/VC7.1/src/curl.tmpl
VC71_SRCVCPROJ = projects/Windows/VC7.1/src/curl.vcproj.dist
VC71_SRCVCPROJ_DEPS = $(VC71_SRCTMPL) Makefile.am src/Makefile.inc
VC8_LIBTMPL = projects/Windows/VC8/lib/libcurl.tmpl
VC8_LIBVCPROJ = projects/Windows/VC8/lib/libcurl.vcproj.dist
VC8_LIBVCPROJ_DEPS = $(VC8_LIBTMPL) Makefile.am lib/Makefile.inc
VC8_SRCTMPL = projects/Windows/VC8/src/curl.tmpl
VC8_SRCVCPROJ = projects/Windows/VC8/src/curl.vcproj.dist
VC8_SRCVCPROJ_DEPS = $(VC8_SRCTMPL) Makefile.am src/Makefile.inc
VC9_LIBTMPL = projects/Windows/VC9/lib/libcurl.tmpl
VC9_LIBVCPROJ = projects/Windows/VC9/lib/libcurl.vcproj.dist
VC9_LIBVCPROJ_DEPS = $(VC9_LIBTMPL) Makefile.am lib/Makefile.inc
VC9_SRCTMPL = projects/Windows/VC9/src/curl.tmpl
VC9_SRCVCPROJ = projects/Windows/VC9/src/curl.vcproj.dist
VC9_SRCVCPROJ_DEPS = $(VC9_SRCTMPL) Makefile.am src/Makefile.inc
VC10_LIBTMPL = projects/Windows/VC10/lib/libcurl.tmpl
VC10_LIBVCXPROJ = projects/Windows/VC10/lib/libcurl.vcxproj.dist
VC10_LIBVCXPROJ_DEPS = $(VC10_LIBTMPL) Makefile.am lib/Makefile.inc
VC10_SRCTMPL = projects/Windows/VC10/src/curl.tmpl
VC10_SRCVCXPROJ = projects/Windows/VC10/src/curl.vcxproj.dist
VC10_SRCVCXPROJ_DEPS = $(VC10_SRCTMPL) Makefile.am src/Makefile.inc
VC11_LIBTMPL = projects/Windows/VC11/lib/libcurl.tmpl
VC11_LIBVCXPROJ = projects/Windows/VC11/lib/libcurl.vcxproj.dist
VC11_LIBVCXPROJ_DEPS = $(VC11_LIBTMPL) Makefile.am lib/Makefile.inc
VC11_SRCTMPL = projects/Windows/VC11/src/curl.tmpl
VC11_SRCVCXPROJ = projects/Windows/VC11/src/curl.vcxproj.dist
VC11_SRCVCXPROJ_DEPS = $(VC11_SRCTMPL) Makefile.am src/Makefile.inc
VC12_LIBTMPL = projects/Windows/VC12/lib/libcurl.tmpl
VC12_LIBVCXPROJ = projects/Windows/VC12/lib/libcurl.vcxproj.dist
VC12_LIBVCXPROJ_DEPS = $(VC12_LIBTMPL) Makefile.am lib/Makefile.inc
VC12_SRCTMPL = projects/Windows/VC12/src/curl.tmpl
VC12_SRCVCXPROJ = projects/Windows/VC12/src/curl.vcxproj.dist
VC12_SRCVCXPROJ_DEPS = $(VC12_SRCTMPL) Makefile.am src/Makefile.inc
VC14_LIBTMPL = projects/Windows/VC14/lib/libcurl.tmpl
VC14_LIBVCXPROJ = projects/Windows/VC14/lib/libcurl.vcxproj.dist
VC14_LIBVCXPROJ_DEPS = $(VC14_LIBTMPL) Makefile.am lib/Makefile.inc
VC14_SRCTMPL = projects/Windows/VC14/src/curl.tmpl
VC14_SRCVCXPROJ = projects/Windows/VC14/src/curl.vcxproj.dist
VC14_SRCVCXPROJ_DEPS = $(VC14_SRCTMPL) Makefile.am src/Makefile.inc
VC_DIST = projects/README \
projects/build-openssl.bat \
projects/build-wolfssl.bat \
projects/checksrc.bat \
projects/Windows/VC6/curl-all.dsw \
projects/Windows/VC6/lib/libcurl.dsw \
projects/Windows/VC6/src/curl.dsw \
projects/Windows/VC7/curl-all.sln \
projects/Windows/VC7/lib/libcurl.sln \
projects/Windows/VC7/src/curl.sln \
projects/Windows/VC7.1/curl-all.sln \
projects/Windows/VC7.1/lib/libcurl.sln \
projects/Windows/VC7.1/src/curl.sln \
projects/Windows/VC8/curl-all.sln \
projects/Windows/VC8/lib/libcurl.sln \
projects/Windows/VC8/src/curl.sln \
projects/Windows/VC9/curl-all.sln \
projects/Windows/VC9/lib/libcurl.sln \
projects/Windows/VC9/src/curl.sln \
projects/Windows/VC10/curl-all.sln \
projects/Windows/VC10/lib/libcurl.sln \
projects/Windows/VC10/lib/libcurl.vcxproj.filters \
projects/Windows/VC10/src/curl.sln \
projects/Windows/VC10/src/curl.vcxproj.filters \
projects/Windows/VC11/curl-all.sln \
projects/Windows/VC11/lib/libcurl.sln \
projects/Windows/VC11/lib/libcurl.vcxproj.filters \
projects/Windows/VC11/src/curl.sln \
projects/Windows/VC11/src/curl.vcxproj.filters \
projects/Windows/VC12/curl-all.sln \
projects/Windows/VC12/lib/libcurl.sln \
projects/Windows/VC12/lib/libcurl.vcxproj.filters \
projects/Windows/VC12/src/curl.sln \
projects/Windows/VC12/src/curl.vcxproj.filters \
projects/Windows/VC14/curl-all.sln \
projects/Windows/VC14/lib/libcurl.sln \
projects/Windows/VC14/lib/libcurl.vcxproj.filters \
projects/Windows/VC14/src/curl.sln \
projects/Windows/VC14/src/curl.vcxproj.filters
WINBUILD_DIST = winbuild/BUILD.WINDOWS.txt winbuild/gen_resp_file.bat \
winbuild/MakefileBuild.vc winbuild/Makefile.vc \
winbuild/Makefile.msvc.names
EXTRA_DIST = CHANGES COPYING maketgz Makefile.dist curl-config.in \
RELEASE-NOTES buildconf libcurl.pc.in MacOSX-Framework scripts/zsh.pl \
$(CMAKE_DIST) $(VC_DIST) $(WINBUILD_DIST) lib/libcurl.vers.in \
buildconf.bat
CLEANFILES = $(VC6_LIBDSP) $(VC6_SRCDSP) $(VC7_LIBVCPROJ) $(VC7_SRCVCPROJ) \
$(VC71_LIBVCPROJ) $(VC71_SRCVCPROJ) $(VC8_LIBVCPROJ) $(VC8_SRCVCPROJ) \
$(VC9_LIBVCPROJ) $(VC9_SRCVCPROJ) $(VC10_LIBVCXPROJ) $(VC10_SRCVCXPROJ) \
$(VC11_LIBVCXPROJ) $(VC11_SRCVCXPROJ) $(VC12_LIBVCXPROJ) $(VC12_SRCVCXPROJ) \
$(VC14_LIBVCXPROJ) $(VC14_SRCVCXPROJ)
bin_SCRIPTS = curl-config
SUBDIRS = lib src include
DIST_SUBDIRS = $(SUBDIRS) tests packages docs scripts
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcurl.pc
# List of files required to generate VC IDE .dsp, .vcproj and .vcxproj files
include lib/Makefile.inc
include src/Makefile.inc
dist-hook:
rm -rf $(top_builddir)/tests/log
find $(distdir) -name "*.dist" -exec rm {} \;
(distit=`find $(srcdir) -name "*.dist" | grep -v ./ares/`; \
for file in $$distit; do \
strip=`echo $$file | sed -e s/^$(srcdir)// -e s/\.dist//`; \
cp $$file $(distdir)$$strip; \
done)
html:
cd docs && make html
pdf:
cd docs && make pdf
check: test examples check-docs
if CROSSCOMPILING
test-full: test
test-torture: test
test:
@echo "NOTICE: we can't run the tests when cross-compiling!"
else
test:
@(cd tests; $(MAKE) all quiet-test)
test-full:
@(cd tests; $(MAKE) all full-test)
test-torture:
@(cd tests; $(MAKE) all torture-test)
test-am:
@(cd tests; $(MAKE) all am-test)
endif
examples:
@(cd docs/examples; $(MAKE) check)
check-docs:
@(cd docs/libcurl; $(MAKE) check)
# This is a hook to have 'make clean' also clean up the docs and the tests
# dir. The extra check for the Makefiles being present is necessary because
# 'make distcheck' will make clean first in these directories _before_ it runs
# this hook.
clean-local:
@(if test -f tests/Makefile; then cd tests; $(MAKE) clean; fi)
@(if test -f docs/Makefile; then cd docs; $(MAKE) clean; fi)
#
# Build source and binary rpms. For rpm-3.0 and above, the ~/.rpmmacros
# must contain the following line:
# %_topdir /home/loic/local/rpm
# and that /home/loic/local/rpm contains the directory SOURCES, BUILD etc.
#
# cd /home/loic/local/rpm ; mkdir -p SOURCES BUILD RPMS/i386 SPECS SRPMS
#
# If additional configure flags are needed to build the package, add the
# following in ~/.rpmmacros
# %configure CFLAGS="%{optflags}" ./configure %{_target_platform} --prefix=%{_prefix} ${AM_CONFIGFLAGS}
# and run make rpm in the following way:
# AM_CONFIGFLAGS='--with-uri=/home/users/loic/local/RedHat-6.2' make rpm
#
rpms:
$(MAKE) RPMDIST=curl rpm
$(MAKE) RPMDIST=curl-ssl rpm
rpm:
RPM_TOPDIR=`rpm --showrc | $(PERL) -n -e 'print if(s/.*_topdir\s+(.*)/$$1/)'` ; \
cp $(srcdir)/packages/Linux/RPM/$(RPMDIST).spec $$RPM_TOPDIR/SPECS ; \
cp $(PACKAGE)-$(VERSION).tar.gz $$RPM_TOPDIR/SOURCES ; \
rpm -ba --clean --rmsource $$RPM_TOPDIR/SPECS/$(RPMDIST).spec ; \
mv $$RPM_TOPDIR/RPMS/i386/$(RPMDIST)-*.rpm . ; \
mv $$RPM_TOPDIR/SRPMS/$(RPMDIST)-*.src.rpm .
#
# Build a Solaris pkgadd format file
# run 'make pkgadd' once you've done './configure' and 'make' to make a Solaris pkgadd format
# file (which ends up back in this directory).
# The pkgadd file is in 'pkgtrans' format, so to install on Solaris, do
# pkgadd -d ./HAXXcurl-*
#
# gak - libtool requires an absoulte directory, hence the pwd below...
pkgadd:
umask 022 ; \
make install DESTDIR=`/bin/pwd`/packages/Solaris/root ; \
cat COPYING > $(srcdir)/packages/Solaris/copyright ; \
cd $(srcdir)/packages/Solaris && $(MAKE) package
#
# Build a cygwin binary tarball installation file
# resulting .tar.bz2 file will end up at packages/Win32/cygwin
cygwinbin:
$(MAKE) -C packages/Win32/cygwin cygwinbin
# We extend the standard install with a custom hook:
install-data-hook:
cd include && $(MAKE) install
cd docs && $(MAKE) install
# We extend the standard uninstall with a custom hook:
uninstall-hook:
cd include && $(MAKE) uninstall
cd docs && $(MAKE) uninstall
ca-bundle: lib/mk-ca-bundle.pl
@echo "generating a fresh ca-bundle.crt"
@perl $< -b -l -u lib/ca-bundle.crt
ca-firefox: lib/firefox-db2pem.sh
@echo "generating a fresh ca-bundle.crt"
./lib/firefox-db2pem.sh lib/ca-bundle.crt
checksrc:
cd lib && $(MAKE) checksrc
cd src && $(MAKE) checksrc
cd tests && $(MAKE) checksrc
cd include/curl && $(MAKE) checksrc
cd docs/examples && $(MAKE) checksrc
.PHONY: vc-ide
vc-ide: $(VC6_LIBDSP_DEPS) $(VC6_SRCDSP_DEPS) $(VC7_LIBVCPROJ_DEPS) \
$(VC7_SRCVCPROJ_DEPS) $(VC71_LIBVCPROJ_DEPS) $(VC71_SRCVCPROJ_DEPS) \
$(VC8_LIBVCPROJ_DEPS) $(VC8_SRCVCPROJ_DEPS) $(VC9_LIBVCPROJ_DEPS) \
$(VC9_SRCVCPROJ_DEPS) $(VC10_LIBVCXPROJ_DEPS) $(VC10_SRCVCXPROJ_DEPS) \
$(VC11_LIBVCXPROJ_DEPS) $(VC11_SRCVCXPROJ_DEPS) $(VC12_LIBVCXPROJ_DEPS) \
$(VC12_SRCVCXPROJ_DEPS) $(VC14_LIBVCXPROJ_DEPS) $(VC14_SRCVCXPROJ_DEPS)
@(win32_lib_srcs='$(LIB_CFILES)'; \
win32_lib_hdrs='$(LIB_HFILES) config-win32.h'; \
win32_lib_rc='$(LIB_RCFILES)'; \
win32_lib_vauth_srcs='$(LIB_VAUTH_CFILES)'; \
win32_lib_vauth_hdrs='$(LIB_VAUTH_HFILES)'; \
win32_lib_vtls_srcs='$(LIB_VTLS_CFILES)'; \
win32_lib_vtls_hdrs='$(LIB_VTLS_HFILES)'; \
win32_src_srcs='$(CURL_CFILES)'; \
win32_src_hdrs='$(CURL_HFILES)'; \
win32_src_rc='$(CURL_RCFILES)'; \
win32_src_x_srcs='$(CURLX_CFILES)'; \
win32_src_x_hdrs='$(CURLX_HFILES) ../lib/config-win32.h'; \
\
sorted_lib_srcs=`for file in $$win32_lib_srcs; do echo $$file; done | sort`; \
sorted_lib_hdrs=`for file in $$win32_lib_hdrs; do echo $$file; done | sort`; \
sorted_lib_vauth_srcs=`for file in $$win32_lib_vauth_srcs; do echo $$file; done | sort`; \
sorted_lib_vauth_hdrs=`for file in $$win32_lib_vauth_hdrs; do echo $$file; done | sort`; \
sorted_lib_vtls_srcs=`for file in $$win32_lib_vtls_srcs; do echo $$file; done | sort`; \
sorted_lib_vtls_hdrs=`for file in $$win32_lib_vtls_hdrs; do echo $$file; done | sort`; \
sorted_src_srcs=`for file in $$win32_src_srcs; do echo $$file; done | sort`; \
sorted_src_hdrs=`for file in $$win32_src_hdrs; do echo $$file; done | sort`; \
sorted_src_x_srcs=`for file in $$win32_src_x_srcs; do echo $$file; done | sort`; \
sorted_src_x_hdrs=`for file in $$win32_src_x_hdrs; do echo $$file; done | sort`; \
\
awk_code='\
function gen_element(type, dir, file)\
{\
sub(/vauth\//, "", file);\
sub(/vtls\//, "", file);\
\
spaces=" ";\
if(dir == "lib\\vauth" || dir == "lib\\vtls")\
tabs=" ";\
else\
tabs=" ";\
\
if(type == "dsp") {\
printf("# Begin Source File\r\n");\
printf("\r\n");\
printf("SOURCE=..\\..\\..\\..\\%s\\%s\r\n", dir, file);\
printf("# End Source File\r\n");\
}\
else if(type == "vcproj1") {\
printf("%s<File\r\n", tabs);\
printf("%s RelativePath=\"..\\..\\..\\..\\%s\\%s\">\r\n",\
tabs, dir, file);\
printf("%s</File>\r\n", tabs);\
}\
else if(type == "vcproj2") {\
printf("%s<File\r\n", tabs);\
printf("%s RelativePath=\"..\\..\\..\\..\\%s\\%s\"\r\n",\
tabs, dir, file);\
printf("%s>\r\n", tabs);\
printf("%s</File>\r\n", tabs);\
}\
else if(type == "vcxproj") {\
i = index(file, ".");\
ext = substr(file, i == 0 ? 0 : i + 1);\
\
if(ext == "c")\
printf("%s<ClCompile Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
spaces, dir, file);\
else if(ext == "h")\
printf("%s<ClInclude Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
spaces, dir, file);\
else if(ext == "rc")\
printf("%s<ResourceCompile Include=\"..\\..\\..\\..\\%s\\%s\" />\r\n",\
spaces, dir, file);\
}\
}\
\
{\
\
if($$0 == "CURL_LIB_C_FILES") {\
split(lib_srcs, arr);\
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
}\
else if($$0 == "CURL_LIB_H_FILES") {\
split(lib_hdrs, arr);\
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
}\
else if($$0 == "CURL_LIB_RC_FILES") {\
split(lib_rc, arr);\
for(val in arr) gen_element(proj_type, "lib", arr[val]);\
}\
else if($$0 == "CURL_LIB_VAUTH_C_FILES") {\
split(lib_vauth_srcs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\
}\
else if($$0 == "CURL_LIB_VAUTH_H_FILES") {\
split(lib_vauth_hdrs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vauth", arr[val]);\
}\
else if($$0 == "CURL_LIB_VTLS_C_FILES") {\
split(lib_vtls_srcs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\
}\
else if($$0 == "CURL_LIB_VTLS_H_FILES") {\
split(lib_vtls_hdrs, arr);\
for(val in arr) gen_element(proj_type, "lib\\vtls", arr[val]);\
}\
else if($$0 == "CURL_SRC_C_FILES") {\
split(src_srcs, arr);\
for(val in arr) gen_element(proj_type, "src", arr[val]);\
}\
else if($$0 == "CURL_SRC_H_FILES") {\
split(src_hdrs, arr);\
for(val in arr) gen_element(proj_type, "src", arr[val]);\
}\
else if($$0 == "CURL_SRC_RC_FILES") {\
split(src_rc, arr);\
for(val in arr) gen_element(proj_type, "src", arr[val]);\
}\
else if($$0 == "CURL_SRC_X_C_FILES") {\
split(src_x_srcs, arr);\
for(val in arr) {\
sub(/..\/lib\//, "", arr[val]);\
gen_element(proj_type, "lib", arr[val]);\
}\
}\
else if($$0 == "CURL_SRC_X_H_FILES") {\
split(src_x_hdrs, arr);\
for(val in arr) {\
sub(/..\/lib\//, "", arr[val]);\
gen_element(proj_type, "lib", arr[val]);\
}\
}\
else\
printf("%s\r\n", $$0);\
}';\
\
echo "generating '$(VC6_LIBDSP)'"; \
awk -v proj_type=dsp \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC6_LIBTMPL) > $(VC6_LIBDSP) || { exit 1; }; \
\
echo "generating '$(VC6_SRCDSP)'"; \
awk -v proj_type=dsp \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC6_SRCTMPL) > $(VC6_SRCDSP) || { exit 1; }; \
\
echo "generating '$(VC7_LIBVCPROJ)'"; \
awk -v proj_type=vcproj1 \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC7_LIBTMPL) > $(VC7_LIBVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC7_SRCVCPROJ)'"; \
awk -v proj_type=vcproj1 \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC7_SRCTMPL) > $(VC7_SRCVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC71_LIBVCPROJ)'"; \
awk -v proj_type=vcproj1 \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC71_LIBTMPL) > $(VC71_LIBVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC71_SRCVCPROJ)'"; \
awk -v proj_type=vcproj1 \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC71_SRCTMPL) > $(VC71_SRCVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC8_LIBVCPROJ)'"; \
awk -v proj_type=vcproj2 \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC8_LIBTMPL) > $(VC8_LIBVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC8_SRCVCPROJ)'"; \
awk -v proj_type=vcproj2 \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC8_SRCTMPL) > $(VC8_SRCVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC9_LIBVCPROJ)'"; \
awk -v proj_type=vcproj2 \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC9_LIBTMPL) > $(VC9_LIBVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC9_SRCVCPROJ)'"; \
awk -v proj_type=vcproj2 \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC9_SRCTMPL) > $(VC9_SRCVCPROJ) || { exit 1; }; \
\
echo "generating '$(VC10_LIBVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC10_LIBTMPL) > $(VC10_LIBVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC10_SRCVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC10_SRCTMPL) > $(VC10_SRCVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC11_LIBVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC11_LIBTMPL) > $(VC11_LIBVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC11_SRCVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC11_SRCTMPL) > $(VC11_SRCVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC12_LIBVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC12_LIBTMPL) > $(VC12_LIBVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC12_SRCVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC12_SRCTMPL) > $(VC12_SRCVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC14_LIBVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v lib_srcs="$$sorted_lib_srcs" \
-v lib_hdrs="$$sorted_lib_hdrs" \
-v lib_rc="$$win32_lib_rc" \
-v lib_vauth_srcs="$$sorted_lib_vauth_srcs" \
-v lib_vauth_hdrs="$$sorted_lib_vauth_hdrs" \
-v lib_vtls_srcs="$$sorted_lib_vtls_srcs" \
-v lib_vtls_hdrs="$$sorted_lib_vtls_hdrs" \
"$$awk_code" $(srcdir)/$(VC14_LIBTMPL) > $(VC14_LIBVCXPROJ) || { exit 1; }; \
\
echo "generating '$(VC14_SRCVCXPROJ)'"; \
awk -v proj_type=vcxproj \
-v src_srcs="$$sorted_src_srcs" \
-v src_hdrs="$$sorted_src_hdrs" \
-v src_rc="$$win32_src_rc" \
-v src_x_srcs="$$sorted_src_x_srcs" \
-v src_x_hdrs="$$sorted_src_x_hdrs" \
"$$awk_code" $(srcdir)/$(VC14_SRCTMPL) > $(VC14_SRCVCXPROJ) || { exit 1; };)

File diff suppressed because it is too large Load Diff

View File

@@ -1,49 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
README
Curl is a command line tool for transferring data specified with URL
syntax. Find out how to use curl by reading the curl.1 man page or the
MANUAL document. Find out how to install Curl by reading the INSTALL
document.
libcurl is the library curl is using to do its job. It is readily
available to be used by your software. Read the libcurl.3 man page to
learn how!
You find answers to the most frequent questions we get in the FAQ document.
Study the COPYING file for distribution terms and similar. If you distribute
curl binaries or other binaries that involve libcurl, you might enjoy the
LICENSE-MIXING document.
CONTACT
If you have problems, questions, ideas or suggestions, please contact us
by posting to a suitable mailing list. See https://curl.haxx.se/mail/
All contributors to the project are listed in the THANKS document.
WEB SITE
Visit the curl web site for the latest news and downloads:
https://curl.haxx.se/
GIT
To download the very latest source off the GIT server do this:
git clone https://github.com/curl/curl.git
(you'll get a directory named curl created, filled with the source code)
NOTICE
Curl contains pieces of source code that is Copyright (c) 1998, 1999
Kungliga Tekniska Högskolan. This notice is included here to comply with the
distribution terms.

View File

@@ -1,32 +0,0 @@
Curl and libcurl 7.52.1
Public curl releases: 162
Command line options: 204
curl_easy_setopt() options: 243
Public functions in libcurl: 61
Contributors: 1480
This release includes the following bugfixes:
o CVE-2016-9594: unititialized random [1]
o lib557: fix checksrc warnings
o lib: fix MSVC compiler warnings
o lib557.c: use a shorter MAXIMIZE representation [2]
o tests: run checksrc on debug builds
This release includes the following known bugs:
o see docs/KNOWN_BUGS (https://curl.haxx.se/docs/knownbugs.html)
This release would not have looked like this without help, code, reports and
advice from friends like these:
Daniel Stenberg, Kamil Dudka, Marcel Raad, Ray Satiro,
(4 contributors)
Thanks! (and sorry if I forgot to mention someone)
References to bug reports and discussions on issues:
[1] = https://curl.haxx.se/docs/adv_20161223.html
[2] = https://curl.haxx.se/mail/lib-2016-12/0098.html

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,449 +0,0 @@
#!/bin/sh
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
#--------------------------------------------------------------------------
# die prints argument string to stdout and exits this shell script.
#
die(){
echo "buildconf: $@"
exit 1
}
#--------------------------------------------------------------------------
# findtool works as 'which' but we use a different name to make it more
# obvious we aren't using 'which'! ;-)
# Unlike 'which' does, the current directory is ignored.
#
findtool(){
file="$1"
if { echo "$file" | grep "/" >/dev/null 2>&1; } then
# when file is given with a path check it first
if test -f "$file"; then
echo "$file"
return
fi
fi
old_IFS=$IFS; IFS=':'
for path in $PATH
do
IFS=$old_IFS
# echo "checks for $file in $path" >&2
if test "$path" -a "$path" != '.' -a -f "$path/$file"; then
echo "$path/$file"
return
fi
done
IFS=$old_IFS
}
#--------------------------------------------------------------------------
# removethis() removes all files and subdirectories with the given name,
# inside and below the current subdirectory at invocation time.
#
removethis(){
if test "$#" = "1"; then
find . -depth -name $1 -print > buildconf.tmp.$$
while read fdname
do
if test -f "$fdname"; then
rm -f "$fdname"
elif test -d "$fdname"; then
rm -f -r "$fdname"
fi
done < buildconf.tmp.$$
rm -f buildconf.tmp.$$
fi
}
#--------------------------------------------------------------------------
# Ensure that buildconf runs from the subdirectory where configure.ac lives
#
if test ! -f configure.ac ||
test ! -f src/tool_main.c ||
test ! -f lib/urldata.h ||
test ! -f include/curl/curl.h ||
test ! -f m4/curl-functions.m4; then
echo "Can not run buildconf from outside of curl's source subdirectory!"
echo "Change to the subdirectory where buildconf is found, and try again."
exit 1
fi
#--------------------------------------------------------------------------
# autoconf 2.57 or newer. Unpatched version 2.67 does not generate proper
# configure script. Unpatched version 2.68 is simply unusable, we should
# disallow 2.68 usage.
#
need_autoconf="2.57"
ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
if test -z "$ac_version"; then
echo "buildconf: autoconf not found."
echo " You need autoconf version $need_autoconf or newer installed."
exit 1
fi
old_IFS=$IFS; IFS='.'; set $ac_version; IFS=$old_IFS
if test "$1" = "2" -a "$2" -lt "57" || test "$1" -lt "2"; then
echo "buildconf: autoconf version $ac_version found."
echo " You need autoconf version $need_autoconf or newer installed."
echo " If you have a sufficient autoconf installed, but it"
echo " is not named 'autoconf', then try setting the"
echo " AUTOCONF environment variable."
exit 1
fi
if test "$1" = "2" -a "$2" -eq "67"; then
echo "buildconf: autoconf version $ac_version (BAD)"
echo " Unpatched version generates broken configure script."
elif test "$1" = "2" -a "$2" -eq "68"; then
echo "buildconf: autoconf version $ac_version (BAD)"
echo " Unpatched version generates unusable configure script."
else
echo "buildconf: autoconf version $ac_version (ok)"
fi
am4te_version=`${AUTOM4TE:-autom4te} --version 2>/dev/null|head -n 1| sed -e 's/autom4te\(.*\)/\1/' -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
if test -z "$am4te_version"; then
echo "buildconf: autom4te not found. Weird autoconf installation!"
exit 1
fi
if test "$am4te_version" = "$ac_version"; then
echo "buildconf: autom4te version $am4te_version (ok)"
else
echo "buildconf: autom4te version $am4te_version (ERROR: does not match autoconf version)"
exit 1
fi
#--------------------------------------------------------------------------
# autoheader 2.50 or newer
#
ah_version=`${AUTOHEADER:-autoheader} --version 2>/dev/null|head -n 1| sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
if test -z "$ah_version"; then
echo "buildconf: autoheader not found."
echo " You need autoheader version 2.50 or newer installed."
exit 1
fi
old_IFS=$IFS; IFS='.'; set $ah_version; IFS=$old_IFS
if test "$1" = "2" -a "$2" -lt "50" || test "$1" -lt "2"; then
echo "buildconf: autoheader version $ah_version found."
echo " You need autoheader version 2.50 or newer installed."
echo " If you have a sufficient autoheader installed, but it"
echo " is not named 'autoheader', then try setting the"
echo " AUTOHEADER environment variable."
exit 1
fi
echo "buildconf: autoheader version $ah_version (ok)"
#--------------------------------------------------------------------------
# automake 1.7 or newer
#
need_automake="1.7"
am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
if test -z "$am_version"; then
echo "buildconf: automake not found."
echo " You need automake version $need_automake or newer installed."
exit 1
fi
old_IFS=$IFS; IFS='.'; set $am_version; IFS=$old_IFS
if test "$1" = "1" -a "$2" -lt "7" || test "$1" -lt "1"; then
echo "buildconf: automake version $am_version found."
echo " You need automake version $need_automake or newer installed."
echo " If you have a sufficient automake installed, but it"
echo " is not named 'automake', then try setting the"
echo " AUTOMAKE environment variable."
exit 1
fi
echo "buildconf: automake version $am_version (ok)"
acloc_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|head -n 1| sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//' -e 's/\(.*\)\(-p.*\)/\1/'`
if test -z "$acloc_version"; then
echo "buildconf: aclocal not found. Weird automake installation!"
exit 1
fi
if test "$acloc_version" = "$am_version"; then
echo "buildconf: aclocal version $acloc_version (ok)"
else
echo "buildconf: aclocal version $acloc_version (ERROR: does not match automake version)"
exit 1
fi
#--------------------------------------------------------------------------
# GNU libtoolize preliminary check
#
want_lt_major=1
want_lt_minor=4
want_lt_patch=2
want_lt_version=1.4.2
# This approach that tries 'glibtoolize' first is intended for systems that
# have GNU libtool named as 'glibtoolize' and libtoolize not being GNU's.
libtoolize=`findtool glibtoolize 2>/dev/null`
if test ! -x "$libtoolize"; then
libtoolize=`findtool ${LIBTOOLIZE:-libtoolize}`
fi
if test -z "$libtoolize"; then
echo "buildconf: libtoolize not found."
echo " You need GNU libtoolize $want_lt_version or newer installed."
exit 1
fi
lt_pver=`$libtoolize --version 2>/dev/null|head -n 1`
lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"`
lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"`
if test -z "$lt_version"; then
echo "buildconf: libtoolize not found."
echo " You need GNU libtoolize $want_lt_version or newer installed."
exit 1
fi
old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS
lt_major=$1
lt_minor=$2
lt_patch=$3
if test -z "$lt_major"; then
lt_status="bad"
elif test "$lt_major" -gt "$want_lt_major"; then
lt_status="good"
elif test "$lt_major" -lt "$want_lt_major"; then
lt_status="bad"
elif test -z "$lt_minor"; then
lt_status="bad"
elif test "$lt_minor" -gt "$want_lt_minor"; then
lt_status="good"
elif test "$lt_minor" -lt "$want_lt_minor"; then
lt_status="bad"
elif test -z "$lt_patch"; then
lt_status="bad"
elif test "$lt_patch" -gt "$want_lt_patch"; then
lt_status="good"
elif test "$lt_patch" -lt "$want_lt_patch"; then
lt_status="bad"
else
lt_status="good"
fi
if test "$lt_status" != "good"; then
echo "buildconf: libtoolize version $lt_version found."
echo " You need GNU libtoolize $want_lt_version or newer installed."
exit 1
fi
echo "buildconf: libtoolize version $lt_version (ok)"
#--------------------------------------------------------------------------
# m4 check
#
m4=`(${M4:-m4} --version || ${M4:-gm4} --version) 2>/dev/null | head -n 1`;
m4_version=`echo $m4 | sed -e 's/^.* \([0-9]\)/\1/' -e 's/[a-z]* *$//'`
if { echo $m4 | grep "GNU" >/dev/null 2>&1; } then
echo "buildconf: GNU m4 version $m4_version (ok)"
else
if test -z "$m4"; then
echo "buildconf: m4 version not recognized. You need a GNU m4 installed!"
else
echo "buildconf: m4 version $m4 found. You need a GNU m4 installed!"
fi
exit 1
fi
#--------------------------------------------------------------------------
# perl check
#
PERL=`findtool ${PERL:-perl}`
if test -z "$PERL"; then
echo "buildconf: perl not found"
exit 1
fi
#--------------------------------------------------------------------------
# Remove files generated on previous buildconf/configure run.
#
for fname in .deps \
.libs \
*.la \
*.lo \
*.a \
*.o \
Makefile \
Makefile.in \
aclocal.m4 \
aclocal.m4.bak \
ares_build.h \
ares_config.h \
ares_config.h.in \
autom4te.cache \
compile \
config.guess \
curl_config.h \
curl_config.h.in \
config.log \
config.lt \
config.status \
config.sub \
configure \
configurehelp.pm \
curl-config \
curlbuild.h \
depcomp \
libcares.pc \
libcurl.pc \
libtool \
libtool.m4 \
libtool.m4.tmp \
ltmain.sh \
ltoptions.m4 \
ltsugar.m4 \
ltversion.m4 \
lt~obsolete.m4 \
missing \
install-sh \
stamp-h1 \
stamp-h2 \
stamp-h3 ; do
removethis "$fname"
done
#--------------------------------------------------------------------------
# run the correct scripts now
#
echo "buildconf: running libtoolize"
${libtoolize} --copy --force || die "libtoolize command failed"
# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4
# subdirectory and this local copy is patched to fix some warnings that
# are triggered when running aclocal and using autoconf 2.62 or later.
if test "$lt_major" = "1" && test "$lt_minor" = "5"; then
if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then
echo "buildconf: copying libtool.m4 to local m4 subdir"
ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir`
if test -f $ac_dir/libtool.m4; then
cp -f $ac_dir/libtool.m4 m4/libtool.m4
else
echo "buildconf: $ac_dir/libtool.m4 not found"
fi
if test -f m4/libtool.m4; then
echo "buildconf: renaming some variables in local m4/libtool.m4"
$PERL -i.tmp -pe \
's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \
s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \
m4/libtool.m4
rm -f m4/libtool.m4.tmp
fi
fi
fi
if test -f m4/libtool.m4; then
echo "buildconf: converting all mv to mv -f in local m4/libtool.m4"
$PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4
rm -f m4/libtool.m4.tmp
fi
echo "buildconf: running aclocal"
${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed"
echo "buildconf: converting all mv to mv -f in local aclocal.m4"
$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4
echo "buildconf: running autoheader"
${AUTOHEADER:-autoheader} || die "autoheader command failed"
echo "buildconf: running autoconf"
${AUTOCONF:-autoconf} || die "autoconf command failed"
if test -d ares; then
cd ares
echo "buildconf: running in ares"
./buildconf
cd ..
fi
echo "buildconf: running automake"
${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed"
#--------------------------------------------------------------------------
# GNU libtool complementary check
#
# Depending on the libtool and automake versions being used, config.guess
# might not be installed in the subdirectory until automake has finished.
# So we can not attempt to use it until this very last buildconf stage.
#
if test ! -f ./config.guess; then
echo "buildconf: config.guess not found"
else
buildhost=`./config.guess 2>/dev/null|head -n 1`
case $buildhost in
*-*-darwin*)
need_lt_major=1
need_lt_minor=5
need_lt_patch=26
need_lt_check="yes"
;;
*-*-hpux*)
need_lt_major=1
need_lt_minor=5
need_lt_patch=24
need_lt_check="yes"
;;
esac
if test ! -z "$need_lt_check"; then
if test -z "$lt_major"; then
lt_status="bad"
elif test "$lt_major" -gt "$need_lt_major"; then
lt_status="good"
elif test "$lt_major" -lt "$need_lt_major"; then
lt_status="bad"
elif test -z "$lt_minor"; then
lt_status="bad"
elif test "$lt_minor" -gt "$need_lt_minor"; then
lt_status="good"
elif test "$lt_minor" -lt "$need_lt_minor"; then
lt_status="bad"
elif test -z "$lt_patch"; then
lt_status="bad"
elif test "$lt_patch" -gt "$need_lt_patch"; then
lt_status="good"
elif test "$lt_patch" -lt "$need_lt_patch"; then
lt_status="bad"
else
lt_status="good"
fi
if test "$lt_status" != "good"; then
need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch"
echo "buildconf: libtool version $lt_version found."
echo " $buildhost requires GNU libtool $need_lt_version or newer installed."
rm -f configure
exit 1
fi
fi
fi
#--------------------------------------------------------------------------
# Finished successfully.
#
echo "buildconf: OK"
exit 0

View File

@@ -1,350 +0,0 @@
@echo off
rem ***************************************************************************
rem * _ _ ____ _
rem * Project ___| | | | _ \| |
rem * / __| | | | |_) | |
rem * | (__| |_| | _ <| |___
rem * \___|\___/|_| \_\_____|
rem *
rem * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
rem *
rem * This software is licensed as described in the file COPYING, which
rem * you should have received as part of this distribution. The terms
rem * are also available at https://curl.haxx.se/docs/copyright.html.
rem *
rem * You may opt to use, copy, modify, merge, publish, distribute and/or sell
rem * copies of the Software, and permit persons to whom the Software is
rem * furnished to do so, under the terms of the COPYING file.
rem *
rem * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
rem * KIND, either express or implied.
rem *
rem ***************************************************************************
rem NOTES
rem
rem This batch file must be used to set up a git tree to build on systems where
rem there is no autotools support (i.e. DOS and Windows).
rem
:begin
rem Set our variables
if "%OS%" == "Windows_NT" setlocal
set MODE=GENERATE
rem Switch to this batch file's directory
cd /d "%~0\.." 1>NUL 2>&1
rem Check we are running from a curl git repository
if not exist GIT-INFO goto norepo
rem Detect programs. HAVE_<PROGNAME>
rem When not found the variable is set undefined. The undefined pattern
rem allows for statements like "if not defined HAVE_PERL (command)"
groff --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_GROFF=) else (set HAVE_GROFF=Y)
nroff --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_NROFF=) else (set HAVE_NROFF=Y)
perl --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_PERL=) else (set HAVE_PERL=Y)
gzip --version <NUL 1>NUL 2>&1
if errorlevel 1 (set HAVE_GZIP=) else (set HAVE_GZIP=Y)
:parseArgs
if "%~1" == "" goto start
if /i "%~1" == "-clean" (
set MODE=CLEAN
) else if /i "%~1" == "-?" (
goto syntax
) else if /i "%~1" == "-h" (
goto syntax
) else if /i "%~1" == "-help" (
goto syntax
) else (
goto unknown
)
shift & goto parseArgs
:start
if "%MODE%" == "GENERATE" (
echo.
echo Generating prerequisite files
call :generate
if errorlevel 4 goto nogencurlbuild
if errorlevel 3 goto nogenhugehelp
if errorlevel 2 goto nogenmakefile
if errorlevel 1 goto warning
) else (
echo.
echo Removing prerequisite files
call :clean
if errorlevel 3 goto nocleancurlbuild
if errorlevel 2 goto nocleanhugehelp
if errorlevel 1 goto nocleanmakefile
)
goto success
rem Main generate function.
rem
rem Returns:
rem
rem 0 - success
rem 1 - success with simplified tool_hugehelp.c
rem 2 - failed to generate Makefile
rem 3 - failed to generate tool_hugehelp.c
rem 4 - failed to generate curlbuild.h
rem
:generate
if "%OS%" == "Windows_NT" setlocal
set BASIC_HUGEHELP=0
rem Create Makefile
echo * %CD%\Makefile
if exist Makefile.dist (
copy /Y Makefile.dist Makefile 1>NUL 2>&1
if errorlevel 1 (
if "%OS%" == "Windows_NT" endlocal
exit /B 2
)
)
rem Create tool_hugehelp.c
echo * %CD%\src\tool_hugehelp.c
call :genHugeHelp
if errorlevel 2 (
if "%OS%" == "Windows_NT" endlocal
exit /B 3
)
if errorlevel 1 (
set BASIC_HUGEHELP=1
)
cmd /c exit 0
rem Create curlbuild.h
echo * %CD%\include\curl\curlbuild.h
if exist include\curl\curlbuild.h.dist (
copy /Y include\curl\curlbuild.h.dist include\curl\curlbuild.h 1>NUL 2>&1
if errorlevel 1 (
if "%OS%" == "Windows_NT" endlocal
exit /B 4
)
)
rem Setup c-ares git tree
if exist ares\buildconf.bat (
echo.
echo Configuring c-ares build environment
cd ares
call buildconf.bat
cd ..
)
if "%BASIC_HUGEHELP%" == "1" (
if "%OS%" == "Windows_NT" endlocal
exit /B 1
)
if "%OS%" == "Windows_NT" endlocal
exit /B 0
rem Main clean function.
rem
rem Returns:
rem
rem 0 - success
rem 1 - failed to clean Makefile
rem 2 - failed to clean tool_hugehelp.c
rem 3 - failed to clean curlbuild.h
rem
:clean
rem Remove Makefile
echo * %CD%\Makefile
if exist Makefile (
del Makefile 2>NUL
if exist Makefile (
exit /B 1
)
)
rem Remove tool_hugehelp.c
echo * %CD%\src\tool_hugehelp.c
if exist src\tool_hugehelp.c (
del src\tool_hugehelp.c 2>NUL
if exist src\tool_hugehelp.c (
exit /B 2
)
)
rem Remove curlbuild.h
echo * %CD%\include\curl\curlbuild.h
if exist include\curl\curlbuild.h (
del include\curl\curlbuild.h 2>NUL
if exist include\curl\curlbuild.h (
exit /B 3
)
)
exit /B
rem Function to generate src\tool_hugehelp.c
rem
rem Returns:
rem
rem 0 - full tool_hugehelp.c generated
rem 1 - simplified tool_hugehelp.c
rem 2 - failure
rem
:genHugeHelp
if "%OS%" == "Windows_NT" setlocal
set LC_ALL=C
set ROFFCMD=
set BASIC=1
if defined HAVE_PERL (
if defined HAVE_GROFF (
set ROFFCMD=groff -mtty-char -Tascii -P-c -man
) else if defined HAVE_NROFF (
set ROFFCMD=nroff -c -Tascii -man
)
)
if defined ROFFCMD (
echo #include "tool_setup.h"> src\tool_hugehelp.c
echo #include "tool_hugehelp.h">> src\tool_hugehelp.c
if defined HAVE_GZIP (
echo #ifndef HAVE_LIBZ>> src\tool_hugehelp.c
)
%ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl docs\MANUAL >> src\tool_hugehelp.c
if defined HAVE_GZIP (
echo #else>> src\tool_hugehelp.c
%ROFFCMD% docs\curl.1 2>NUL | perl src\mkhelp.pl -c docs\MANUAL >> src\tool_hugehelp.c
echo #endif /^* HAVE_LIBZ ^*/>> src\tool_hugehelp.c
)
set BASIC=0
) else (
if exist src\tool_hugehelp.c.cvs (
copy /Y src\tool_hugehelp.c.cvs src\tool_hugehelp.c 1>NUL 2>&1
) else (
echo #include "tool_setup.h"> src\tool_hugehelp.c
echo #include "tool_hugehelp.hd">> src\tool_hugehelp.c
echo.>> src\tool_hugehelp.c
echo void hugehelp(void^)>> src\tool_hugehelp.c
echo {>> src\tool_hugehelp.c
echo #ifdef USE_MANUAL>> src\tool_hugehelp.c
echo fputs("Built-in manual not included\n", stdout^);>> src\tool_hugehelp.c
echo #endif>> src\tool_hugehelp.c
echo }>> src\tool_hugehelp.c
)
)
findstr "/C:void hugehelp(void)" src\tool_hugehelp.c 1>NUL 2>&1
if errorlevel 1 (
if "%OS%" == "Windows_NT" endlocal
exit /B 2
)
if "%BASIC%" == "1" (
if "%OS%" == "Windows_NT" endlocal
exit /B 1
)
if "%OS%" == "Windows_NT" endlocal
exit /B 0
rem Function to clean-up local variables under DOS, Windows 3.x and
rem Windows 9x as setlocal isn't available until Windows NT
rem
:dosCleanup
set MODE=
set HAVE_GROFF=
set HAVE_NROFF=
set HAVE_PERL=
set HAVE_GZIP=
set BASIC_HUGEHELP=
set LC_ALL
set ROFFCMD=
set BASIC=
exit /B
:syntax
rem Display the help
echo.
echo Usage: buildconf [-clean]
echo.
echo -clean - Removes the files
goto error
:unknown
echo.
echo Error: Unknown argument '%1'
goto error
:norepo
echo.
echo Error: This batch file should only be used with a curl git repository
goto error
:nogenmakefile
echo.
echo Error: Unable to generate Makefile
goto error
:nogenhugehelp
echo.
echo Error: Unable to generate src\tool_hugehelp.c
goto error
:nogencurlbuild
echo.
echo Error: Unable to generate include\curl\curlbuild.h
goto error
:nocleanmakefile
echo.
echo Error: Unable to clean Makefile
goto error
:nocleanhugehelp
echo.
echo Error: Unable to clean src\tool_hugehelp.c
goto error
:nocleancurlbuild
echo.
echo Error: Unable to clean include\curl\curlbuild.h
goto error
:warning
echo.
echo Warning: The curl manual could not be integrated in the source. This means when
echo you build curl the manual will not be available (curl --man^). Integration of
echo the manual is not required and a summary of the options will still be available
echo (curl --help^). To integrate the manual your PATH is required to have
echo groff/nroff, perl and optionally gzip for compression.
goto success
:error
if "%OS%" == "Windows_NT" (
endlocal
) else (
call :dosCleanup
)
exit /B 1
:success
if "%OS%" == "Windows_NT" (
endlocal
) else (
call :dosCleanup
)
exit /B 0

View File

@@ -1,347 +0,0 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2012-10-14.11; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,178 +0,0 @@
#! /bin/sh
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 2001 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
prefix=@prefix@
exec_prefix=@exec_prefix@
includedir=@includedir@
cppflag_curl_staticlib=@CPPFLAG_CURL_STATICLIB@
usage()
{
cat <<EOF
Usage: curl-config [OPTION]
Available values for OPTION include:
--built-shared says 'yes' if libcurl was built shared
--ca ca bundle install path
--cc compiler
--cflags pre-processor and compiler flags
--checkfor [version] check for (lib)curl of the specified version
--configure the arguments given to configure when building curl
--features newline separated list of enabled features
--help display this help and exit
--libs library linking information
--prefix curl install prefix
--protocols newline separated list of enabled protocols
--static-libs static libcurl library linking information
--version output version information
--vernum output the version information as a number (hexadecimal)
EOF
exit $1
}
if test $# -eq 0; then
usage 1
fi
while test $# -gt 0; do
case "$1" in
# this deals with options in the style
# --option=value and extracts the value part
# [not currently used]
-*=*) value=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) value= ;;
esac
case "$1" in
--built-shared)
echo @ENABLE_SHARED@
;;
--ca)
echo @CURL_CA_BUNDLE@
;;
--cc)
echo "@CC@"
;;
--prefix)
echo "$prefix"
;;
--feature|--features)
for feature in @SUPPORT_FEATURES@ ""; do
test -n "$feature" && echo "$feature"
done
;;
--protocols)
for protocol in @SUPPORT_PROTOCOLS@; do
echo "$protocol"
done
;;
--version)
echo libcurl @CURLVERSION@
exit 0
;;
--checkfor)
checkfor=$2
cmajor=`echo $checkfor | cut -d. -f1`
cminor=`echo $checkfor | cut -d. -f2`
# when extracting the patch part we strip off everything after a
# dash as that's used for things like version 1.2.3-CVS
cpatch=`echo $checkfor | cut -d. -f3 | cut -d- -f1`
checknum=`echo "$cmajor*256*256 + $cminor*256 + ${cpatch:-0}" | bc`
numuppercase=`echo @VERSIONNUM@ | tr 'a-f' 'A-F'`
nownum=`echo "obase=10; ibase=16; $numuppercase" | bc`
if test "$nownum" -ge "$checknum"; then
# silent success
exit 0
else
echo "requested version $checkfor is newer than existing @CURLVERSION@"
exit 1
fi
;;
--vernum)
echo @VERSIONNUM@
exit 0
;;
--help)
usage 0
;;
--cflags)
if test "X$cppflag_curl_staticlib" = "X-DCURL_STATICLIB"; then
CPPFLAG_CURL_STATICLIB="-DCURL_STATICLIB "
else
CPPFLAG_CURL_STATICLIB=""
fi
if test "X@includedir@" = "X/usr/include"; then
echo "$CPPFLAG_CURL_STATICLIB"
else
echo "${CPPFLAG_CURL_STATICLIB}-I@includedir@"
fi
;;
--libs)
if test "X@libdir@" != "X/usr/lib" -a "X@libdir@" != "X/usr/lib64"; then
CURLLIBDIR="-L@libdir@ "
else
CURLLIBDIR=""
fi
if test "X@REQUIRE_LIB_DEPS@" = "Xyes"; then
echo ${CURLLIBDIR}-lcurl @LIBCURL_LIBS@
else
echo ${CURLLIBDIR}-lcurl
fi
;;
--static-libs)
if test "X@ENABLE_STATIC@" != "Xno" ; then
echo @libdir@/libcurl.@libext@ @LDFLAGS@ @LIBCURL_LIBS@
else
echo "curl was built with static libraries disabled" >&2
exit 1
fi
;;
--configure)
echo @CONFIGURE_OPTIONS@
;;
*)
echo "unknown option: $1"
usage 1
;;
esac
shift
done
exit 0

View File

@@ -1,791 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2013-05-30.07; # UTC
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -1,106 +0,0 @@
libcurl bindings
================
Creative people have written bindings or interfaces for various environments
and programming languages. Using one of these allows you to take advantage of
curl powers from within your favourite language or system.
This is a list of all known interfaces as of this writing.
The bindings listed below are not part of the curl/libcurl distribution
archives, but must be downloaded and installed separately.
[Ada95](http://www.almroth.com/adacurl/index.html) Written by Andreas Almroth
[Basic](http://scriptbasic.com/) ScriptBasic bindings written by Peter Verhas
[C++](http://curlpp.org/) Written by Jean-Philippe Barrette-LaPierre
[Ch](http://chcurl.sourceforge.net/) Written by Stephen Nestinger and Jonathan Rogado
Cocoa: [BBHTTP](https://github.com/brunodecarvalho/BBHTTP) written by Bruno de Carvalho
[curlhandle](http://curlhandle.sourceforge.net/) Written by Dan Wood
[D](http://dlang.org/library/std/net/curl.html) Written by Kenneth Bogert
[Dylan](http://dylanlibs.sourceforge.net/) Written by Chris Double
[Eiffel](https://room.eiffel.com/library/curl) Written by Eiffel Software
[Euphoria](http://rays-web.com/eulibcurl.htm) Written by Ray Smith
[Falcon](http://www.falconpl.org/index.ftd?page_id=prjs&prj_id=curl)
[Ferite](http://www.ferite.org/) Written by Paul Querna
[Gambas](http://gambas.sourceforge.net/)
[glib/GTK+](http://atterer.net/glibcurl/) Written by Richard Atterer
[Guile](http://www.lonelycactus.com/guile-curl.html) Written by Michael L. Gran
[Harbour](https://github.com/vszakats/harbour-core/tree/master/contrib/hbcurl) Written by Viktor Szakáts
[Haskell](http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl) Written by Galois, Inc
[Java](https://github.com/pjlegato/curl-java)
[Julia](https://github.com/forio/Curl.jl) Written by Paul Howe
[Lisp](http://common-lisp.net/project/cl-curl/) Written by Liam Healy
Lua: [luacurl](http://luacurl.luaforge.net/) by Alexander Marinov, [Lua-cURL](http://luaforge.net/projects/lua-curl/) by Jürgen Hötzel
[Mono](http://forge.novell.com/modules/xfmod/project/?libcurl-mono) Written by Jeffrey Phillips
[.NET](https://sourceforge.net/projects/libcurl-net/) libcurl-net by Jeffrey Phillips
[node.js](https://github.com/JCMais/node-libcurl) node-libcurl by Jonathan Cardoso Machado
[Object-Pascal](http://www.tekool.com/opcurl) Free Pascal, Delphi and Kylix binding written by Christophe Espern.
[O'Caml](https://sourceforge.net/projects/ocurl/) Written by Lars Nilsson
[Pascal](http://houston.quik.com/jkp/curlpas/) Free Pascal, Delphi and Kylix binding written by Jeffrey Pohlmeyer.
[Perl](https://github.com/szbalint/WWW--Curl) Maintained by Cris Bailiff and Bálint Szilakszi
[PHP](https://php.net/curl) Originally written by Sterling Hughes
[PostgreSQL](http://gborg.postgresql.org/project/pgcurl/projdisplay.php) Written by Gian Paolo Ciceri
[Python](http://pycurl.sourceforge.net/) PycURL by Kjetil Jacobsen
[R](http://cran.r-project.org/package=curl)
[Rexx](http://rexxcurl.sourceforge.net/) Written Mark Hessling
RPG, support for ILE/RPG on OS/400 is included in source distribution
Ruby: [curb](http://curb.rubyforge.org/) written by Ross Bamford, [ruby-curl-multi](http://curl-multi.rubyforge.org/) written by Kristjan Petursson and Keith Rarick
[Rust](https://github.com/carllerche/curl-rust) curl-rust - by Carl Lerche
[Scheme](http://www.metapaper.net/lisovsky/web/curl/) Bigloo binding by Kirill Lisovsky
[S-Lang](http://www.jedsoft.org/slang/modules/curl.html) by John E Davis
[Smalltalk](http://www.squeaksource.com/CurlPlugin/) Written by Danil Osipchuk
[SP-Forth](http://www.forth.org.ru/~ac/lib/lin/curl/) Written by ygrek
[SPL](http://www.clifford.at/spl/) Written by Clifford Wolf
[Tcl](http://mirror.yellow5.com/tclcurl/) Tclcurl by Andrés García
[Visual Basic](https://sourceforge.net/projects/libcurl-vb/) libcurl-vb by Jeffrey Phillips
[Visual Foxpro](http://www.ctl32.com.ar/libcurl.asp) by Carlos Alloatti
[Q](http://q-lang.sourceforge.net/) The libcurl module is part of the default install
[wxWidgets](http://wxcode.sourceforge.net/components/wxcurl/) Written by Casey O'Donnell
[XBLite](http://perso.wanadoo.fr/xblite/libraries.html) Written by David Szafranski
[Xojo](https://github.com/charonn0/RB-libcURL) Written by Andrew Lambert

View File

@@ -1,247 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
BUGS
1. Bugs
1.1 There are still bugs
1.2 Where to report
1.3 What to report
1.4 libcurl problems
1.5 Who will fix the problems
1.6 How to get a stack trace
1.7 Bugs in libcurl bindings
2. Bug fixing procedure
2.1 What happens on first filing
2.2 First response
2.3 Not reproducible
2.4 Unresponsive
2.5 Lack of time/interest
2.6 KNOWN_BUGS
2.7 TODO
2.8 Closing off stalled bugs
==============================================================================
1.1 There are still bugs
Curl and libcurl have grown substantially since the beginning. At the time
of writing (January 2013), there are about 83,000 lines of source code, and
by the time you read this it has probably grown even more.
Of course there are lots of bugs left. And lots of misfeatures.
To help us make curl the stable and solid product we want it to be, we need
bug reports and bug fixes.
1.2 Where to report
If you can't fix a bug yourself and submit a fix for it, try to report an as
detailed report as possible to a curl mailing list to allow one of us to
have a go at a solution. You can optionally also post your bug/problem at
curl's bug tracking system over at
https://github.com/curl/curl/issues
Please read the rest of this document below first before doing that!
If you feel you need to ask around first, find a suitable mailing list and
post there. The lists are available on https://curl.haxx.se/mail/
1.3 What to report
When reporting a bug, you should include all information that will help us
understand what's wrong, what you expected to happen and how to repeat the
bad behavior. You therefore need to tell us:
- your operating system's name and version number
- what version of curl you're using (curl -V is fine)
- versions of the used libraries that libcurl is built to use
- what URL you were working with (if possible), at least which protocol
and anything and everything else you think matters. Tell us what you
expected to happen, tell use what did happen, tell us how you could make it
work another way. Dig around, try out, test. Then include all the tiny bits
and pieces in your report. You will benefit from this yourself, as it will
enable us to help you quicker and more accurately.
Since curl deals with networks, it often helps us if you include a protocol
debug dump with your bug report. The output you get by using the -v or
--trace options.
If curl crashed, causing a core dump (in unix), there is hardly any use to
send that huge file to anyone of us. Unless we have an exact same system
setup as you, we can't do much with it. Instead we ask you to get a stack
trace and send that (much smaller) output to us instead!
The address and how to subscribe to the mailing lists are detailed in the
MANUAL file.
1.4 libcurl problems
When you've written your own application with libcurl to perform transfers,
it is even more important to be specific and detailed when reporting bugs.
Tell us the libcurl version and your operating system. Tell us the name and
version of all relevant sub-components like for example the SSL library
you're using and what name resolving your libcurl uses. If you use SFTP or
SCP, the libssh2 version is relevant etc.
Showing us a real source code example repeating your problem is the best way
to get our attention and it will greatly increase our chances to understand
your problem and to work on a fix (if we agree it truly is a problem).
Lots of problems that appear to be libcurl problems are actually just abuses
of the libcurl API or other malfunctions in your applications. It is advised
that you run your problematic program using a memory debug tool like
valgrind or similar before you post memory-related or "crashing" problems to
us.
1.5 Who will fix the problems
If the problems or bugs you describe are considered to be bugs, we want to
have the problems fixed.
There are no developers in the curl project that are paid to work on bugs.
All developers that take on reported bugs do this on a voluntary basis. We
do it out of an ambition to keep curl and libcurl excellent products and out
of pride.
But please do not assume that you can just lump over something to us and it
will then magically be fixed after some given time. Most often we need
feedback and help to understand what you've experienced and how to repeat a
problem. Then we may only be able to assist YOU to debug the problem and to
track down the proper fix.
We get reports from many people every month and each report can take a
considerable amount of time to really go to the bottom with.
1.6 How to get a stack trace
First, you must make sure that you compile all sources with -g and that you
don't 'strip' the final executable. Try to avoid optimizing the code as
well, remove -O, -O2 etc from the compiler options.
Run the program until it cores.
Run your debugger on the core file, like '<debugger> curl core'. <debugger>
should be replaced with the name of your debugger, in most cases that will
be 'gdb', but 'dbx' and others also occur.
When the debugger has finished loading the core file and presents you a
prompt, enter 'where' (without the quotes) and press return.
The list that is presented is the stack trace. If everything worked, it is
supposed to contain the chain of functions that were called when curl
crashed. Include the stack trace with your detailed bug report. It'll help a
lot.
1.7 Bugs in libcurl bindings
There will of course pop up bugs in libcurl bindings. You should then
primarily approach the team that works on that particular binding and see
what you can do to help them fix the problem.
If you suspect that the problem exists in the underlying libcurl, then
please convert your program over to plain C and follow the steps outlined
above.
2. Bug fixing procedure
2.1 What happens on first filing
When a new issue is posted in the issue tracker or on the mailing list, the
team of developers first need to see the report. Maybe they took the day
off, maybe they're off in the woods hunting. Have patience. Allow at least a
few days before expecting someone to have responded.
In the issue tracker you can expect that some labels will be set on the
issue to help categorize it.
2.2 First response
If your issue/bug report wasn't perfect at once (and few are), chances are
that someone will ask follow-up questions. Which version did you use? Which
options did you use? How often does the problem occur? How can we reproduce
this problem? Which protocols does it involve? Or perhaps much more specific
and deep diving questions. It all depends on your specific issue.
You should then respond to these follow-up questions and provide more info
about the problem, so that we can help you figure it out. Or maybe you can
help us figure it out. An active back-and-forth communication is important
and the key for finding a cure and landing a fix.
2.3 Not reproducible
For problems that we can't reproduce and can't understand even after having
gotten all the info we need and having studied the source code over again,
are really hard to solve so then we may require further work from you who
actually see or experience the problem.
2.4 Unresponsive
If the problem haven't been understood or reproduced, and there's nobody
responding to follow-up questions or questions asking for clarifications or
for discussing possible ways to move forward with the task, we take that as
a strong suggestion that the bug is not important.
Unimportant issues will be closed as inactive sooner or later as they can't
be fixed. The inactivity period (waiting for responses) should not be
shorter than two weeks but may extend months.
2.5 Lack of time/interest
Bugs that are filed and are understood can unfortunately end up in the
"nobody cares enough about it to work on it" category. Such bugs are
perfectly valid problems that *should* get fixed but apparently aren't. We
try to mark such bugs as "KNOWN_BUGS material" after a time of inactivity
and if no activity is noticed after yet some time those bugs are added to
KNOWN_BUGS and are closed in the issue tracker.
2.6 KNOWN_BUGS
This is a list of known bugs. Bugs we know exist and that have been pointed
out but that haven't yet been fixed. The reasons for why they haven't been
fixed can involve anything really, but the primary reason is that nobody has
considered these problems to be important enough to spend the necesary time
and effort to have them fixed.
The KNOWN_BUGS are always up for grabs and we will always love the ones who
bring one of them back to live and offers solutions to them.
The KNOWN_BUGS document has a sibling document known as TODO.
2.7 TODO
Issues that are filed or reported that aren't really bugs but more missing
features or ideas for future improvements and so on are marked as
'enhancement' or 'feature-request' and will be added to the TODO document
instead and the issue is closed. We don't keep TODO items in the issue
tracker.
The TODO document is full of ideas and suggestions of what we can add or fix
one day. You're always encouraged and free to grab one of those items and
take up a discussion with the curl development team on how that could be
implemented or provided in the project so that you can work on ticking it
odd that document.
If the issue is rather a bug and not a missing feature or functionality, it
is listed in KNOWN_BUGS instead.
2.8 Closing off stalled bugs
The issue and pull request trackers on https://github.com/curl/curl will
only hold "active" entries (using a non-precise defintion of what active
actually is, but they're at least not completely dead). Those that are
abandonded or in other ways dormant will be closed and sometimes added to
TODO and KNOWN_BUGS instead.
This way, we only have "active" issues open on github. Irrelevant issues and
pull requests will not distract developes or casual visitors.

View File

@@ -1,124 +0,0 @@
# checksrc
This is the tool we use within the curl project to scan C source code and
check that it adheres to our [Source Code Style guide](CODE_STYLE.md).
## Usage
checksrc.pl [options] [file1] [file2] ...
## Command line options
`-W[file]` whitelists that file and excludes it from being checked. Helpful
when, for example, one of the files is generated.
`-D[dir]` directory name to prepend to file names when accessing them.
`-h` shows the help output, that also lists all recognized warnings
## What does checksrc warn for?
checksrc does not check and verify the code against the entire style guide,
but the script is instead an effort to detect the most common mistakes and
syntax mistakes that contributors make before they get accustomed to our code
style. Heck, many of us regulars do the mistakes too and this script helps us
keep the code in shape.
checksrc.pl -h
Lists how to use the script and it lists all existing warnings it has and
problems it detects. At the time of this writing, the existing checksrc
warnings are:
- `BADCOMMAND`: There's a bad !checksrc! instruction in the code. See the
**Ignore certain warnings** section below for details.
- `BANNEDFUNC`: A banned function was used. The functions sprintf, vsprintf,
strcat, strncat, gets are **never** allowed in curl source code.
- `BRACEELSE`: '} else' on the same line. The else is supposed to be on the
following line.
- `BRACEPOS`: wrong position for an open brace (`{`).
- `COMMANOSPACE`: a comma without following space
- `COPYRIGHT`: the file is missing a copyright statement!
- `CPPCOMMENTS`: `//` comment detected, that's not C89 compliant
- `FOPENMODE`: `fopen()` needs a macro for the mode string, use it
- `INDENTATION`: detected a wrong start column for code. Note that this warning
only checks some specific places and will certainly miss many bad
indentations.
- `LONGLINE`: A line is longer than 79 columns.
- `PARENBRACE`: `){` was used without sufficient space in between.
- `RETURNNOSPACE`: `return` was used without space between the keyword and the
following value.
- `SPACEAFTERPAREN`: there was a space after open parenthesis, `( text`.
- `SPACEBEFORECLOSE`: there was a space before a close parenthesis, `text )`.
- `SPACEBEFORECOMMA`: there was a space before a comma, `one , two`.
- `SPACEBEFOREPAREN`: there was a space before an open parenthesis, `if (`,
where one was not expected
- `SPACESEMILCOLON`: there was a space before semicolon, ` ;`.
- `TABS`: TAB characters are not allowed!
- `TRAILINGSPACE`: Trailing white space on the line
- `UNUSEDIGNORE`: a checksrc inlined warning ignore was asked for but not used,
that's an ignore that should be removed or changed to get used.
## Ignore certain warnings
Due to the nature of the source code and the flaws of the checksrc tool, there
is sometimes a need to ignore specific warnings. checksrc allows a few
different ways to do this.
### Inline ignore
You can control what to ignore within a specific source file by providing
instructions to checksrc in the source code itself. You need a magic marker
that is `!checksrc!` followed by the instruction. The instruction can ask to
ignore a specific warning N number of times or you ignore all of them until
you mark the end of the ignored section.
Inline ignores are only done for that single specific source code file.
Example
/* !checksrc! disable LONGLINE all */
This will ignore the warning for overly long lines until it is re-enabled with:
/* !checksrc! enable LONGLINE */
If the enabling isn't performed before the end of the file, it will be enabled
automatically for the next file.
You can also opt to ignore just N violations so that if you have a single long
line you just can't shorten and is agreed to be fine anyway:
/* !checksrc! disable LONGLINE 1 */
... and the warning for long lines will be enabled again automatically after
it has ignored that single warning. The number `1` can of course be changed to
any other integer number. It can be used to make sure only the exact intended
instances are ignored and nothing extra.
### Directory wide ignore patterns
This is a method we've transitioned away from. Use inline ignores as far as
possible.
Make a `checksrc.whitelist` file in the directory of the source code with the
false positive, and include the full offending line into this file.

View File

@@ -1,32 +0,0 @@
Contributor Code of Conduct
===========================
As contributors and maintainers of this project, we pledge to respect all
people who contribute through reporting issues, posting feature requests,
updating documentation, submitting pull requests or patches, and other
activities.
We are committed to making participation in this project a harassment-free
experience for everyone, regardless of level of experience, gender, gender
identity and expression, sexual orientation, disability, personal appearance,
body size, race, ethnicity, age, or religion.
Examples of unacceptable behavior by participants include the use of sexual
language or imagery, derogatory comments or personal attacks, trolling, public
or private harassment, insults, or other unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct. Project maintainers who do not
follow the Code of Conduct may be removed from the project team.
This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by opening an issue or contacting one or more of the project
maintainers.
This Code of Conduct is adapted from the [Contributor
Covenant](http://contributor-covenant.org), version 1.1.0, available at
[http://contributor-covenant.org/version/1/1/0/](http://contributor-covenant.org/version/1/1/0/)

View File

@@ -1,238 +0,0 @@
# curl C code style
Source code that has a common style is easier to read than code that uses
different styles in different places. It helps making the code feel like one
single code base. Easy-to-read is a very important property of code and helps
making it easier to review when new things are added and it helps debugging
code when developers are trying to figure out why things go wrong. A unified
style is more important than individual contributors having their own personal
tastes satisfied.
Our C code has a few style rules. Most of them are verified and upheld by the
`lib/checksrc.pl` script. Invoked with `make checksrc` or even by default by
the build system when built after `./configure --enable-debug` has been used.
It is normally not a problem for anyone to follow the guidelines, as you just
need to copy the style already used in the source code and there are no
particularly unusual rules in our set of rules.
We also work hard on writing code that are warning-free on all the major
platforms and in general on as many platforms as possible. Code that obviously
will cause warnings will not be accepted as-is.
## Naming
Try using a non-confusing naming scheme for your new functions and variable
names. It doesn't necessarily have to mean that you should use the same as in
other places of the code, just that the names should be logical,
understandable and be named according to what they're used for. File-local
functions should be made static. We like lower case names.
See the [INTERNALS](INTERNALS.md) document on how we name non-exported
library-global symbols.
## Indenting
We use only spaces for indentation, never TABs. We use two spaces for each new
open brace.
if(something_is_true) {
while(second_statement == fine) {
moo();
}
}
## Comments
Since we write C89 code, `//` comments are not allowed. They weren't
introduced in the C standard until C99. We use only `/*` and `*/` comments:
/* this is a comment */
## Long lines
Source code in curl may never be wider than 79 columns and there are two
reasons for maintaining this even in the modern era of very large and high
resolution screens:
1. Narrower columns are easier to read than very wide ones. There's a reason
newspapers have used columns for decades or centuries.
2. Narrower columns allow developers to easier show multiple pieces of code
next to each other in different windows. I often have two or three source
code windows next to each other on the same screen - as well as multiple
terminal and debugging windows.
## Braces
In if/while/do/for expressions, we write the open brace on the same line as
the keyword and we then set the closing brace on the same indentation level as
the initial keyword. Like this:
if(age < 40) {
/* clearly a youngster */
}
You may omit the braces if they would contain only a one-line statement:
if(!x)
continue;
For functions the opening brace should be on a separate line:
int main(int argc, char **argv)
{
return 1;
}
## 'else' on the following line
When adding an `else` clause to a conditional expression using braces, we add
it on a new line after the closing brace. Like this:
if(age < 40) {
/* clearly a youngster */
}
else {
/* probably grumpy */
}
## No space before parentheses
When writing expressions using if/while/do/for, there shall be no space
between the keyword and the open parenthesis. Like this:
while(1) {
/* loop forever */
}
## Use boolean conditions
Rather than test a conditional value such as a bool against TRUE or FALSE, a
pointer against NULL or != NULL and an int against zero or not zero in
if/while conditions we prefer:
result = do_something();
if(!result) {
/* something went wrong */
return result;
}
## No assignments in conditions
To increase readability and reduce complexity of conditionals, we avoid
assigning variables within if/while conditions. We frown upon this style:
if((ptr = malloc(100)) == NULL)
return NULL;
and instead we encourage the above version to be spelled out more clearly:
ptr = malloc(100);
if(!ptr)
return NULL;
## New block on a new line
We never write multiple statements on the same source line, even for very
short if() conditions.
if(a)
return TRUE;
else if(b)
return FALSE;
and NEVER:
if(a) return TRUE;
else if(b) return FALSE;
## Space around operators
Please use spaces on both sides of operators in C expressions. Postfix `(),
[], ->, ., ++, --` and Unary `+, - !, ~, &` operators excluded they should
have no space.
Examples:
bla = func();
who = name[0];
age += 1;
true = !false;
size += -2 + 3 * (a + b);
ptr->member = a++;
struct.field = b--;
ptr = &address;
contents = *pointer;
complement = ~bits;
empty = (!*string) ? TRUE : FALSE;
## Column alignment
Some statements cannot be completed on a single line because the line would
be too long, the statement too hard to read, or due to other style guidelines
above. In such a case the statement will span multiple lines.
If a continuation line is part of an expression or sub-expression then you
should align on the appropriate column so that it's easy to tell what part of
the statement it is. Operators should not start continuation lines. In other
cases follow the 2-space indent guideline. Here are some examples from libcurl:
~~~c
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
(handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
(handle->set.httpreq == HTTPREQ_GET ||
handle->set.httpreq == HTTPREQ_HEAD))
/* didn't ask for HTTP/1.0 and a GET or HEAD */
return TRUE;
~~~
~~~c
case CURLOPT_KEEP_SENDING_ON_ERROR:
data->set.http_keep_sending_on_error = (0 != va_arg(param, long)) ?
TRUE : FALSE;
break;
~~~
~~~c
data->set.http_disable_hostname_check_before_authentication =
(0 != va_arg(param, long)) ? TRUE : FALSE;
~~~
~~~c
if(option) {
result = parse_login_details(option, strlen(option),
(userp ? &user : NULL),
(passwdp ? &passwd : NULL),
NULL);
}
~~~
~~~c
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
"server response left\n",
(int)clipamount));
~~~
## Platform dependent code
Use `#ifdef HAVE_FEATURE` to do conditional code. We avoid checking for
particular operating systems or hardware in the #ifdef lines. The HAVE_FEATURE
shall be generated by the configure script for unix-like systems and they are
hard-coded in the config-[system].h files for the others.
We also encourage use of macros/functions that possibly are empty or defined
to constants when libcurl is built without that feature, to make the code
seamless. Like this style where the `magic()` function works differently
depending on a build-time conditional:
#ifdef HAVE_MAGIC
void magic(int a)
{
return a + 2;
}
#else
#define magic(x) 1
#endif
int content = magic(3);

View File

@@ -1,247 +0,0 @@
# Contributing to the curl project
This document is intended to offer guidelines on how to best contribute to the
curl project. This concerns new features as well as corrections to existing
flaws or bugs.
## Learning curl
### Join the Community
Skip over to [https://curl.haxx.se/mail/](https://curl.haxx.se/mail/) and join
the appropriate mailing list(s). Read up on details before you post
questions. Read this file before you start sending patches! We prefer
questions sent to and discussions being held on the mailing list(s), not sent
to individuals.
Before posting to one of the curl mailing lists, please read up on the
[mailing list etiquette](https://curl.haxx.se/mail/etiquette.html).
We also hang out on IRC in #curl on irc.freenode.net
If you're at all interested in the code side of things, consider clicking
'watch' on the [curl repo on github](https://github.com/curl/curl) to get
notified on pull requests and new issues posted there.
### License and copyright
When contributing with code, you agree to put your changes and new code under
the same license curl and libcurl is already using unless stated and agreed
otherwise.
If you add a larger piece of code, you can opt to make that file or set of
files to use a different license as long as they don't enforce any changes to
the rest of the package and they make sense. Such "separate parts" can not be
GPL licensed (as we don't want copyleft to affect users of libcurl) but they
must use "GPL compatible" licenses (as we want to allow users to use libcurl
properly in GPL licensed environments).
When changing existing source code, you do not alter the copyright of the
original file(s). The copyright will still be owned by the original creator(s)
or those who have been assigned copyright by the original author(s).
By submitting a patch to the curl project, you are assumed to have the right
to the code and to be allowed by your employer or whatever to hand over that
patch/code to us. We will credit you for your changes as far as possible, to
give credit but also to keep a trace back to who made what changes. Please
always provide us with your full real name when contributing!
### What To Read
Source code, the man pages, the [INTERNALS
document](https://curl.haxx.se/dev/internals.html),
[TODO](https://curl.haxx.se/docs/todo.html),
[KNOWN_BUGS](https://curl.haxx.se/docs/knownbugs.html) and the [most recent
changes](https://curl.haxx.se/dev/sourceactivity.html) in git. Just lurking on
the [curl-library mailing
list](https://curl.haxx.se/mail/list.cgi?list=curl-library) will give you a
lot of insights on what's going on right now. Asking there is a good idea too.
## Write a good patch
### Follow code style
When writing C code, follow the
[CODE_STYLE](https://curl.haxx.se/dev/code-style.html) already established in
the project. Consistent style makes code easier to read and mistakes less
likely to happen. Run `make checksrc` before you submit anything, to make sure
you follow the basic style. That script doesn't verify everything, but if it
complains you know you have work to do.
### Non-clobbering All Over
When you write new functionality or fix bugs, it is important that you don't
fiddle all over the source files and functions. Remember that it is likely
that other people have done changes in the same source files as you have and
possibly even in the same functions. If you bring completely new
functionality, try writing it in a new source file. If you fix bugs, try to
fix one bug at a time and send them as separate patches.
### Write Separate Changes
It is annoying when you get a huge patch from someone that is said to fix 511
odd problems, but discussions and opinions don't agree with 510 of them - or
509 of them were already fixed in a different way. Then the person merging
this change needs to extract the single interesting patch from somewhere
within the huge pile of source, and that gives a lot of extra work.
Preferably, each fix that correct a problem should be in its own patch/commit
with its own description/commit message stating exactly what they correct so
that all changes can be selectively applied by the maintainer or other
interested parties.
Also, separate changes enable bisecting much better when we track problems
and regression in the future.
### Patch Against Recent Sources
Please try to get the latest available sources to make your patches against.
It makes the lives of the developers so much easier. The very best is if you
get the most up-to-date sources from the git repository, but the latest
release archive is quite OK as well!
### Documentation
Writing docs is dead boring and one of the big problems with many open source
projects. Someone's gotta do it. It makes it a lot easier if you submit a
small description of your fix or your new features with every contribution so
that it can be swiftly added to the package documentation.
The documentation is always made in man pages (nroff formatted) or plain
ASCII files. All HTML files on the web site and in the release archives are
generated from the nroff/ASCII versions.
### Test Cases
Since the introduction of the test suite, we can quickly verify that the main
features are working as they're supposed to. To maintain this situation and
improve it, all new features and functions that are added need to be tested
in the test suite. Every feature that is added should get at least one valid
test case that verifies that it works as documented. If every submitter also
posts a few test cases, it won't end up as a heavy burden on a single person!
If you don't have test cases or perhaps you have done something that is very
hard to write tests for, do explain exactly how you have otherwise tested and
verified your changes.
## Sharing Your Changes
### How to get your changes into the main sources
Ideally you file a [pull request on
github](https://github.com/curl/curl/pulls), but you can also send your plain
patch to [the curl-library mailing
list](https://curl.haxx.se/mail/list.cgi?list=curl-library).
Either way, your change will be reviewed and discussed there and you will be
expected to correct flaws pointed out and update accordingly, or the change
risk stalling and eventually just get deleted without action. As a submitter
of a change, you are the owner of that change until it has been merged.
Respond on the list or on github about the change and answer questions and/or
fix nits/flaws. This is very important. We will take lack of replies as a
sign that you're not very anxious to get your patch accepted and we tend to
simply drop such changes.
### About pull requests
With github it is easy to send a [pull
request](https://github.com/curl/curl/pulls) to the curl project to have
changes merged.
We prefer pull requests to mailed patches, as it makes it a proper git commit
that is easy to merge and they are easy to track and not that easy to loose
in a flood of many emails, like they sometimes do on the mailing lists.
When you adjust your pull requests after review, consider squashing the
commits so that we can review the full updated version more easily.
### Making quality patches
Make the patch against as recent sources as possible.
If you've followed the tips in this document and your patch still hasn't been
incorporated or responded to after some weeks, consider resubmitting it to
the list or better yet: change it to a pull request.
### Write good commit messages
A short guide to how to write commit messages in the curl project.
---- start ----
[area]: [short line describing the main effect]
-- empty line --
[full description, no wider than 72 columns that describe as much as
possible as to why this change is made, and possibly what things
it fixes and everything else that is related]
-- empty line --
[Bug: URL to source of the report or more related discussion]
[Reported-by: John Doe - credit the reporter]
[whatever-else-by: credit all helpers, finders, doers]
---- stop ----
Don't forget to use commit --author="" if you commit someone else's work,
and make sure that you have your own user and email setup correctly in git
before you commit
### Write Access to git Repository
If you are a very frequent contributor, you may be given push access to the
git repository and then you'll be able to push your changes straight into the
git repo instead of sending changes as pull requests or by mail as patches.
Just ask if this is what you'd want. You will be required to have posted
several high quality patches first, before you can be granted push access.
### How To Make a Patch with git
You need to first checkout the repository:
git clone https://github.com/curl/curl.git
You then proceed and edit all the files you like and you commit them to your
local repository:
git commit [file]
As usual, group your commits so that you commit all changes that at once that
constitutes a logical change.
Once you have done all your commits and you're happy with what you see, you
can make patches out of your changes that are suitable for mailing:
git format-patch remotes/origin/master
This creates files in your local directory named NNNN-[name].patch for each
commit.
Now send those patches off to the curl-library list. You can of course opt to
do that with the 'git send-email' command.
### How To Make a Patch without git
Keep a copy of the unmodified curl sources. Make your changes in a separate
source tree. When you think you have something that you want to offer the
curl community, use GNU diff to generate patches.
If you have modified a single file, try something like:
diff -u unmodified-file.c my-changed-one.c > my-fixes.diff
If you have modified several files, possibly in different directories, you
can use diff recursively:
diff -ur curl-original-dir curl-modified-sources-dir > my-fixes.diff
The GNU diff and GNU patch tools exist for virtually all platforms, including
all kinds of Unixes and Windows:
For unix-like operating systems:
- [https://savannah.gnu.org/projects/patch/](https://savannah.gnu.org/projects/patch/)
- [https://www.gnu.org/software/diffutils/](https://www.gnu.org/software/diffutils/)
For Windows:
- [http://gnuwin32.sourceforge.net/packages/patch.htm](http://gnuwin32.sourceforge.net/packages/patch.htm)
- [http://gnuwin32.sourceforge.net/packages/diffutils.htm](http://gnuwin32.sourceforge.net/packages/diffutils.htm)

File diff suppressed because it is too large Load Diff

View File

@@ -1,206 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
FEATURES
curl tool
- config file support
- multiple URLs in a single command line
- range "globbing" support: [0-13], {one,two,three}
- multiple file upload on a single command line
- custom maximum transfer rate
- redirectable stderr
- metalink support (*13)
libcurl
- full URL syntax with no length limit
- custom maximum download time
- custom least download speed acceptable
- custom output result after completion
- guesses protocol from host name unless specified
- uses .netrc
- progress bar with time statistics while downloading
- "standard" proxy environment variables support
- compiles on win32 (reported builds on 40+ operating systems)
- selectable network interface for outgoing traffic
- IPv6 support on unix and Windows
- persistent connections
- socks 4 + 5 support, with or without local name resolving
- supports user name and password in proxy environment variables
- operations through proxy "tunnel" (using CONNECT)
- support for large files (>2GB and >4GB) during upload and download
- replaceable memory functions (malloc, free, realloc, etc)
- asynchronous name resolving (*6)
- both a push and a pull style interface
- international domain names (*11)
HTTP
- HTTP/1.1 compliant (optionally uses 1.0)
- GET
- PUT
- HEAD
- POST
- Pipelining
- multipart formpost (RFC1867-style)
- authentication: Basic, Digest, NTLM (*9) and Negotiate (SPNEGO) (*3)
to server and proxy
- resume (both GET and PUT)
- follow redirects
- maximum amount of redirects to follow
- custom HTTP request
- cookie get/send fully parsed
- reads/writes the netscape cookie file format
- custom headers (replace/remove internally generated headers)
- custom user-agent string
- custom referrer string
- range
- proxy authentication
- time conditions
- via http-proxy
- retrieve file modification date
- Content-Encoding support for deflate and gzip
- "Transfer-Encoding: chunked" support in uploads
- data compression (*12)
- HTTP/2 (*5)
HTTPS (*1)
- (all the HTTP features)
- using client certificates
- verify server certificate
- via http-proxy
- select desired encryption
- force usage of a specific SSL version (SSLv2 (*7), SSLv3 (*10) or TLSv1)
FTP
- download
- authentication
- Kerberos 5 (*14)
- active/passive using PORT, EPRT, PASV or EPSV
- single file size information (compare to HTTP HEAD)
- 'type=' URL support
- dir listing
- dir listing names-only
- upload
- upload append
- upload via http-proxy as HTTP PUT
- download resume
- upload resume
- custom ftp commands (before and/or after the transfer)
- simple "range" support
- via http-proxy
- all operations can be tunneled through a http-proxy
- customizable to retrieve file modification date
- no dir depth limit
FTPS (*1)
- implicit ftps:// support that use SSL on both connections
- explicit "AUTH TLS" and "AUTH SSL" usage to "upgrade" plain ftp://
connection to use SSL for both or one of the connections
SCP (*8)
- both password and public key auth
SFTP (*8)
- both password and public key auth
- with custom commands sent before/after the transfer
TFTP
- download
- upload
TELNET
- connection negotiation
- custom telnet options
- stdin/stdout I/O
LDAP (*2)
- full LDAP URL support
DICT
- extended DICT URL support
FILE
- URL support
- upload
- resume
SMB
- SMBv1 over TCP and SSL
- download
- upload
- authentication with NTLMv1
SMTP
- authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9), Kerberos 5
(*4) and External.
- send e-mails
- mail from support
- mail size support
- mail auth support for trusted server-to-server relaying
- multiple recipients
- via http-proxy
SMTPS (*1)
- implicit smtps:// support
- explicit "STARTTLS" usage to "upgrade" plain smtp:// connections to use SSL
- via http-proxy
POP3
- authentication: Clear Text, APOP and SASL
- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
Kerberos 5 (*4) and External.
- list e-mails
- retrieve e-mails
- enhanced command support for: CAPA, DELE, TOP, STAT, UIDL and NOOP via
custom requests
- via http-proxy
POP3S (*1)
- implicit pop3s:// support
- explicit "STLS" usage to "upgrade" plain pop3:// connections to use SSL
- via http-proxy
IMAP
- authentication: Clear Text and SASL
- SASL based authentication: Plain, Login, CRAM-MD5, Digest-MD5, NTLM (*9),
Kerberos 5 (*4) and External.
- list the folders of a mailbox
- select a mailbox with support for verifying the UIDVALIDITY
- fetch e-mails with support for specifying the UID and SECTION
- upload e-mails via the append command
- enhanced command support for: EXAMINE, CREATE, DELETE, RENAME, STATUS,
STORE, COPY and UID via custom requests
- via http-proxy
IMAPS (*1)
- implicit imaps:// support
- explicit "STARTTLS" usage to "upgrade" plain imap:// connections to use SSL
- via http-proxy
FOOTNOTES
=========
*1 = requires OpenSSL, GnuTLS, NSS, yassl, axTLS, PolarSSL, WinSSL (native
Windows), Secure Transport (native iOS/OS X) or GSKit (native IBM i)
*2 = requires OpenLDAP
*3 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos) or
SSPI (native Windows)
*4 = requires a GSS-API implementation, however, only Windows SSPI is
currently supported
*5 = requires nghttp2 and possibly a recent TLS library
*6 = requires c-ares
*7 = requires OpenSSL, NSS, GSKit, WinSSL or Secure Transport; GnuTLS, for
example, only supports SSLv3 and TLSv1
*8 = requires libssh2
*9 = requires OpenSSL, GnuTLS, mbedTLS, NSS, yassl, Secure Transport or SSPI
(native Windows)
*10 = requires any of the SSL libraries in (*1) above other than axTLS, which
does not support SSLv3
*11 = requires libidn or Windows
*12 = requires libz
*13 = requires libmetalink, and either an Apple or Microsoft operating
system, or OpenSSL, or GnuTLS, or NSS
*14 = requires a GSS-API implementation (such as Heimdal or MIT Kerberos)

View File

@@ -1,278 +0,0 @@
How curl Became Like This
=========================
Towards the end of 1996, Daniel Stenberg was spending time writing an IRC bot
for an Amiga related channel on EFnet. He then came up with the idea to make
currency-exchange calculations available to Internet Relay Chat (IRC)
users. All the necessary data are published on the Web; he just needed to
automate their retrieval.
Daniel simply adopted an existing command-line open-source tool, httpget, that
Brazilian Rafael Sagula had written and recently release version 0.1 of. After
a few minor adjustments, it did just what he needed.
1997
----
HttpGet 1.0 was released on April 8th 1997 with brand new HTTP proxy support.
We soon found and fixed support for getting currencies over GOPHER. Once FTP
download support was added, the name of the project was changed and urlget 2.0
was released in August 1997. The http-only days were already passed.
1998
----
The project slowly grew bigger. When upload capabilities were added and the
name once again was misleading, a second name change was made and on March 20,
1998 curl 4 was released. (The version numbering from the previous names was
kept.)
(Unrelated to this project a company called Curl Corporation registered a US
trademark on the name "CURL" on May 18 1998. That company had then already
registered the curl.com domain back in November of the previous year. All this
was revealed to us much later.)
SSL support was added, powered by the SSLeay library.
August, first announcement of curl on freshmeat.net.
October, with the curl 4.9 release and the introduction of cookie support,
curl was no longer released under the GPL license. Now we're at 4000 lines of
code, we switched over to the MPL license to restrict the effects of
"copyleft".
November, configure script and reported successful compiles on several
major operating systems. The never-quite-understood -F option was added and
curl could now simulate quite a lot of a browser. TELNET support was added.
Curl 5 was released in December 1998 and introduced the first ever curl man
page. People started making Linux RPM packages out of it.
1999
----
January, DICT support added.
OpenSSL took over where SSLeay was abandoned.
May, first Debian package.
August, LDAP:// and FILE:// support added. The curl web site gets 1300 visits
weekly. Moved site to curl.haxx.nu.
Released curl 6.0 in September. 15000 lines of code.
December 28, added the project on Sourceforge and started using its services
for managing the project.
2000
----
Spring 2000, major internal overhaul to provide a suitable library interface.
The first non-beta release was named 7.1 and arrived in August. This offered
the easy interface and turned out to be the beginning of actually getting
other software and programs to get based on and powered by libcurl. Almost
20000 lines of code.
June 2000: the curl site moves to "curl.haxx.se"
August, the curl web site gets 4000 visits weekly.
The PHP guys adopted libcurl already the same month, when the first ever third
party libcurl binding showed up. CURL has been a supported module in PHP since
the release of PHP 4.0.2. This would soon get followers. More than 16
different bindings exist at the time of this writing.
September, kerberos4 support was added.
In November started the work on a test suite for curl. It was later re-written
from scratch again. The libcurl major SONAME number was set to 1.
2001
----
January, Daniel released curl 7.5.2 under a new license again: MIT (or
MPL). The MIT license is extremely liberal and can be used combined with GPL
in other projects. This would finally put an end to the "complaints" from
people involved in GPLed projects that previously were prohibited from using
libcurl while it was released under MPL only. (Due to the fact that MPL is
deemed "GPL incompatible".)
curl supports HTTP 1.1 starting with the release of 7.7, March 22 2001. This
also introduced libcurl's ability to do persistent connections. 24000 lines of
code. The libcurl major SONAME number was bumped to 2 due to this overhaul.
The first experimental ftps:// support was added in March 2001.
August. curl is bundled in Mac OS X, 10.1. It was already becoming more and
more of a standard utility of Linux distributions and a regular in the BSD
ports collections. The curl web site gets 8000 visits weekly. Curl Corporation
contacted Daniel to discuss "the name issue". After Daniel's reply, they have
never since got in touch again.
September, libcurl 7.9 introduces cookie jar and curl_formadd(). During the
forthcoming 7.9.x releases, we introduced the multi interface slowly and
without much whistles.
2002
----
June, the curl web site gets 13000 visits weekly. curl and libcurl is
35000 lines of code. Reported successful compiles on more than 40 combinations
of CPUs and operating systems.
To estimate number of users of the curl tool or libcurl library is next to
impossible. Around 5000 downloaded packages each week from the main site gives
a hint, but the packages are mirrored extensively, bundled with numerous OS
distributions and otherwise retrieved as part of other software.
September, with the release of curl 7.10 it is released under the MIT license
only.
2003
----
January. Started working on the distributed curl tests. The autobuilds.
February, the curl site averages at 20000 visits weekly. At any given moment,
there's an average of 3 people browsing the curl.haxx.se site.
Multiple new authentication schemes are supported: Digest (May), NTLM (June)
and Negotiate (June).
November: curl 7.10.8 is released. 45000 lines of code. ~55000 unique visitors
to the curl.haxx.se site. Five official web mirrors.
December, full-fledged SSL for FTP is supported.
2004
----
January: curl 7.11.0 introduced large file support.
June: curl 7.12.0 introduced IDN support. 10 official web mirrors.
This release bumped the major SONAME to 3 due to the removal of the
curl_formparse() function
August: Curl and libcurl 7.12.1
Public curl release number: 82
Releases counted from the very beginning: 109
Available command line options: 96
Available curl_easy_setopt() options: 120
Number of public functions in libcurl: 36
Amount of public web site mirrors: 12
Number of known libcurl bindings: 26
2005
----
April. GnuTLS can now optionally be used for the secure layer when curl is
built.
April: Added the multi_socket() API
September: TFTP support was added.
More than 100,000 unique visitors of the curl web site. 25 mirrors.
December: security vulnerability: libcurl URL Buffer Overflow
2006
----
January. We dropped support for Gopher. We found bugs in the implementation
that turned out having been introduced years ago, so with the conclusion that
nobody had found out in all this time we removed it instead of fixing it.
March: security vulnerability: libcurl TFTP Packet Buffer Overflow
September: The major SONAME number for libcurl was bumped to 4 due to the
removal of ftp third party transfer support.
November: Added SCP and SFTP support
2007
----
February: Added support for the Mozilla NSS library to do the SSL/TLS stuff
July: security vulnerability: libcurl GnuTLS insufficient cert verification
2008
----
November:
Command line options: 128
curl_easy_setopt() options: 158
Public functions in libcurl: 58
Known libcurl bindings: 37
Contributors: 683
145,000 unique visitors. >100 GB downloaded.
2009
----
March: security vulnerability: libcurl Arbitrary File Access
August: security vulnerability: libcurl embedded zero in cert name
December: Added support for IMAP, POP3 and SMTP
2010
----
January: Added support for RTSP
February: security vulnerability: libcurl data callback excessive length
March: The project switched over to use git (hosted by github) instead of CVS
for source code control
May: Added support for RTMP
Added support for PolarSSL to do the SSL/TLS stuff
August:
Public curl releases: 117
Command line options: 138
curl_easy_setopt() options: 180
Public functions in libcurl: 58
Known libcurl bindings: 39
Contributors: 808
Gopher support added (re-added actually)
2012
----
July: Added support for Schannel (native Windows TLS backend) and Darwin SSL
(Native Mac OS X and iOS TLS backend).
Supports metalink
October: SSH-agent support.
2013
----
February: Cleaned up internals to always uses the "multi" non-blocking
approach internally and only expose the blocking API with a wrapper.
September: First small steps on supporting HTTP/2 with nghttp2.
October: Removed krb4 support.
December: Happy eyeballs.
2014
----
March: first real release supporting HTTP/2
September: Web site had 245,000 unique visitors and served 236GB data

View File

@@ -1,104 +0,0 @@
# HTTP Cookies
## Cookie overview
Cookies are `name=contents` pairs that a HTTP server tells the client to
hold and then the client sends back those to the server on subsequent
requests to the same domains and paths for which the cookies were set.
Cookies are either "session cookies" which typically are forgotten when the
session is over which is often translated to equal when browser quits, or
the cookies aren't session cookies they have expiration dates after which
the client will throw them away.
Cookies are set to the client with the Set-Cookie: header and are sent to
servers with the Cookie: header.
For a very long time, the only spec explaining how to use cookies was the
original [Netscape spec from 1994](https://curl.haxx.se/rfc/cookie_spec.html).
In 2011, [RFC6265](https://www.ietf.org/rfc/rfc6265.txt) was finally
published and details how cookies work within HTTP.
## Cookies saved to disk
Netscape once created a file format for storing cookies on disk so that they
would survive browser restarts. curl adopted that file format to allow
sharing the cookies with browsers, only to see browsers move away from that
format. Modern browsers no longer use it, while curl still does.
The netscape cookie file format stores one cookie per physical line in the
file with a bunch of associated meta data, each field separated with
TAB. That file is called the cookiejar in curl terminology.
When libcurl saves a cookiejar, it creates a file header of its own in which
there is a URL mention that will link to the web version of this document.
## Cookies with curl the command line tool
curl has a full cookie "engine" built in. If you just activate it, you can
have curl receive and send cookies exactly as mandated in the specs.
Command line options:
`-b, --cookie`
tell curl a file to read cookies from and start the cookie engine, or if it
isn't a file it will pass on the given string. -b name=var works and so does
-b cookiefile.
`-j, --junk-session-cookies`
when used in combination with -b, it will skip all "session cookies" on load
so as to appear to start a new cookie session.
`-c, --cookie-jar`
tell curl to start the cookie engine and write cookies to the given file
after the request(s)
## Cookies with libcurl
libcurl offers several ways to enable and interface the cookie engine. These
options are the ones provided by the native API. libcurl bindings may offer
access to them using other means.
`CURLOPT_COOKIE`
Is used when you want to specify the exact contents of a cookie header to
send to the server.
`CURLOPT_COOKIEFILE`
Tell libcurl to activate the cookie engine, and to read the initial set of
cookies from the given file. Read-only.
`CURLOPT_COOKIEJAR`
Tell libcurl to activate the cookie engine, and when the easy handle is
closed save all known cookies to the given cookiejar file. Write-only.
`CURLOPT_COOKIELIST`
Provide detailed information about a single cookie to add to the internal
storage of cookies. Pass in the cookie as a HTTP header with all the details
set, or pass in a line from a netscape cookie file. This option can also be
used to flush the cookies etc.
`CURLINFO_COOKIELIST`
Extract cookie information from the internal cookie storage as a linked
list.
## Cookies with javascript
These days a lot of the web is built up by javascript. The webbrowser loads
complete programs that render the page you see. These javascript programs
can also set and access cookies.
Since curl and libcurl are plain HTTP clients without any knowledge of or
capability to handle javascript, such cookies will not be detected or used.
Often, if you want to mimic what a browser does on such web sites, you can
record web browser HTTP traffic when using such a site and then repeat the
cookie operations using curl or libcurl.

View File

@@ -1,126 +0,0 @@
HTTP/2 with curl
================
[HTTP/2 Spec](https://www.rfc-editor.org/rfc/rfc7540.txt)
[http2 explained](https://daniel.haxx.se/http2/)
Build prerequisites
-------------------
- nghttp2
- OpenSSL, libressl, BoringSSL, NSS, GnutTLS, mbedTLS, wolfSSL or SChannel
with a new enough version.
[nghttp2](https://nghttp2.org/)
-------------------------------
libcurl uses this 3rd party library for the low level protocol handling
parts. The reason for this is that HTTP/2 is much more complex at that layer
than HTTP/1.1 (which we implement on our own) and that nghttp2 is an already
existing and well functional library.
We require at least version 1.0.0.
Over an http:// URL
-------------------
If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will
include an upgrade header in the initial request to the host to allow
upgrading to HTTP/2.
Possibly we can later introduce an option that will cause libcurl to fail if
not possible to upgrade. Possibly we introduce an option that makes libcurl
use HTTP/2 at once over http://
Over an https:// URL
--------------------
If `CURLOPT_HTTP_VERSION` is set to `CURL_HTTP_VERSION_2_0`, libcurl will use
ALPN (or NPN) to negotiate which protocol to continue with. Possibly introduce
an option that will cause libcurl to fail if not possible to use HTTP/2.
`CURL_HTTP_VERSION_2TLS` was added in 7.47.0 as a way to ask libcurl to prefer
HTTP/2 for HTTPS but stick to 1.1 by default for plain old HTTP connections.
ALPN is the TLS extension that HTTP/2 is expected to use. The NPN extension is
for a similar purpose, was made prior to ALPN and is used for SPDY so early
HTTP/2 servers are implemented using NPN before ALPN support is widespread.
`CURLOPT_SSL_ENABLE_ALPN` and `CURLOPT_SSL_ENABLE_NPN` are offered to allow
applications to explicitly disable ALPN or NPN.
SSL libs
--------
The challenge is the ALPN and NPN support and all our different SSL
backends. You may need a fairly updated SSL library version for it to provide
the necessary TLS features. Right now we support:
- OpenSSL: ALPN and NPN
- libressl: ALPN and NPN
- BoringSSL: ALPN and NPN
- NSS: ALPN and NPN
- GnuTLS: ALPN
- mbedTLS: ALPN
- SChannel: ALPN
- wolfSSL: ALPN
Multiplexing
------------
Starting in 7.43.0, libcurl fully supports HTTP/2 multiplexing, which is the
term for doing multiple independent transfers over the same physical TCP
connection.
To take advantage of multiplexing, you need to use the multi interface and set
`CURLMOPT_PIPELINING` to `CURLPIPE_MULTIPLEX`. With that bit set, libcurl will
attempt to re-use existing HTTP/2 connections and just add a new stream over
that when doing subsequent parallel requests.
While libcurl sets up a connection to a HTTP server there is a period during
which it doesn't know if it can pipeline or do multiplexing and if you add new
transfers in that period, libcurl will default to start new connections for
those transfers. With the new option `CURLOPT_PIPEWAIT` (added in 7.43.0), you
can ask that a transfer should rather wait and see in case there's a
connection for the same host in progress that might end up being possible to
multiplex on. It favours keeping the number of connections low to the cost of
slightly longer time to first byte transferred.
Applications
------------
We hide HTTP/2's binary nature and convert received HTTP/2 traffic to headers
in HTTP 1.1 style. This allows applications to work unmodified.
curl tool
---------
curl offers the `--http2` command line option to enable use of HTTP/2.
curl offers the `--http2-prior-knowledge` command line option to enable use of
HTTP/2 without HTTP/1.1 Upgrade.
Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections.
curl tool limitations
---------------------
The command line tool won't do any HTTP/2 multiplexing even though libcurl
supports it, simply because the curl tool is not written to take advantage of
the libcurl API that's necessary for this (the multi interface). We have an
outstanding TODO item for this and **you** can help us make it happen.
The command line tool also doesn't support HTTP/2 server push for the same
reason it doesn't do multiplexing: it needs to use the multi interface for
that so that multiplexing is supported.
HTTP Alternative Services
-------------------------
Alt-Svc is an extension with a corresponding frame (ALTSVC) in HTTP/2 that
tells the client about an alternative "route" to the same content for the same
origin server that you get the response from. A browser or long-living client
can use that hint to create a new connection asynchronously. For libcurl, we
may introduce a way to bring such clues to the application and/or let a
subsequent request use the alternate route automatically.
[Detailed in RFC 7838](https://tools.ietf.org/html/rfc7838)

View File

@@ -1,9 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
How To Compile
see INSTALL.md

View File

@@ -1,513 +0,0 @@
# how to install curl and libcurl
## Installing Binary Packages
Lots of people download binary distributions of curl and libcurl. This
document does not describe how to install curl or libcurl using such a binary
package. This document describes how to compile, build and install curl and
libcurl from source code.
## Building from git
If you get your code off a git repository instead of a release tarball, see
the `GIT-INFO` file in the root directory for specific instructions on how to
proceed.
# Unix
A normal Unix installation is made in three or four steps (after you've
unpacked the source archive):
./configure
make
make test (optional)
make install
You probably need to be root when doing the last command.
Get a full listing of all available configure options by invoking it like:
./configure --help
If you want to install curl in a different file hierarchy than `/usr/local`,
specify that when running configure:
./configure --prefix=/path/to/curl/tree
If you have write permission in that directory, you can do 'make install'
without being root. An example of this would be to make a local install in
your own home directory:
./configure --prefix=$HOME
make
make install
The configure script always tries to find a working SSL library unless
explicitly told not to. If you have OpenSSL installed in the default search
path for your compiler/linker, you don't need to do anything special. If you
have OpenSSL installed in /usr/local/ssl, you can run configure like:
./configure --with-ssl
If you have OpenSSL installed somewhere else (for example, /opt/OpenSSL) and
you have pkg-config installed, set the pkg-config path first, like this:
env PKG_CONFIG_PATH=/opt/OpenSSL/lib/pkgconfig ./configure --with-ssl
Without pkg-config installed, use this:
./configure --with-ssl=/opt/OpenSSL
If you insist on forcing a build without SSL support, even though you may
have OpenSSL installed in your system, you can run configure like this:
./configure --without-ssl
If you have OpenSSL installed, but with the libraries in one place and the
header files somewhere else, you have to set the LDFLAGS and CPPFLAGS
environment variables prior to running configure. Something like this should
work:
CPPFLAGS="-I/path/to/ssl/include" LDFLAGS="-L/path/to/ssl/lib" ./configure
If you have shared SSL libs installed in a directory where your run-time
linker doesn't find them (which usually causes configure failures), you can
provide the -R option to ld on some operating systems to set a hard-coded
path to the run-time linker:
LDFLAGS=-R/usr/local/ssl/lib ./configure --with-ssl
## More Options
To force a static library compile, disable the shared library creation by
running configure like:
./configure --disable-shared
To tell the configure script to skip searching for thread-safe functions, add
an option like:
./configure --disable-thread
If you're a curl developer and use gcc, you might want to enable more debug
options with the `--enable-debug` option.
curl can be built to use a whole range of libraries to provide various useful
services, and configure will try to auto-detect a decent default. But if you
want to alter it, you can select how to deal with each individual library.
## Select TLS backend
The default OpenSSL configure check will also detect and use BoringSSL or
libressl.
- GnuTLS: `--without-ssl --with-gnutls`.
- Cyassl: `--without-ssl --with-cyassl`
- NSS: `--without-ssl --with-nss`
- PolarSSL: `--without-ssl --with-polarssl`
- mbedTLS: `--without-ssl --with-mbedtls`
- axTLS: `--without-ssl --with-axtls`
- schannel: `--without-ssl --with-winssl`
- secure transport: `--with-winssl --with-darwinssl`
# Windows
## Building Windows DLLs and C run-time (CRT) linkage issues
As a general rule, building a DLL with static CRT linkage is highly
discouraged, and intermixing CRTs in the same app is something to avoid at
any cost.
Reading and comprehending Microsoft Knowledge Base articles KB94248 and
KB140584 is a must for any Windows developer. Especially important is full
understanding if you are not going to follow the advice given above.
- [How To Use the C Run-Time](https://support.microsoft.com/kb/94248/en-us)
- [How to link with the correct C Run-Time CRT library](https://support.microsoft.com/kb/140584/en-us)
- [Potential Errors Passing CRT Objects Across DLL Boundaries](https://msdn.microsoft.com/en-us/library/ms235460)
If your app is misbehaving in some strange way, or it is suffering from
memory corruption, before asking for further help, please try first to
rebuild every single library your app uses as well as your app using the
debug multithreaded dynamic C runtime.
If you get linkage errors read section 5.7 of the FAQ document.
## MingW32
Make sure that MinGW32's bin dir is in the search path, for example:
set PATH=c:\mingw32\bin;%PATH%
then run `mingw32-make mingw32` in the root dir. There are other
make targets available to build libcurl with more features, use:
- `mingw32-make mingw32-zlib` to build with Zlib support;
- `mingw32-make mingw32-ssl-zlib` to build with SSL and Zlib enabled;
- `mingw32-make mingw32-ssh2-ssl-zlib` to build with SSH2, SSL, Zlib;
- `mingw32-make mingw32-ssh2-ssl-sspi-zlib` to build with SSH2, SSL, Zlib
and SSPI support.
If you have any problems linking libraries or finding header files, be sure
to verify that the provided "Makefile.m32" files use the proper paths, and
adjust as necessary. It is also possible to override these paths with
environment variables, for example:
set ZLIB_PATH=c:\zlib-1.2.8
set OPENSSL_PATH=c:\openssl-1.0.2c
set LIBSSH2_PATH=c:\libssh2-1.6.0
It is also possible to build with other LDAP SDKs than MS LDAP; currently
it is possible to build with native Win32 OpenLDAP, or with the Novell CLDAP
SDK. If you want to use these you need to set these vars:
set LDAP_SDK=c:\openldap
set USE_LDAP_OPENLDAP=1
or for using the Novell SDK:
set USE_LDAP_NOVELL=1
If you want to enable LDAPS support then set LDAPS=1.
## Cygwin
Almost identical to the unix installation. Run the configure script in the
curl source tree root with `sh configure`. Make sure you have the sh
executable in /bin/ or you'll see the configure fail toward the end.
Run `make`
## Borland C++ compiler
Ensure that your build environment is properly set up to use the compiler and
associated tools. PATH environment variable must include the path to bin
subdirectory of your compiler installation, eg: `c:\Borland\BCC55\bin`
It is advisable to set environment variable BCCDIR to the base path of the
compiler installation.
set BCCDIR=c:\Borland\BCC55
In order to build a plain vanilla version of curl and libcurl run the
following command from curl's root directory:
make borland
To build curl and libcurl with zlib and OpenSSL support set environment
variables `ZLIB_PATH` and `OPENSSL_PATH` to the base subdirectories of the
already built zlib and OpenSSL libraries and from curl's root directory run
command:
make borland-ssl-zlib
libcurl library will be built in 'lib' subdirectory while curl tool is built
in 'src' subdirectory. In order to use libcurl library it is advisable to
modify compiler's configuration file bcc32.cfg located in
`c:\Borland\BCC55\bin` to reflect the location of libraries include paths for
example the '-I' line could result in something like:
-I"c:\Borland\BCC55\include;c:\curl\include;c:\openssl\inc32"
bcc3.cfg `-L` line could also be modified to reflect the location of of
libcurl library resulting for example:
-L"c:\Borland\BCC55\lib;c:\curl\lib;c:\openssl\out32"
In order to build sample program `simple.c` from the docs\examples
subdirectory run following command from mentioned subdirectory:
bcc32 simple.c libcurl.lib cw32mt.lib
In order to build sample program simplessl.c an SSL enabled libcurl is
required, as well as the OpenSSL libeay32.lib and ssleay32.lib libraries.
## Disabling Specific Protocols in Windows builds
The configure utility, unfortunately, is not available for the Windows
environment, therefore, you cannot use the various disable-protocol options of
the configure utility on this platform.
However, you can use the following defines to disable specific
protocols:
- `HTTP_ONLY` disables all protocols except HTTP
- `CURL_DISABLE_FTP` disables FTP
- `CURL_DISABLE_LDAP` disables LDAP
- `CURL_DISABLE_TELNET` disables TELNET
- `CURL_DISABLE_DICT` disables DICT
- `CURL_DISABLE_FILE` disables FILE
- `CURL_DISABLE_TFTP` disables TFTP
- `CURL_DISABLE_HTTP` disables HTTP
- `CURL_DISABLE_IMAP` disables IMAP
- `CURL_DISABLE_POP3` disables POP3
- `CURL_DISABLE_SMTP` disables SMTP
If you want to set any of these defines you have the following options:
- Modify lib/config-win32.h
- Modify lib/curl_setup.h
- Modify lib/Makefile.vc6
- Modify the "Preprocessor Definitions" in the libcurl project
Note: The pre-processor settings can be found using the Visual Studio IDE
under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
versions.
## Using BSD-style lwIP instead of Winsock TCP/IP stack in Win32 builds
In order to compile libcurl and curl using BSD-style lwIP TCP/IP stack it is
necessary to make definition of preprocessor symbol USE_LWIPSOCK visible to
libcurl and curl compilation processes. To set this definition you have the
following alternatives:
- Modify lib/config-win32.h and src/config-win32.h
- Modify lib/Makefile.vc6
- Modify the "Preprocessor Definitions" in the libcurl project
Note: The pre-processor settings can be found using the Visual Studio IDE
under "Project -> Settings -> C/C++ -> General" in VC6 and "Project ->
Properties -> Configuration Properties -> C/C++ -> Preprocessor" in later
versions.
Once that libcurl has been built with BSD-style lwIP TCP/IP stack support, in
order to use it with your program it is mandatory that your program includes
lwIP header file `<lwip/opt.h>` (or another lwIP header that includes this)
before including any libcurl header. Your program does not need the
`USE_LWIPSOCK` preprocessor definition which is for libcurl internals only.
Compilation has been verified with [lwIP
1.4.0](http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip) and
[contrib-1.4.0](http://download.savannah.gnu.org/releases/lwip/contrib-1.4.0.zip).
This BSD-style lwIP TCP/IP stack support must be considered experimental given
that it has been verified that lwIP 1.4.0 still needs some polish, and libcurl
might yet need some additional adjustment, caveat emptor.
## Important static libcurl usage note
When building an application that uses the static libcurl library on Windows,
you must add `-DCURL_STATICLIB` to your `CFLAGS`. Otherwise the linker will
look for dynamic import symbols.
## Legacy Windows and SSL
WinSSL (specifically SChannel from Windows SSPI), is the native SSL library in
Windows. However, WinSSL in Windows <= XP is unable to connect to servers that
no longer support the legacy handshakes and algorithms used by those
versions. If you will be using curl in one of those earlier versions of
Windows you should choose another SSL backend such as OpenSSL.
# Apple iOS and Mac OS X
On modern Apple operating systems, curl can be built to use Apple's SSL/TLS
implementation, Secure Transport, instead of OpenSSL. To build with Secure
Transport for SSL/TLS, use the configure option `--with-darwinssl`. (It is not
necessary to use the option `--without-ssl`.) This feature requires iOS 5.0 or
later, or OS X 10.5 ("Leopard") or later.
When Secure Transport is in use, the curl options `--cacert` and `--capath`
and their libcurl equivalents, will be ignored, because Secure Transport uses
the certificates stored in the Keychain to evaluate whether or not to trust
the server. This, of course, includes the root certificates that ship with the
OS. The `--cert` and `--engine` options, and their libcurl equivalents, are
currently unimplemented in curl with Secure Transport.
For OS X users: In OS X 10.8 ("Mountain Lion"), Apple made a major overhaul to
the Secure Transport API that, among other things, added support for the newer
TLS 1.1 and 1.2 protocols. To get curl to support TLS 1.1 and 1.2, you must
build curl on Mountain Lion or later, or by using the equivalent SDK. If you
set the `MACOSX_DEPLOYMENT_TARGET` environmental variable to an earlier
version of OS X prior to building curl, then curl will use the new Secure
Transport API on Mountain Lion and later, and fall back on the older API when
the same curl binary is executed on older cats. For example, running these
commands in curl's directory in the shell will build the code such that it
will run on cats as old as OS X 10.6 ("Snow Leopard") (using bash):
export MACOSX_DEPLOYMENT_TARGET="10.6"
./configure --with-darwinssl
make
# Cross compile
Download and unpack the curl package.
'cd' to the new directory. (e.g. `cd curl-7.12.3`)
Set environment variables to point to the cross-compile toolchain and call
configure with any options you need. Be sure and specify the `--host` and
`--build` parameters at configuration time. The following script is an
example of cross-compiling for the IBM 405GP PowerPC processor using the
toolchain from MonteVista for Hardhat Linux.
#! /bin/sh
export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
export AR=ppc_405-ar
export AS=ppc_405-as
export LD=ppc_405-ld
export RANLIB=ppc_405-ranlib
export CC=ppc_405-gcc
export NM=ppc_405-nm
./configure --target=powerpc-hardhat-linux
--host=powerpc-hardhat-linux
--build=i586-pc-linux-gnu
--prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
--exec-prefix=/usr/local
You may also need to provide a parameter like `--with-random=/dev/urandom` to
configure as it cannot detect the presence of a random number generating
device for a target system. The `--prefix` parameter specifies where curl
will be installed. If `configure` completes successfully, do `make` and `make
install` as usual.
In some cases, you may be able to simplify the above commands to as little as:
./configure --host=ARCH-OS
# REDUCING SIZE
There are a number of configure options that can be used to reduce the size of
libcurl for embedded applications where binary size is an important factor.
First, be sure to set the CFLAGS variable when configuring with any relevant
compiler optimization flags to reduce the size of the binary. For gcc, this
would mean at minimum the -Os option, and potentially the `-march=X`,
`-mdynamic-no-pic` and `-flto` options as well, e.g.
./configure CFLAGS='-Os' LDFLAGS='-Wl,-Bsymbolic'...
Note that newer compilers often produce smaller code than older versions
due to improved optimization.
Be sure to specify as many `--disable-` and `--without-` flags on the
configure command-line as you can to disable all the libcurl features that you
know your application is not going to need. Besides specifying the
`--disable-PROTOCOL` flags for all the types of URLs your application will not
use, here are some other flags that can reduce the size of the library:
- `--disable-ares` (disables support for the C-ARES DNS library)
- `--disable-cookies` (disables support for HTTP cookies)
- `--disable-crypto-auth` (disables HTTP cryptographic authentication)
- `--disable-ipv6` (disables support for IPv6)
- `--disable-manual` (disables support for the built-in documentation)
- `--disable-proxy` (disables support for HTTP and SOCKS proxies)
- `--disable-unix-sockets` (disables support for UNIX sockets)
- `--disable-verbose` (eliminates debugging strings and error code strings)
- `--disable-versioned-symbols` (disables support for versioned symbols)
- `--enable-hidden-symbols` (eliminates unneeded symbols in the shared library)
- `--without-libidn` (disables support for the libidn DNS library)
- `--without-librtmp` (disables support for RTMP)
- `--without-ssl` (disables support for SSL/TLS)
- `--without-zlib` (disables support for on-the-fly decompression)
The GNU compiler and linker have a number of options that can reduce the
size of the libcurl dynamic libraries on some platforms even further.
Specify them by providing appropriate CFLAGS and LDFLAGS variables on the
configure command-line, e.g.
CFLAGS="-Os -ffunction-sections -fdata-sections
-fno-unwind-tables -fno-asynchronous-unwind-tables -flto"
LDFLAGS="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections"
Be sure also to strip debugging symbols from your binaries after compiling
using 'strip' (or the appropriate variant if cross-compiling). If space is
really tight, you may be able to remove some unneeded sections of the shared
library using the -R option to objcopy (e.g. the .comment section).
Using these techniques it is possible to create a basic HTTP-only shared
libcurl library for i386 Linux platforms that is only 113 KiB in size, and an
FTP-only library that is 113 KiB in size (as of libcurl version 7.50.3, using
gcc 5.4.0).
You may find that statically linking libcurl to your application will result
in a lower total size than dynamically linking.
Note that the curl test harness can detect the use of some, but not all, of
the `--disable` statements suggested above. Use will cause tests relying on
those features to fail. The test harness can be manually forced to skip the
relevant tests by specifying certain key words on the runtests.pl command
line. Following is a list of appropriate key words:
- `--disable-cookies` !cookies
- `--disable-manual` !--manual
- `--disable-proxy` !HTTP\ proxy !proxytunnel !SOCKS4 !SOCKS5
# PORTS
This is a probably incomplete list of known hardware and operating systems
that curl has been compiled for. If you know a system curl compiles and
runs on, that isn't listed, please let us know!
- Alpha DEC OSF 4
- Alpha Digital UNIX v3.2
- Alpha FreeBSD 4.1, 4.5
- Alpha Linux 2.2, 2.4
- Alpha NetBSD 1.5.2
- Alpha OpenBSD 3.0
- Alpha OpenVMS V7.1-1H2
- Alpha Tru64 v5.0 5.1
- AVR32 Linux
- ARM Android 1.5, 2.1, 2.3, 3.2, 4.x
- ARM INTEGRITY
- ARM iOS
- Cell Linux
- Cell Cell OS
- HP-PA HP-UX 9.X 10.X 11.X
- HP-PA Linux
- HP3000 MPE/iX
- MicroBlaze uClinux
- MIPS IRIX 6.2, 6.5
- MIPS Linux
- OS/400
- Pocket PC/Win CE 3.0
- Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2
- PowerPC Darwin 1.0
- PowerPC INTEGRITY
- PowerPC Linux
- PowerPC Mac OS 9
- PowerPC Mac OS X
- SH4 Linux 2.6.X
- SH4 OS21
- SINIX-Z v5
- Sparc Linux
- Sparc Solaris 2.4, 2.5, 2.5.1, 2.6, 7, 8, 9, 10
- Sparc SunOS 4.1.X
- StrongARM (and other ARM) RISC OS 3.1, 4.02
- StrongARM/ARM7/ARM9 Linux 2.4, 2.6
- StrongARM NetBSD 1.4.1
- Symbian OS (P.I.P.S.) 9.x
- TPF
- Ultrix 4.3a
- UNICOS 9.0
- i386 BeOS
- i386 DOS
- i386 eCos 1.3.1
- i386 Esix 4.1
- i386 FreeBSD
- i386 HURD
- i386 Haiku OS
- i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6
- i386 Mac OS X
- i386 MINIX 3.1
- i386 NetBSD
- i386 Novell NetWare
- i386 OS/2
- i386 OpenBSD
- i386 QNX 6
- i386 SCO unix
- i386 Solaris 2.7
- i386 Windows 95, 98, ME, NT, 2000, XP, 2003
- i486 ncr-sysv4.3.03 (NCR MP-RAS)
- ia64 Linux 2.3.99
- m68k AmigaOS 3
- m68k Linux
- m68k uClinux
- m68k OpenBSD
- m88k dg-dgux5.4R3.00
- s390 Linux
- x86_64 Linux
- XScale/PXA250 Linux 2.4
- Nios II uClinux

File diff suppressed because it is too large Load Diff

View File

@@ -1,622 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
Known Bugs
These are problems and bugs known to exist at the time of this release. Feel
free to join in and help us correct one or more of these! Also be sure to
check the changelog of the current development status, as one or more of these
problems may have been fixed or changed somewhat since this was written!
1. HTTP
1.1 CURLFORM_CONTENTLEN in an array
1.2 Disabling HTTP Pipelining
1.3 STARTTRANSFER time is wrong for HTTP POSTs
1.4 multipart formposts file name encoding
1.5 Expect-100 meets 417
1.6 Unnecessary close when 401 received waiting for 100
1.8 DNS timing is wrong for HTTP redirects
1.9 HTTP/2 frames while in the connection pool kill reuse
1.10 Strips trailing dot from host name
1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
1.12 HTTP/2 server push enabled when no pushes can be accepted
2. TLS
2.1 Hangs with PolarSSL
2.2 CURLINFO_SSL_VERIFYRESULT has limited support
2.3 DER in keychain
2.4 GnuTLS backend skips really long certificate fields
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
3.2 No disconnect command
3.3 SMTP to multiple recipients
3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses
4. Command line
4.1 -J with %-encoded file nameas
4.2 -J with -C - fails
4.3 --retry and transfer timeouts
5. Build and portability issues
5.1 Windows Borland compiler
5.2 curl-config --libs contains private details
5.3 libidn and old iconv
5.4 AIX shared build with c-ares fails
5.5 can't handle Unicode arguments in Windows
5.6 cmake support gaps
5.7 Visual Studio project gaps
5.8 configure finding libs in wrong directory
5.9 Utilize Requires.private directives in libcurl.pc
5.10 Fix the gcc typechecks
6. Authentication
6.1 NTLM authentication and unicode
6.2 MIT Kerberos for Windows build
6.3 NTLM in system context uses wrong name
6.4 Negotiate and Kerberos V5 need a fake user name
7. FTP
7.1 FTP without or slow 220 response
7.2 FTP with CONNECT and slow server
7.3 FTP with NOBODY and FAILONERROR
7.4 FTP with ACCT
7.5 ASCII FTP
7.6 FTP with NULs in URL parts
7.7 FTP and empty path parts in the URL
7.8 Premature transfer end but healthy control channel
8. TELNET
8.1 TELNET and time limtiations don't work
8.2 Microsoft telnet server
9. SFTP and SCP
9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct
10. SOCKS
10.1 SOCKS proxy connections are done blocking
10.2 SOCKS don't support timeouts
10.3 FTPS over SOCKS
10.4 active FTP over a SOCKS
11. Internals
11.1 Curl leaks .onion hostnames in DNS
11.2 error buffer not set if connection to multiple addresses fails
11.3 c-ares deviates from stock resolver on http://1346569778
12. LDAP and OpenLDAP
12.1 OpenLDAP hangs after returning results
13. TCP/IP
13.1 --interface for ipv6 binds to unusable IP address
==============================================================================
1. HTTP
1.1 CURLFORM_CONTENTLEN in an array
It is not possible to pass a 64-bit value using CURLFORM_CONTENTLEN with
CURLFORM_ARRAY, when compiled on 32-bit platforms that support 64-bit
integers. This is because the underlying structure 'curl_forms' uses a dual
purpose char* for storing these values in via casting. For more information
see the now closed related issue:
https://github.com/curl/curl/issues/608
1.2 Disabling HTTP Pipelining
Disabling HTTP Pipelining when there are ongoing transfers can lead to
heap corruption and crash. https://curl.haxx.se/bug/view.cgi?id=1411
1.3 STARTTRANSFER time is wrong for HTTP POSTs
Wrong STARTTRANSFER timer accounting for POST requests Timer works fine with
GET requests, but while using POST the time for CURLINFO_STARTTRANSFER_TIME
is wrong. While using POST CURLINFO_STARTTRANSFER_TIME minus
CURLINFO_PRETRANSFER_TIME is near to zero every time.
https://github.com/curl/curl/issues/218
https://curl.haxx.se/bug/view.cgi?id=1213
1.4 multipart formposts file name encoding
When creating multipart formposts. The file name part can be encoded with
something beyond ascii but currently libcurl will only pass in the verbatim
string the app provides. There are several browsers that already do this
encoding. The key seems to be the updated draft to RFC2231:
https://tools.ietf.org/html/draft-reschke-rfc2231-in-http-02
1.5 Expect-100 meets 417
If an upload using Expect: 100-continue receives an HTTP 417 response, it
ought to be automatically resent without the Expect:. A workaround is for
the client application to redo the transfer after disabling Expect:.
https://curl.haxx.se/mail/archive-2008-02/0043.html
1.6 Unnecessary close when 401 received waiting for 100
libcurl closes the connection if an HTTP 401 reply is received while it is
waiting for the the 100-continue response.
https://curl.haxx.se/mail/lib-2008-08/0462.html
1.8 DNS timing is wrong for HTTP redirects
When extracting timing information after HTTP redirects, only the last
transfer's results are returned and not the totals:
https://github.com/curl/curl/issues/522
1.9 HTTP/2 frames while in the connection pool kill reuse
If the server sends HTTP/2 frames (like for example an HTTP/2 PING frame) to
curl while the connection is held in curl's connection pool, the socket will
be found readable when considered for reuse and that makes curl think it is
dead and then it will be closed and a new connection gets created instead.
This is *best* fixed by adding monitoring to connections while they are kept
in the pool so that pings can be responded to appropriately.
1.10 Strips trailing dot from host name
When given a URL wit a trailing dot for the host name part:
"https://example.com./", libcurl will strip off the dot and use the name
without a dot internally and send it dot-less in HTTP Host: headers and in
the TLS SNI field.
The HTTP part violates RFC 7230 section 5.4 but the SNI part is accordance
with RFC 6066 section 3.
URLs using these trailing dots are very rare in the wild and we have not seen
or gotten any real-world problems with such URLs reported. The popular
browsers seem to have stayed with not stripping the dot for both uses (thus
they violate RFC 6066 instead of RFC 7230).
Daniel took the discussion to the HTTPbis mailing list in March 2016:
https://lists.w3.org/Archives/Public/ietf-http-wg/2016JanMar/0430.html but
there was not major rush or interest to fix this. The impression I get is
that most HTTP people rather not rock the boat now and instead prioritize web
compatibility rather than to strictly adhere to these RFCs.
Our current approach allows a knowing client to send a custom HTTP header
with the dot added.
It can also be noted that while adding a trailing dot to the host name in
most (all?) cases will make the name resolve to the same set of IP addresses,
many HTTP servers will not happily accept the trailing dot there unless that
has been specificly configured to be a fine virtual host.
If URLs with trailing dots for host names become more popular or even just
used more than for just plain fun experiments, I'm sure we will have reason
to go back and reconsider.
See https://github.com/curl/curl/issues/716 for the discussion.
1.11 CURLOPT_SEEKFUNCTION not called with CURLFORM_STREAM
I'm using libcurl to POST form data using a FILE* with the CURLFORM_STREAM
option of curl_formadd(). I've noticed that if the connection drops at just
the right time, the POST is reattempted without the data from the file. It
seems like the file stream position isn't getting reset to the beginning of
the file. I found the CURLOPT_SEEKFUNCTION option and set that with a
function that performs an fseek() on the FILE*. However, setting that didn't
seem to fix the issue or even get called. See
https://github.com/curl/curl/issues/768
1.12 HTTP/2 server push enabled when no pushes can be accepted
If the easy interface is used, we can't accept any server pushes so we should
switch off them already in the h2 settings as otherwise we risk wasting
bandwidth when the server tries to send pushes libcurl will never accept.
See https://github.com/curl/curl/issues/927
2. TLS
2.1 Hangs with PolarSSL
"curl_easy_perform hangs with imap and PolarSSL"
https://github.com/curl/curl/issues/334
Most likely, a fix similar to commit c111178bd4 (for mbedTLS) is
necessary. Or if we just wait a little longer we'll rip out all support for
PolarSSL instead...
2.2 CURLINFO_SSL_VERIFYRESULT has limited support
CURLINFO_SSL_VERIFYRESULT is only implemented for the OpenSSL and NSS
backends, so relying on this information in a generic app is flaky.
2.3 DER in keychain
Curl doesn't recognize certificates in DER format in keychain, but it works
with PEM. https://curl.haxx.se/bug/view.cgi?id=1065
2.4 GnuTLS backend skips really long certificate fields
libcurl calls gnutls_x509_crt_get_dn() with a fixed buffer size and if the
field is too long in the cert, it'll just return an error and the field will
be displayed blank.
3. Email protocols
3.1 IMAP SEARCH ALL truncated response
IMAP "SEARCH ALL" truncates output on large boxes. "A quick search of the
code reveals that pingpong.c contains some truncation code, at line 408, when
it deems the server response to be too large truncating it to 40 characters"
https://curl.haxx.se/bug/view.cgi?id=1366
3.2 No disconnect command
The disconnect commands (LOGOUT and QUIT) may not be sent by IMAP, POP3 and
SMTP if a failure occurs during the authentication phase of a connection.
3.3 SMTP to multiple recipients
When sending data to multiple recipients, curl will abort and return failure
if one of the recipients indicate failure (on the "RCPT TO"
command). Ordinary mail programs would proceed and still send to the ones
that can receive data. This is subject for change in the future.
https://curl.haxx.se/bug/view.cgi?id=1116
3.4 POP3 expects "CRLF.CRLF" eob for some single-line responses
You have to tell libcurl not to expect a body, when dealing with one line
response commands. Please see the POP3 examples and test cases which show
this for the NOOP and DELE commands. https://curl.haxx.se/bug/?i=740
4. Command line
4.1 -J with %-encoded file nameas
-J/--remote-header-name doesn't decode %-encoded file names. RFC6266 details
how it should be done. The can of worm is basically that we have no charset
handling in curl and ascii >=128 is a challenge for us. Not to mention that
decoding also means that we need to check for nastiness that is attempted,
like "../" sequences and the like. Probably everything to the left of any
embedded slashes should be cut off.
https://curl.haxx.se/bug/view.cgi?id=1294
4.2 -J with -C - fails
When using -J (with -O), automatically resumed downloading together with "-C
-" fails. Without -J the same command line works! This happens because the
resume logic is worked out before the target file name (and thus its
pre-transfer size) has been figured out!
https://curl.haxx.se/bug/view.cgi?id=1169
4.3 --retry and transfer timeouts
If using --retry and the transfer timeouts (possibly due to using -m or
-y/-Y) the next attempt doesn't resume the transfer properly from what was
downloaded in the previous attempt but will truncate and restart at the
original position where it was at before the previous failed attempt. See
https://curl.haxx.se/mail/lib-2008-01/0080.html and Mandriva bug report
https://qa.mandriva.com/show_bug.cgi?id=22565
5. Build and portability issues
5.1 Windows Borland compiler
When building with the Windows Borland compiler, it fails because the "tlib"
tool doesn't support hyphens (minus signs) in file names and we have such in
the build. https://curl.haxx.se/bug/view.cgi?id=1222
5.2 curl-config --libs contains private details
"curl-config --libs" will include details set in LDFLAGS when configure is
run that might be needed only for building libcurl. Further, curl-config
--cflags suffers from the same effects with CFLAGS/CPPFLAGS.
5.3 libidn and old iconv
Test case 165 might fail on a system which has libidn present, but with an
old iconv version (2.1.3 is a known bad version), since it doesn't recognize
the charset when named ISO8859-1. Changing the name to ISO-8859-1 makes the
test pass, but instead makes it fail on Solaris hosts that use its native
iconv.
5.4 AIX shared build with c-ares fails
curl version 7.12.2 fails on AIX if compiled with --enable-ares. The
workaround is to combine --enable-ares with --disable-shared
5.5 can't handle Unicode arguments in Windows
If a URL or filename can't be encoded using the user's current codepage then
it can only be encoded properly in the Unicode character set. Windows uses
UTF-16 encoding for Unicode and stores it in wide characters, however curl
and libcurl are not equipped for that at the moment. And, except for Cygwin,
Windows can't use UTF-8 as a locale.
https://curl.haxx.se/bug/?i=345
https://curl.haxx.se/bug/?i=731
5.6 cmake support gaps
The cmake build setup lacks several features that the autoconf build
offers. This includes:
- symbol hiding when the shared library is built
- use of correct soname for the shared library build
- support for several TLS backends are missing
- the unit tests cause link failures in regular non-static builds
- no nghttp2 check
5.7 Visual Studio project gaps
The Visual Studio projects lack some features that the autoconf and nmake
builds offer, such as the following:
- support for zlib and nghttp2
- use of static runtime libraries
- add the test suite components
In addition to this the following could be implemented:
- support for other development IDEs
- add PATH environment variables for third-party DLLs
5.8 configure finding libs in wrong directory
When the configure script checks for third-party libraries, it adds those
directories to the LDFLAGS variable and then tries linking to see if it
works. When successful, the found directory is kept in the LDFLAGS variable
when the script continues to execute and do more tests and possibly check for
more libraries.
This can make subsequent checks for libraries wrongly detect another
installation in a directory that was previously added to LDFLAGS by another
library check!
A possibly better way to do these checks would be to keep the pristine LDFLAGS
even after successful checks and instead add those verified paths to a
separate variable that only after all library checks have been performed gets
appended to LDFLAGS.
5.9 Utilize Requires.private directives in libcurl.pc
https://github.com/curl/curl/issues/864
5.10 Fix the gcc typechecks
Issue #846 identifies a problem with the gcc-typechecks and how the types are
documented and checked for CURLINFO_CERTINFO but our attempts to fix the
issue were futile and needs more attention.
https://github.com/curl/curl/issues/846
6. Authentication
6.1 NTLM authentication and unicode
NTLM authentication involving unicode user name or password only works
properly if built with UNICODE defined together with the WinSSL/schannel
backend. The original problem was mentioned in:
https://curl.haxx.se/mail/lib-2009-10/0024.html
https://curl.haxx.se/bug/view.cgi?id=896
The WinSSL/schannel version verified to work as mentioned in
https://curl.haxx.se/mail/lib-2012-07/0073.html
6.2 MIT Kerberos for Windows build
libcurl fails to build with MIT Kerberos for Windows (KfW) due to KfW's
library header files exporting symbols/macros that should be kept private to
the KfW library. See ticket #5601 at http://krbdev.mit.edu/rt/
6.3 NTLM in system context uses wrong name
NTLM authentication using SSPI (on Windows) when (lib)curl is running in
"system context" will make it use wrong(?) user name - at least when compared
to what winhttp does. See https://curl.haxx.se/bug/view.cgi?id=535
6.4 Negotiate and Kerberos V5 need a fake user name
In order to get Negotiate (SPNEGO) authentication to work in HTTP or Kerberos
V5 in the e-mail protocols, you need to provide a (fake) user name (this
concerns both curl and the lib) because the code wrongly only considers
authentication if there's a user name provided by setting
conn->bits.user_passwd in url.c https://curl.haxx.se/bug/view.cgi?id=440 How?
https://curl.haxx.se/mail/lib-2004-08/0182.html A possible solution is to
either modify this variable to be set or introduce a variable such as
new conn->bits.want_authentication which is set when any of the authentication
options are set.
7. FTP
7.1 FTP without or slow 220 response
If a connection is made to a FTP server but the server then just never sends
the 220 response or otherwise is dead slow, libcurl will not acknowledge the
connection timeout during that phase but only the "real" timeout - which may
surprise users as it is probably considered to be the connect phase to most
people. Brought up (and is being misunderstood) in:
https://curl.haxx.se/bug/view.cgi?id=856
7.2 FTP with CONNECT and slow server
When doing FTP over a socks proxy or CONNECT through HTTP proxy and the multi
interface is used, libcurl will fail if the (passive) TCP connection for the
data transfer isn't more or less instant as the code does not properly wait
for the connect to be confirmed. See test case 564 for a first shot at a test
case.
7.3 FTP with NOBODY and FAILONERROR
It seems sensible to be able to use CURLOPT_NOBODY and CURLOPT_FAILONERROR
with FTP to detect if a file exists or not, but it is not working:
https://curl.haxx.se/mail/lib-2008-07/0295.html
7.4 FTP with ACCT
When doing an operation over FTP that requires the ACCT command (but not when
logging in), the operation will fail since libcurl doesn't detect this and
thus fails to issue the correct command:
https://curl.haxx.se/bug/view.cgi?id=635
7.5 ASCII FTP
FTP ASCII transfers do not follow RFC959. They don't convert the data
accordingly (not for sending nor for receiving). RFC 959 section 3.1.1.1
clearly describes how this should be done:
The sender converts the data from an internal character representation to
the standard 8-bit NVT-ASCII representation (see the Telnet
specification). The receiver will convert the data from the standard
form to his own internal form.
Since 7.15.4 at least line endings are converted.
7.6 FTP with NULs in URL parts
FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>,
<password>, and <fpath> components, encoded as "%00". The problem is that
curl_unescape does not detect this, but instead returns a shortened C string.
From a strict FTP protocol standpoint, NUL is a valid character within RFC
959 <string>, so the way to handle this correctly in curl would be to use a
data structure other than a plain C string, one that can handle embedded NUL
characters. From a practical standpoint, most FTP servers would not
meaningfully support NUL characters within RFC 959 <string>, anyway (e.g.,
Unix pathnames may not contain NUL).
7.7 FTP and empty path parts in the URL
libcurl ignores empty path parts in FTP URLs, whereas RFC1738 states that
such parts should be sent to the server as 'CWD ' (without an argument). The
only exception to this rule, is that we knowingly break this if the empty
part is first in the path, as then we use the double slashes to indicate that
the user wants to reach the root dir (this exception SHALL remain even when
this bug is fixed).
7.8 Premature transfer end but healthy control channel
When 'multi_done' is called before the transfer has been completed the normal
way, it is considered a "premature" transfer end. In this situation, libcurl
closes the connection assuming it doesn't know the state of the connection so
it can't be reused for subsequent requests.
With FTP however, this isn't necessarily true but there are a bunch of
situations (listed in the ftp_done code) where it *could* keep the connection
alive even in this situation - but the current code doesn't. Fixing this would
allow libcurl to reuse FTP connections better.
8. TELNET
8.1 TELNET and time limtiations don't work
When using telnet, the time limitation options don't work.
https://curl.haxx.se/bug/view.cgi?id=846
8.2 Microsoft telnet server
There seems to be a problem when connecting to the Microsoft telnet server.
https://curl.haxx.se/bug/view.cgi?id=649
9. SFTP and SCP
9.1 SFTP doesn't do CURLOPT_POSTQUOTE correct
When libcurl sends CURLOPT_POSTQUOTE commands when connected to a SFTP server
using the multi interface, the commands are not being sent correctly and
instead the connection is "cancelled" (the operation is considered done)
prematurely. There is a half-baked (busy-looping) patch provided in the bug
report but it cannot be accepted as-is. See
https://curl.haxx.se/bug/view.cgi?id=748
10. SOCKS
10.1 SOCKS proxy connections are done blocking
Both SOCKS5 and SOCKS4 proxy connections are done blocking, which is very bad
when used with the multi interface.
10.2 SOCKS don't support timeouts
The SOCKS4 connection codes don't properly acknowledge (connect) timeouts.
According to bug #1556528, even the SOCKS5 connect code does not do it right:
https://curl.haxx.se/bug/view.cgi?id=604
When connecting to a SOCK proxy, the (connect) timeout is not properly
acknowledged after the actual TCP connect (during the SOCKS "negotiate"
phase).
10.3 FTPS over SOCKS
libcurl doesn't support FTPS over a SOCKS proxy.
10.4 active FTP over a SOCKS
libcurl doesn't support active FTP over a SOCKS proxy
11. Internals
11.1 Curl leaks .onion hostnames in DNS
Curl sends DNS requests for hostnames with a .onion TLD. This leaks
information about what the user is attempting to access, and violates this
requirement of RFC7686: https://tools.ietf.org/html/rfc7686
Issue: https://github.com/curl/curl/issues/543
11.2 error buffer not set if connection to multiple addresses fails
If you ask libcurl to resolve a hostname like example.com to IPv6 addresses
only. But you only have IPv4 connectivity. libcurl will correctly fail with
CURLE_COULDNT_CONNECT. But the error buffer set by CURLOPT_ERRORBUFFER
remains empty. Issue: https://github.com/curl/curl/issues/544
11.3 c-ares deviates from stock resolver on http://1346569778
When using the socket resolvers, that URL becomes:
* Rebuilt URL to: http://1346569778/
* Trying 80.67.6.50...
but with c-ares it instead says "Could not resolve: 1346569778 (Domain name
not found)"
See https://github.com/curl/curl/issues/893
12. LDAP and OpenLDAP
12.1 OpenLDAP hangs after returning results
By configuration defaults, openldap automatically chase referrals on
secondary socket descriptors. The OpenLDAP backend is asynchronous and thus
should monitor all socket descriptors involved. Currently, these secondary
descriptors are not monitored, causing openldap library to never receive
data from them.
As a temporary workaround, disable referrals chasing by configuration.
The fix is not easy: proper automatic referrals chasing requires a
synchronous bind callback and monitoring an arbitrary number of socket
descriptors for a single easy handle (currently limited to 5).
Generic LDAP is synchronous: OK.
See https://github.com/curl/curl/issues/622 and
https://curl.haxx.se/mail/lib-2016-01/0101.html
13. TCP/IP
13.1 --interface for ipv6 binds to unusable IP address
Since IPv6 provides a lot of addresses with different scope, binding to an
IPv6 address needs to take the proper care so that it doesn't bind to a
locally scoped address as that is bound to fail.
https://github.com/curl/curl/issues/686

View File

@@ -1,127 +0,0 @@
License Mixing
==============
libcurl can be built to use a fair amount of various third party libraries,
libraries that are written and provided by other parties that are distributed
using their own licenses. Even libcurl itself contains code that may cause
problems to some. This document attempts to describe what licenses libcurl and
the other libraries use and what possible dilemmas linking and mixing them all
can lead to for end users.
I am not a lawyer and this is not legal advice!
One common dilemma is that [GPL](https://www.gnu.org/licenses/gpl.html)
licensed code is not allowed to be linked with code licensed under the
[Original BSD license](https://spdx.org/licenses/BSD-4-Clause.html) (with the
announcement clause). You may still build your own copies that use them all,
but distributing them as binaries would be to violate the GPL license - unless
you accompany your license with an
[exception](https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs). This
particular problem was addressed when the [Modified BSD
license](https://opensource.org/licenses/BSD-3-Clause) was created, which does
not have the announcement clause that collides with GPL.
## libcurl
Uses an [MIT style license](https://curl.haxx.se/docs/copyright.html) that is
very liberal.
## OpenSSL
(May be used for SSL/TLS support) Uses an Original BSD-style license with an
announcement clause that makes it "incompatible" with GPL. You are not
allowed to ship binaries that link with OpenSSL that includes GPL code
(unless that specific GPL code includes an exception for OpenSSL - a habit
that is growing more and more common). If OpenSSL's licensing is a problem
for you, consider using another TLS library.
## GnuTLS
(May be used for SSL/TLS support) Uses the
[LGPL](https://www.gnu.org/licenses/lgpl.html) license. If this is a problem
for you, consider using another TLS library. Also note that GnuTLS itself
depends on and uses other libs (libgcrypt and libgpg-error) and they too are
LGPL- or GPL-licensed.
## WolfSSL
(May be used for SSL/TLS support) Uses the GPL license or a proprietary
license. If this is a problem for you, consider using another TLS library.
## NSS
(May be used for SSL/TLS support) Is covered by the
[MPL](https://www.mozilla.org/MPL/) license, the GPL license and the LGPL
license. You may choose to license the code under MPL terms, GPL terms, or
LGPL terms. These licenses grant you different permissions and impose
different obligations. You should select the license that best meets your
needs.
## axTLS
(May be used for SSL/TLS support) Uses a Modified BSD-style license.
## mbedTLS
(May be used for SSL/TLS support) Uses the [Apache 2.0
license](https://opensource.org/licenses/Apache-2.0) or the GPL license.
You may choose to license the code under Apache 2.0 terms or GPL terms.
These licenses grant you different permissions and impose different
obligations. You should select the license that best meets your needs.
## BoringSSL
(May be used for SSL/TLS support) As an OpenSSL fork, it has the same
license as that.
## libressl
(May be used for SSL/TLS support) As an OpenSSL fork, it has the same
license as that.
## c-ares
(Used for asynchronous name resolves) Uses an MIT license that is very
liberal and imposes no restrictions on any other library or part you may link
with.
## zlib
(Used for compressed Transfer-Encoding support) Uses an MIT-style license
that shouldn't collide with any other library.
## MIT Kerberos
(May be used for GSS support) MIT licensed, that shouldn't collide with any
other parts.
## Heimdal
(May be used for GSS support) Heimdal is Original BSD licensed with the
announcement clause.
## GNU GSS
(May be used for GSS support) GNU GSS is GPL licensed. Note that you may not
distribute binary curl packages that uses this if you build curl to also link
and use any Original BSD licensed libraries!
## libidn
(Used for IDNA support) Uses the GNU Lesser General Public License [3]. LGPL
is a variation of GPL with slightly less aggressive "copyleft". This license
requires more requirements to be met when distributing binaries, see the
license for details. Also note that if you distribute a binary that includes
this library, you must also include the full LGPL license text. Please
properly point out what parts of the distributed package that the license
addresses.
## OpenLDAP
(Used for LDAP support) Uses a Modified BSD-style license. Since libcurl uses
OpenLDAP as a shared library only, I have not heard of anyone that ships
OpenLDAP linked with libcurl in an app.
## libssh2
(Used for scp and sftp support) libssh2 uses a Modified BSD-style license.

View File

@@ -1,264 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
MAIL ETIQUETTE
1. About the lists
1.1 Mailing Lists
1.2 Netiquette
1.3 Do Not Mail a Single Individual
1.4 Subscription Required
1.5 Moderation of new posters
1.6 Handling trolls and spam
1.7 How to unsubscribe
1.8 I posted, now what?
2. Sending mail
2.1 Reply or New Mail
2.2 Reply to the List
2.3 Use a Sensible Subject
2.4 Do Not Top-Post
2.5 HTML is not for mails
2.6 Quoting
2.7 Digest
2.8 Please Tell Us How You Solved The Problem!
==============================================================================
1. About the lists
1.1 Mailing Lists
The mailing lists we have are all listed and described at
https://curl.haxx.se/mail/
Each mailing list is targeted to a specific set of users and subjects,
please use the one or the ones that suit you the most.
Each mailing list have hundreds up to thousands of readers, meaning that
each mail sent will be received and read by a very large amount of people.
People from various cultures, regions, religions and continents.
1.2 Netiquette
Netiquette is a common name for how to behave on the internet. Of course, in
each particular group and subculture there will be differences in what is
acceptable and what is considered good manners.
This document outlines what we in the curl project considers to be good
etiquette, and primarily this focus on how to behave on and how to use our
mailing lists.
1.3 Do Not Mail a Single Individual
Many people send one question to one person. One person gets many mails, and
there is only one person who can give you a reply. The question may be
something that other people are also wanting to ask. These other people have
no way to read the reply, but to ask the one person the question. The one
person consequently gets overloaded with mail.
If you really want to contact an individual and perhaps pay for his or her
services, by all means go ahead, but if it's just another curl question,
take it to a suitable list instead.
1.4 Subscription Required
All curl mailing lists require that you are subscribed to allow a mail to go
through to all the subscribers.
If you post without being subscribed (or from a different mail address than
the one you are subscribed with), your mail will simply be silently
discarded. You have to subscribe first, then post.
The reason for this unfortunate and strict subscription policy is of course
to stop spam from pestering the lists.
1.5 Moderation of new posters
Several of the curl mailing lists automatically make all posts from new
subscribers require moderation. This means that after you've subscribed and
send your first mail to a list, that mail will not be let through to the
list until a mailing list administrator has verified that it is OK and
permits it to get posted.
Once a first post has been made that proves the sender is actually talking
about curl-related subjects, the moderation "flag" will be switched off and
future posts will go through without being moderated.
The reason for this moderation policy is that we do suffer from spammers who
actually subscribe and send spam to our lists.
1.6 Handling trolls and spam
Despite our good intentions and hard work to keep spam off the lists and to
maintain a friendly and positive atmosphere, there will be times when spam
and or trolls get through.
Troll - "someone who posts inflammatory, extraneous, or off-topic messages
in an online community"
Spam - "use of electronic messaging systems to send unsolicited bulk
messages"
No matter what, we NEVER EVER respond to trolls or spammers on the list. If
you believe the list admin should do something particular, contact him/her
off-list. The subject will be taken care of as good as possible to prevent
repeated offenses, but responding on the list to such messages never lead to
anything good and only puts the light even more on the offender: which was
the entire purpose of it getting sent to the list in the first place.
Don't feed the trolls!
1.7 How to unsubscribe
You unsubscribe the same way you subscribed in the first place. You go to
the page for the particular mailing list you're subscribed to and you enter
your email address and password and press the unsubscribe button.
Also, this information is included in the headers of every mail that is sent
out to all curl related mailing lists and there's a footer in each mail that
links to the "admin" page on which you can unsubscribe and change other
options.
You NEVER EVER email the mailing list requesting someone else to get you off
the list.
1.8 I posted, now what?
If you aren't subscribed with the exact same email address that you used to
send the email, your post will just be silently discarded.
If you posted for the first time to the mailing list, you first need to wait
for an administrator to allow your email to go through. This normally
happens very quickly but in case we're asleep, you may have to wait a few
hours.
Once your email goes through it is sent out to several hundred or even
thousand recipients. Your email may cover an area that not that many people
know about or are interested in. Or possibly the person who knows about it
is on vacation or under a very heavy work load right now. You have to wait
for a response and you must not expect to get a response at all, but
hopefully you get an answer within a couple of days.
You do yourself and all of us a service when you include as many details as
possible already in your first email. Mention your operating system and
environment. Tell us which curl version you're using and tell us what you
did, what happened and what you expected would happen. Preferably, show us
what you did in details enough to allow others to help point out the problem
or repeat the same steps in their places.
Failing to include details will only delay responses and make people respond
and ask for the details and you have to send a follow-up email that includes
them.
Expect the responses to primarily help YOU debug the issue, or ask you
questions that can lead you or others towards a solution or explanation to
whatever you experience.
If you are a repeat offender to the guidelines outlined in this document,
chances are that people will ignore you at will and your chances to get
responses will greatly diminish.
2. Sending mail
2.1 Reply or New Mail
Please do not reply to an existing message as a short-cut to post a message
to the lists.
Many mail programs and web archivers use information within mails to keep
them together as "threads", as collections of posts that discuss a certain
subject. If you don't intend to reply on the same or similar subject, don't
just hit reply on an existing mail and change subject, create a new mail.
2.2 Reply to the List
When replying to a message from the list, make sure that you do "group
reply" or "reply to all", and not just reply to the author of the single
mail you reply to.
We're actively discouraging replying back to the single person by setting
the Reply-To: field in outgoing mails back to the mailing list address,
making it harder for people to mail the author only by mistake.
2.3 Use a Sensible Subject
Please use a subject of the mail that makes sense and that is related to the
contents of your mail. It makes it a lot easier to find your mail afterwards
and it makes it easier to track mail threads and topics.
2.4 Do Not Top-Post
If you reply to a message, don't use top-posting. Top-posting is when you
write the new text at the top of a mail and you insert the previous quoted
mail conversation below. It forces users to read the mail in a backwards
order to properly understand it.
This is why top posting is so bad:
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?
Apart from the screwed up read order (especially when mixed together in a
thread when someone responds using the mandated bottom-posting style), it
also makes it impossible to quote only parts of the original mail.
When you reply to a mail. You let the mail client insert the previous mail
quoted. Then you put the cursor on the first line of the mail and you move
down through the mail, deleting all parts of the quotes that don't add
context for your comments. When you want to add a comment you do so, inline,
right after the quotes that relate to your comment. Then you continue
downwards again.
When most of the quotes have been removed and you've added your own words,
you're done!
2.5 HTML is not for mails
Please switch off those HTML encoded messages. You can mail all those funny
mails to your friends. We speak plain text mails.
2.6 Quoting
Quote as little as possible. Just enough to provide the context you cannot
leave out. A lengthy description can be found here:
https://www.netmeister.org/news/learn2quote.html
2.7 Digest
We allow subscribers to subscribe to the "digest" version of the mailing
lists. A digest is a collection of mails lumped together in one single mail.
Should you decide to reply to a mail sent out as a digest, there are two
things you MUST consider if you really really cannot subscribe normally
instead:
Cut off all mails and chatter that is not related to the mail you want to
reply to.
Change the subject name to something sensible and related to the subject,
preferably even the actual subject of the single mail you wanted to reply to
2.8 Please Tell Us How You Solved The Problem!
Many people mail questions to the list, people spend some of their time and
make an effort in providing good answers to these questions.
If you are the one who asks, please consider responding once more in case
one of the hints was what solved your problems. The guys who write answers
feel good to know that they provided a good answer and that you fixed the
problem. Far too often, the person who asked the question is never heard of
again, and we never get to know if he/she is gone because the problem was
solved or perhaps because the problem was unsolvable!
Getting the solution posted also helps other users that experience the same
problem(s). They get to see (possibly in the web archives) that the
suggested fixes actually has helped at least one person.

File diff suppressed because it is too large Load Diff

View File

@@ -1,62 +0,0 @@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1
noinst_man_MANS = mk-ca-bundle.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
HTMLPAGES = $(GENHTMLPAGES) index.html
SUBDIRS = examples libcurl cmdline-opts
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
EXTRA_DIST = MANUAL BUGS CONTRIBUTE.md FAQ FEATURES INTERNALS.md SSLCERTS.md \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS KNOWN_BUGS \
BINDINGS.md $(man_MANS) HISTORY.md INSTALL INSTALL.md LICENSE-MIXING.md \
README.netware MAIL-ETIQUETTE HTTP-COOKIES.md SECURITY.md RELEASE-PROCEDURE \
SSL-PROBLEMS.md HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md CODE_STYLE.md \
CHECKSRC.md
MAN2HTML= roffit $< >$@
SUFFIXES = .1 .html .pdf
html: $(HTMLPAGES)
cd libcurl && make html
pdf: $(PDFPAGES)
cd libcurl && make pdf
.1.html:
$(MAN2HTML)
.1.pdf:
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
groff -Tps -man $< >$$foo.ps; \
ps2pdf $$foo.ps $@; \
rm $$foo.ps; \
echo "converted $< to $@")

View File

@@ -1,837 +0,0 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
#***************************************************************************
# _ _ ____ _
# Project ___| | | | _ \| |
# / __| | | | |_) | |
# | (__| |_| | _ <| |___
# \___|\___/|_| \_\_____|
#
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at https://curl.haxx.se/docs/copyright.html.
#
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
# copies of the Software, and permit persons to whom the Software is
# furnished to do so, under the terms of the COPYING file.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
###########################################################################
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = docs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
$(top_srcdir)/m4/curl-confopts.m4 \
$(top_srcdir)/m4/curl-functions.m4 \
$(top_srcdir)/m4/curl-openssl.m4 \
$(top_srcdir)/m4/curl-override.m4 \
$(top_srcdir)/m4/curl-reentrant.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/xc-am-iface.m4 \
$(top_srcdir)/m4/xc-cc-check.m4 \
$(top_srcdir)/m4/xc-lt-iface.m4 \
$(top_srcdir)/m4/xc-translit.m4 \
$(top_srcdir)/m4/xc-val-flgs.m4 \
$(top_srcdir)/m4/zz40-xc-ovr.m4 \
$(top_srcdir)/m4/zz50-xc-ovr.m4 \
$(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/lib/curl_config.h \
$(top_builddir)/include/curl/curlbuild.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
depcomp =
am__depfiles_maybe =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
man1dir = $(mandir)/man1
am__installdirs = "$(DESTDIR)$(man1dir)"
MANS = $(man_MANS)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
distdir
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in INSTALL THANKS TODO
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BLANK_AT_MAKETIME = @BLANK_AT_MAKETIME@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@
CONFIGURE_OPTIONS = @CONFIGURE_OPTIONS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPPFLAG_CURL_STATICLIB = @CPPFLAG_CURL_STATICLIB@
CURLVERSION = @CURLVERSION@
CURL_CA_BUNDLE = @CURL_CA_BUNDLE@
CURL_CFLAG_EXTRAS = @CURL_CFLAG_EXTRAS@
CURL_DISABLE_DICT = @CURL_DISABLE_DICT@
CURL_DISABLE_FILE = @CURL_DISABLE_FILE@
CURL_DISABLE_FTP = @CURL_DISABLE_FTP@
CURL_DISABLE_GOPHER = @CURL_DISABLE_GOPHER@
CURL_DISABLE_HTTP = @CURL_DISABLE_HTTP@
CURL_DISABLE_IMAP = @CURL_DISABLE_IMAP@
CURL_DISABLE_LDAP = @CURL_DISABLE_LDAP@
CURL_DISABLE_LDAPS = @CURL_DISABLE_LDAPS@
CURL_DISABLE_POP3 = @CURL_DISABLE_POP3@
CURL_DISABLE_PROXY = @CURL_DISABLE_PROXY@
CURL_DISABLE_RTSP = @CURL_DISABLE_RTSP@
CURL_DISABLE_SMB = @CURL_DISABLE_SMB@
CURL_DISABLE_SMTP = @CURL_DISABLE_SMTP@
CURL_DISABLE_TELNET = @CURL_DISABLE_TELNET@
CURL_DISABLE_TFTP = @CURL_DISABLE_TFTP@
CURL_LT_SHLIB_VERSIONED_FLAVOUR = @CURL_LT_SHLIB_VERSIONED_FLAVOUR@
CURL_NETWORK_AND_TIME_LIBS = @CURL_NETWORK_AND_TIME_LIBS@
CURL_NETWORK_LIBS = @CURL_NETWORK_LIBS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ENABLE_SHARED = @ENABLE_SHARED@
ENABLE_STATIC = @ENABLE_STATIC@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_GNUTLS_SRP = @HAVE_GNUTLS_SRP@
HAVE_LDAP_SSL = @HAVE_LDAP_SSL@
HAVE_LIBZ = @HAVE_LIBZ@
HAVE_OPENSSL_SRP = @HAVE_OPENSSL_SRP@
IDN_ENABLED = @IDN_ENABLED@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPV6_ENABLED = @IPV6_ENABLED@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBCURL_LIBS = @LIBCURL_LIBS@
LIBMETALINK_CPPFLAGS = @LIBMETALINK_CPPFLAGS@
LIBMETALINK_LDFLAGS = @LIBMETALINK_LDFLAGS@
LIBMETALINK_LIBS = @LIBMETALINK_LIBS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MANOPT = @MANOPT@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NROFF = @NROFF@
NSS_LIBS = @NSS_LIBS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKGADD_NAME = @PKGADD_NAME@
PKGADD_PKG = @PKGADD_PKG@
PKGADD_VENDOR = @PKGADD_VENDOR@
PKGCONFIG = @PKGCONFIG@
RANDOM_FILE = @RANDOM_FILE@
RANLIB = @RANLIB@
REQUIRE_LIB_DEPS = @REQUIRE_LIB_DEPS@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
SSL_ENABLED = @SSL_ENABLED@
SSL_LIBS = @SSL_LIBS@
STRIP = @STRIP@
SUPPORT_FEATURES = @SUPPORT_FEATURES@
SUPPORT_PROTOCOLS = @SUPPORT_PROTOCOLS@
USE_ARES = @USE_ARES@
USE_AXTLS = @USE_AXTLS@
USE_CYASSL = @USE_CYASSL@
USE_DARWINSSL = @USE_DARWINSSL@
USE_GNUTLS = @USE_GNUTLS@
USE_GNUTLS_NETTLE = @USE_GNUTLS_NETTLE@
USE_LIBRTMP = @USE_LIBRTMP@
USE_LIBSSH2 = @USE_LIBSSH2@
USE_MBEDTLS = @USE_MBEDTLS@
USE_NGHTTP2 = @USE_NGHTTP2@
USE_NSS = @USE_NSS@
USE_OPENLDAP = @USE_OPENLDAP@
USE_POLARSSL = @USE_POLARSSL@
USE_SCHANNEL = @USE_SCHANNEL@
USE_UNIX_SOCKETS = @USE_UNIX_SOCKETS@
USE_WINDOWS_SSPI = @USE_WINDOWS_SSPI@
VERSION = @VERSION@
VERSIONNUM = @VERSIONNUM@
ZLIB_LIBS = @ZLIB_LIBS@
ZSH_FUNCTIONS_DIR = @ZSH_FUNCTIONS_DIR@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libext = @libext@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign no-dependencies
man_MANS = curl.1 curl-config.1
noinst_man_MANS = mk-ca-bundle.1
GENHTMLPAGES = curl.html curl-config.html mk-ca-bundle.html
PDFPAGES = curl.pdf curl-config.pdf mk-ca-bundle.pdf
HTMLPAGES = $(GENHTMLPAGES) index.html
SUBDIRS = examples libcurl cmdline-opts
CLEANFILES = $(GENHTMLPAGES) $(PDFPAGES)
EXTRA_DIST = MANUAL BUGS CONTRIBUTE.md FAQ FEATURES INTERNALS.md SSLCERTS.md \
README.win32 RESOURCES TODO TheArtOfHttpScripting THANKS VERSIONS KNOWN_BUGS \
BINDINGS.md $(man_MANS) HISTORY.md INSTALL INSTALL.md LICENSE-MIXING.md \
README.netware MAIL-ETIQUETTE HTTP-COOKIES.md SECURITY.md RELEASE-PROCEDURE \
SSL-PROBLEMS.md HTTP2.md ROADMAP.md CODE_OF_CONDUCT.md CODE_STYLE.md \
CHECKSRC.md
MAN2HTML = roffit $< >$@
SUFFIXES = .1 .html .pdf
all: all-recursive
.SUFFIXES:
.SUFFIXES: .1 .html .pdf
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign docs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-man1: $(man_MANS)
@$(NORMAL_INSTALL)
@list1=''; \
list2='$(man_MANS)'; \
test -n "$(man1dir)" \
&& test -n "`echo $$list1$$list2`" \
|| exit 0; \
echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
$(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
{ for i in $$list1; do echo "$$i"; done; \
if test -n "$$list2"; then \
for i in $$list2; do echo "$$i"; done \
| sed -n '/\.1[a-z]*$$/p'; \
fi; \
} | while read p; do \
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; echo "$$p"; \
done | \
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
sed 'N;N;s,\n, ,g' | { \
list=; while read file base inst; do \
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
fi; \
done; \
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
while read files; do \
test -z "$$files" || { \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
done; }
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list=''; test -n "$(man1dir)" || exit 0; \
files=`{ for i in $$list; do echo "$$i"; done; \
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
sed -n '/\.1[a-z]*$$/p'; \
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(MANS)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(man1dir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html-am:
info: info-recursive
info-am:
install-data-am: install-man
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man: install-man1
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-man
uninstall-man: uninstall-man1
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
check-am clean clean-generic clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-man1 install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-man uninstall-man1
.PRECIOUS: Makefile
html: $(HTMLPAGES)
cd libcurl && make html
pdf: $(PDFPAGES)
cd libcurl && make pdf
.1.html:
$(MAN2HTML)
.1.pdf:
@(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \
groff -Tps -man $< >$$foo.ps; \
ps2pdf $$foo.ps $@; \
rm $$foo.ps; \
echo "converted $< to $@")
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -1,27 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
README.netware
Read the README file first.
Curl has been successfully compiled with gcc / nlmconv on different flavours
of Linux as well as with the official Metrowerks CodeWarrior compiler.
While not being the main development target, a continuously growing share of
curl users are NetWare-based, specially also consuming the lib from PHP.
The unix-style man pages are tricky to read on windows, so therefore are all
those pages converted to HTML as well as pdf, and included in the release
archives.
The main curl.1 man page is also "built-in" in the command line tool. Use a
command line similar to this in order to extract a separate text file:
curl -M >manual.txt
Read the INSTALL file for instructions how to compile curl self.

View File

@@ -1,26 +0,0 @@
_ _ ____ _
___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
README.win32
Read the README file first.
Curl has been compiled, built and run on all sorts of Windows and win32
systems. While not being the main develop target, a fair share of curl users
are win32-based.
The unix-style man pages are tricky to read on windows, so therefore are all
those pages converted to HTML as well as pdf, and included in the release
archives.
The main curl.1 man page is also "built-in" in the command line tool. Use a
command line similar to this in order to extract a separate text file:
curl -M >manual.txt
Read the INSTALL file for instructions how to compile curl self.

View File

@@ -1,92 +0,0 @@
curl release procedure - how to do a release
============================================
in the source code repo
-----------------------
- edit `RELEASE-NOTES` to be accurate
- update `docs/THANKS`
- make sure all relevant changes are committed on the master branch
- tag the git repo in this style: `git tag -a curl-7_34_0`. -a annotates the
tag and we use underscores instead of dots in the version number.
- run "./maketgz 7.34.0" to build the release tarballs. It is important that
you run this on a machine with the correct set of autotools etc installed
as this is what then will be shipped and used by most users on *nix like
systems.
- push the git commits and the new tag
- gpg sign the 4 tarballs as maketgz suggests
- upload the 8 resulting files to the primary download directory
in the curl-www repo
--------------------
- edit `Makefile` (version number and date),
- edit `_newslog.html` (announce the new release) and
- edit `_changes.html` (insert changes+bugfixes from RELEASE-NOTES)
- commit all local changes
- tag the repo with the same tag as used for the source repo
- make sure all relevant changes are committed and pushed on the master branch
(the web site then updates its contents automatically)
on github
---------
- edit the newly made release tag so that it is listed as the latest release
inform
------
- send an email to curl-users, curl-announce and curl-library. Insert the
RELEASE-NOTES into the mail.
celebrate
---------
- suitable beverage intake is encouraged for the festivities
curl release scheduling
=======================
Basics
------
We do releases every 8 weeks on Wednesdays. If critical problems arise, we can
insert releases outside of the schedule or we can move the release date - but
this is very rare.
Each 8 week release cycle is split in two 4-week periods.
- During the first 4 weeks after a release, we allow new features and changes
to curl and libcurl. If we accept any such changes, we bump the minor number
used for the next release.
- During the second 4-week period we do not merge any features or changes, we
then only focus on fixing bugs and polishing things to make a solid coming
release.
Coming dates
------------
Based on the description above, here are some planned release dates (at the
time of this writing):
- September 7, 2016 (version 7.50.2)
- November 2, 2016
- December 28, 2016
- February 22, 2017
- April 19, 2017
- June 14, 2017
- August 9, 2017

View File

@@ -1,83 +0,0 @@
_ _ ____ _
Project ___| | | | _ \| |
/ __| | | | |_) | |
| (__| |_| | _ <| |___
\___|\___/|_| \_\_____|
This document lists documents and standards used by curl.
RFC 959 - The FTP protocol
RFC 1635 - How to Use Anonymous FTP
RFC 1738 - Uniform Resource Locators
RFC 1777 - defines the LDAP protocol
RFC 1808 - Relative Uniform Resource Locators
RFC 1867 - Form-based File Upload in HTML
RFC 1950 - ZLIB Compressed Data Format Specification
RFC 1951 - DEFLATE Compressed Data Format Specification
RFC 1952 - gzip compression format
RFC 1959 - LDAP URL syntax
RFC 2045-2049 - Everything you need to know about MIME! (needed for form
based upload)
RFC 2068 - HTTP 1.1 (obsoleted by RFC 2616)
RFC 2104 - Keyed-Hashing for Message Authentication
RFC 2109 - HTTP State Management Mechanism (cookie stuff)
- Also, read Netscape's specification at
https://curl.haxx.se/rfc/cookie_spec.html
RFC 2183 - The Content-Disposition Header Field
RFC 2195 - CRAM-MD5 authentication
RFC 2229 - A Dictionary Server Protocol
RFC 2255 - Newer LDAP URL syntax document.
RFC 2231 - MIME Parameter Value and Encoded Word Extensions:
Character Sets, Languages, and Continuations
RFC 2388 - "Returning Values from Forms: multipart/form-data"
Use this as an addition to the RFC1867
RFC 2396 - "Uniform Resource Identifiers: Generic Syntax and Semantics" This
one obsoletes RFC 1738, but since RFC 1738 is often mentioned
I've left it in this list.
RFC 2428 - FTP Extensions for IPv6 and NATs
RFC 2577 - FTP Security Considerations
RFC 2616 - HTTP 1.1, the latest
RFC 2617 - HTTP Authentication
RFC 2718 - Guidelines for new URL Schemes
RFC 2732 - Format for Literal IPv6 Addresses in URL's
RFC 2818 - HTTP Over TLS (TLS is the successor to SSL)
RFC 2821 - SMTP protocol
RFC 2964 - Use of HTTP State Management
RFC 2965 - HTTP State Management Mechanism. Cookies. Obsoletes RFC2109
RFC 3207 - SMTP over TLS
RFC 4616 - PLAIN authentication
RFC 4954 - SMTP Authentication

View File

@@ -1,142 +0,0 @@
curl the next few years - perhaps
=================================
Roadmap of things Daniel Stenberg and Steve Holme want to work on next. It is
intended to serve as a guideline for others for information, feedback and
possible participation.
HTTP/2
------
Improve performance. Measurements and tests have shown that in several cases
doing transfers over HTTP/2 can be notably slower than the same transfer done
over HTTP/1. Some of that difference can be attributed the inefficient window
size handling currently in use but there are probably more to be learned and
worked on to optimize this.
QUIC
----
The standardization process of QUIC has been taken to the IETF and can be
followed on the [IETF QUIC Mailing
list](https://www.ietf.org/mailman/listinfo/quic). I'd like us to get on the
bandwagon. Ideally, this would be done with a separate library/project to
handle the binary/framing layer in a similar fashion to how HTTP/2 is
implemented. This, to allow other projects to benefit from the work and to
thus broaden the interest and chance of others to participate.
TLS 1.3
-------
The new version of the TLS protocol is in the pipeline and will soon start to
get used out in the wild. It offers some new interesting features and will
need the TLS libraries to adapt and quite likely provide additional or
modified APIs. libcurl needs to adapt accordingly.
HTTP cookies
------------
Two cookie drafts have been adopted by the httpwg in IETF and we should
support them as the popular browsers will as well:
[Deprecate modification of 'secure' cookies from non-secure
origins](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-00)
[Cookie Prefixes](https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00)
[Firefox bug report about secure cookies](https://bugzilla.mozilla.org/show_bug.cgi?id=976073)
SRV records
-----------
How to find services for specific domains/hosts.
HTTPS to proxy
--------------
To avoid network traffic to/from the proxy getting snooped on. There's a git
branch in the public git repository for this that we need to make sure works
for all TLS backends and then merge!
curl_formadd()
--------------
make sure there's an easy handle passed in to `curl_formadd()`,
`curl_formget()` and `curl_formfree()` by adding replacement functions and
deprecating the old ones to allow custom mallocs and more
Third-party SASL
----------------
Add support for third-party SASL libraries such as Cyrus SASL.
SASL authentication in LDAP
---------------------------
...
Simplify the SMTP email
-----------------------
Simplify the SMTP email interface so that programmers don't have to
construct the body of an email that contains all the headers, alternative
content, images and attachments - maintain raw interface so that
programmers that want to do this can
email capabilities
------------------
Allow the email protocols to return the capabilities before
authenticating. This will allow an application to decide on the best
authentication mechanism
Win32 pthreads
--------------
Allow Windows threading model to be replaced by Win32 pthreads port
dynamic buffer size
-------------------
Implement a dynamic buffer size to allow SFTP to use much larger buffers and
possibly allow the size to be customizable by applications. Use less memory
when handles are not in use?
New stuff - curl
----------------
1. Embed a language interpreter (lua?). For that middle ground where curl
isnt enough and a libcurl binding feels “too much”. Build-time conditional
of course.
2. Simplify the SMTP command line so that the headers and multi-part content
don't have to be constructed before calling curl
Improve
-------
1. build for windows (considered hard by many users)
2. curl -h output (considered overwhelming to users)
3. we have > 170 command line options, is there a way to redo things to
simplify or improve the situation as we are likely to keep adding
features/options in the future too
4. docs (considered "bad" by users but how do we make it better?)
- split up curl.1
5. authentication framework (consider merging HTTP and SASL authentication to
give one API for protocols to call)
6. Perform some of the clean up from the TODO document, removing old
definitions and such like that are currently earmarked to be removed years
ago
Remove
------
1. makefile.vc files as there is no point in maintaining two sets of Windows
makefiles. Note: These are currently being used by the Windows autobuilds

Some files were not shown because too many files have changed in this diff Show More