正在显示
63 个修改的文件
包含
4632 行增加
和
0 行删除
.gitignore
0 → 100644
| 1 | +build/* |
.vscode/settings.json
0 → 100644
| 1 | +{ | ||
| 2 | + "files.associations": { | ||
| 3 | + "*.ipp": "cpp", | ||
| 4 | + "any": "cpp", | ||
| 5 | + "array": "cpp", | ||
| 6 | + "atomic": "cpp", | ||
| 7 | + "strstream": "cpp", | ||
| 8 | + "bit": "cpp", | ||
| 9 | + "*.tcc": "cpp", | ||
| 10 | + "bitset": "cpp", | ||
| 11 | + "cctype": "cpp", | ||
| 12 | + "chrono": "cpp", | ||
| 13 | + "clocale": "cpp", | ||
| 14 | + "cmath": "cpp", | ||
| 15 | + "codecvt": "cpp", | ||
| 16 | + "complex": "cpp", | ||
| 17 | + "condition_variable": "cpp", | ||
| 18 | + "csignal": "cpp", | ||
| 19 | + "cstdarg": "cpp", | ||
| 20 | + "cstddef": "cpp", | ||
| 21 | + "cstdint": "cpp", | ||
| 22 | + "cstdio": "cpp", | ||
| 23 | + "cstdlib": "cpp", | ||
| 24 | + "cstring": "cpp", | ||
| 25 | + "ctime": "cpp", | ||
| 26 | + "cwchar": "cpp", | ||
| 27 | + "cwctype": "cpp", | ||
| 28 | + "deque": "cpp", | ||
| 29 | + "list": "cpp", | ||
| 30 | + "map": "cpp", | ||
| 31 | + "set": "cpp", | ||
| 32 | + "unordered_map": "cpp", | ||
| 33 | + "vector": "cpp", | ||
| 34 | + "exception": "cpp", | ||
| 35 | + "algorithm": "cpp", | ||
| 36 | + "functional": "cpp", | ||
| 37 | + "iterator": "cpp", | ||
| 38 | + "memory": "cpp", | ||
| 39 | + "memory_resource": "cpp", | ||
| 40 | + "numeric": "cpp", | ||
| 41 | + "optional": "cpp", | ||
| 42 | + "random": "cpp", | ||
| 43 | + "ratio": "cpp", | ||
| 44 | + "regex": "cpp", | ||
| 45 | + "source_location": "cpp", | ||
| 46 | + "string": "cpp", | ||
| 47 | + "string_view": "cpp", | ||
| 48 | + "system_error": "cpp", | ||
| 49 | + "tuple": "cpp", | ||
| 50 | + "type_traits": "cpp", | ||
| 51 | + "utility": "cpp", | ||
| 52 | + "slist": "cpp", | ||
| 53 | + "fstream": "cpp", | ||
| 54 | + "future": "cpp", | ||
| 55 | + "initializer_list": "cpp", | ||
| 56 | + "iomanip": "cpp", | ||
| 57 | + "iosfwd": "cpp", | ||
| 58 | + "iostream": "cpp", | ||
| 59 | + "istream": "cpp", | ||
| 60 | + "limits": "cpp", | ||
| 61 | + "mutex": "cpp", | ||
| 62 | + "new": "cpp", | ||
| 63 | + "ostream": "cpp", | ||
| 64 | + "shared_mutex": "cpp", | ||
| 65 | + "sstream": "cpp", | ||
| 66 | + "stdexcept": "cpp", | ||
| 67 | + "streambuf": "cpp", | ||
| 68 | + "thread": "cpp", | ||
| 69 | + "cinttypes": "cpp", | ||
| 70 | + "typeindex": "cpp", | ||
| 71 | + "typeinfo": "cpp", | ||
| 72 | + "variant": "cpp", | ||
| 73 | + "cfenv": "cpp" | ||
| 74 | + } | ||
| 75 | +} |
.vscode/tasks.json
0 → 100644
| 1 | +{ | ||
| 2 | + "tasks": [ | ||
| 3 | + { | ||
| 4 | + "type": "cppbuild", | ||
| 5 | + "label": "C/C++: g++ build active file", | ||
| 6 | + "command": "/usr/bin/g++", | ||
| 7 | + "args": [ | ||
| 8 | + "-fdiagnostics-color=always", | ||
| 9 | + "-g", | ||
| 10 | + "${file}", | ||
| 11 | + "-o", | ||
| 12 | + "${fileDirname}/${fileBasenameNoExtension}" | ||
| 13 | + ], | ||
| 14 | + "options": { | ||
| 15 | + "cwd": "${fileDirname}" | ||
| 16 | + }, | ||
| 17 | + "problemMatcher": [ | ||
| 18 | + "$gcc" | ||
| 19 | + ], | ||
| 20 | + "group": { | ||
| 21 | + "kind": "build", | ||
| 22 | + "isDefault": true | ||
| 23 | + }, | ||
| 24 | + "detail": "Task generated by Debugger." | ||
| 25 | + } | ||
| 26 | + ], | ||
| 27 | + "version": "2.0.0" | ||
| 28 | +} |
CMakeLists.txt
0 → 100644
| 1 | +CMAKE_MINIMUM_REQUIRED(VERSION 3.6 FATAL_ERROR) | ||
| 2 | +# set path to additional CMake modules | ||
| 3 | +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) | ||
| 4 | +SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE) | ||
| 5 | + | ||
| 6 | +############################################################# | ||
| 7 | +# Project and version | ||
| 8 | +SET(CPACK_PACKAGE_VERSION_MAJOR "3") | ||
| 9 | +SET(CPACK_PACKAGE_VERSION_MINOR "0") | ||
| 10 | +SET(CPACK_PACKAGE_VERSION_PATCH "0") | ||
| 11 | +SET(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}) | ||
| 12 | +SET(RELEASE_NAME "Master") | ||
| 13 | +PROJECT(DMap VERSION ${COMPLETE_VERSION}) | ||
| 14 | + | ||
| 15 | +# we default to Release build type | ||
| 16 | +if(NOT CMAKE_BUILD_TYPE) | ||
| 17 | + SET(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) | ||
| 18 | +endif() | ||
| 19 | + | ||
| 20 | +MESSAGE(STATUS "Build type: ${CMAKE_BUILD_TYPE}") | ||
| 21 | + | ||
| 22 | +# Note the version no is Mmmpp for Major/minor/patch, 0-padded, thus '10100' for 1.1.0 | ||
| 23 | +MATH(EXPR DMAP_VERSION_INT "${CPACK_PACKAGE_VERSION_MAJOR}*10000+${CPACK_PACKAGE_VERSION_MINOR}*100+${CPACK_PACKAGE_VERSION_PATCH}") | ||
| 24 | +MESSAGE(STATUS "DMAP version: ${COMPLETE_VERSION} ${RELEASE_NAME} (${DMAP_VERSION_INT})") | ||
| 25 | + | ||
| 26 | +SET (WITH_CORE TRUE CACHE BOOL "Determines whether DMap core should be built.") | ||
| 27 | +MARK_AS_ADVANCED(WITH_CORE) | ||
| 28 | + | ||
| 29 | +IF(WITH_CORE) | ||
| 30 | + | ||
| 31 | + SET (WITH_BINDINGS FALSE CACHE BOOL "Determines whether python bindings should be built") | ||
| 32 | + IF (WITH_BINDINGS) | ||
| 33 | + # By default bindings will be installed only to DMap directory | ||
| 34 | + # Someone might want to install it to python site-packages directory | ||
| 35 | + # as otherwise user has to use PYTHONPATH environment variable to add | ||
| 36 | + # DMap bindings to package search path | ||
| 37 | + SET (BINDINGS_GLOBAL_INSTALL TRUE CACHE BOOL "Install bindings to global python directory? (might need root)") | ||
| 38 | + SET (WITH_STAGED_PLUGINS FALSE CACHE BOOL "Stage-install core Python plugins to run from build directory? (utilities and console are always staged)") | ||
| 39 | + SET (WITH_PY_COMPILE FALSE CACHE BOOL "Determines whether Python modules in staged or installed locations are byte-compiled") | ||
| 40 | + ADD_DEFINITIONS(-DWITH_BINDINGS) | ||
| 41 | + ENDIF (WITH_BINDINGS) | ||
| 42 | + | ||
| 43 | + SET (WITH_SERVER TRUE CACHE BOOL "Determines whether DMap server should be built") | ||
| 44 | + IF(WITH_SERVER) | ||
| 45 | + SET (WITH_SERVER_PLUGINS ${WITH_BINDINGS} CACHE BOOL "Determines whether DMap server support for python plugins should be built") | ||
| 46 | + IF(WITH_SERVER_PLUGINS AND NOT WITH_BINDINGS) | ||
| 47 | + MESSAGE(FATAL_ERROR "Server plugins are not supported without python bindings. Enable WITH_BINDINGS or disable WITH_SERVER_PLUGINS") | ||
| 48 | + ENDIF(WITH_SERVER_PLUGINS AND NOT WITH_BINDINGS) | ||
| 49 | + IF(WITH_SERVER_PLUGINS) | ||
| 50 | + SET(HAVE_SERVER_PYTHON_PLUGINS TRUE) | ||
| 51 | + ENDIF(WITH_SERVER_PLUGINS) | ||
| 52 | + ENDIF(WITH_SERVER) | ||
| 53 | + | ||
| 54 | + # try to configure and build POSTGRESQL support | ||
| 55 | + SET (WITH_POSTGRESQL TRUE CACHE BOOL "Determines whether POSTGRESQL support should be built") | ||
| 56 | + IF (WITH_POSTGRESQL) | ||
| 57 | + SET (POSTGRESQL_PREFIX "" CACHE PATH "Path to POSTGRESQL base directory") | ||
| 58 | + ENDIF (WITH_POSTGRESQL) | ||
| 59 | + | ||
| 60 | + ############################################################# | ||
| 61 | + # search for dependencies | ||
| 62 | + | ||
| 63 | + # required | ||
| 64 | + FIND_PACKAGE(Boost 1.57 REQUIRED COMPONENTS filesystem REQUIRED) | ||
| 65 | + FIND_PACKAGE(Boost 1.57 COMPONENTS regex REQUIRED) | ||
| 66 | + FIND_PACKAGE(Boost 1.57 COMPONENTS system REQUIRED) | ||
| 67 | + #FIND_PACKAGE(Proj) | ||
| 68 | + #FIND_PACKAGE(GEOS) | ||
| 69 | + #FIND_PACKAGE(GDAL) | ||
| 70 | + #FIND_PACKAGE(Spatialindex REQUIRED) | ||
| 71 | + | ||
| 72 | + # optional | ||
| 73 | + IF (WITH_POSTGRESQL) | ||
| 74 | + FIND_PACKAGE(Postgres) # PostgreSQL provider | ||
| 75 | + ENDIF (WITH_POSTGRESQL) | ||
| 76 | + | ||
| 77 | + #[[ | ||
| 78 | + IF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND) | ||
| 79 | + MESSAGE (SEND_ERROR "Some dependencies were not found! Proj: ${PROJ_FOUND}, Geos: ${GEOS_FOUND}, GDAL: ${GDAL_FOUND}") | ||
| 80 | + ENDIF (NOT PROJ_FOUND OR NOT GEOS_FOUND OR NOT GDAL_FOUND) | ||
| 81 | + ]] | ||
| 82 | + IF (POSTGRES_FOUND) | ||
| 83 | + SET (HAVE_POSTGRESQL TRUE) | ||
| 84 | + ENDIF (POSTGRES_FOUND) | ||
| 85 | + | ||
| 86 | +ENDIF(WITH_CORE) | ||
| 87 | + | ||
| 88 | +############################################################# | ||
| 89 | +SET(CMAKE_CXX_STANDARD 14) | ||
| 90 | +SET(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
| 91 | +# SET(CMAKE_CXX_EXTENSIONS OFF) | ||
| 92 | +############################################################# | ||
| 93 | +# platform specific stuff | ||
| 94 | +IF (WITH_CORE) | ||
| 95 | + IF (WIN32) | ||
| 96 | + ADD_DEFINITIONS(-DIS_WIN32) | ||
| 97 | + SET (DEFAULT_LIB_SUBDIR lib) | ||
| 98 | + SET (DEFAULT_LIBEXEC_SUBDIR .) | ||
| 99 | + SET (DEFAULT_DATA_SUBDIR .) | ||
| 100 | + SET (DEFAULT_PLUGIN_SUBDIR plugins) | ||
| 101 | + SET (DEFAULT_INCLUDE_SUBDIR include) | ||
| 102 | + SET (DEFAULT_SERVER_MODULE_SUBDIR server) | ||
| 103 | + | ||
| 104 | + IF (MSVC) | ||
| 105 | + SET (DEFAULT_BIN_SUBDIR bin) | ||
| 106 | + SET (DEFAULT_CGIBIN_SUBDIR bin) | ||
| 107 | + # put all the build products into a single directory | ||
| 108 | + # under build (doesn't affect install target) to make for | ||
| 109 | + # easier debugging. | ||
| 110 | + | ||
| 111 | + # Turn on defines for non standard maths stuff | ||
| 112 | + ADD_DEFINITIONS(-D_USE_MATH_DEFINES) | ||
| 113 | + | ||
| 114 | + # Turn off deprecation warnings | ||
| 115 | + ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS) | ||
| 116 | + ADD_DEFINITIONS(-D_CRT_NONSTDC_NO_WARNINGS) | ||
| 117 | + | ||
| 118 | + IF (INSTALL_DEPS) | ||
| 119 | + INSTALL(DIRECTORY ${INSTALL_DEPS} DESTINATION .) | ||
| 120 | + ENDIF (INSTALL_DEPS) | ||
| 121 | + ELSE(MSVC) | ||
| 122 | + SET (DEFAULT_BIN_SUBDIR .) | ||
| 123 | + SET (DEFAULT_CGIBIN_SUBDIR .) | ||
| 124 | + ENDIF(MSVC) | ||
| 125 | + ELSE (WIN32) | ||
| 126 | + # UNIX | ||
| 127 | + ADD_DEFINITIONS(-DIS_LINUX) | ||
| 128 | + SET (DEFAULT_BIN_SUBDIR bin) | ||
| 129 | + SET (DEFAULT_CGIBIN_SUBDIR bin) | ||
| 130 | + SET (DEFAULT_LIB_SUBDIR lib${LIB_SUFFIX}) | ||
| 131 | + SET (DEFAULT_DATA_SUBDIR share/dmap) | ||
| 132 | + SET (DEFAULT_LIBEXEC_SUBDIR lib${LIB_SUFFIX}/dmap) | ||
| 133 | + SET (DEFAULT_PLUGIN_SUBDIR lib${LIB_SUFFIX}/dmap/plugins) | ||
| 134 | + SET (DEFAULT_INCLUDE_SUBDIR include/dmap) | ||
| 135 | + SET (DEFAULT_SERVER_MODULE_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR}/server) | ||
| 136 | + ENDIF (WIN32) | ||
| 137 | + #[[ | ||
| 138 | + if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") | ||
| 139 | + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined") | ||
| 140 | + SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined") | ||
| 141 | + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined") | ||
| 142 | + endif() #"${CMAKE_SYSTEM_NAME}" MATCHES "Linux") | ||
| 143 | + ]] | ||
| 144 | + INCLUDE(GenerateExportHeader) | ||
| 145 | + | ||
| 146 | +ENDIF (WITH_CORE) | ||
| 147 | + | ||
| 148 | + | ||
| 149 | +############################################################# | ||
| 150 | +# user-changeable settings which can be used to customize | ||
| 151 | +# layout of DMAP installation | ||
| 152 | +# (default values are platform-specific) | ||
| 153 | + | ||
| 154 | +SET (DMAP_BIN_SUBDIR ${DEFAULT_BIN_SUBDIR} CACHE STRING "Subdirectory where executables will be installed") | ||
| 155 | +SET (DMAP_CGIBIN_SUBDIR ${DEFAULT_CGIBIN_SUBDIR} CACHE STRING "Subdirectory where CGI executables will be installed") | ||
| 156 | +SET (DMAP_LIB_SUBDIR ${DEFAULT_LIB_SUBDIR} CACHE STRING "Subdirectory where libraries will be installed") | ||
| 157 | +SET (DMAP_LIBEXEC_SUBDIR ${DEFAULT_LIBEXEC_SUBDIR} CACHE STRING "Subdirectory where private executables will be installed") | ||
| 158 | +SET (DMAP_DATA_SUBDIR ${DEFAULT_DATA_SUBDIR} CACHE STRING "Subdirectory where DMAP data will be installed") | ||
| 159 | +SET (DMAP_PLUGIN_SUBDIR ${DEFAULT_PLUGIN_SUBDIR} CACHE STRING "Subdirectory where plugins will be installed") | ||
| 160 | +SET (DMAP_INCLUDE_SUBDIR ${DEFAULT_INCLUDE_SUBDIR} CACHE STRING "Subdirectory where header files will be installed") | ||
| 161 | +SET (DMAP_SERVER_MODULE_SUBDIR ${DEFAULT_SERVER_MODULE_SUBDIR} CACHE STRING "Subdirectory where server modules will be installed") | ||
| 162 | + | ||
| 163 | +# mark *_SUBDIR variables as advanced as this is not something | ||
| 164 | +# that an average user would use | ||
| 165 | +MARK_AS_ADVANCED (DMAP_BIN_SUBDIR DMAP_CGIBIN_SUBDIR DMAP_LIB_SUBDIR DMAP_LIBEXEC_SUBDIR DMAP_DATA_SUBDIR DMAP_PLUGIN_SUBDIR DMAP_INCLUDE_SUBDIR) | ||
| 166 | + | ||
| 167 | +# full paths for the installation | ||
| 168 | +SET (DMAP_BIN_DIR ${DMAP_BIN_SUBDIR}) | ||
| 169 | +SET (DMAP_CGIBIN_DIR ${DMAP_CGIBIN_SUBDIR}) | ||
| 170 | +SET (DMAP_LIB_DIR ${DMAP_LIB_SUBDIR}) | ||
| 171 | +SET (DMAP_LIBEXEC_DIR ${DMAP_LIBEXEC_SUBDIR}) | ||
| 172 | +SET (DMAP_DATA_DIR ${DMAP_DATA_SUBDIR}) | ||
| 173 | +SET (DMAP_PLUGIN_DIR ${DMAP_PLUGIN_SUBDIR}) | ||
| 174 | +SET (DMAP_INCLUDE_DIR ${DMAP_INCLUDE_SUBDIR}) | ||
| 175 | +SET (DMAP_SERVER_MODULE_DIR ${DMAP_SERVER_MODULE_SUBDIR}) | ||
| 176 | + | ||
| 177 | +# set the default locations where the targets (executables, libraries) will land when compiled | ||
| 178 | +# this is to allow running dmap from the source tree without having to actually do a "make install" | ||
| 179 | +SET (DMAP_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output) | ||
| 180 | +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${DMAP_OUTPUT_DIRECTORY}/${DMAP_BIN_SUBDIR}) | ||
| 181 | +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${DMAP_OUTPUT_DIRECTORY}/${DMAP_LIB_SUBDIR}) | ||
| 182 | +SET (TEST_DATA_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata") | ||
| 183 | + | ||
| 184 | +# write a marker with source directory path into the output's bin directory | ||
| 185 | +# if run from the build directory DMAP will detect it and alter the paths | ||
| 186 | +FILE(WRITE ${DMAP_OUTPUT_DIRECTORY}/${DMAP_BIN_SUBDIR}/dmapbuildpath.txt "${CMAKE_SOURCE_DIR}\n${DMAP_OUTPUT_DIRECTORY}") | ||
| 187 | + | ||
| 188 | +############################################################# | ||
| 189 | +# Python build dependency | ||
| 190 | + | ||
| 191 | +FIND_PACKAGE(PythonInterp 3 REQUIRED) | ||
| 192 | + | ||
| 193 | +############################################################# | ||
| 194 | +# Python bindings | ||
| 195 | + | ||
| 196 | +# IF (WITH_CORE AND WITH_BINDINGS) | ||
| 197 | + | ||
| 198 | + FIND_PACKAGE(PythonLibrary ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} EXACT REQUIRED) | ||
| 199 | + LIST( | ||
| 200 | + APPEND _components | ||
| 201 | + python${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR} | ||
| 202 | + python${PYTHON_VERSION_MAJOR} | ||
| 203 | + python | ||
| 204 | + ) | ||
| 205 | + SET(DMAP_BOOST_PYTHON_FOUND "") | ||
| 206 | + | ||
| 207 | + foreach(_component IN ITEMS ${_components}) | ||
| 208 | + find_package(Boost COMPONENTS ${_component}) | ||
| 209 | + if(Boost_FOUND) | ||
| 210 | + SET(DMAP_BOOST_PYTHON_FOUND ${_component}) | ||
| 211 | + break() | ||
| 212 | + endif() | ||
| 213 | + endforeach() | ||
| 214 | + | ||
| 215 | + if(DMAP_BOOST_PYTHON_FOUND STREQUAL "") | ||
| 216 | + message(FATAL_ERROR "No matching Boost.Python component found") | ||
| 217 | + endif() | ||
| 218 | + #MESSAGE(STATUS "XXX python: ${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}") | ||
| 219 | + | ||
| 220 | + IF (NOT BINDINGS_GLOBAL_INSTALL) | ||
| 221 | + SET(PYTHON_SITE_PACKAGES_DIR ${DMAP_DATA_DIR}/python) | ||
| 222 | + ENDIF (NOT BINDINGS_GLOBAL_INSTALL) | ||
| 223 | + | ||
| 224 | +# ENDIF (WITH_CORE AND WITH_BINDINGS) | ||
| 225 | + | ||
| 226 | +############################################################# | ||
| 227 | +# create dmpconfig.h | ||
| 228 | +# installed with app target | ||
| 229 | +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/cmake_templates/dmpconfig.h.in ${CMAKE_BINARY_DIR}/dmpconfig.h) | ||
| 230 | +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}) | ||
| 231 | + | ||
| 232 | +#[[ | ||
| 233 | +message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX}") | ||
| 234 | + | ||
| 235 | +include(GNUInstallDirs) | ||
| 236 | +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) | ||
| 237 | +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) | ||
| 238 | +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) | ||
| 239 | + | ||
| 240 | +set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries") | ||
| 241 | +set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables") | ||
| 242 | +set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files") | ||
| 243 | + | ||
| 244 | +# Report to user | ||
| 245 | +foreach(p LIB BIN INCLUDE CMAKE) | ||
| 246 | + file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path ) | ||
| 247 | + message(STATUS "Installing ${p} components to ${_path}") | ||
| 248 | + unset(_path) | ||
| 249 | +endforeach() | ||
| 250 | +]] | ||
| 251 | +############################################################# | ||
| 252 | +# process subdirs | ||
| 253 | + | ||
| 254 | +ADD_SUBDIRECTORY(apache) | ||
| 255 | +ADD_SUBDIRECTORY(src) | ||
| 256 | +ADD_SUBDIRECTORY(python) | ||
| 257 | + | ||
| 258 | +include(Dart) | ||
| 259 | +# enable testing and define tests | ||
| 260 | +enable_testing() | ||
| 261 | +add_subdirectory(tests) | ||
| 262 | + | ||
| 263 | + |
apache/CMakeLists.txt
0 → 100644
| 1 | + | ||
| 2 | +option(WITH_APACHE "Build Apache Module" ON) | ||
| 3 | + | ||
| 4 | +if(WITH_APACHE) | ||
| 5 | + add_library(mod_dmapserver MODULE mod_dmapserver.c) | ||
| 6 | + set_target_properties(mod_dmapserver PROPERTIES PREFIX "") | ||
| 7 | + | ||
| 8 | + find_package(APACHE) | ||
| 9 | + if(APACHE_FOUND) | ||
| 10 | + include_directories(${APACHE_INCLUDE_DIR}) | ||
| 11 | + target_link_libraries(mod_dmapserver ${APACHE_LIBRARY}) | ||
| 12 | + else(APACHE_FOUND) | ||
| 13 | + MESSAGE (SEND_ERROR "APACHE dependency was not found!") | ||
| 14 | + endif(APACHE_FOUND) | ||
| 15 | + | ||
| 16 | + find_package(APR) | ||
| 17 | + if(APR_FOUND) | ||
| 18 | + include_directories(${APR_INCLUDE_DIR} ${APU_INCLUDE_DIR}) | ||
| 19 | + target_link_libraries(mod_dmapserver ${APR_LIBRARY} ${APU_LIBRARY}) | ||
| 20 | + if(DEFINED APR_CPPFLAGS) | ||
| 21 | + add_definitions("${APR_CPPFLAGS}") | ||
| 22 | + endif(DEFINED APR_CPPFLAGS) | ||
| 23 | + else(APR_FOUND) | ||
| 24 | + MESSAGE (SEND_ERROR "APR dependency was not found!") | ||
| 25 | + endif(APR_FOUND) | ||
| 26 | + | ||
| 27 | + if(APACHE_MODULE_DIR) | ||
| 28 | + INSTALL(TARGETS mod_dmapserver DESTINATION ${APACHE_MODULE_DIR}) | ||
| 29 | + endif(APACHE_MODULE_DIR) | ||
| 30 | +else(WITH_APACHE) | ||
| 31 | + message(STATUS " * Apache Module support status: DISABLED") | ||
| 32 | +endif(WITH_APACHE) |
apache/mod_dmapserver.c
0 → 100644
| 1 | +/* Include the required headers from httpd */ | ||
| 2 | +#include "httpd.h" | ||
| 3 | +#include "http_core.h" | ||
| 4 | +#include "http_protocol.h" | ||
| 5 | +#include "http_request.h" | ||
| 6 | + | ||
| 7 | +/* Define prototypes of our functions in this module */ | ||
| 8 | +static void register_hooks(apr_pool_t *pool); | ||
| 9 | +static int example_handler(request_rec *r); | ||
| 10 | + | ||
| 11 | +/* Define our module as an entity and assign a function for registering hooks */ | ||
| 12 | + | ||
| 13 | +module AP_MODULE_DECLARE_DATA example_module = | ||
| 14 | +{ | ||
| 15 | + STANDARD20_MODULE_STUFF, | ||
| 16 | + NULL, // Per-directory configuration handler | ||
| 17 | + NULL, // Merge handler for per-directory configurations | ||
| 18 | + NULL, // Per-server configuration handler | ||
| 19 | + NULL, // Merge handler for per-server configurations | ||
| 20 | + NULL, // Any directives we may have for httpd | ||
| 21 | + register_hooks // Our hook registering function | ||
| 22 | +}; | ||
| 23 | + | ||
| 24 | + | ||
| 25 | +/* register_hooks: Adds a hook to the httpd process */ | ||
| 26 | +static void register_hooks(apr_pool_t *pool) | ||
| 27 | +{ | ||
| 28 | + | ||
| 29 | + /* Hook the request handler */ | ||
| 30 | + ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST); | ||
| 31 | +} | ||
| 32 | + | ||
| 33 | +/* The handler function for our module. | ||
| 34 | + * This is where all the fun happens! | ||
| 35 | + */ | ||
| 36 | + | ||
| 37 | +static int example_handler(request_rec *r) | ||
| 38 | +{ | ||
| 39 | + /* First off, we need to check if this is a call for the "example" handler. | ||
| 40 | + * If it is, we accept it and do our things, it not, we simply return DECLINED, | ||
| 41 | + * and Apache will try somewhere else. | ||
| 42 | + */ | ||
| 43 | + if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED); | ||
| 44 | + | ||
| 45 | + // The first thing we will do is write a simple "Hello, world!" back to the client. | ||
| 46 | + ap_rputs("Hello, world!<br/>", r); | ||
| 47 | + return OK; | ||
| 48 | +} |
cmake/FindAPACHE.cmake
0 → 100644
| 1 | +# | ||
| 2 | +# APACHE_FOUND - System has APACHE | ||
| 3 | +# APACHE_INCLUDE_DIR - The APACHE include directory | ||
| 4 | +# | ||
| 5 | +# APACHE_LOCATION | ||
| 6 | +# setting this enables search for apache libraries / headers in this location | ||
| 7 | + | ||
| 8 | +# | ||
| 9 | +# Include directories | ||
| 10 | +# | ||
| 11 | +find_path(APACHE_INCLUDE_DIR | ||
| 12 | + NAMES httpd.h | ||
| 13 | + PATH_SUFFIXES httpd apache apache2 apache22 apache24 | ||
| 14 | +) | ||
| 15 | + | ||
| 16 | +if(NOT DEFINED APACHE_MODULE_DIR) | ||
| 17 | + find_program(APXS_BIN NAMES apxs apxs2 | ||
| 18 | + PATH_SUFFIXES httpd apache apache2 | ||
| 19 | + ) | ||
| 20 | + | ||
| 21 | + if(APXS_BIN) | ||
| 22 | + EXECUTE_PROCESS(COMMAND ${APXS_BIN} -q LIBEXECDIR | ||
| 23 | + OUTPUT_VARIABLE APACHE_MODULE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
| 24 | + endif(APXS_BIN) | ||
| 25 | +endif(NOT DEFINED APACHE_MODULE_DIR) | ||
| 26 | + | ||
| 27 | +include(FindPackageHandleStandardArgs) | ||
| 28 | +# handle the QUIETLY and REQUIRED arguments and set APACHE_FOUND to TRUE if | ||
| 29 | +# all listed variables are TRUE | ||
| 30 | +find_package_handle_standard_args(APACHE DEFAULT_MSG APACHE_INCLUDE_DIR ) | ||
| 31 | +mark_as_advanced(APACHE_INCLUDE_DIR) |
cmake/FindAPR.cmake
0 → 100644
| 1 | +# Licensed to the Apache Software Foundation (ASF) under one | ||
| 2 | +# or more contributor license agreements. See the NOTICE file | ||
| 3 | +# distributed with this work for additional information | ||
| 4 | +# regarding copyright ownership. The ASF licenses this file | ||
| 5 | +# to you under the Apache License, Version 2.0 (the | ||
| 6 | +# "License"); you may not use this file except in compliance | ||
| 7 | +# with the License. You may obtain a copy of the License at | ||
| 8 | +# | ||
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
| 10 | +# | ||
| 11 | +# Unless required by applicable law or agreed to in writing, | ||
| 12 | +# software distributed under the License is distributed on an | ||
| 13 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| 14 | +# KIND, either express or implied. See the License for the | ||
| 15 | +# specific language governing permissions and limitations | ||
| 16 | +# under the License. | ||
| 17 | + | ||
| 18 | +# - Find Apache Portable Runtime | ||
| 19 | +# Find the APR includes and libraries | ||
| 20 | +# This module defines | ||
| 21 | +# APR_INCLUDE_DIR and APRUTIL_INCLUDE_DIR, where to find apr.h, etc. | ||
| 22 | +# APR_LIBRARIES and APRUTIL_LIBRARIES, the libraries needed to use APR. | ||
| 23 | +# APR_FOUND and APRUTIL_FOUND, If false, do not try to use APR. | ||
| 24 | +# also defined, but not for general use are | ||
| 25 | +# APR_LIBRARY and APRUTIL_LIBRARY, where to find the APR library. | ||
| 26 | + | ||
| 27 | +# APR first. | ||
| 28 | + | ||
| 29 | +FIND_PROGRAM(APR_CONFIG_BIN | ||
| 30 | + NAMES apr-config apr-1-config ) | ||
| 31 | + | ||
| 32 | +if(APR_CONFIG_BIN) | ||
| 33 | + execute_process( | ||
| 34 | + COMMAND ${APR_CONFIG_BIN} --includedir | ||
| 35 | + OUTPUT_VARIABLE HINT_APR_INCLUDE_DIR | ||
| 36 | + OUTPUT_STRIP_TRAILING_WHITESPACE | ||
| 37 | + ) | ||
| 38 | + execute_process( | ||
| 39 | + COMMAND ${APR_CONFIG_BIN} --cppflags | ||
| 40 | + OUTPUT_VARIABLE APR_CPPFLAGS | ||
| 41 | + OUTPUT_STRIP_TRAILING_WHITESPACE | ||
| 42 | + ) | ||
| 43 | +endif(APR_CONFIG_BIN) | ||
| 44 | + | ||
| 45 | +FIND_PATH(APR_INCLUDE_DIR | ||
| 46 | + NAMES apr.h | ||
| 47 | + HINTS ${HINT_APR_INCLUDE_DIR} | ||
| 48 | + PATH_SUFFIXES apr-1 apr-1.0 apr | ||
| 49 | +) | ||
| 50 | + | ||
| 51 | +FIND_LIBRARY(APR_LIBRARY | ||
| 52 | + NAMES apr-1 apr | ||
| 53 | + PATH_SUFFIXES apr-1 apr-1.0 apr | ||
| 54 | +) | ||
| 55 | + | ||
| 56 | +set(APR_INCLUDE_DIRS ${APR_INCLUDE_DIR}) | ||
| 57 | +set(APR_LIBRARIES ${APR_LIBRARY}) | ||
| 58 | +include(FindPackageHandleStandardArgs) | ||
| 59 | +find_package_handle_standard_args(APR DEFAULT_MSG APR_LIBRARY APR_INCLUDE_DIR) | ||
| 60 | +mark_as_advanced(APR_LIBRARY APR_INCLUDE_DIR) | ||
| 61 | + | ||
| 62 | +# Next, APRUTIL. | ||
| 63 | + | ||
| 64 | +FIND_PATH(APU_INCLUDE_DIR | ||
| 65 | + NAMES apu.h | ||
| 66 | + PATH_SUFFIXES apr-1 apr-1.0 apr | ||
| 67 | +) | ||
| 68 | + | ||
| 69 | +FIND_LIBRARY(APU_LIBRARY | ||
| 70 | + NAMES aprutil-1 aprutil | ||
| 71 | + PATH_SUFFIXES apr-1 apr-1.0 apr | ||
| 72 | +) | ||
| 73 | + | ||
| 74 | + | ||
| 75 | +set(APU_INCLUDE_DIRS ${APU_INCLUDE_DIR}) | ||
| 76 | +set(APU_LIBRARIES ${APU_LIBRARY}) | ||
| 77 | +find_package_handle_standard_args(APU DEFAULT_MSG APU_LIBRARY APU_INCLUDE_DIR) | ||
| 78 | +mark_as_advanced(APU_LIBRARY APU_INCLUDE_DIR) |
cmake/FindCairo.cmake
0 → 100644
| 1 | +# - Try to find the CAIRO library | ||
| 2 | +# Once done this will define | ||
| 3 | +# | ||
| 4 | +# CAIRO_ROOT_DIR - Set this variable to the root installation of CAIRO | ||
| 5 | +# | ||
| 6 | +# Read-Only variables: | ||
| 7 | +# CAIRO_FOUND - system has the CAIRO library | ||
| 8 | +# CAIRO_INCLUDE_DIR - the CAIRO include directory | ||
| 9 | +# CAIRO_LIBRARIES - The libraries needed to use CAIRO | ||
| 10 | +# CAIRO_VERSION - This is set to $major.$minor.$revision (eg. 0.9.8) | ||
| 11 | + | ||
| 12 | +#============================================================================= | ||
| 13 | +# Copyright 2012 Dmitry Baryshnikov <polimax at mail dot ru> | ||
| 14 | +# | ||
| 15 | +# Distributed under the OSI-approved BSD License (the "License"); | ||
| 16 | +# see accompanying file Copyright.txt for details. | ||
| 17 | +# | ||
| 18 | +# This software is distributed WITHOUT ANY WARRANTY; without even the | ||
| 19 | +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
| 20 | +# See the License for more information. | ||
| 21 | +#============================================================================= | ||
| 22 | +# (To distribute this file outside of CMake, substitute the full | ||
| 23 | +# License text for the above reference.) | ||
| 24 | + | ||
| 25 | +find_package(PkgConfig) | ||
| 26 | + | ||
| 27 | +if(PKG_CONFIG_FOUND) | ||
| 28 | + pkg_check_modules(_CAIRO cairo) | ||
| 29 | +endif (PKG_CONFIG_FOUND) | ||
| 30 | + | ||
| 31 | +SET(_CAIRO_ROOT_HINTS | ||
| 32 | + $ENV{CAIRO} | ||
| 33 | + ${CAIRO_ROOT_DIR} | ||
| 34 | + ) | ||
| 35 | +SET(_CAIRO_ROOT_PATHS | ||
| 36 | + $ENV{CAIRO}/src | ||
| 37 | + /usr | ||
| 38 | + /usr/local | ||
| 39 | + ) | ||
| 40 | +SET(_CAIRO_ROOT_HINTS_AND_PATHS | ||
| 41 | + HINTS ${_CAIRO_ROOT_HINTS} | ||
| 42 | + PATHS ${_CAIRO_ROOT_PATHS} | ||
| 43 | + ) | ||
| 44 | + | ||
| 45 | +FIND_PATH(CAIRO_INCLUDE_DIR | ||
| 46 | + NAMES | ||
| 47 | + cairo.h | ||
| 48 | + HINTS | ||
| 49 | + ${_CAIRO_INCLUDEDIR} | ||
| 50 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 51 | + PATH_SUFFIXES | ||
| 52 | + include | ||
| 53 | + "include/cairo" | ||
| 54 | +) | ||
| 55 | + | ||
| 56 | +IF(NOT PKGCONFIG_FOUND AND WIN32 AND NOT CYGWIN) | ||
| 57 | + # MINGW should go here too | ||
| 58 | + IF(MSVC) | ||
| 59 | + # Implementation details: | ||
| 60 | + # We are using the libraries located in the VC subdir instead of the parent directory eventhough : | ||
| 61 | + FIND_LIBRARY(CAIRO_DEBUG | ||
| 62 | + NAMES | ||
| 63 | + cairod | ||
| 64 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 65 | + PATH_SUFFIXES | ||
| 66 | + "lib" | ||
| 67 | + "VC" | ||
| 68 | + "lib/VC" | ||
| 69 | + ) | ||
| 70 | + | ||
| 71 | + FIND_LIBRARY(CAIRO_RELEASE | ||
| 72 | + NAMES | ||
| 73 | + cairo | ||
| 74 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 75 | + PATH_SUFFIXES | ||
| 76 | + "lib" | ||
| 77 | + "VC" | ||
| 78 | + "lib/VC" | ||
| 79 | + ) | ||
| 80 | + | ||
| 81 | + if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE ) | ||
| 82 | + if(NOT CAIRO_DEBUG) | ||
| 83 | + set(CAIRO_DEBUG ${CAIRO_RELEASE}) | ||
| 84 | + endif(NOT CAIRO_DEBUG) | ||
| 85 | + set( CAIRO_LIBRARIES | ||
| 86 | + optimized ${CAIRO_RELEASE} debug ${CAIRO_DEBUG} | ||
| 87 | + ) | ||
| 88 | + else() | ||
| 89 | + set( CAIRO_LIBRARIES ${CAIRO_RELEASE}) | ||
| 90 | + endif() | ||
| 91 | + MARK_AS_ADVANCED(CAIRO_DEBUG CAIRO_RELEASE) | ||
| 92 | + ELSEIF(MINGW) | ||
| 93 | + # same player, for MingW | ||
| 94 | + FIND_LIBRARY(CAIRO | ||
| 95 | + NAMES | ||
| 96 | + cairo | ||
| 97 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 98 | + PATH_SUFFIXES | ||
| 99 | + "lib" | ||
| 100 | + "lib/MinGW" | ||
| 101 | + ) | ||
| 102 | + | ||
| 103 | + MARK_AS_ADVANCED(CAIRO) | ||
| 104 | + set( CAIRO_LIBRARIES ${CAIRO}) | ||
| 105 | + ELSE(MSVC) | ||
| 106 | + # Not sure what to pick for -say- intel, let's use the toplevel ones and hope someone report issues: | ||
| 107 | + FIND_LIBRARY(CAIRO | ||
| 108 | + NAMES | ||
| 109 | + cairo | ||
| 110 | + HINTS | ||
| 111 | + ${_CAIRO_LIBDIR} | ||
| 112 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 113 | + PATH_SUFFIXES | ||
| 114 | + lib | ||
| 115 | + ) | ||
| 116 | + | ||
| 117 | + MARK_AS_ADVANCED(CAIRO) | ||
| 118 | + set( CAIRO_LIBRARIES ${CAIRO} ) | ||
| 119 | + ENDIF(MSVC) | ||
| 120 | +ELSE() | ||
| 121 | + | ||
| 122 | + FIND_LIBRARY(CAIRO_LIBRARY | ||
| 123 | + NAMES | ||
| 124 | + cairo | ||
| 125 | + HINTS | ||
| 126 | + ${_CAIRO_LIBDIR} | ||
| 127 | + ${_CAIRO_ROOT_HINTS_AND_PATHS} | ||
| 128 | + PATH_SUFFIXES | ||
| 129 | + "lib" | ||
| 130 | + "local/lib" | ||
| 131 | + ) | ||
| 132 | + | ||
| 133 | + MARK_AS_ADVANCED(CAIRO_LIBRARY) | ||
| 134 | + | ||
| 135 | + # compat defines | ||
| 136 | + SET(CAIRO_LIBRARIES ${CAIRO_LIBRARY}) | ||
| 137 | + | ||
| 138 | +ENDIF() | ||
| 139 | + | ||
| 140 | +#message( STATUS "Cairo_FIND_VERSION=${Cairo_FIND_VERSION}.") | ||
| 141 | +#message( STATUS "CAIRO_INCLUDE_DIR=${CAIRO_INCLUDE_DIR}.") | ||
| 142 | + | ||
| 143 | +# Fetch version from cairo-version.h if a version was requested by find_package() | ||
| 144 | +if(CAIRO_INCLUDE_DIR AND Cairo_FIND_VERSION) | ||
| 145 | + file(READ "${CAIRO_INCLUDE_DIR}/cairo-version.h" _CAIRO_VERSION_H_CONTENTS) | ||
| 146 | + string(REGEX REPLACE "^(.*\n)?#define[ \t]+CAIRO_VERSION_MAJOR[ \t]+([0-9]+).*" | ||
| 147 | + "\\2" CAIRO_VERSION_MAJOR ${_CAIRO_VERSION_H_CONTENTS}) | ||
| 148 | + string(REGEX REPLACE "^(.*\n)?#define[ \t]+CAIRO_VERSION_MINOR[ \t]+([0-9]+).*" | ||
| 149 | + "\\2" CAIRO_VERSION_MINOR ${_CAIRO_VERSION_H_CONTENTS}) | ||
| 150 | + string(REGEX REPLACE "^(.*\n)?#define[ \t]+CAIRO_VERSION_MICRO[ \t]+([0-9]+).*" | ||
| 151 | + "\\2" CAIRO_VERSION_MICRO ${_CAIRO_VERSION_H_CONTENTS}) | ||
| 152 | + set(CAIRO_VERSION ${CAIRO_VERSION_MAJOR}.${CAIRO_VERSION_MINOR}.${CAIRO_VERSION_MICRO} | ||
| 153 | + CACHE INTERNAL "The version number for Cairo libraries") | ||
| 154 | +endif() | ||
| 155 | + | ||
| 156 | +include(FindPackageHandleStandardArgs) | ||
| 157 | + | ||
| 158 | +find_package_handle_standard_args(Cairo | ||
| 159 | + REQUIRED_VARS | ||
| 160 | + CAIRO_LIBRARIES | ||
| 161 | + CAIRO_INCLUDE_DIR | ||
| 162 | + VERSION_VAR | ||
| 163 | + CAIRO_VERSION | ||
| 164 | +) | ||
| 165 | + | ||
| 166 | +MARK_AS_ADVANCED(CAIRO_INCLUDE_DIR CAIRO_LIBRARIES) |
cmake/FindFcgi.cmake
0 → 100644
| 1 | +# CMake module to search for FastCGI headers | ||
| 2 | +# | ||
| 3 | +# If it's found it sets FCGI_FOUND to TRUE | ||
| 4 | +# and following variables are set: | ||
| 5 | +# FCGI_INCLUDE_DIR | ||
| 6 | +# FCGI_LIBRARY | ||
| 7 | +FIND_PATH(FCGI_INCLUDE_DIR | ||
| 8 | + fcgio.h | ||
| 9 | + PATHS | ||
| 10 | + /usr/include | ||
| 11 | + /usr/local/include | ||
| 12 | + /usr/include/fastcgi | ||
| 13 | + "$ENV{LIB_DIR}/include" | ||
| 14 | + $ENV{INCLUDE} | ||
| 15 | + ) | ||
| 16 | +FIND_LIBRARY(FCGI_LIBRARY NAMES fcgi libfcgi PATHS | ||
| 17 | + /usr/local/lib | ||
| 18 | + /usr/lib | ||
| 19 | + "$ENV{LIB_DIR}/lib" | ||
| 20 | + "$ENV{LIB}" | ||
| 21 | + ) | ||
| 22 | + | ||
| 23 | +IF (FCGI_INCLUDE_DIR AND FCGI_LIBRARY) | ||
| 24 | + SET(FCGI_FOUND TRUE) | ||
| 25 | +ENDIF (FCGI_INCLUDE_DIR AND FCGI_LIBRARY) | ||
| 26 | + | ||
| 27 | +IF (FCGI_FOUND) | ||
| 28 | + IF (NOT FCGI_FIND_QUIETLY) | ||
| 29 | + MESSAGE(STATUS "Found FCGI: ${FCGI_LIBRARY}") | ||
| 30 | + ENDIF (NOT FCGI_FIND_QUIETLY) | ||
| 31 | +ELSE (FCGI_FOUND) | ||
| 32 | + IF (FCGI_FIND_REQUIRED) | ||
| 33 | + MESSAGE(FATAL_ERROR "Could not find FCGI") | ||
| 34 | + ENDIF (FCGI_FIND_REQUIRED) | ||
| 35 | +ENDIF (FCGI_FOUND) |
cmake/FindLibEvent.cmake
0 → 100644
| 1 | +# - Find LibEvent (a cross event library) | ||
| 2 | +# This module defines | ||
| 3 | +# LIBEVENT_INCLUDE_DIR, where to find LibEvent headers | ||
| 4 | +# LIBEVENT_LIB, LibEvent libraries | ||
| 5 | +# LibEvent_FOUND, If false, do not try to use libevent | ||
| 6 | + | ||
| 7 | +set(LibEvent_EXTRA_PREFIXES /usr/local /opt/local "$ENV{HOME}") | ||
| 8 | +foreach(prefix ${LibEvent_EXTRA_PREFIXES}) | ||
| 9 | + list(APPEND LibEvent_INCLUDE_PATHS "${prefix}/include") | ||
| 10 | + list(APPEND LibEvent_LIB_PATHS "${prefix}/lib") | ||
| 11 | +endforeach() | ||
| 12 | + | ||
| 13 | +find_path(LIBEVENT_INCLUDE_DIR event.h PATHS ${LibEvent_INCLUDE_PATHS}) | ||
| 14 | +find_library(LIBEVENT_LIB NAMES event PATHS ${LibEvent_LIB_PATHS}) | ||
| 15 | +find_library(LIBEVENT_PTHREAD_LIB NAMES event_pthreads PATHS ${LibEvent_LIB_PATHS}) | ||
| 16 | + | ||
| 17 | +if (LIBEVENT_LIB AND LIBEVENT_INCLUDE_DIR AND LIBEVENT_PTHREAD_LIB) | ||
| 18 | + set(LibEvent_FOUND TRUE) | ||
| 19 | + set(LIBEVENT_LIB ${LIBEVENT_LIB} ${LIBEVENT_PTHREAD_LIB}) | ||
| 20 | +else () | ||
| 21 | + set(LibEvent_FOUND FALSE) | ||
| 22 | +endif () | ||
| 23 | + | ||
| 24 | +if (LibEvent_FOUND) | ||
| 25 | + if (NOT LibEvent_FIND_QUIETLY) | ||
| 26 | + message(STATUS "Found libevent: ${LIBEVENT_LIB}") | ||
| 27 | + endif () | ||
| 28 | +else () | ||
| 29 | + if (LibEvent_FIND_REQUIRED) | ||
| 30 | + message(FATAL_ERROR "Could NOT find libevent and libevent_pthread.") | ||
| 31 | + endif () | ||
| 32 | + message(STATUS "libevent and libevent_pthread NOT found.") | ||
| 33 | +endif () | ||
| 34 | + | ||
| 35 | +mark_as_advanced( | ||
| 36 | + LIBEVENT_LIB | ||
| 37 | + LIBEVENT_INCLUDE_DIR | ||
| 38 | + ) |
cmake/FindLibPython.py
0 → 100644
| 1 | +# -*- coding: utf-8 -*- | ||
| 2 | +# | ||
| 3 | +# Copyright (c) 2007, Simon Edwards <simon@simonzone.com> | ||
| 4 | +# All rights reserved. | ||
| 5 | +# | ||
| 6 | +# Redistribution and use in source and binary forms, with or without | ||
| 7 | +# modification, are permitted provided that the following conditions are met: | ||
| 8 | +# * Redistributions of source code must retain the above copyright | ||
| 9 | +# notice, this list of conditions and the following disclaimer. | ||
| 10 | +# * Redistributions in binary form must reproduce the above copyright | ||
| 11 | +# notice, this list of conditions and the following disclaimer in the | ||
| 12 | +# documentation and/or other materials provided with the distribution. | ||
| 13 | +# * Neither the name of the Simon Edwards <simon@simonzone.com> nor the | ||
| 14 | +# names of its contributors may be used to endorse or promote products | ||
| 15 | +# derived from this software without specific prior written permission. | ||
| 16 | +# | ||
| 17 | +# THIS SOFTWARE IS PROVIDED BY Simon Edwards <simon@simonzone.com> ''AS IS'' AND ANY | ||
| 18 | +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 19 | +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 20 | +# DISCLAIMED. IN NO EVENT SHALL Simon Edwards <simon@simonzone.com> BE LIABLE FOR ANY | ||
| 21 | +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| 22 | +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 23 | +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
| 24 | +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 25 | +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 26 | +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 27 | +# | ||
| 28 | +# FindLibPython.py | ||
| 29 | +# Copyright (c) 2007, Simon Edwards <simon@simonzone.com> | ||
| 30 | +# Redistribution and use is allowed according to the terms of the BSD license. | ||
| 31 | +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
| 32 | + | ||
| 33 | +import sys | ||
| 34 | +import distutils.sysconfig | ||
| 35 | + | ||
| 36 | +print("exec_prefix:%s" % sys.exec_prefix) | ||
| 37 | +print("short_version:%s" % sys.version[:3]) | ||
| 38 | +print("long_version:%s" % sys.version.split()[0]) | ||
| 39 | +print("py_inc_dir:%s" % distutils.sysconfig.get_python_inc()) | ||
| 40 | +print("site_packages_dir:%s" % distutils.sysconfig.get_python_lib(plat_specific=1)) |
cmake/FindPostgres.cmake
0 → 100644
| 1 | +# Find PostgreSQL | ||
| 2 | +# ~~~~~~~~~~~~~~~ | ||
| 3 | +# Copyright (c) 2007, Martin Dobias <wonder.sk at gmail.com> | ||
| 4 | +# Redistribution and use is allowed according to the terms of the BSD license. | ||
| 5 | +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
| 6 | +# | ||
| 7 | +# CMake module to search for PostgreSQL library | ||
| 8 | +# | ||
| 9 | +# pg_config is searched for in POSTGRES_CONFIG dir, | ||
| 10 | +# default /usr/bin | ||
| 11 | +# | ||
| 12 | +# If it's found it sets POSTGRES_FOUND to TRUE | ||
| 13 | +# and following variables are set: | ||
| 14 | +# POSTGRES_INCLUDE_DIR | ||
| 15 | +# POSTGRES_LIBRARY | ||
| 16 | + | ||
| 17 | +IF(ANDROID) | ||
| 18 | + SET(POSTGRES_INCLUDE_DIR ${POSTGRES_INCLUDE_DIR} CACHE STRING INTERNAL) | ||
| 19 | + SET(POSTGRES_LIBRARY ${PG_TMP}/libpq.so CACHE STRING INTERNAL) | ||
| 20 | +ENDIF(ANDROID) | ||
| 21 | + | ||
| 22 | +IF(WIN32 AND NOT ANDROID) | ||
| 23 | + IF (NOT POSTGRES_INCLUDE_DIR) | ||
| 24 | + FIND_PATH(POSTGRES_INCLUDE_DIR libpq-fe.h | ||
| 25 | + /usr/local/include | ||
| 26 | + /usr/include | ||
| 27 | + c:/msys/local/include | ||
| 28 | + "$ENV{LIB_DIR}/include/postgresql" | ||
| 29 | + "$ENV{LIB_DIR}/include" | ||
| 30 | + ) | ||
| 31 | + ENDIF (NOT POSTGRES_INCLUDE_DIR) | ||
| 32 | + | ||
| 33 | + IF (NOT POSTGRES_LIBRARY) | ||
| 34 | + FIND_LIBRARY(POSTGRES_LIBRARY NAMES pq libpq libpqdll PATHS | ||
| 35 | + /usr/local/lib | ||
| 36 | + /usr/lib | ||
| 37 | + c:/msys/local/lib | ||
| 38 | + "$ENV{LIB_DIR}/lib" | ||
| 39 | + ) | ||
| 40 | + ENDIF (NOT POSTGRES_LIBRARY) | ||
| 41 | + | ||
| 42 | +ELSE(WIN32) | ||
| 43 | + IF(UNIX) | ||
| 44 | + | ||
| 45 | + SET(POSTGRES_CONFIG_PREFER_PATH "$ENV{POSTGRES_HOME}/bin" CACHE STRING "preferred path to PG (pg_config)") | ||
| 46 | + FIND_PROGRAM(POSTGRES_CONFIG pg_config | ||
| 47 | + ${POSTGRES_CONFIG_PREFER_PATH} | ||
| 48 | + /usr/local/pgsql/bin/ | ||
| 49 | + /usr/local/bin/ | ||
| 50 | + /usr/bin/ | ||
| 51 | + ) | ||
| 52 | + # MESSAGE("DBG POSTGRES_CONFIG ${POSTGRES_CONFIG}") | ||
| 53 | + | ||
| 54 | + IF (POSTGRES_CONFIG) | ||
| 55 | + # set INCLUDE_DIR | ||
| 56 | + EXEC_PROGRAM(${POSTGRES_CONFIG} | ||
| 57 | + ARGS --includedir | ||
| 58 | + OUTPUT_VARIABLE PG_TMP) | ||
| 59 | + SET(POSTGRES_INCLUDE_DIR ${PG_TMP} CACHE STRING INTERNAL) | ||
| 60 | + | ||
| 61 | + # set LIBRARY_DIR | ||
| 62 | + EXEC_PROGRAM(${POSTGRES_CONFIG} | ||
| 63 | + ARGS --libdir | ||
| 64 | + OUTPUT_VARIABLE PG_TMP) | ||
| 65 | + IF (APPLE) | ||
| 66 | + SET(POSTGRES_LIBRARY ${PG_TMP}/libpq.dylib CACHE STRING INTERNAL) | ||
| 67 | + ELSEIF (CYGWIN) | ||
| 68 | + EXEC_PROGRAM(${POSTGRES_CONFIG} | ||
| 69 | + ARGS --libs | ||
| 70 | + OUTPUT_VARIABLE PG_TMP) | ||
| 71 | + | ||
| 72 | + STRING(REGEX MATCHALL "[-][L]([^ ;])+" _LDIRS "${PG_TMP}") | ||
| 73 | + STRING(REGEX MATCHALL "[-][l]([^ ;])+" _LLIBS "${PG_TMP}") | ||
| 74 | + | ||
| 75 | + FIND_LIBRARY(POSTGRES_LIBRARY NAMES pq PATHS /usr/lib /usr/local/lib) | ||
| 76 | + | ||
| 77 | + SET(_DIRS) | ||
| 78 | + FOREACH(_DIR ${_LDIRS}) | ||
| 79 | + STRING(REPLACE "-L" "" _DIR ${_DIR}) | ||
| 80 | + SET(_DIRS ${_DIRS} ${_DIR}) | ||
| 81 | + ENDFOREACH(_DIR ${_LDIRS}) | ||
| 82 | + | ||
| 83 | + SET(_LIBS) | ||
| 84 | + FOREACH(_LIB ${_LLIBS}) | ||
| 85 | + STRING(REPLACE "-l" "" _LIB ${_LIB}) | ||
| 86 | + SET(_LIBS ${_LIBS} ${_LIB}) | ||
| 87 | + ENDFOREACH(_LIB ${_LDIRS}) | ||
| 88 | + | ||
| 89 | + FOREACH(_LIBNAME ${_LIBS}) | ||
| 90 | + UNSET(PG_LIB CACHE) | ||
| 91 | + FIND_LIBRARY(PG_LIB NAMES ${_LIBNAME} PATHS ${_DIRS} /usr/lib /usr/local/lib) | ||
| 92 | + IF(NOT PG_LIB) | ||
| 93 | + MESSAGE(FATAL "PostgreSQL dependency library ${_LIBNAME} not found") | ||
| 94 | + ENDIF(NOT PG_LIB) | ||
| 95 | + SET(POSTGRES_LIBRARY ${POSTGRES_LIBRARY} ${PG_LIB}) | ||
| 96 | + ENDFOREACH(_LIBNAME ${_LIBS}) | ||
| 97 | + | ||
| 98 | + ELSE (CYGWIN) | ||
| 99 | + FIND_LIBRARY(POSTGRES_LIBRARY NAMES pq libpq libpqdll PATHS ${PG_TMP}/lib) | ||
| 100 | + ENDIF (APPLE) | ||
| 101 | + ENDIF(POSTGRES_CONFIG) | ||
| 102 | + | ||
| 103 | + ENDIF(UNIX) | ||
| 104 | +ENDIF(WIN32 AND NOT ANDROID) | ||
| 105 | + | ||
| 106 | + | ||
| 107 | +IF (POSTGRES_INCLUDE_DIR AND POSTGRES_LIBRARY) | ||
| 108 | + SET(POSTGRES_FOUND TRUE) | ||
| 109 | + IF(EXISTS "${POSTGRES_INCLUDE_DIR}/pg_config.h") | ||
| 110 | + SET(HAVE_PGCONFIG TRUE) | ||
| 111 | + ELSE(EXISTS "${POSTGRES_INCLUDE_DIR}/pg_config.h") | ||
| 112 | + SET(HAVE_PGCONFIG FALSE) | ||
| 113 | + ENDIF(EXISTS "${POSTGRES_INCLUDE_DIR}/pg_config.h") | ||
| 114 | +ENDIF (POSTGRES_INCLUDE_DIR AND POSTGRES_LIBRARY) | ||
| 115 | + | ||
| 116 | + | ||
| 117 | +IF (POSTGRES_FOUND) | ||
| 118 | + | ||
| 119 | + IF (NOT POSTGRES_FIND_QUIETLY) | ||
| 120 | + MESSAGE(STATUS "Found PostgreSQL: ${POSTGRES_LIBRARY}") | ||
| 121 | + ENDIF (NOT POSTGRES_FIND_QUIETLY) | ||
| 122 | + | ||
| 123 | +ELSE (POSTGRES_FOUND) | ||
| 124 | + | ||
| 125 | + #SET (POSTGRES_INCLUDE_DIR "") | ||
| 126 | + #SET (POSTGRES_LIBRARY "") | ||
| 127 | + | ||
| 128 | + IF (POSTGRES_FIND_REQUIRED) | ||
| 129 | + MESSAGE(FATAL_ERROR "Could not find PostgreSQL") | ||
| 130 | + ELSE (POSTGRES_FIND_REQUIRED) | ||
| 131 | + MESSAGE(STATUS "Could not find PostgreSQL") | ||
| 132 | + ENDIF (POSTGRES_FIND_REQUIRED) | ||
| 133 | + | ||
| 134 | +ENDIF (POSTGRES_FOUND) |
cmake/FindPythonLibrary.cmake
0 → 100644
| 1 | +# Find Python | ||
| 2 | +# ~~~~~~~~~~~ | ||
| 3 | +# Find the Python interpreter and related Python directories. | ||
| 4 | +# | ||
| 5 | +# This file defines the following variables: | ||
| 6 | +# | ||
| 7 | +# PYTHON_EXECUTABLE - The path and filename of the Python interpreter. | ||
| 8 | +# | ||
| 9 | +# PYTHON_SHORT_VERSION - The version of the Python interpreter found, | ||
| 10 | +# excluding the patch version number. (e.g. 2.5 and not 2.5.1)) | ||
| 11 | +# | ||
| 12 | +# PYTHON_LONG_VERSION - The version of the Python interpreter found as a human | ||
| 13 | +# readable string. | ||
| 14 | +# | ||
| 15 | +# PYTHON_SITE_PACKAGES_DIR - Location of the Python site-packages directory. | ||
| 16 | +# | ||
| 17 | +# PYTHON_INCLUDE_PATH - Directory holding the python.h include file. | ||
| 18 | +# | ||
| 19 | +# PYTHON_LIBRARY, PYTHON_LIBRARIES- Location of the Python library. | ||
| 20 | + | ||
| 21 | +# Copyright (c) 2007, Simon Edwards <simon@simonzone.com> | ||
| 22 | +# Redistribution and use is allowed according to the terms of the BSD license. | ||
| 23 | +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
| 24 | + | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +INCLUDE(CMakeFindFrameworks) | ||
| 28 | + | ||
| 29 | +if(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${PYTHON_SITE_PACKAGES_DIR}") | ||
| 30 | + # Already in cache, be silent | ||
| 31 | + set(PYTHONLIBRARY_FOUND TRUE) | ||
| 32 | +else(EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${PYTHON_SITE_PACKAGES_DIR}") | ||
| 33 | + | ||
| 34 | + FIND_PACKAGE(PythonInterp 3) | ||
| 35 | + | ||
| 36 | + if(PYTHONINTERP_FOUND) | ||
| 37 | + FIND_FILE(_find_lib_python_py FindLibPython.py PATHS ${CMAKE_MODULE_PATH} NO_CMAKE_FIND_ROOT_PATH) | ||
| 38 | + | ||
| 39 | + EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} ${_find_lib_python_py} OUTPUT_VARIABLE python_config) | ||
| 40 | + if(python_config) | ||
| 41 | + STRING(REGEX REPLACE ".*exec_prefix:([^\n]+).*$" "\\1" PYTHON_PREFIX ${python_config}) | ||
| 42 | + STRING(REGEX REPLACE ".*\nshort_version:([^\n]+).*$" "\\1" PYTHON_SHORT_VERSION ${python_config}) | ||
| 43 | + STRING(REGEX REPLACE ".*\nlong_version:([^\n]+).*$" "\\1" PYTHON_LONG_VERSION ${python_config}) | ||
| 44 | + STRING(REGEX REPLACE ".*\npy_inc_dir:([^\n]+).*$" "\\1" PYTHON_INCLUDE_PATH ${python_config}) | ||
| 45 | + if(NOT PYTHON_SITE_PACKAGES_DIR) | ||
| 46 | + if(NOT PYTHON_LIBS_WITH_KDE_LIBS) | ||
| 47 | + STRING(REGEX REPLACE ".*\nsite_packages_dir:([^\n]+).*$" "\\1" PYTHON_SITE_PACKAGES_DIR ${python_config}) | ||
| 48 | + else(NOT PYTHON_LIBS_WITH_KDE_LIBS) | ||
| 49 | + set(PYTHON_SITE_PACKAGES_DIR ${KDE4_LIB_INSTALL_DIR}/python${PYTHON_SHORT_VERSION}/site-packages) | ||
| 50 | + endif(NOT PYTHON_LIBS_WITH_KDE_LIBS) | ||
| 51 | + endif(NOT PYTHON_SITE_PACKAGES_DIR) | ||
| 52 | + STRING(REGEX REPLACE "([0-9]+).([0-9]+)" "\\1\\2" PYTHON_SHORT_VERSION_NO_DOT ${PYTHON_SHORT_VERSION}) | ||
| 53 | + set(PYTHON_LIBRARY_NAMES python${PYTHON_SHORT_VERSION} python${PYTHON_SHORT_VERSION_NO_DOT} python${PYTHON_SHORT_VERSION}m python${PYTHON_SHORT_VERSION_NO_DOT}m) | ||
| 54 | + if(WIN32) | ||
| 55 | + STRING(REPLACE "\\" "/" PYTHON_SITE_PACKAGES_DIR ${PYTHON_SITE_PACKAGES_DIR}) | ||
| 56 | + FIND_LIBRARY(PYTHON_LIBRARY NAMES ${PYTHON_LIBRARY_NAMES} PATHS ${PYTHON_PREFIX}/lib ${PYTHON_PREFIX}/libs) | ||
| 57 | + endif(WIN32) | ||
| 58 | + FIND_LIBRARY(PYTHON_LIBRARY NAMES ${PYTHON_LIBRARY_NAMES}) | ||
| 59 | + set(PYTHON_INCLUDE_PATH ${PYTHON_INCLUDE_PATH} CACHE FILEPATH "Directory holding the python.h include file" FORCE) | ||
| 60 | + set(PYTHONLIBRARY_FOUND TRUE) | ||
| 61 | + endif(python_config) | ||
| 62 | + | ||
| 63 | + # adapted from cmake's builtin FindPythonLibs | ||
| 64 | + if(APPLE) | ||
| 65 | + # If a framework has been detected in the include path, make sure | ||
| 66 | + # framework's versioned library (not any .dylib) is used for linking | ||
| 67 | + # NOTE: don't rely upon Python.framework/Versions/Current, since that may be 2.7 | ||
| 68 | + if("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework") | ||
| 69 | + set(PYTHON_LIBRARY "") | ||
| 70 | + set(PYTHON_DEBUG_LIBRARY "") | ||
| 71 | + # get clean path to just framework | ||
| 72 | + STRING(REGEX REPLACE "^(.*/Python\\.framework).*$" "\\1" _py_fw "${PYTHON_INCLUDE_PATH}") | ||
| 73 | + if("${_py_fw}" MATCHES "Cellar/python") | ||
| 74 | + # Appears to be a Homebrew Python install; do specific fix ups | ||
| 75 | + # get Homebrew prefix (may not be /usr/local) | ||
| 76 | + STRING(REGEX REPLACE "^(.+)/Cellar.*$" "\\1" _hb_prefix "${_py_fw}") | ||
| 77 | + # prefer the Homebrew prefix framework over only versioned Python keg | ||
| 78 | + set(_py_fw "${_hb_prefix}/Frameworks/Python.framework") | ||
| 79 | + # prefer the symlinked-to Homebrew site-packages over only versioned Python keg | ||
| 80 | + set(PYTHON_SITE_PACKAGES_DIR "${_hb_prefix}/lib/python${PYTHON_SHORT_VERSION}/site-packages") | ||
| 81 | + endif("${_py_fw}" MATCHES "Cellar/python") | ||
| 82 | + # prefer the Headers subdirectory for includes | ||
| 83 | + if(EXISTS "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Headers") | ||
| 84 | + set(PYTHON_INCLUDE_PATH "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Headers" CACHE FILEPATH "Directory holding the python.h include file" FORCE) | ||
| 85 | + endif(EXISTS "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Headers") | ||
| 86 | + endif("${PYTHON_INCLUDE_PATH}" MATCHES "Python\\.framework") | ||
| 87 | + if(NOT PYTHON_LIBRARY) | ||
| 88 | + # ensure the versioned framework's library is defined, instead of relying upon -F search paths | ||
| 89 | + if(EXISTS "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Python") | ||
| 90 | + set(PYTHON_LIBRARY "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Python" CACHE FILEPATH "Python framework library" FORCE) | ||
| 91 | + endif(EXISTS "${_py_fw}/Versions/${PYTHON_SHORT_VERSION}/Python") | ||
| 92 | + endif(NOT PYTHON_LIBRARY) | ||
| 93 | + if(PYTHON_LIBRARY) | ||
| 94 | + set(PYTHONLIBRARY_FOUND TRUE) | ||
| 95 | + endif(PYTHON_LIBRARY) | ||
| 96 | + endif(APPLE) | ||
| 97 | + endif(PYTHONINTERP_FOUND) | ||
| 98 | + | ||
| 99 | + if(PYTHONLIBRARY_FOUND) | ||
| 100 | + if(APPLE) | ||
| 101 | + # keep reference to system or custom python site-packages | ||
| 102 | + # useful during app-bundling operations | ||
| 103 | + set(PYTHON_SITE_PACKAGES_SYS ${PYTHON_SITE_PACKAGES_DIR} CACHE FILEPATH "Directory holding Python site packages") | ||
| 104 | + endif(APPLE) | ||
| 105 | + set(PYTHON_LIBRARIES ${PYTHON_LIBRARY}) | ||
| 106 | + if(NOT PYTHONLIBRARY_FIND_QUIETLY) | ||
| 107 | + message(STATUS "Found Python executable: ${PYTHON_EXECUTABLE}") | ||
| 108 | + message(STATUS "Found Python version: ${PYTHON_LONG_VERSION}") | ||
| 109 | + message(STATUS "Found Python library: ${PYTHON_LIBRARY}") | ||
| 110 | + message(STATUS "Found Python site-packages: ${PYTHON_SITE_PACKAGES_DIR}") | ||
| 111 | + endif(NOT PYTHONLIBRARY_FIND_QUIETLY) | ||
| 112 | + else(PYTHONLIBRARY_FOUND) | ||
| 113 | + if(PYTHONLIBRARY_FIND_REQUIRED) | ||
| 114 | + message(FATAL_ERROR "Could not find Python") | ||
| 115 | + endif(PYTHONLIBRARY_FIND_REQUIRED) | ||
| 116 | + endif(PYTHONLIBRARY_FOUND) | ||
| 117 | + | ||
| 118 | +endif (EXISTS "${PYTHON_INCLUDE_PATH}" AND EXISTS "${PYTHON_LIBRARY}" AND EXISTS "${PYTHON_SITE_PACKAGES_DIR}") |
cmake/PythonMacros.cmake
0 → 100644
| 1 | +# Python macros | ||
| 2 | +# ~~~~~~~~~~~~~ | ||
| 3 | +# Copyright (c) 2007, Simon Edwards <simon@simonzone.com> | ||
| 4 | +# | ||
| 5 | +# Redistribution and use is allowed according to the terms of the BSD license. | ||
| 6 | +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. | ||
| 7 | +# | ||
| 8 | +# This file defines the following macros: | ||
| 9 | +# | ||
| 10 | +# PYTHON_INSTALL (SOURCE_FILE DESTINATION_DIR) | ||
| 11 | +# Install the SOURCE_FILE, which is a Python .py file, into the | ||
| 12 | +# destination directory during install. The file will be byte compiled | ||
| 13 | +# and both the .py file and .pyc file will be installed. | ||
| 14 | + | ||
| 15 | +GET_FILENAME_COMPONENT(PYTHON_MACROS_MODULE_PATH ${CMAKE_CURRENT_LIST_FILE} PATH) | ||
| 16 | + | ||
| 17 | +MACRO(PYTHON_INSTALL SOURCE_FILE DESTINATION_DIR) | ||
| 18 | + | ||
| 19 | + FIND_FILE(_python_compile_py PythonCompile.py PATHS ${CMAKE_MODULE_PATH}) | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + # Install the source file. | ||
| 23 | + INSTALL(FILES ${SOURCE_FILE} DESTINATION ${DESTINATION_DIR}) | ||
| 24 | + | ||
| 25 | + # Byte compile and install the .pyc file. | ||
| 26 | + GET_FILENAME_COMPONENT(_absfilename ${SOURCE_FILE} ABSOLUTE) | ||
| 27 | + GET_FILENAME_COMPONENT(_filename ${SOURCE_FILE} NAME) | ||
| 28 | + GET_FILENAME_COMPONENT(_filenamebase ${SOURCE_FILE} NAME_WE) | ||
| 29 | + GET_FILENAME_COMPONENT(_basepath ${SOURCE_FILE} PATH) | ||
| 30 | + | ||
| 31 | + if(WIN32) | ||
| 32 | + string(REGEX REPLACE ".:/" "/" _basepath "${_basepath}") | ||
| 33 | + endif(WIN32) | ||
| 34 | + | ||
| 35 | + SET(_bin_py ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filename}) | ||
| 36 | + SET(_bin_pyc ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}/${_filenamebase}.pyc) | ||
| 37 | + | ||
| 38 | + FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${_basepath}) | ||
| 39 | + | ||
| 40 | + SET(_message "-DMESSAGE=Byte-compiling ${_bin_py}") | ||
| 41 | + | ||
| 42 | + GET_FILENAME_COMPONENT(_abs_bin_py ${_bin_py} ABSOLUTE) | ||
| 43 | + IF(_abs_bin_py STREQUAL ${_absfilename}) # Don't copy the file onto itself. | ||
| 44 | + ADD_CUSTOM_COMMAND( | ||
| 45 | + TARGET compile_python_files | ||
| 46 | + COMMAND ${CMAKE_COMMAND} -E echo ${message} | ||
| 47 | + COMMAND ${PYTHON_EXECUTABLE} ${_python_compile_py} ${_bin_py} | ||
| 48 | + DEPENDS ${_absfilename} | ||
| 49 | + ) | ||
| 50 | + ELSE(_abs_bin_py STREQUAL ${_absfilename}) | ||
| 51 | + ADD_CUSTOM_COMMAND( | ||
| 52 | + TARGET compile_python_files | ||
| 53 | + COMMAND ${CMAKE_COMMAND} -E echo ${message} | ||
| 54 | + COMMAND ${CMAKE_COMMAND} -E copy ${_absfilename} ${_bin_py} | ||
| 55 | + COMMAND ${PYTHON_EXECUTABLE} ${_python_compile_py} ${_bin_py} | ||
| 56 | + DEPENDS ${_absfilename} | ||
| 57 | + ) | ||
| 58 | + ENDIF(_abs_bin_py STREQUAL ${_absfilename}) | ||
| 59 | + | ||
| 60 | + INSTALL(FILES ${_bin_pyc} DESTINATION ${DESTINATION_DIR}) | ||
| 61 | +ENDMACRO(PYTHON_INSTALL) |
cmake_templates/dmpconfig.h.in
0 → 100644
| 1 | +/************************************************************************** | ||
| 2 | +* file: dmpconfig.h.in | ||
| 3 | + | ||
| 4 | +* Author: wanzhongping | ||
| 5 | +* Date: 2021-02-24 16:21:32 | ||
| 6 | +* Email: zhongpingw@chinadci.com | ||
| 7 | +* copyright: 广州城市信息研究所有限公司 | ||
| 8 | +***************************************************************************/ | ||
| 9 | + | ||
| 10 | +#ifndef __dmpconfig_h_in__ | ||
| 11 | +#define __dmpconfig_h_in__ | ||
| 12 | + | ||
| 13 | +#define VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}-${RELEASE_NAME}" | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +#define VERSION_INT ${DMAP_VERSION_INT} | ||
| 17 | + | ||
| 18 | +#define RELEASE_NAME "${RELEASE_NAME}" | ||
| 19 | + | ||
| 20 | +#define DMAP_PLUGIN_SUBDIR "${DMAP_PLUGIN_SUBDIR}" | ||
| 21 | +#define DMAP_DATA_SUBDIR "${DMAP_DATA_SUBDIR}" | ||
| 22 | +#define DMAP_LIBEXEC_SUBDIR "${DMAP_LIBEXEC_SUBDIR}" | ||
| 23 | +#define DMAP_LIB_SUBDIR "${DMAP_LIB_SUBDIR}" | ||
| 24 | +#define CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" | ||
| 25 | +#define CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}" | ||
| 26 | +#define DMAP_SERVER_MODULE_SUBDIR "${DMAP_SERVER_MODULE_SUBDIR}" | ||
| 27 | + | ||
| 28 | + | ||
| 29 | +#cmakedefine HAVE_SERVER_PYTHON_PLUGINS | ||
| 30 | + | ||
| 31 | + | ||
| 32 | + | ||
| 33 | +#endif //__dmpconfig_h_in__ |
pgsql/bin/clusterdb
0 → 100644
不能预览此文件类型
pgsql/bin/createdb
0 → 100644
不能预览此文件类型
pgsql/bin/createuser
0 → 100644
不能预览此文件类型
pgsql/bin/dropdb
0 → 100644
不能预览此文件类型
pgsql/bin/dropuser
0 → 100644
不能预览此文件类型
pgsql/bin/ecpg
0 → 100644
不能预览此文件类型
pgsql/bin/initdb
0 → 100644
不能预览此文件类型
pgsql/bin/pg_archivecleanup
0 → 100644
不能预览此文件类型
pgsql/bin/pg_basebackup
0 → 100644
不能预览此文件类型
pgsql/bin/pg_config
0 → 100644
不能预览此文件类型
pgsql/bin/pg_controldata
0 → 100644
不能预览此文件类型
pgsql/bin/pg_ctl
0 → 100644
不能预览此文件类型
pgsql/bin/pg_dump
0 → 100644
不能预览此文件类型
pgsql/bin/pg_dumpall
0 → 100644
不能预览此文件类型
pgsql/bin/pg_isready
0 → 100644
不能预览此文件类型
pgsql/bin/pg_receivewal
0 → 100644
不能预览此文件类型
pgsql/bin/pg_recvlogical
0 → 100644
不能预览此文件类型
pgsql/bin/pg_resetwal
0 → 100644
不能预览此文件类型
pgsql/bin/pg_restore
0 → 100644
不能预览此文件类型
pgsql/bin/pg_rewind
0 → 100644
不能预览此文件类型
pgsql/bin/pg_test_fsync
0 → 100644
不能预览此文件类型
pgsql/bin/pg_test_timing
0 → 100644
不能预览此文件类型
pgsql/bin/pg_upgrade
0 → 100644
不能预览此文件类型
pgsql/bin/pg_verify_checksums
0 → 100644
不能预览此文件类型
pgsql/bin/pg_waldump
0 → 100644
不能预览此文件类型
pgsql/bin/pgbench
0 → 100644
不能预览此文件类型
pgsql/bin/postgres
0 → 100644
不能预览此文件类型
pgsql/bin/postmaster
0 → 100644
不能预览此文件类型
pgsql/bin/psql
0 → 100644
不能预览此文件类型
pgsql/bin/reindexdb
0 → 100644
不能预览此文件类型
pgsql/bin/vacuumdb
0 → 100644
不能预览此文件类型
pgsql/include/ecpg_config.h
0 → 100644
| 1 | +/* src/interfaces/ecpg/include/ecpg_config.h. Generated from ecpg_config.h.in by configure. */ | ||
| 2 | +/* Define to 1 if the system has the type `int64'. */ | ||
| 3 | +/* #undef HAVE_INT64 */ | ||
| 4 | + | ||
| 5 | +/* Define to 1 if `long int' works and is 64 bits. */ | ||
| 6 | +#define HAVE_LONG_INT_64 1 | ||
| 7 | + | ||
| 8 | +/* Define to 1 if the system has the type `long long int'. */ | ||
| 9 | +#define HAVE_LONG_LONG_INT 1 | ||
| 10 | + | ||
| 11 | +/* Define to 1 if `long long int' works and is 64 bits. */ | ||
| 12 | +/* #undef HAVE_LONG_LONG_INT_64 */ | ||
| 13 | + | ||
| 14 | +/* Define to 1 to build client libraries as thread-safe code. | ||
| 15 | + * (--enable-thread-safety) */ | ||
| 16 | +#define ENABLE_THREAD_SAFETY 1 |
pgsql/include/ecpg_informix.h
0 → 100644
| 1 | +/* | ||
| 2 | + * This file contains stuff needed to be as compatible to Informix as possible. | ||
| 3 | + * src/interfaces/ecpg/include/ecpg_informix.h | ||
| 4 | + */ | ||
| 5 | +#ifndef _ECPG_INFORMIX_H | ||
| 6 | +#define _ECPG_INFORMIX_H | ||
| 7 | + | ||
| 8 | +#include <ecpglib.h> | ||
| 9 | +#include <pgtypes_date.h> | ||
| 10 | +#include <pgtypes_interval.h> | ||
| 11 | +#include <pgtypes_numeric.h> | ||
| 12 | +#include <pgtypes_timestamp.h> | ||
| 13 | + | ||
| 14 | +#define SQLNOTFOUND 100 | ||
| 15 | + | ||
| 16 | +#define ECPG_INFORMIX_NUM_OVERFLOW -1200 | ||
| 17 | +#define ECPG_INFORMIX_NUM_UNDERFLOW -1201 | ||
| 18 | +#define ECPG_INFORMIX_DIVIDE_ZERO -1202 | ||
| 19 | +#define ECPG_INFORMIX_BAD_YEAR -1204 | ||
| 20 | +#define ECPG_INFORMIX_BAD_MONTH -1205 | ||
| 21 | +#define ECPG_INFORMIX_BAD_DAY -1206 | ||
| 22 | +#define ECPG_INFORMIX_ENOSHORTDATE -1209 | ||
| 23 | +#define ECPG_INFORMIX_DATE_CONVERT -1210 | ||
| 24 | +#define ECPG_INFORMIX_OUT_OF_MEMORY -1211 | ||
| 25 | +#define ECPG_INFORMIX_ENOTDMY -1212 | ||
| 26 | +#define ECPG_INFORMIX_BAD_NUMERIC -1213 | ||
| 27 | +#define ECPG_INFORMIX_BAD_EXPONENT -1216 | ||
| 28 | +#define ECPG_INFORMIX_BAD_DATE -1218 | ||
| 29 | +#define ECPG_INFORMIX_EXTRA_CHARS -1264 | ||
| 30 | + | ||
| 31 | +#ifdef __cplusplus | ||
| 32 | +extern "C" | ||
| 33 | +{ | ||
| 34 | +#endif | ||
| 35 | + | ||
| 36 | +extern int rdatestr(date, char *); | ||
| 37 | +extern void rtoday(date *); | ||
| 38 | +extern int rjulmdy(date, short *); | ||
| 39 | +extern int rdefmtdate(date *, const char *, const char *); | ||
| 40 | +extern int rfmtdate(date, const char *, char *); | ||
| 41 | +extern int rmdyjul(short *, date *); | ||
| 42 | +extern int rstrdate(const char *, date *); | ||
| 43 | +extern int rdayofweek(date); | ||
| 44 | + | ||
| 45 | +extern int rfmtlong(long, const char *, char *); | ||
| 46 | +extern int rgetmsg(int, char *, int); | ||
| 47 | +extern int risnull(int, const char *); | ||
| 48 | +extern int rsetnull(int, char *); | ||
| 49 | +extern int rtypalign(int, int); | ||
| 50 | +extern int rtypmsize(int, int); | ||
| 51 | +extern int rtypwidth(int, int); | ||
| 52 | +extern void rupshift(char *); | ||
| 53 | + | ||
| 54 | +extern int byleng(char *, int); | ||
| 55 | +extern void ldchar(char *, int, char *); | ||
| 56 | + | ||
| 57 | +extern void ECPG_informix_set_var(int, void *, int); | ||
| 58 | +extern void *ECPG_informix_get_var(int); | ||
| 59 | +extern void ECPG_informix_reset_sqlca(void); | ||
| 60 | + | ||
| 61 | +/* Informix defines these in decimal.h */ | ||
| 62 | +int decadd(decimal *, decimal *, decimal *); | ||
| 63 | +int deccmp(decimal *, decimal *); | ||
| 64 | +void deccopy(decimal *, decimal *); | ||
| 65 | +int deccvasc(const char *, int, decimal *); | ||
| 66 | +int deccvdbl(double, decimal *); | ||
| 67 | +int deccvint(int, decimal *); | ||
| 68 | +int deccvlong(long, decimal *); | ||
| 69 | +int decdiv(decimal *, decimal *, decimal *); | ||
| 70 | +int decmul(decimal *, decimal *, decimal *); | ||
| 71 | +int decsub(decimal *, decimal *, decimal *); | ||
| 72 | +int dectoasc(decimal *, char *, int, int); | ||
| 73 | +int dectodbl(decimal *, double *); | ||
| 74 | +int dectoint(decimal *, int *); | ||
| 75 | +int dectolong(decimal *, long *); | ||
| 76 | + | ||
| 77 | +/* Informix defines these in datetime.h */ | ||
| 78 | +extern void dtcurrent(timestamp *); | ||
| 79 | +extern int dtcvasc(char *, timestamp *); | ||
| 80 | +extern int dtsub(timestamp *, timestamp *, interval *); | ||
| 81 | +extern int dttoasc(timestamp *, char *); | ||
| 82 | +extern int dttofmtasc(timestamp *, char *, int, char *); | ||
| 83 | +extern int intoasc(interval *, char *); | ||
| 84 | +extern int dtcvfmtasc(char *, char *, timestamp *); | ||
| 85 | + | ||
| 86 | +#ifdef __cplusplus | ||
| 87 | +} | ||
| 88 | +#endif | ||
| 89 | + | ||
| 90 | +#endif /* ndef _ECPG_INFORMIX_H */ |
pgsql/include/ecpgerrno.h
0 → 100644
| 1 | +/* src/interfaces/ecpg/include/ecpgerrno.h */ | ||
| 2 | + | ||
| 3 | +#ifndef _ECPG_ERRNO_H | ||
| 4 | +#define _ECPG_ERRNO_H | ||
| 5 | + | ||
| 6 | +#include <errno.h> | ||
| 7 | + | ||
| 8 | +/* This is a list of all error codes the embedded SQL program can return */ | ||
| 9 | +#define ECPG_NO_ERROR 0 | ||
| 10 | +#define ECPG_NOT_FOUND 100 | ||
| 11 | + | ||
| 12 | +/* system error codes returned by ecpglib get the correct number, | ||
| 13 | + * but are made negative | ||
| 14 | + */ | ||
| 15 | +#define ECPG_OUT_OF_MEMORY -ENOMEM | ||
| 16 | + | ||
| 17 | +/* first we have a set of ecpg messages, they start at 200 */ | ||
| 18 | +#define ECPG_UNSUPPORTED -200 | ||
| 19 | +#define ECPG_TOO_MANY_ARGUMENTS -201 | ||
| 20 | +#define ECPG_TOO_FEW_ARGUMENTS -202 | ||
| 21 | +#define ECPG_TOO_MANY_MATCHES -203 | ||
| 22 | +#define ECPG_INT_FORMAT -204 | ||
| 23 | +#define ECPG_UINT_FORMAT -205 | ||
| 24 | +#define ECPG_FLOAT_FORMAT -206 | ||
| 25 | +#define ECPG_NUMERIC_FORMAT -207 | ||
| 26 | +#define ECPG_INTERVAL_FORMAT -208 | ||
| 27 | +#define ECPG_DATE_FORMAT -209 | ||
| 28 | +#define ECPG_TIMESTAMP_FORMAT -210 | ||
| 29 | +#define ECPG_CONVERT_BOOL -211 | ||
| 30 | +#define ECPG_EMPTY -212 | ||
| 31 | +#define ECPG_MISSING_INDICATOR -213 | ||
| 32 | +#define ECPG_NO_ARRAY -214 | ||
| 33 | +#define ECPG_DATA_NOT_ARRAY -215 | ||
| 34 | +#define ECPG_ARRAY_INSERT -216 | ||
| 35 | + | ||
| 36 | +#define ECPG_NO_CONN -220 | ||
| 37 | +#define ECPG_NOT_CONN -221 | ||
| 38 | + | ||
| 39 | +#define ECPG_INVALID_STMT -230 | ||
| 40 | + | ||
| 41 | +/* dynamic SQL related */ | ||
| 42 | +#define ECPG_UNKNOWN_DESCRIPTOR -240 | ||
| 43 | +#define ECPG_INVALID_DESCRIPTOR_INDEX -241 | ||
| 44 | +#define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242 | ||
| 45 | +#define ECPG_VAR_NOT_NUMERIC -243 | ||
| 46 | +#define ECPG_VAR_NOT_CHAR -244 | ||
| 47 | + | ||
| 48 | +/* finally the backend error messages, they start at 400 */ | ||
| 49 | +#define ECPG_PGSQL -400 | ||
| 50 | +#define ECPG_TRANS -401 | ||
| 51 | +#define ECPG_CONNECT -402 | ||
| 52 | +#define ECPG_DUPLICATE_KEY -403 | ||
| 53 | +#define ECPG_SUBSELECT_NOT_ONE -404 | ||
| 54 | + | ||
| 55 | +/* for compatibility we define some different error codes for the same error | ||
| 56 | + * if adding a new one make sure to not double define it */ | ||
| 57 | +#define ECPG_INFORMIX_DUPLICATE_KEY -239 | ||
| 58 | +#define ECPG_INFORMIX_SUBSELECT_NOT_ONE -284 | ||
| 59 | + | ||
| 60 | +/* backend WARNINGs, starting at 600 */ | ||
| 61 | +#define ECPG_WARNING_UNRECOGNIZED -600 | ||
| 62 | + /* WARNING: (transaction aborted): queries ignored until END */ | ||
| 63 | + | ||
| 64 | + /* | ||
| 65 | + * WARNING: current transaction is aborted, queries ignored until end of | ||
| 66 | + * transaction block | ||
| 67 | + */ | ||
| 68 | +#define ECPG_WARNING_QUERY_IGNORED -601 | ||
| 69 | + /* WARNING: PerformPortalClose: portal "*" not found */ | ||
| 70 | +#define ECPG_WARNING_UNKNOWN_PORTAL -602 | ||
| 71 | + /* WARNING: BEGIN: already a transaction in progress */ | ||
| 72 | +#define ECPG_WARNING_IN_TRANSACTION -603 | ||
| 73 | + /* WARNING: AbortTransaction and not in in-progress state */ | ||
| 74 | + /* WARNING: COMMIT: no transaction in progress */ | ||
| 75 | +#define ECPG_WARNING_NO_TRANSACTION -604 | ||
| 76 | + /* WARNING: BlankPortalAssignName: portal * already exists */ | ||
| 77 | +#define ECPG_WARNING_PORTAL_EXISTS -605 | ||
| 78 | + | ||
| 79 | +#endif /* !_ECPG_ERRNO_H */ |
pgsql/include/ecpglib.h
0 → 100644
| 1 | +/* | ||
| 2 | + * this is a small part of c.h since we don't want to leak all postgres | ||
| 3 | + * definitions into ecpg programs | ||
| 4 | + * src/interfaces/ecpg/include/ecpglib.h | ||
| 5 | + */ | ||
| 6 | + | ||
| 7 | +#ifndef _ECPGLIB_H | ||
| 8 | +#define _ECPGLIB_H | ||
| 9 | + | ||
| 10 | +#include "libpq-fe.h" | ||
| 11 | +#include "ecpgtype.h" | ||
| 12 | +#include "sqlca.h" | ||
| 13 | +#include <string.h> | ||
| 14 | + | ||
| 15 | +#ifdef ENABLE_NLS | ||
| 16 | +extern char *ecpg_gettext(const char *msgid) pg_attribute_format_arg(1); | ||
| 17 | +#else | ||
| 18 | +#define ecpg_gettext(x) (x) | ||
| 19 | +#endif | ||
| 20 | + | ||
| 21 | +#ifndef __cplusplus | ||
| 22 | +#ifndef bool | ||
| 23 | +#define bool char | ||
| 24 | +#endif /* ndef bool */ | ||
| 25 | + | ||
| 26 | +#ifndef true | ||
| 27 | +#define true ((bool) 1) | ||
| 28 | +#endif /* ndef true */ | ||
| 29 | +#ifndef false | ||
| 30 | +#define false ((bool) 0) | ||
| 31 | +#endif /* ndef false */ | ||
| 32 | +#endif /* not C++ */ | ||
| 33 | + | ||
| 34 | +#ifndef TRUE | ||
| 35 | +#define TRUE 1 | ||
| 36 | +#endif /* TRUE */ | ||
| 37 | + | ||
| 38 | +#ifndef FALSE | ||
| 39 | +#define FALSE 0 | ||
| 40 | +#endif /* FALSE */ | ||
| 41 | + | ||
| 42 | +#ifdef __cplusplus | ||
| 43 | +extern "C" | ||
| 44 | +{ | ||
| 45 | +#endif | ||
| 46 | + | ||
| 47 | +void ECPGdebug(int, FILE *); | ||
| 48 | +bool ECPGstatus(int, const char *); | ||
| 49 | +bool ECPGsetcommit(int, const char *, const char *); | ||
| 50 | +bool ECPGsetconn(int, const char *); | ||
| 51 | +bool ECPGconnect(int, int, const char *, const char *, const char *, const char *, int); | ||
| 52 | +bool ECPGdo(const int, const int, const int, const char *, const bool, const int, const char *,...); | ||
| 53 | +bool ECPGtrans(int, const char *, const char *); | ||
| 54 | +bool ECPGdisconnect(int, const char *); | ||
| 55 | +bool ECPGprepare(int, const char *, const bool, const char *, const char *); | ||
| 56 | +bool ECPGdeallocate(int, int, const char *, const char *); | ||
| 57 | +bool ECPGdeallocate_all(int, int, const char *); | ||
| 58 | +char *ECPGprepared_statement(const char *, const char *, int); | ||
| 59 | +PGconn *ECPGget_PGconn(const char *); | ||
| 60 | +PGTransactionStatusType ECPGtransactionStatus(const char *); | ||
| 61 | + | ||
| 62 | +char *ECPGerrmsg(void); | ||
| 63 | + | ||
| 64 | + /* print an error message */ | ||
| 65 | +void sqlprint(void); | ||
| 66 | + | ||
| 67 | +/* define this for simplicity as well as compatibility */ | ||
| 68 | + | ||
| 69 | +#define SQLCODE sqlca.sqlcode | ||
| 70 | +#define SQLSTATE sqlca.sqlstate | ||
| 71 | + | ||
| 72 | +/* dynamic SQL */ | ||
| 73 | + | ||
| 74 | +bool ECPGdo_descriptor(int, const char *, const char *, const char *); | ||
| 75 | +bool ECPGdeallocate_desc(int, const char *); | ||
| 76 | +bool ECPGallocate_desc(int, const char *); | ||
| 77 | +bool ECPGget_desc_header(int, const char *, int *); | ||
| 78 | +bool ECPGget_desc(int, const char *, int,...); | ||
| 79 | +bool ECPGset_desc_header(int, const char *, int); | ||
| 80 | +bool ECPGset_desc(int, const char *, int,...); | ||
| 81 | + | ||
| 82 | +void ECPGset_noind_null(enum ECPGttype, void *); | ||
| 83 | +bool ECPGis_noind_null(enum ECPGttype, const void *); | ||
| 84 | +bool ECPGdescribe(int, int, bool, const char *, const char *,...); | ||
| 85 | + | ||
| 86 | +void ECPGset_var(int, void *, int); | ||
| 87 | +void *ECPGget_var(int number); | ||
| 88 | + | ||
| 89 | +/* dynamic result allocation */ | ||
| 90 | +void ECPGfree_auto_mem(void); | ||
| 91 | + | ||
| 92 | +#ifdef ENABLE_THREAD_SAFETY | ||
| 93 | +void ecpg_pthreads_init(void); | ||
| 94 | +#endif | ||
| 95 | + | ||
| 96 | +#ifdef __cplusplus | ||
| 97 | +} | ||
| 98 | +#endif | ||
| 99 | + | ||
| 100 | +#endif /* _ECPGLIB_H */ |
pgsql/include/ecpgtype.h
0 → 100644
| 1 | +/* | ||
| 2 | + * This file implements a data structure that is built and maintained by the | ||
| 3 | + * preprocessor. | ||
| 4 | + * | ||
| 5 | + * All types that can be handled for host variable declarations has to | ||
| 6 | + * be handled eventually. | ||
| 7 | + * | ||
| 8 | + * src/interfaces/ecpg/include/ecpgtype.h | ||
| 9 | + */ | ||
| 10 | + | ||
| 11 | +/* | ||
| 12 | + * Here are all the types that we are to handle. Note that it is the type | ||
| 13 | + * that is registered and that has nothing whatsoever to do with the storage | ||
| 14 | + * class. | ||
| 15 | + * | ||
| 16 | + * Simple types | ||
| 17 | + * integers: char, short, int, long (signed and unsigned) | ||
| 18 | + * floats: float, double | ||
| 19 | + * | ||
| 20 | + * Complex types: | ||
| 21 | + * VARCHAR, VARCHAR2 - Strings with length (maxlen is given in the declaration) | ||
| 22 | + * Arrays of simple types and of VARCHAR, VARCHAR2 (size given in declaration) | ||
| 23 | + * Records build of simple types, arrays and other structs. | ||
| 24 | + * | ||
| 25 | + * Complicating things: | ||
| 26 | + * typedefs and struct names! | ||
| 27 | + * | ||
| 28 | + * Conclusion: | ||
| 29 | + * This is a typically recursive definition. A structure of typed list elements | ||
| 30 | + * would probably work fine: | ||
| 31 | + */ | ||
| 32 | + | ||
| 33 | +#ifndef _ECPGTYPE_H | ||
| 34 | +#define _ECPGTYPE_H | ||
| 35 | + | ||
| 36 | +#ifdef __cplusplus | ||
| 37 | +extern "C" | ||
| 38 | +{ | ||
| 39 | +#endif | ||
| 40 | + | ||
| 41 | +enum ECPGttype | ||
| 42 | +{ | ||
| 43 | + ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short, | ||
| 44 | + ECPGt_int, ECPGt_unsigned_int, ECPGt_long, ECPGt_unsigned_long, | ||
| 45 | + ECPGt_long_long, ECPGt_unsigned_long_long, | ||
| 46 | + ECPGt_bool, | ||
| 47 | + ECPGt_float, ECPGt_double, | ||
| 48 | + ECPGt_varchar, ECPGt_varchar2, | ||
| 49 | + ECPGt_numeric, /* this is a decimal that stores its digits in | ||
| 50 | + * a malloced array */ | ||
| 51 | + ECPGt_decimal, /* this is a decimal that stores its digits in | ||
| 52 | + * a fixed array */ | ||
| 53 | + ECPGt_date, | ||
| 54 | + ECPGt_timestamp, | ||
| 55 | + ECPGt_interval, | ||
| 56 | + ECPGt_array, | ||
| 57 | + ECPGt_struct, | ||
| 58 | + ECPGt_union, | ||
| 59 | + ECPGt_descriptor, /* sql descriptor, no C variable */ | ||
| 60 | + ECPGt_char_variable, | ||
| 61 | + ECPGt_const, /* a constant is needed sometimes */ | ||
| 62 | + ECPGt_EOIT, /* End of insert types. */ | ||
| 63 | + ECPGt_EORT, /* End of result types. */ | ||
| 64 | + ECPGt_NO_INDICATOR, /* no indicator */ | ||
| 65 | + ECPGt_string, /* trimmed (char *) type */ | ||
| 66 | + ECPGt_sqlda /* C struct descriptor */ | ||
| 67 | +}; | ||
| 68 | + | ||
| 69 | + /* descriptor items */ | ||
| 70 | +enum ECPGdtype | ||
| 71 | +{ | ||
| 72 | + ECPGd_count = 1, | ||
| 73 | + ECPGd_data, | ||
| 74 | + ECPGd_di_code, | ||
| 75 | + ECPGd_di_precision, | ||
| 76 | + ECPGd_indicator, | ||
| 77 | + ECPGd_key_member, | ||
| 78 | + ECPGd_length, | ||
| 79 | + ECPGd_name, | ||
| 80 | + ECPGd_nullable, | ||
| 81 | + ECPGd_octet, | ||
| 82 | + ECPGd_precision, | ||
| 83 | + ECPGd_ret_length, | ||
| 84 | + ECPGd_ret_octet, | ||
| 85 | + ECPGd_scale, | ||
| 86 | + ECPGd_type, | ||
| 87 | + ECPGd_EODT, /* End of descriptor types. */ | ||
| 88 | + ECPGd_cardinality | ||
| 89 | +}; | ||
| 90 | + | ||
| 91 | +#define IS_SIMPLE_TYPE(type) (((type) >= ECPGt_char && (type) <= ECPGt_interval) || ((type) == ECPGt_string)) | ||
| 92 | + | ||
| 93 | +/* we also have to handle different statement types */ | ||
| 94 | +enum ECPG_statement_type | ||
| 95 | +{ | ||
| 96 | + ECPGst_normal, | ||
| 97 | + ECPGst_execute, | ||
| 98 | + ECPGst_exec_immediate, | ||
| 99 | + ECPGst_prepnormal | ||
| 100 | +}; | ||
| 101 | + | ||
| 102 | +#ifdef __cplusplus | ||
| 103 | +} | ||
| 104 | +#endif | ||
| 105 | + | ||
| 106 | +#endif /* _ECPGTYPE_H */ |
pgsql/include/informix/esql/datetime.h
0 → 100644
| 1 | +/* src/interfaces/ecpg/include/datetime.h */ | ||
| 2 | + | ||
| 3 | +#ifndef _ECPG_DATETIME_H | ||
| 4 | +#define _ECPG_DATETIME_H | ||
| 5 | + | ||
| 6 | +#include <ecpg_informix.h> | ||
| 7 | + | ||
| 8 | +/* source created by ecpg which defines these symbols */ | ||
| 9 | +#ifndef _ECPGLIB_H | ||
| 10 | +typedef timestamp dtime_t; | ||
| 11 | +typedef interval intrvl_t; | ||
| 12 | +#endif /* ndef _ECPGLIB_H */ | ||
| 13 | + | ||
| 14 | +#endif /* ndef _ECPG_DATETIME_H */ |
pgsql/include/informix/esql/decimal.h
0 → 100644
| 1 | +/* src/interfaces/ecpg/include/decimal.h */ | ||
| 2 | + | ||
| 3 | +#ifndef _ECPG_DECIMAL_H | ||
| 4 | +#define _ECPG_DECIMAL_H | ||
| 5 | + | ||
| 6 | +#include <ecpg_informix.h> | ||
| 7 | + | ||
| 8 | +/* source created by ecpg which defines this */ | ||
| 9 | +#ifndef _ECPGLIB_H | ||
| 10 | +typedef decimal dec_t; | ||
| 11 | +#endif /* ndef _ECPGLIB_H */ | ||
| 12 | + | ||
| 13 | +#endif /* ndef _ECPG_DECIMAL_H */ |
pgsql/include/informix/esql/sqltypes.h
0 → 100644
| 1 | +#ifndef ECPG_SQLTYPES_H | ||
| 2 | +#define ECPG_SQLTYPES_H | ||
| 3 | + | ||
| 4 | +#include <limits.h> | ||
| 5 | + | ||
| 6 | +#define CCHARTYPE ECPGt_char | ||
| 7 | +#define CSHORTTYPE ECPGt_short | ||
| 8 | +#define CINTTYPE ECPGt_int | ||
| 9 | +#define CLONGTYPE ECPGt_long | ||
| 10 | +#define CFLOATTYPE ECPGt_float | ||
| 11 | +#define CDOUBLETYPE ECPGt_double | ||
| 12 | +#define CDECIMALTYPE ECPGt_decimal | ||
| 13 | +#define CFIXCHARTYPE 108 | ||
| 14 | +#define CSTRINGTYPE ECPGt_char | ||
| 15 | +#define CDATETYPE ECPGt_date | ||
| 16 | +#define CMONEYTYPE 111 | ||
| 17 | +#define CDTIMETYPE ECPGt_timestamp | ||
| 18 | +#define CLOCATORTYPE 113 | ||
| 19 | +#define CVCHARTYPE ECPGt_varchar | ||
| 20 | +#define CINVTYPE 115 | ||
| 21 | +#define CFILETYPE 116 | ||
| 22 | +#define CINT8TYPE ECPGt_long_long | ||
| 23 | +#define CCOLLTYPE 118 | ||
| 24 | +#define CLVCHARTYPE 119 | ||
| 25 | +#define CFIXBINTYPE 120 | ||
| 26 | +#define CVARBINTYPE 121 | ||
| 27 | +#define CBOOLTYPE ECPGt_bool | ||
| 28 | +#define CROWTYPE 123 | ||
| 29 | +#define CLVCHARPTRTYPE 124 | ||
| 30 | +#define CTYPEMAX 25 | ||
| 31 | + | ||
| 32 | +/* | ||
| 33 | + * Values used in sqlda->sqlvar[i]->sqltype | ||
| 34 | + */ | ||
| 35 | +#define SQLCHAR ECPGt_char | ||
| 36 | +#define SQLSMINT ECPGt_short | ||
| 37 | +#define SQLINT ECPGt_int | ||
| 38 | +#define SQLFLOAT ECPGt_double | ||
| 39 | +#define SQLSMFLOAT ECPGt_float | ||
| 40 | +#define SQLDECIMAL ECPGt_decimal | ||
| 41 | +#define SQLSERIAL ECPGt_int | ||
| 42 | +#define SQLDATE ECPGt_date | ||
| 43 | +#define SQLDTIME ECPGt_timestamp | ||
| 44 | +#define SQLTEXT ECPGt_char | ||
| 45 | +#define SQLVCHAR ECPGt_char | ||
| 46 | +#define SQLINTERVAL ECPGt_interval | ||
| 47 | +#define SQLNCHAR ECPGt_char | ||
| 48 | +#define SQLNVCHAR ECPGt_char | ||
| 49 | +#ifdef HAVE_LONG_LONG_INT_64 | ||
| 50 | +#define SQLINT8 ECPGt_long_long | ||
| 51 | +#define SQLSERIAL8 ECPGt_long_long | ||
| 52 | +#else | ||
| 53 | +#define SQLINT8 ECPGt_long | ||
| 54 | +#define SQLSERIAL8 ECPGt_long | ||
| 55 | +#endif | ||
| 56 | + | ||
| 57 | +#endif /* ndef ECPG_SQLTYPES_H */ |
pgsql/include/internal/c.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * c.h | ||
| 4 | + * Fundamental C definitions. This is included by every .c file in | ||
| 5 | + * PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate). | ||
| 6 | + * | ||
| 7 | + * Note that the definitions here are not intended to be exposed to clients | ||
| 8 | + * of the frontend interface libraries --- so we don't worry much about | ||
| 9 | + * polluting the namespace with lots of stuff... | ||
| 10 | + * | ||
| 11 | + * | ||
| 12 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 13 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 14 | + * | ||
| 15 | + * src/include/c.h | ||
| 16 | + * | ||
| 17 | + *------------------------------------------------------------------------- | ||
| 18 | + */ | ||
| 19 | +/* | ||
| 20 | + *---------------------------------------------------------------- | ||
| 21 | + * TABLE OF CONTENTS | ||
| 22 | + * | ||
| 23 | + * When adding stuff to this file, please try to put stuff | ||
| 24 | + * into the relevant section, or add new sections as appropriate. | ||
| 25 | + * | ||
| 26 | + * section description | ||
| 27 | + * ------- ------------------------------------------------ | ||
| 28 | + * 0) pg_config.h and standard system headers | ||
| 29 | + * 1) compiler characteristics | ||
| 30 | + * 2) bool, true, false | ||
| 31 | + * 3) standard system types | ||
| 32 | + * 4) IsValid macros for system types | ||
| 33 | + * 5) offsetof, lengthof, alignment | ||
| 34 | + * 6) assertions | ||
| 35 | + * 7) widely useful macros | ||
| 36 | + * 8) random stuff | ||
| 37 | + * 9) system-specific hacks | ||
| 38 | + * | ||
| 39 | + * NOTE: since this file is included by both frontend and backend modules, | ||
| 40 | + * it's usually wrong to put an "extern" declaration here, unless it's | ||
| 41 | + * ifdef'd so that it's seen in only one case or the other. | ||
| 42 | + * typedefs and macros are the kind of thing that might go here. | ||
| 43 | + * | ||
| 44 | + *---------------------------------------------------------------- | ||
| 45 | + */ | ||
| 46 | +#ifndef C_H | ||
| 47 | +#define C_H | ||
| 48 | + | ||
| 49 | +#include "postgres_ext.h" | ||
| 50 | + | ||
| 51 | +/* Must undef pg_config_ext.h symbols before including pg_config.h */ | ||
| 52 | +#undef PG_INT64_TYPE | ||
| 53 | + | ||
| 54 | +#include "pg_config.h" | ||
| 55 | +#include "pg_config_manual.h" /* must be after pg_config.h */ | ||
| 56 | +#include "pg_config_os.h" /* must be before any system header files */ | ||
| 57 | + | ||
| 58 | +/* System header files that should be available everywhere in Postgres */ | ||
| 59 | +#include <stdio.h> | ||
| 60 | +#include <stdlib.h> | ||
| 61 | +#include <string.h> | ||
| 62 | +#include <stddef.h> | ||
| 63 | +#include <stdarg.h> | ||
| 64 | +#ifdef HAVE_STRINGS_H | ||
| 65 | +#include <strings.h> | ||
| 66 | +#endif | ||
| 67 | +#ifdef HAVE_STDINT_H | ||
| 68 | +#include <stdint.h> | ||
| 69 | +#endif | ||
| 70 | +#include <sys/types.h> | ||
| 71 | +#include <errno.h> | ||
| 72 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 73 | +#include <fcntl.h> /* ensure O_BINARY is available */ | ||
| 74 | +#endif | ||
| 75 | +#include <locale.h> | ||
| 76 | +#ifdef ENABLE_NLS | ||
| 77 | +#include <libintl.h> | ||
| 78 | +#endif | ||
| 79 | + | ||
| 80 | + | ||
| 81 | +/* ---------------------------------------------------------------- | ||
| 82 | + * Section 1: compiler characteristics | ||
| 83 | + * | ||
| 84 | + * type prefixes (const, signed, volatile, inline) are handled in pg_config.h. | ||
| 85 | + * ---------------------------------------------------------------- | ||
| 86 | + */ | ||
| 87 | + | ||
| 88 | +/* | ||
| 89 | + * Disable "inline" if PG_FORCE_DISABLE_INLINE is defined. | ||
| 90 | + * This is used to work around compiler bugs and might also be useful for | ||
| 91 | + * investigatory purposes. | ||
| 92 | + */ | ||
| 93 | +#ifdef PG_FORCE_DISABLE_INLINE | ||
| 94 | +#undef inline | ||
| 95 | +#define inline | ||
| 96 | +#endif | ||
| 97 | + | ||
| 98 | +/* | ||
| 99 | + * Attribute macros | ||
| 100 | + * | ||
| 101 | + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html | ||
| 102 | + * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html | ||
| 103 | + * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html | ||
| 104 | + * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/function_attributes.html | ||
| 105 | + * XLC: http://www-01.ibm.com/support/knowledgecenter/SSGH2K_11.1.0/com.ibm.xlc111.aix.doc/language_ref/type_attrib.html | ||
| 106 | + */ | ||
| 107 | + | ||
| 108 | +/* only GCC supports the unused attribute */ | ||
| 109 | +#ifdef __GNUC__ | ||
| 110 | +#define pg_attribute_unused() __attribute__((unused)) | ||
| 111 | +#else | ||
| 112 | +#define pg_attribute_unused() | ||
| 113 | +#endif | ||
| 114 | + | ||
| 115 | +/* | ||
| 116 | + * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only | ||
| 117 | + * used in assert-enabled builds, to avoid compiler warnings about unused | ||
| 118 | + * variables in assert-disabled builds. | ||
| 119 | + */ | ||
| 120 | +#ifdef USE_ASSERT_CHECKING | ||
| 121 | +#define PG_USED_FOR_ASSERTS_ONLY | ||
| 122 | +#else | ||
| 123 | +#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused() | ||
| 124 | +#endif | ||
| 125 | + | ||
| 126 | +/* GCC and XLC support format attributes */ | ||
| 127 | +#if defined(__GNUC__) || defined(__IBMC__) | ||
| 128 | +#define pg_attribute_format_arg(a) __attribute__((format_arg(a))) | ||
| 129 | +#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a))) | ||
| 130 | +#else | ||
| 131 | +#define pg_attribute_format_arg(a) | ||
| 132 | +#define pg_attribute_printf(f,a) | ||
| 133 | +#endif | ||
| 134 | + | ||
| 135 | +/* GCC, Sunpro and XLC support aligned, packed and noreturn */ | ||
| 136 | +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) | ||
| 137 | +#define pg_attribute_aligned(a) __attribute__((aligned(a))) | ||
| 138 | +#define pg_attribute_noreturn() __attribute__((noreturn)) | ||
| 139 | +#define pg_attribute_packed() __attribute__((packed)) | ||
| 140 | +#define HAVE_PG_ATTRIBUTE_NORETURN 1 | ||
| 141 | +#else | ||
| 142 | +/* | ||
| 143 | + * NB: aligned and packed are not given default definitions because they | ||
| 144 | + * affect code functionality; they *must* be implemented by the compiler | ||
| 145 | + * if they are to be used. | ||
| 146 | + */ | ||
| 147 | +#define pg_attribute_noreturn() | ||
| 148 | +#endif | ||
| 149 | + | ||
| 150 | +/* | ||
| 151 | + * Use "pg_attribute_always_inline" in place of "inline" for functions that | ||
| 152 | + * we wish to force inlining of, even when the compiler's heuristics would | ||
| 153 | + * choose not to. But, if possible, don't force inlining in unoptimized | ||
| 154 | + * debug builds. | ||
| 155 | + */ | ||
| 156 | +#if (defined(__GNUC__) && __GNUC__ > 3 && defined(__OPTIMIZE__)) || defined(__SUNPRO_C) || defined(__IBMC__) | ||
| 157 | +/* GCC > 3, Sunpro and XLC support always_inline via __attribute__ */ | ||
| 158 | +#define pg_attribute_always_inline __attribute__((always_inline)) inline | ||
| 159 | +#elif defined(_MSC_VER) | ||
| 160 | +/* MSVC has a special keyword for this */ | ||
| 161 | +#define pg_attribute_always_inline __forceinline | ||
| 162 | +#else | ||
| 163 | +/* Otherwise, the best we can do is to say "inline" */ | ||
| 164 | +#define pg_attribute_always_inline inline | ||
| 165 | +#endif | ||
| 166 | + | ||
| 167 | +/* | ||
| 168 | + * Forcing a function not to be inlined can be useful if it's the slow path of | ||
| 169 | + * a performance-critical function, or should be visible in profiles to allow | ||
| 170 | + * for proper cost attribution. Note that unlike the pg_attribute_XXX macros | ||
| 171 | + * above, this should be placed before the function's return type and name. | ||
| 172 | + */ | ||
| 173 | +/* GCC, Sunpro and XLC support noinline via __attribute__ */ | ||
| 174 | +#if (defined(__GNUC__) && __GNUC__ > 2) || defined(__SUNPRO_C) || defined(__IBMC__) | ||
| 175 | +#define pg_noinline __attribute__((noinline)) | ||
| 176 | +/* msvc via declspec */ | ||
| 177 | +#elif defined(_MSC_VER) | ||
| 178 | +#define pg_noinline __declspec(noinline) | ||
| 179 | +#else | ||
| 180 | +#define pg_noinline | ||
| 181 | +#endif | ||
| 182 | + | ||
| 183 | +/* | ||
| 184 | + * Mark a point as unreachable in a portable fashion. This should preferably | ||
| 185 | + * be something that the compiler understands, to aid code generation. | ||
| 186 | + * In assert-enabled builds, we prefer abort() for debugging reasons. | ||
| 187 | + */ | ||
| 188 | +#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) | ||
| 189 | +#define pg_unreachable() __builtin_unreachable() | ||
| 190 | +#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) | ||
| 191 | +#define pg_unreachable() __assume(0) | ||
| 192 | +#else | ||
| 193 | +#define pg_unreachable() abort() | ||
| 194 | +#endif | ||
| 195 | + | ||
| 196 | +/* | ||
| 197 | + * Hints to the compiler about the likelihood of a branch. Both likely() and | ||
| 198 | + * unlikely() return the boolean value of the contained expression. | ||
| 199 | + * | ||
| 200 | + * These should only be used sparingly, in very hot code paths. It's very easy | ||
| 201 | + * to mis-estimate likelihoods. | ||
| 202 | + */ | ||
| 203 | +#if __GNUC__ >= 3 | ||
| 204 | +#define likely(x) __builtin_expect((x) != 0, 1) | ||
| 205 | +#define unlikely(x) __builtin_expect((x) != 0, 0) | ||
| 206 | +#else | ||
| 207 | +#define likely(x) ((x) != 0) | ||
| 208 | +#define unlikely(x) ((x) != 0) | ||
| 209 | +#endif | ||
| 210 | + | ||
| 211 | +/* | ||
| 212 | + * CppAsString | ||
| 213 | + * Convert the argument to a string, using the C preprocessor. | ||
| 214 | + * CppAsString2 | ||
| 215 | + * Convert the argument to a string, after one round of macro expansion. | ||
| 216 | + * CppConcat | ||
| 217 | + * Concatenate two arguments together, using the C preprocessor. | ||
| 218 | + * | ||
| 219 | + * Note: There used to be support here for pre-ANSI C compilers that didn't | ||
| 220 | + * support # and ##. Nowadays, these macros are just for clarity and/or | ||
| 221 | + * backward compatibility with existing PostgreSQL code. | ||
| 222 | + */ | ||
| 223 | +#define CppAsString(identifier) #identifier | ||
| 224 | +#define CppAsString2(x) CppAsString(x) | ||
| 225 | +#define CppConcat(x, y) x##y | ||
| 226 | + | ||
| 227 | +/* | ||
| 228 | + * dummyret is used to set return values in macros that use ?: to make | ||
| 229 | + * assignments. gcc wants these to be void, other compilers like char | ||
| 230 | + */ | ||
| 231 | +#ifdef __GNUC__ /* GNU cc */ | ||
| 232 | +#define dummyret void | ||
| 233 | +#else | ||
| 234 | +#define dummyret char | ||
| 235 | +#endif | ||
| 236 | + | ||
| 237 | +/* Which __func__ symbol do we have, if any? */ | ||
| 238 | +#ifdef HAVE_FUNCNAME__FUNC | ||
| 239 | +#define PG_FUNCNAME_MACRO __func__ | ||
| 240 | +#else | ||
| 241 | +#ifdef HAVE_FUNCNAME__FUNCTION | ||
| 242 | +#define PG_FUNCNAME_MACRO __FUNCTION__ | ||
| 243 | +#else | ||
| 244 | +#define PG_FUNCNAME_MACRO NULL | ||
| 245 | +#endif | ||
| 246 | +#endif | ||
| 247 | + | ||
| 248 | + | ||
| 249 | +/* ---------------------------------------------------------------- | ||
| 250 | + * Section 2: bool, true, false | ||
| 251 | + * ---------------------------------------------------------------- | ||
| 252 | + */ | ||
| 253 | + | ||
| 254 | +/* | ||
| 255 | + * bool | ||
| 256 | + * Boolean value, either true or false. | ||
| 257 | + * | ||
| 258 | + * Use stdbool.h if available and its bool has size 1. That's useful for | ||
| 259 | + * better compiler and debugger output and for compatibility with third-party | ||
| 260 | + * libraries. But PostgreSQL currently cannot deal with bool of other sizes; | ||
| 261 | + * there are static assertions around the code to prevent that. | ||
| 262 | + * | ||
| 263 | + * For C++ compilers, we assume the compiler has a compatible built-in | ||
| 264 | + * definition of bool. | ||
| 265 | + */ | ||
| 266 | + | ||
| 267 | +#ifndef __cplusplus | ||
| 268 | + | ||
| 269 | +#if defined(HAVE_STDBOOL_H) && SIZEOF_BOOL == 1 | ||
| 270 | +#include <stdbool.h> | ||
| 271 | +#define USE_STDBOOL 1 | ||
| 272 | +#else | ||
| 273 | + | ||
| 274 | +#ifndef bool | ||
| 275 | +typedef char bool; | ||
| 276 | +#endif | ||
| 277 | + | ||
| 278 | +#ifndef true | ||
| 279 | +#define true ((bool) 1) | ||
| 280 | +#endif | ||
| 281 | + | ||
| 282 | +#ifndef false | ||
| 283 | +#define false ((bool) 0) | ||
| 284 | +#endif | ||
| 285 | + | ||
| 286 | +#endif | ||
| 287 | +#endif /* not C++ */ | ||
| 288 | + | ||
| 289 | + | ||
| 290 | +/* ---------------------------------------------------------------- | ||
| 291 | + * Section 3: standard system types | ||
| 292 | + * ---------------------------------------------------------------- | ||
| 293 | + */ | ||
| 294 | + | ||
| 295 | +/* | ||
| 296 | + * Pointer | ||
| 297 | + * Variable holding address of any memory resident object. | ||
| 298 | + * | ||
| 299 | + * XXX Pointer arithmetic is done with this, so it can't be void * | ||
| 300 | + * under "true" ANSI compilers. | ||
| 301 | + */ | ||
| 302 | +typedef char *Pointer; | ||
| 303 | + | ||
| 304 | +/* | ||
| 305 | + * intN | ||
| 306 | + * Signed integer, EXACTLY N BITS IN SIZE, | ||
| 307 | + * used for numerical computations and the | ||
| 308 | + * frontend/backend protocol. | ||
| 309 | + */ | ||
| 310 | +#ifndef HAVE_INT8 | ||
| 311 | +typedef signed char int8; /* == 8 bits */ | ||
| 312 | +typedef signed short int16; /* == 16 bits */ | ||
| 313 | +typedef signed int int32; /* == 32 bits */ | ||
| 314 | +#endif /* not HAVE_INT8 */ | ||
| 315 | + | ||
| 316 | +/* | ||
| 317 | + * uintN | ||
| 318 | + * Unsigned integer, EXACTLY N BITS IN SIZE, | ||
| 319 | + * used for numerical computations and the | ||
| 320 | + * frontend/backend protocol. | ||
| 321 | + */ | ||
| 322 | +#ifndef HAVE_UINT8 | ||
| 323 | +typedef unsigned char uint8; /* == 8 bits */ | ||
| 324 | +typedef unsigned short uint16; /* == 16 bits */ | ||
| 325 | +typedef unsigned int uint32; /* == 32 bits */ | ||
| 326 | +#endif /* not HAVE_UINT8 */ | ||
| 327 | + | ||
| 328 | +/* | ||
| 329 | + * bitsN | ||
| 330 | + * Unit of bitwise operation, AT LEAST N BITS IN SIZE. | ||
| 331 | + */ | ||
| 332 | +typedef uint8 bits8; /* >= 8 bits */ | ||
| 333 | +typedef uint16 bits16; /* >= 16 bits */ | ||
| 334 | +typedef uint32 bits32; /* >= 32 bits */ | ||
| 335 | + | ||
| 336 | +/* | ||
| 337 | + * 64-bit integers | ||
| 338 | + */ | ||
| 339 | +#ifdef HAVE_LONG_INT_64 | ||
| 340 | +/* Plain "long int" fits, use it */ | ||
| 341 | + | ||
| 342 | +#ifndef HAVE_INT64 | ||
| 343 | +typedef long int int64; | ||
| 344 | +#endif | ||
| 345 | +#ifndef HAVE_UINT64 | ||
| 346 | +typedef unsigned long int uint64; | ||
| 347 | +#endif | ||
| 348 | +#define INT64CONST(x) (x##L) | ||
| 349 | +#define UINT64CONST(x) (x##UL) | ||
| 350 | +#elif defined(HAVE_LONG_LONG_INT_64) | ||
| 351 | +/* We have working support for "long long int", use that */ | ||
| 352 | + | ||
| 353 | +#ifndef HAVE_INT64 | ||
| 354 | +typedef long long int int64; | ||
| 355 | +#endif | ||
| 356 | +#ifndef HAVE_UINT64 | ||
| 357 | +typedef unsigned long long int uint64; | ||
| 358 | +#endif | ||
| 359 | +#define INT64CONST(x) (x##LL) | ||
| 360 | +#define UINT64CONST(x) (x##ULL) | ||
| 361 | +#else | ||
| 362 | +/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ | ||
| 363 | +#error must have a working 64-bit integer datatype | ||
| 364 | +#endif | ||
| 365 | + | ||
| 366 | +/* snprintf format strings to use for 64-bit integers */ | ||
| 367 | +#define INT64_FORMAT "%" INT64_MODIFIER "d" | ||
| 368 | +#define UINT64_FORMAT "%" INT64_MODIFIER "u" | ||
| 369 | + | ||
| 370 | +/* | ||
| 371 | + * 128-bit signed and unsigned integers | ||
| 372 | + * There currently is only limited support for such types. | ||
| 373 | + * E.g. 128bit literals and snprintf are not supported; but math is. | ||
| 374 | + * Also, because we exclude such types when choosing MAXIMUM_ALIGNOF, | ||
| 375 | + * it must be possible to coerce the compiler to allocate them on no | ||
| 376 | + * more than MAXALIGN boundaries. | ||
| 377 | + */ | ||
| 378 | +#if defined(PG_INT128_TYPE) | ||
| 379 | +#if defined(pg_attribute_aligned) || ALIGNOF_PG_INT128_TYPE <= MAXIMUM_ALIGNOF | ||
| 380 | +#define HAVE_INT128 1 | ||
| 381 | + | ||
| 382 | +typedef PG_INT128_TYPE int128 | ||
| 383 | +#if defined(pg_attribute_aligned) | ||
| 384 | +pg_attribute_aligned(MAXIMUM_ALIGNOF) | ||
| 385 | +#endif | ||
| 386 | +; | ||
| 387 | + | ||
| 388 | +typedef unsigned PG_INT128_TYPE uint128 | ||
| 389 | +#if defined(pg_attribute_aligned) | ||
| 390 | +pg_attribute_aligned(MAXIMUM_ALIGNOF) | ||
| 391 | +#endif | ||
| 392 | +; | ||
| 393 | + | ||
| 394 | +#endif | ||
| 395 | +#endif | ||
| 396 | + | ||
| 397 | +/* | ||
| 398 | + * stdint.h limits aren't guaranteed to be present and aren't guaranteed to | ||
| 399 | + * have compatible types with our fixed width types. So just define our own. | ||
| 400 | + */ | ||
| 401 | +#define PG_INT8_MIN (-0x7F-1) | ||
| 402 | +#define PG_INT8_MAX (0x7F) | ||
| 403 | +#define PG_UINT8_MAX (0xFF) | ||
| 404 | +#define PG_INT16_MIN (-0x7FFF-1) | ||
| 405 | +#define PG_INT16_MAX (0x7FFF) | ||
| 406 | +#define PG_UINT16_MAX (0xFFFF) | ||
| 407 | +#define PG_INT32_MIN (-0x7FFFFFFF-1) | ||
| 408 | +#define PG_INT32_MAX (0x7FFFFFFF) | ||
| 409 | +#define PG_UINT32_MAX (0xFFFFFFFFU) | ||
| 410 | +#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) | ||
| 411 | +#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF) | ||
| 412 | +#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF) | ||
| 413 | + | ||
| 414 | +/* Max value of size_t might also be missing if we don't have stdint.h */ | ||
| 415 | +#ifndef SIZE_MAX | ||
| 416 | +#if SIZEOF_SIZE_T == 8 | ||
| 417 | +#define SIZE_MAX PG_UINT64_MAX | ||
| 418 | +#else | ||
| 419 | +#define SIZE_MAX PG_UINT32_MAX | ||
| 420 | +#endif | ||
| 421 | +#endif | ||
| 422 | + | ||
| 423 | +/* | ||
| 424 | + * We now always use int64 timestamps, but keep this symbol defined for the | ||
| 425 | + * benefit of external code that might test it. | ||
| 426 | + */ | ||
| 427 | +#define HAVE_INT64_TIMESTAMP | ||
| 428 | + | ||
| 429 | +/* | ||
| 430 | + * Size | ||
| 431 | + * Size of any memory resident object, as returned by sizeof. | ||
| 432 | + */ | ||
| 433 | +typedef size_t Size; | ||
| 434 | + | ||
| 435 | +/* | ||
| 436 | + * Index | ||
| 437 | + * Index into any memory resident array. | ||
| 438 | + * | ||
| 439 | + * Note: | ||
| 440 | + * Indices are non negative. | ||
| 441 | + */ | ||
| 442 | +typedef unsigned int Index; | ||
| 443 | + | ||
| 444 | +/* | ||
| 445 | + * Offset | ||
| 446 | + * Offset into any memory resident array. | ||
| 447 | + * | ||
| 448 | + * Note: | ||
| 449 | + * This differs from an Index in that an Index is always | ||
| 450 | + * non negative, whereas Offset may be negative. | ||
| 451 | + */ | ||
| 452 | +typedef signed int Offset; | ||
| 453 | + | ||
| 454 | +/* | ||
| 455 | + * Common Postgres datatype names (as used in the catalogs) | ||
| 456 | + */ | ||
| 457 | +typedef float float4; | ||
| 458 | +typedef double float8; | ||
| 459 | + | ||
| 460 | +/* | ||
| 461 | + * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, | ||
| 462 | + * CommandId | ||
| 463 | + */ | ||
| 464 | + | ||
| 465 | +/* typedef Oid is in postgres_ext.h */ | ||
| 466 | + | ||
| 467 | +/* | ||
| 468 | + * regproc is the type name used in the include/catalog headers, but | ||
| 469 | + * RegProcedure is the preferred name in C code. | ||
| 470 | + */ | ||
| 471 | +typedef Oid regproc; | ||
| 472 | +typedef regproc RegProcedure; | ||
| 473 | + | ||
| 474 | +typedef uint32 TransactionId; | ||
| 475 | + | ||
| 476 | +typedef uint32 LocalTransactionId; | ||
| 477 | + | ||
| 478 | +typedef uint32 SubTransactionId; | ||
| 479 | + | ||
| 480 | +#define InvalidSubTransactionId ((SubTransactionId) 0) | ||
| 481 | +#define TopSubTransactionId ((SubTransactionId) 1) | ||
| 482 | + | ||
| 483 | +/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */ | ||
| 484 | +typedef TransactionId MultiXactId; | ||
| 485 | + | ||
| 486 | +typedef uint32 MultiXactOffset; | ||
| 487 | + | ||
| 488 | +typedef uint32 CommandId; | ||
| 489 | + | ||
| 490 | +#define FirstCommandId ((CommandId) 0) | ||
| 491 | +#define InvalidCommandId (~(CommandId)0) | ||
| 492 | + | ||
| 493 | +/* | ||
| 494 | + * Array indexing support | ||
| 495 | + */ | ||
| 496 | +#define MAXDIM 6 | ||
| 497 | +typedef struct | ||
| 498 | +{ | ||
| 499 | + int indx[MAXDIM]; | ||
| 500 | +} IntArray; | ||
| 501 | + | ||
| 502 | +/* ---------------- | ||
| 503 | + * Variable-length datatypes all share the 'struct varlena' header. | ||
| 504 | + * | ||
| 505 | + * NOTE: for TOASTable types, this is an oversimplification, since the value | ||
| 506 | + * may be compressed or moved out-of-line. However datatype-specific routines | ||
| 507 | + * are mostly content to deal with de-TOASTed values only, and of course | ||
| 508 | + * client-side routines should never see a TOASTed value. But even in a | ||
| 509 | + * de-TOASTed value, beware of touching vl_len_ directly, as its | ||
| 510 | + * representation is no longer convenient. It's recommended that code always | ||
| 511 | + * use macros VARDATA_ANY, VARSIZE_ANY, VARSIZE_ANY_EXHDR, VARDATA, VARSIZE, | ||
| 512 | + * and SET_VARSIZE instead of relying on direct mentions of the struct fields. | ||
| 513 | + * See postgres.h for details of the TOASTed form. | ||
| 514 | + * ---------------- | ||
| 515 | + */ | ||
| 516 | +struct varlena | ||
| 517 | +{ | ||
| 518 | + char vl_len_[4]; /* Do not touch this field directly! */ | ||
| 519 | + char vl_dat[FLEXIBLE_ARRAY_MEMBER]; /* Data content is here */ | ||
| 520 | +}; | ||
| 521 | + | ||
| 522 | +#define VARHDRSZ ((int32) sizeof(int32)) | ||
| 523 | + | ||
| 524 | +/* | ||
| 525 | + * These widely-used datatypes are just a varlena header and the data bytes. | ||
| 526 | + * There is no terminating null or anything like that --- the data length is | ||
| 527 | + * always VARSIZE_ANY_EXHDR(ptr). | ||
| 528 | + */ | ||
| 529 | +typedef struct varlena bytea; | ||
| 530 | +typedef struct varlena text; | ||
| 531 | +typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */ | ||
| 532 | +typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ | ||
| 533 | + | ||
| 534 | +/* | ||
| 535 | + * Specialized array types. These are physically laid out just the same | ||
| 536 | + * as regular arrays (so that the regular array subscripting code works | ||
| 537 | + * with them). They exist as distinct types mostly for historical reasons: | ||
| 538 | + * they have nonstandard I/O behavior which we don't want to change for fear | ||
| 539 | + * of breaking applications that look at the system catalogs. There is also | ||
| 540 | + * an implementation issue for oidvector: it's part of the primary key for | ||
| 541 | + * pg_proc, and we can't use the normal btree array support routines for that | ||
| 542 | + * without circularity. | ||
| 543 | + */ | ||
| 544 | +typedef struct | ||
| 545 | +{ | ||
| 546 | + int32 vl_len_; /* these fields must match ArrayType! */ | ||
| 547 | + int ndim; /* always 1 for int2vector */ | ||
| 548 | + int32 dataoffset; /* always 0 for int2vector */ | ||
| 549 | + Oid elemtype; | ||
| 550 | + int dim1; | ||
| 551 | + int lbound1; | ||
| 552 | + int16 values[FLEXIBLE_ARRAY_MEMBER]; | ||
| 553 | +} int2vector; | ||
| 554 | + | ||
| 555 | +typedef struct | ||
| 556 | +{ | ||
| 557 | + int32 vl_len_; /* these fields must match ArrayType! */ | ||
| 558 | + int ndim; /* always 1 for oidvector */ | ||
| 559 | + int32 dataoffset; /* always 0 for oidvector */ | ||
| 560 | + Oid elemtype; | ||
| 561 | + int dim1; | ||
| 562 | + int lbound1; | ||
| 563 | + Oid values[FLEXIBLE_ARRAY_MEMBER]; | ||
| 564 | +} oidvector; | ||
| 565 | + | ||
| 566 | +/* | ||
| 567 | + * Representation of a Name: effectively just a C string, but null-padded to | ||
| 568 | + * exactly NAMEDATALEN bytes. The use of a struct is historical. | ||
| 569 | + */ | ||
| 570 | +typedef struct nameData | ||
| 571 | +{ | ||
| 572 | + char data[NAMEDATALEN]; | ||
| 573 | +} NameData; | ||
| 574 | +typedef NameData *Name; | ||
| 575 | + | ||
| 576 | +#define NameStr(name) ((name).data) | ||
| 577 | + | ||
| 578 | + | ||
| 579 | +/* ---------------------------------------------------------------- | ||
| 580 | + * Section 4: IsValid macros for system types | ||
| 581 | + * ---------------------------------------------------------------- | ||
| 582 | + */ | ||
| 583 | +/* | ||
| 584 | + * BoolIsValid | ||
| 585 | + * True iff bool is valid. | ||
| 586 | + */ | ||
| 587 | +#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true) | ||
| 588 | + | ||
| 589 | +/* | ||
| 590 | + * PointerIsValid | ||
| 591 | + * True iff pointer is valid. | ||
| 592 | + */ | ||
| 593 | +#define PointerIsValid(pointer) ((const void*)(pointer) != NULL) | ||
| 594 | + | ||
| 595 | +/* | ||
| 596 | + * PointerIsAligned | ||
| 597 | + * True iff pointer is properly aligned to point to the given type. | ||
| 598 | + */ | ||
| 599 | +#define PointerIsAligned(pointer, type) \ | ||
| 600 | + (((uintptr_t)(pointer) % (sizeof (type))) == 0) | ||
| 601 | + | ||
| 602 | +#define OffsetToPointer(base, offset) \ | ||
| 603 | + ((void *)((char *) base + offset)) | ||
| 604 | + | ||
| 605 | +#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) | ||
| 606 | + | ||
| 607 | +#define RegProcedureIsValid(p) OidIsValid(p) | ||
| 608 | + | ||
| 609 | + | ||
| 610 | +/* ---------------------------------------------------------------- | ||
| 611 | + * Section 5: offsetof, lengthof, alignment | ||
| 612 | + * ---------------------------------------------------------------- | ||
| 613 | + */ | ||
| 614 | +/* | ||
| 615 | + * offsetof | ||
| 616 | + * Offset of a structure/union field within that structure/union. | ||
| 617 | + * | ||
| 618 | + * XXX This is supposed to be part of stddef.h, but isn't on | ||
| 619 | + * some systems (like SunOS 4). | ||
| 620 | + */ | ||
| 621 | +#ifndef offsetof | ||
| 622 | +#define offsetof(type, field) ((long) &((type *)0)->field) | ||
| 623 | +#endif /* offsetof */ | ||
| 624 | + | ||
| 625 | +/* | ||
| 626 | + * lengthof | ||
| 627 | + * Number of elements in an array. | ||
| 628 | + */ | ||
| 629 | +#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) | ||
| 630 | + | ||
| 631 | +/* ---------------- | ||
| 632 | + * Alignment macros: align a length or address appropriately for a given type. | ||
| 633 | + * The fooALIGN() macros round up to a multiple of the required alignment, | ||
| 634 | + * while the fooALIGN_DOWN() macros round down. The latter are more useful | ||
| 635 | + * for problems like "how many X-sized structures will fit in a page?". | ||
| 636 | + * | ||
| 637 | + * NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2. | ||
| 638 | + * That case seems extremely unlikely to be needed in practice, however. | ||
| 639 | + * | ||
| 640 | + * NOTE: MAXIMUM_ALIGNOF, and hence MAXALIGN(), intentionally exclude any | ||
| 641 | + * larger-than-8-byte types the compiler might have. | ||
| 642 | + * ---------------- | ||
| 643 | + */ | ||
| 644 | + | ||
| 645 | +#define TYPEALIGN(ALIGNVAL,LEN) \ | ||
| 646 | + (((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1))) | ||
| 647 | + | ||
| 648 | +#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) | ||
| 649 | +#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) | ||
| 650 | +#define LONGALIGN(LEN) TYPEALIGN(ALIGNOF_LONG, (LEN)) | ||
| 651 | +#define DOUBLEALIGN(LEN) TYPEALIGN(ALIGNOF_DOUBLE, (LEN)) | ||
| 652 | +#define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN)) | ||
| 653 | +/* MAXALIGN covers only built-in types, not buffers */ | ||
| 654 | +#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) | ||
| 655 | +#define CACHELINEALIGN(LEN) TYPEALIGN(PG_CACHE_LINE_SIZE, (LEN)) | ||
| 656 | + | ||
| 657 | +#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ | ||
| 658 | + (((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1))) | ||
| 659 | + | ||
| 660 | +#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) | ||
| 661 | +#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) | ||
| 662 | +#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN)) | ||
| 663 | +#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) | ||
| 664 | +#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) | ||
| 665 | +#define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN)) | ||
| 666 | + | ||
| 667 | +/* | ||
| 668 | + * The above macros will not work with types wider than uintptr_t, like with | ||
| 669 | + * uint64 on 32-bit platforms. That's not problem for the usual use where a | ||
| 670 | + * pointer or a length is aligned, but for the odd case that you need to | ||
| 671 | + * align something (potentially) wider, use TYPEALIGN64. | ||
| 672 | + */ | ||
| 673 | +#define TYPEALIGN64(ALIGNVAL,LEN) \ | ||
| 674 | + (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1))) | ||
| 675 | + | ||
| 676 | +/* we don't currently need wider versions of the other ALIGN macros */ | ||
| 677 | +#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN)) | ||
| 678 | + | ||
| 679 | + | ||
| 680 | +/* ---------------------------------------------------------------- | ||
| 681 | + * Section 6: assertions | ||
| 682 | + * ---------------------------------------------------------------- | ||
| 683 | + */ | ||
| 684 | + | ||
| 685 | +/* | ||
| 686 | + * USE_ASSERT_CHECKING, if defined, turns on all the assertions. | ||
| 687 | + * - plai 9/5/90 | ||
| 688 | + * | ||
| 689 | + * It should _NOT_ be defined in releases or in benchmark copies | ||
| 690 | + */ | ||
| 691 | + | ||
| 692 | +/* | ||
| 693 | + * Assert() can be used in both frontend and backend code. In frontend code it | ||
| 694 | + * just calls the standard assert, if it's available. If use of assertions is | ||
| 695 | + * not configured, it does nothing. | ||
| 696 | + */ | ||
| 697 | +#ifndef USE_ASSERT_CHECKING | ||
| 698 | + | ||
| 699 | +#define Assert(condition) ((void)true) | ||
| 700 | +#define AssertMacro(condition) ((void)true) | ||
| 701 | +#define AssertArg(condition) ((void)true) | ||
| 702 | +#define AssertState(condition) ((void)true) | ||
| 703 | +#define AssertPointerAlignment(ptr, bndr) ((void)true) | ||
| 704 | +#define Trap(condition, errorType) ((void)true) | ||
| 705 | +#define TrapMacro(condition, errorType) (true) | ||
| 706 | + | ||
| 707 | +#elif defined(FRONTEND) | ||
| 708 | + | ||
| 709 | +#include <assert.h> | ||
| 710 | +#define Assert(p) assert(p) | ||
| 711 | +#define AssertMacro(p) ((void) assert(p)) | ||
| 712 | +#define AssertArg(condition) assert(condition) | ||
| 713 | +#define AssertState(condition) assert(condition) | ||
| 714 | +#define AssertPointerAlignment(ptr, bndr) ((void)true) | ||
| 715 | + | ||
| 716 | +#else /* USE_ASSERT_CHECKING && !FRONTEND */ | ||
| 717 | + | ||
| 718 | +/* | ||
| 719 | + * Trap | ||
| 720 | + * Generates an exception if the given condition is true. | ||
| 721 | + */ | ||
| 722 | +#define Trap(condition, errorType) \ | ||
| 723 | + do { \ | ||
| 724 | + if (condition) \ | ||
| 725 | + ExceptionalCondition(CppAsString(condition), (errorType), \ | ||
| 726 | + __FILE__, __LINE__); \ | ||
| 727 | + } while (0) | ||
| 728 | + | ||
| 729 | +/* | ||
| 730 | + * TrapMacro is the same as Trap but it's intended for use in macros: | ||
| 731 | + * | ||
| 732 | + * #define foo(x) (AssertMacro(x != 0), bar(x)) | ||
| 733 | + * | ||
| 734 | + * Isn't CPP fun? | ||
| 735 | + */ | ||
| 736 | +#define TrapMacro(condition, errorType) \ | ||
| 737 | + ((bool) (! (condition) || \ | ||
| 738 | + (ExceptionalCondition(CppAsString(condition), (errorType), \ | ||
| 739 | + __FILE__, __LINE__), 0))) | ||
| 740 | + | ||
| 741 | +#define Assert(condition) \ | ||
| 742 | + Trap(!(condition), "FailedAssertion") | ||
| 743 | + | ||
| 744 | +#define AssertMacro(condition) \ | ||
| 745 | + ((void) TrapMacro(!(condition), "FailedAssertion")) | ||
| 746 | + | ||
| 747 | +#define AssertArg(condition) \ | ||
| 748 | + Trap(!(condition), "BadArgument") | ||
| 749 | + | ||
| 750 | +#define AssertState(condition) \ | ||
| 751 | + Trap(!(condition), "BadState") | ||
| 752 | + | ||
| 753 | +/* | ||
| 754 | + * Check that `ptr' is `bndr' aligned. | ||
| 755 | + */ | ||
| 756 | +#define AssertPointerAlignment(ptr, bndr) \ | ||
| 757 | + Trap(TYPEALIGN(bndr, (uintptr_t)(ptr)) != (uintptr_t)(ptr), \ | ||
| 758 | + "UnalignedPointer") | ||
| 759 | + | ||
| 760 | +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ | ||
| 761 | + | ||
| 762 | +/* | ||
| 763 | + * ExceptionalCondition is compiled into the backend whether or not | ||
| 764 | + * USE_ASSERT_CHECKING is defined, so as to support use of extensions | ||
| 765 | + * that are built with that #define with a backend that isn't. Hence, | ||
| 766 | + * we should declare it as long as !FRONTEND. | ||
| 767 | + */ | ||
| 768 | +#ifndef FRONTEND | ||
| 769 | +extern void ExceptionalCondition(const char *conditionName, | ||
| 770 | + const char *errorType, | ||
| 771 | + const char *fileName, int lineNumber) pg_attribute_noreturn(); | ||
| 772 | +#endif | ||
| 773 | + | ||
| 774 | +/* | ||
| 775 | + * Macros to support compile-time assertion checks. | ||
| 776 | + * | ||
| 777 | + * If the "condition" (a compile-time-constant expression) evaluates to false, | ||
| 778 | + * throw a compile error using the "errmessage" (a string literal). | ||
| 779 | + * | ||
| 780 | + * gcc 4.6 and up supports _Static_assert(), but there are bizarre syntactic | ||
| 781 | + * placement restrictions. These macros make it safe to use as a statement | ||
| 782 | + * or in an expression, respectively. | ||
| 783 | + * | ||
| 784 | + * Otherwise we fall back on a kluge that assumes the compiler will complain | ||
| 785 | + * about a negative width for a struct bit-field. This will not include a | ||
| 786 | + * helpful error message, but it beats not getting an error at all. | ||
| 787 | + */ | ||
| 788 | +#ifndef __cplusplus | ||
| 789 | +#ifdef HAVE__STATIC_ASSERT | ||
| 790 | +#define StaticAssertStmt(condition, errmessage) \ | ||
| 791 | + do { _Static_assert(condition, errmessage); } while(0) | ||
| 792 | +#define StaticAssertExpr(condition, errmessage) \ | ||
| 793 | + ((void) ({ StaticAssertStmt(condition, errmessage); true; })) | ||
| 794 | +#else /* !HAVE__STATIC_ASSERT */ | ||
| 795 | +#define StaticAssertStmt(condition, errmessage) \ | ||
| 796 | + ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) | ||
| 797 | +#define StaticAssertExpr(condition, errmessage) \ | ||
| 798 | + StaticAssertStmt(condition, errmessage) | ||
| 799 | +#endif /* HAVE__STATIC_ASSERT */ | ||
| 800 | +#else /* C++ */ | ||
| 801 | +#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 | ||
| 802 | +#define StaticAssertStmt(condition, errmessage) \ | ||
| 803 | + static_assert(condition, errmessage) | ||
| 804 | +#define StaticAssertExpr(condition, errmessage) \ | ||
| 805 | + ({ static_assert(condition, errmessage); }) | ||
| 806 | +#else | ||
| 807 | +#define StaticAssertStmt(condition, errmessage) \ | ||
| 808 | + do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) | ||
| 809 | +#define StaticAssertExpr(condition, errmessage) \ | ||
| 810 | + ((void) ({ StaticAssertStmt(condition, errmessage); })) | ||
| 811 | +#endif | ||
| 812 | +#endif /* C++ */ | ||
| 813 | + | ||
| 814 | + | ||
| 815 | +/* | ||
| 816 | + * Compile-time checks that a variable (or expression) has the specified type. | ||
| 817 | + * | ||
| 818 | + * AssertVariableIsOfType() can be used as a statement. | ||
| 819 | + * AssertVariableIsOfTypeMacro() is intended for use in macros, eg | ||
| 820 | + * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) | ||
| 821 | + * | ||
| 822 | + * If we don't have __builtin_types_compatible_p, we can still assert that | ||
| 823 | + * the types have the same size. This is far from ideal (especially on 32-bit | ||
| 824 | + * platforms) but it provides at least some coverage. | ||
| 825 | + */ | ||
| 826 | +#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P | ||
| 827 | +#define AssertVariableIsOfType(varname, typename) \ | ||
| 828 | + StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ | ||
| 829 | + CppAsString(varname) " does not have type " CppAsString(typename)) | ||
| 830 | +#define AssertVariableIsOfTypeMacro(varname, typename) \ | ||
| 831 | + (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ | ||
| 832 | + CppAsString(varname) " does not have type " CppAsString(typename))) | ||
| 833 | +#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ | ||
| 834 | +#define AssertVariableIsOfType(varname, typename) \ | ||
| 835 | + StaticAssertStmt(sizeof(varname) == sizeof(typename), \ | ||
| 836 | + CppAsString(varname) " does not have type " CppAsString(typename)) | ||
| 837 | +#define AssertVariableIsOfTypeMacro(varname, typename) \ | ||
| 838 | + (StaticAssertExpr(sizeof(varname) == sizeof(typename), \ | ||
| 839 | + CppAsString(varname) " does not have type " CppAsString(typename))) | ||
| 840 | +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ | ||
| 841 | + | ||
| 842 | + | ||
| 843 | +/* ---------------------------------------------------------------- | ||
| 844 | + * Section 7: widely useful macros | ||
| 845 | + * ---------------------------------------------------------------- | ||
| 846 | + */ | ||
| 847 | +/* | ||
| 848 | + * Max | ||
| 849 | + * Return the maximum of two numbers. | ||
| 850 | + */ | ||
| 851 | +#define Max(x, y) ((x) > (y) ? (x) : (y)) | ||
| 852 | + | ||
| 853 | +/* | ||
| 854 | + * Min | ||
| 855 | + * Return the minimum of two numbers. | ||
| 856 | + */ | ||
| 857 | +#define Min(x, y) ((x) < (y) ? (x) : (y)) | ||
| 858 | + | ||
| 859 | +/* | ||
| 860 | + * Abs | ||
| 861 | + * Return the absolute value of the argument. | ||
| 862 | + */ | ||
| 863 | +#define Abs(x) ((x) >= 0 ? (x) : -(x)) | ||
| 864 | + | ||
| 865 | +/* | ||
| 866 | + * StrNCpy | ||
| 867 | + * Like standard library function strncpy(), except that result string | ||
| 868 | + * is guaranteed to be null-terminated --- that is, at most N-1 bytes | ||
| 869 | + * of the source string will be kept. | ||
| 870 | + * Also, the macro returns no result (too hard to do that without | ||
| 871 | + * evaluating the arguments multiple times, which seems worse). | ||
| 872 | + * | ||
| 873 | + * BTW: when you need to copy a non-null-terminated string (like a text | ||
| 874 | + * datum) and add a null, do not do it with StrNCpy(..., len+1). That | ||
| 875 | + * might seem to work, but it fetches one byte more than there is in the | ||
| 876 | + * text object. One fine day you'll have a SIGSEGV because there isn't | ||
| 877 | + * another byte before the end of memory. Don't laugh, we've had real | ||
| 878 | + * live bug reports from real live users over exactly this mistake. | ||
| 879 | + * Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead. | ||
| 880 | + */ | ||
| 881 | +#define StrNCpy(dst,src,len) \ | ||
| 882 | + do \ | ||
| 883 | + { \ | ||
| 884 | + char * _dst = (dst); \ | ||
| 885 | + Size _len = (len); \ | ||
| 886 | +\ | ||
| 887 | + if (_len > 0) \ | ||
| 888 | + { \ | ||
| 889 | + strncpy(_dst, (src), _len); \ | ||
| 890 | + _dst[_len-1] = '\0'; \ | ||
| 891 | + } \ | ||
| 892 | + } while (0) | ||
| 893 | + | ||
| 894 | + | ||
| 895 | +/* Get a bit mask of the bits set in non-long aligned addresses */ | ||
| 896 | +#define LONG_ALIGN_MASK (sizeof(long) - 1) | ||
| 897 | + | ||
| 898 | +/* | ||
| 899 | + * MemSet | ||
| 900 | + * Exactly the same as standard library function memset(), but considerably | ||
| 901 | + * faster for zeroing small word-aligned structures (such as parsetree nodes). | ||
| 902 | + * This has to be a macro because the main point is to avoid function-call | ||
| 903 | + * overhead. However, we have also found that the loop is faster than | ||
| 904 | + * native libc memset() on some platforms, even those with assembler | ||
| 905 | + * memset() functions. More research needs to be done, perhaps with | ||
| 906 | + * MEMSET_LOOP_LIMIT tests in configure. | ||
| 907 | + */ | ||
| 908 | +#define MemSet(start, val, len) \ | ||
| 909 | + do \ | ||
| 910 | + { \ | ||
| 911 | + /* must be void* because we don't know if it is integer aligned yet */ \ | ||
| 912 | + void *_vstart = (void *) (start); \ | ||
| 913 | + int _val = (val); \ | ||
| 914 | + Size _len = (len); \ | ||
| 915 | +\ | ||
| 916 | + if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ | ||
| 917 | + (_len & LONG_ALIGN_MASK) == 0 && \ | ||
| 918 | + _val == 0 && \ | ||
| 919 | + _len <= MEMSET_LOOP_LIMIT && \ | ||
| 920 | + /* \ | ||
| 921 | + * If MEMSET_LOOP_LIMIT == 0, optimizer should find \ | ||
| 922 | + * the whole "if" false at compile time. \ | ||
| 923 | + */ \ | ||
| 924 | + MEMSET_LOOP_LIMIT != 0) \ | ||
| 925 | + { \ | ||
| 926 | + long *_start = (long *) _vstart; \ | ||
| 927 | + long *_stop = (long *) ((char *) _start + _len); \ | ||
| 928 | + while (_start < _stop) \ | ||
| 929 | + *_start++ = 0; \ | ||
| 930 | + } \ | ||
| 931 | + else \ | ||
| 932 | + memset(_vstart, _val, _len); \ | ||
| 933 | + } while (0) | ||
| 934 | + | ||
| 935 | +/* | ||
| 936 | + * MemSetAligned is the same as MemSet except it omits the test to see if | ||
| 937 | + * "start" is word-aligned. This is okay to use if the caller knows a-priori | ||
| 938 | + * that the pointer is suitably aligned (typically, because he just got it | ||
| 939 | + * from palloc(), which always delivers a max-aligned pointer). | ||
| 940 | + */ | ||
| 941 | +#define MemSetAligned(start, val, len) \ | ||
| 942 | + do \ | ||
| 943 | + { \ | ||
| 944 | + long *_start = (long *) (start); \ | ||
| 945 | + int _val = (val); \ | ||
| 946 | + Size _len = (len); \ | ||
| 947 | +\ | ||
| 948 | + if ((_len & LONG_ALIGN_MASK) == 0 && \ | ||
| 949 | + _val == 0 && \ | ||
| 950 | + _len <= MEMSET_LOOP_LIMIT && \ | ||
| 951 | + MEMSET_LOOP_LIMIT != 0) \ | ||
| 952 | + { \ | ||
| 953 | + long *_stop = (long *) ((char *) _start + _len); \ | ||
| 954 | + while (_start < _stop) \ | ||
| 955 | + *_start++ = 0; \ | ||
| 956 | + } \ | ||
| 957 | + else \ | ||
| 958 | + memset(_start, _val, _len); \ | ||
| 959 | + } while (0) | ||
| 960 | + | ||
| 961 | + | ||
| 962 | +/* | ||
| 963 | + * MemSetTest/MemSetLoop are a variant version that allow all the tests in | ||
| 964 | + * MemSet to be done at compile time in cases where "val" and "len" are | ||
| 965 | + * constants *and* we know the "start" pointer must be word-aligned. | ||
| 966 | + * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use | ||
| 967 | + * MemSetAligned. Beware of multiple evaluations of the arguments when using | ||
| 968 | + * this approach. | ||
| 969 | + */ | ||
| 970 | +#define MemSetTest(val, len) \ | ||
| 971 | + ( ((len) & LONG_ALIGN_MASK) == 0 && \ | ||
| 972 | + (len) <= MEMSET_LOOP_LIMIT && \ | ||
| 973 | + MEMSET_LOOP_LIMIT != 0 && \ | ||
| 974 | + (val) == 0 ) | ||
| 975 | + | ||
| 976 | +#define MemSetLoop(start, val, len) \ | ||
| 977 | + do \ | ||
| 978 | + { \ | ||
| 979 | + long * _start = (long *) (start); \ | ||
| 980 | + long * _stop = (long *) ((char *) _start + (Size) (len)); \ | ||
| 981 | + \ | ||
| 982 | + while (_start < _stop) \ | ||
| 983 | + *_start++ = 0; \ | ||
| 984 | + } while (0) | ||
| 985 | + | ||
| 986 | + | ||
| 987 | +/* ---------------------------------------------------------------- | ||
| 988 | + * Section 8: random stuff | ||
| 989 | + * ---------------------------------------------------------------- | ||
| 990 | + */ | ||
| 991 | + | ||
| 992 | +/* | ||
| 993 | + * Invert the sign of a qsort-style comparison result, ie, exchange negative | ||
| 994 | + * and positive integer values, being careful not to get the wrong answer | ||
| 995 | + * for INT_MIN. The argument should be an integral variable. | ||
| 996 | + */ | ||
| 997 | +#define INVERT_COMPARE_RESULT(var) \ | ||
| 998 | + ((var) = ((var) < 0) ? 1 : -(var)) | ||
| 999 | + | ||
| 1000 | +/* | ||
| 1001 | + * Use this, not "char buf[BLCKSZ]", to declare a field or local variable | ||
| 1002 | + * holding a page buffer, if that page might be accessed as a page and not | ||
| 1003 | + * just a string of bytes. Otherwise the variable might be under-aligned, | ||
| 1004 | + * causing problems on alignment-picky hardware. (In some places, we use | ||
| 1005 | + * this to declare buffers even though we only pass them to read() and | ||
| 1006 | + * write(), because copying to/from aligned buffers is usually faster than | ||
| 1007 | + * using unaligned buffers.) We include both "double" and "int64" in the | ||
| 1008 | + * union to ensure that the compiler knows the value must be MAXALIGN'ed | ||
| 1009 | + * (cf. configure's computation of MAXIMUM_ALIGNOF). | ||
| 1010 | + */ | ||
| 1011 | +typedef union PGAlignedBlock | ||
| 1012 | +{ | ||
| 1013 | + char data[BLCKSZ]; | ||
| 1014 | + double force_align_d; | ||
| 1015 | + int64 force_align_i64; | ||
| 1016 | +} PGAlignedBlock; | ||
| 1017 | + | ||
| 1018 | +/* Same, but for an XLOG_BLCKSZ-sized buffer */ | ||
| 1019 | +typedef union PGAlignedXLogBlock | ||
| 1020 | +{ | ||
| 1021 | + char data[XLOG_BLCKSZ]; | ||
| 1022 | + double force_align_d; | ||
| 1023 | + int64 force_align_i64; | ||
| 1024 | +} PGAlignedXLogBlock; | ||
| 1025 | + | ||
| 1026 | +/* msb for char */ | ||
| 1027 | +#define HIGHBIT (0x80) | ||
| 1028 | +#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) | ||
| 1029 | + | ||
| 1030 | +/* | ||
| 1031 | + * Support macros for escaping strings. escape_backslash should be true | ||
| 1032 | + * if generating a non-standard-conforming string. Prefixing a string | ||
| 1033 | + * with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming. | ||
| 1034 | + * Beware of multiple evaluation of the "ch" argument! | ||
| 1035 | + */ | ||
| 1036 | +#define SQL_STR_DOUBLE(ch, escape_backslash) \ | ||
| 1037 | + ((ch) == '\'' || ((ch) == '\\' && (escape_backslash))) | ||
| 1038 | + | ||
| 1039 | +#define ESCAPE_STRING_SYNTAX 'E' | ||
| 1040 | + | ||
| 1041 | + | ||
| 1042 | +#define STATUS_OK (0) | ||
| 1043 | +#define STATUS_ERROR (-1) | ||
| 1044 | +#define STATUS_EOF (-2) | ||
| 1045 | +#define STATUS_FOUND (1) | ||
| 1046 | +#define STATUS_WAITING (2) | ||
| 1047 | + | ||
| 1048 | +/* | ||
| 1049 | + * gettext support | ||
| 1050 | + */ | ||
| 1051 | + | ||
| 1052 | +#ifndef ENABLE_NLS | ||
| 1053 | +/* stuff we'd otherwise get from <libintl.h> */ | ||
| 1054 | +#define gettext(x) (x) | ||
| 1055 | +#define dgettext(d,x) (x) | ||
| 1056 | +#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) | ||
| 1057 | +#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) | ||
| 1058 | +#endif | ||
| 1059 | + | ||
| 1060 | +#define _(x) gettext(x) | ||
| 1061 | + | ||
| 1062 | +/* | ||
| 1063 | + * Use this to mark string constants as needing translation at some later | ||
| 1064 | + * time, rather than immediately. This is useful for cases where you need | ||
| 1065 | + * access to the original string and translated string, and for cases where | ||
| 1066 | + * immediate translation is not possible, like when initializing global | ||
| 1067 | + * variables. | ||
| 1068 | + * http://www.gnu.org/software/autoconf/manual/gettext/Special-cases.html | ||
| 1069 | + */ | ||
| 1070 | +#define gettext_noop(x) (x) | ||
| 1071 | + | ||
| 1072 | +/* | ||
| 1073 | + * To better support parallel installations of major PostgreSQL | ||
| 1074 | + * versions as well as parallel installations of major library soname | ||
| 1075 | + * versions, we mangle the gettext domain name by appending those | ||
| 1076 | + * version numbers. The coding rule ought to be that wherever the | ||
| 1077 | + * domain name is mentioned as a literal, it must be wrapped into | ||
| 1078 | + * PG_TEXTDOMAIN(). The macros below do not work on non-literals; but | ||
| 1079 | + * that is somewhat intentional because it avoids having to worry | ||
| 1080 | + * about multiple states of premangling and postmangling as the values | ||
| 1081 | + * are being passed around. | ||
| 1082 | + * | ||
| 1083 | + * Make sure this matches the installation rules in nls-global.mk. | ||
| 1084 | + */ | ||
| 1085 | +#ifdef SO_MAJOR_VERSION | ||
| 1086 | +#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) | ||
| 1087 | +#else | ||
| 1088 | +#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) | ||
| 1089 | +#endif | ||
| 1090 | + | ||
| 1091 | + | ||
| 1092 | +/* ---------------------------------------------------------------- | ||
| 1093 | + * Section 9: system-specific hacks | ||
| 1094 | + * | ||
| 1095 | + * This should be limited to things that absolutely have to be | ||
| 1096 | + * included in every source file. The port-specific header file | ||
| 1097 | + * is usually a better place for this sort of thing. | ||
| 1098 | + * ---------------------------------------------------------------- | ||
| 1099 | + */ | ||
| 1100 | + | ||
| 1101 | +/* | ||
| 1102 | + * NOTE: this is also used for opening text files. | ||
| 1103 | + * WIN32 treats Control-Z as EOF in files opened in text mode. | ||
| 1104 | + * Therefore, we open files in binary mode on Win32 so we can read | ||
| 1105 | + * literal control-Z. The other affect is that we see CRLF, but | ||
| 1106 | + * that is OK because we can already handle those cleanly. | ||
| 1107 | + */ | ||
| 1108 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 1109 | +#define PG_BINARY O_BINARY | ||
| 1110 | +#define PG_BINARY_A "ab" | ||
| 1111 | +#define PG_BINARY_R "rb" | ||
| 1112 | +#define PG_BINARY_W "wb" | ||
| 1113 | +#else | ||
| 1114 | +#define PG_BINARY 0 | ||
| 1115 | +#define PG_BINARY_A "a" | ||
| 1116 | +#define PG_BINARY_R "r" | ||
| 1117 | +#define PG_BINARY_W "w" | ||
| 1118 | +#endif | ||
| 1119 | + | ||
| 1120 | +/* | ||
| 1121 | + * Provide prototypes for routines not present in a particular machine's | ||
| 1122 | + * standard C library. | ||
| 1123 | + */ | ||
| 1124 | + | ||
| 1125 | +#if !HAVE_DECL_SNPRINTF | ||
| 1126 | +extern int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); | ||
| 1127 | +#endif | ||
| 1128 | + | ||
| 1129 | +#if !HAVE_DECL_VSNPRINTF | ||
| 1130 | +extern int vsnprintf(char *str, size_t count, const char *fmt, va_list args); | ||
| 1131 | +#endif | ||
| 1132 | + | ||
| 1133 | +#if defined(HAVE_FDATASYNC) && !HAVE_DECL_FDATASYNC | ||
| 1134 | +extern int fdatasync(int fildes); | ||
| 1135 | +#endif | ||
| 1136 | + | ||
| 1137 | +#ifdef HAVE_LONG_LONG_INT | ||
| 1138 | +/* Older platforms may provide strto[u]ll functionality under other names */ | ||
| 1139 | +#if !defined(HAVE_STRTOLL) && defined(HAVE___STRTOLL) | ||
| 1140 | +#define strtoll __strtoll | ||
| 1141 | +#define HAVE_STRTOLL 1 | ||
| 1142 | +#endif | ||
| 1143 | + | ||
| 1144 | +#if !defined(HAVE_STRTOLL) && defined(HAVE_STRTOQ) | ||
| 1145 | +#define strtoll strtoq | ||
| 1146 | +#define HAVE_STRTOLL 1 | ||
| 1147 | +#endif | ||
| 1148 | + | ||
| 1149 | +#if !defined(HAVE_STRTOULL) && defined(HAVE___STRTOULL) | ||
| 1150 | +#define strtoull __strtoull | ||
| 1151 | +#define HAVE_STRTOULL 1 | ||
| 1152 | +#endif | ||
| 1153 | + | ||
| 1154 | +#if !defined(HAVE_STRTOULL) && defined(HAVE_STRTOUQ) | ||
| 1155 | +#define strtoull strtouq | ||
| 1156 | +#define HAVE_STRTOULL 1 | ||
| 1157 | +#endif | ||
| 1158 | + | ||
| 1159 | +#if defined(HAVE_STRTOLL) && !HAVE_DECL_STRTOLL | ||
| 1160 | +extern long long strtoll(const char *str, char **endptr, int base); | ||
| 1161 | +#endif | ||
| 1162 | + | ||
| 1163 | +#if defined(HAVE_STRTOULL) && !HAVE_DECL_STRTOULL | ||
| 1164 | +extern unsigned long long strtoull(const char *str, char **endptr, int base); | ||
| 1165 | +#endif | ||
| 1166 | +#endif /* HAVE_LONG_LONG_INT */ | ||
| 1167 | + | ||
| 1168 | +#if !defined(HAVE_MEMMOVE) && !defined(memmove) | ||
| 1169 | +#define memmove(d, s, c) bcopy(s, d, c) | ||
| 1170 | +#endif | ||
| 1171 | + | ||
| 1172 | +/* no special DLL markers on most ports */ | ||
| 1173 | +#ifndef PGDLLIMPORT | ||
| 1174 | +#define PGDLLIMPORT | ||
| 1175 | +#endif | ||
| 1176 | +#ifndef PGDLLEXPORT | ||
| 1177 | +#define PGDLLEXPORT | ||
| 1178 | +#endif | ||
| 1179 | + | ||
| 1180 | +/* | ||
| 1181 | + * The following is used as the arg list for signal handlers. Any ports | ||
| 1182 | + * that take something other than an int argument should override this in | ||
| 1183 | + * their pg_config_os.h file. Note that variable names are required | ||
| 1184 | + * because it is used in both the prototypes as well as the definitions. | ||
| 1185 | + * Note also the long name. We expect that this won't collide with | ||
| 1186 | + * other names causing compiler warnings. | ||
| 1187 | + */ | ||
| 1188 | + | ||
| 1189 | +#ifndef SIGNAL_ARGS | ||
| 1190 | +#define SIGNAL_ARGS int postgres_signal_arg | ||
| 1191 | +#endif | ||
| 1192 | + | ||
| 1193 | +/* | ||
| 1194 | + * When there is no sigsetjmp, its functionality is provided by plain | ||
| 1195 | + * setjmp. Incidentally, nothing provides setjmp's functionality in | ||
| 1196 | + * that case. We now support the case only on Windows. | ||
| 1197 | + */ | ||
| 1198 | +#ifdef WIN32 | ||
| 1199 | +#define sigjmp_buf jmp_buf | ||
| 1200 | +#define sigsetjmp(x,y) setjmp(x) | ||
| 1201 | +#define siglongjmp longjmp | ||
| 1202 | +#endif | ||
| 1203 | + | ||
| 1204 | +/* EXEC_BACKEND defines */ | ||
| 1205 | +#ifdef EXEC_BACKEND | ||
| 1206 | +#define NON_EXEC_STATIC | ||
| 1207 | +#else | ||
| 1208 | +#define NON_EXEC_STATIC static | ||
| 1209 | +#endif | ||
| 1210 | + | ||
| 1211 | +/* /port compatibility functions */ | ||
| 1212 | +#include "port.h" | ||
| 1213 | + | ||
| 1214 | +#endif /* C_H */ |
pgsql/include/internal/libpq-int.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * libpq-int.h | ||
| 4 | + * This file contains internal definitions meant to be used only by | ||
| 5 | + * the frontend libpq library, not by applications that call it. | ||
| 6 | + * | ||
| 7 | + * An application can include this file if it wants to bypass the | ||
| 8 | + * official API defined by libpq-fe.h, but code that does so is much | ||
| 9 | + * more likely to break across PostgreSQL releases than code that uses | ||
| 10 | + * only the official API. | ||
| 11 | + * | ||
| 12 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 13 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 14 | + * | ||
| 15 | + * src/interfaces/libpq/libpq-int.h | ||
| 16 | + * | ||
| 17 | + *------------------------------------------------------------------------- | ||
| 18 | + */ | ||
| 19 | + | ||
| 20 | +#ifndef LIBPQ_INT_H | ||
| 21 | +#define LIBPQ_INT_H | ||
| 22 | + | ||
| 23 | +/* We assume libpq-fe.h has already been included. */ | ||
| 24 | +#include "libpq-events.h" | ||
| 25 | + | ||
| 26 | +#include <time.h> | ||
| 27 | +#ifndef WIN32 | ||
| 28 | +#include <sys/time.h> | ||
| 29 | +#endif | ||
| 30 | + | ||
| 31 | +#ifdef ENABLE_THREAD_SAFETY | ||
| 32 | +#ifdef WIN32 | ||
| 33 | +#include "pthread-win32.h" | ||
| 34 | +#else | ||
| 35 | +#include <pthread.h> | ||
| 36 | +#endif | ||
| 37 | +#include <signal.h> | ||
| 38 | +#endif | ||
| 39 | + | ||
| 40 | +/* include stuff common to fe and be */ | ||
| 41 | +#include "getaddrinfo.h" | ||
| 42 | +#include "libpq/pqcomm.h" | ||
| 43 | +/* include stuff found in fe only */ | ||
| 44 | +#include "pqexpbuffer.h" | ||
| 45 | + | ||
| 46 | +#ifdef ENABLE_GSS | ||
| 47 | +#if defined(HAVE_GSSAPI_H) | ||
| 48 | +#include <gssapi.h> | ||
| 49 | +#else | ||
| 50 | +#include <gssapi/gssapi.h> | ||
| 51 | +#endif | ||
| 52 | +#endif | ||
| 53 | + | ||
| 54 | +#ifdef ENABLE_SSPI | ||
| 55 | +#define SECURITY_WIN32 | ||
| 56 | +#if defined(WIN32) && !defined(_MSC_VER) | ||
| 57 | +#include <ntsecapi.h> | ||
| 58 | +#endif | ||
| 59 | +#include <security.h> | ||
| 60 | +#undef SECURITY_WIN32 | ||
| 61 | + | ||
| 62 | +#ifndef ENABLE_GSS | ||
| 63 | +/* | ||
| 64 | + * Define a fake structure compatible with GSSAPI on Unix. | ||
| 65 | + */ | ||
| 66 | +typedef struct | ||
| 67 | +{ | ||
| 68 | + void *value; | ||
| 69 | + int length; | ||
| 70 | +} gss_buffer_desc; | ||
| 71 | +#endif | ||
| 72 | +#endif /* ENABLE_SSPI */ | ||
| 73 | + | ||
| 74 | +#ifdef USE_OPENSSL | ||
| 75 | +#include <openssl/ssl.h> | ||
| 76 | +#include <openssl/err.h> | ||
| 77 | + | ||
| 78 | +#ifndef OPENSSL_NO_ENGINE | ||
| 79 | +#define USE_SSL_ENGINE | ||
| 80 | +#endif | ||
| 81 | +#endif /* USE_OPENSSL */ | ||
| 82 | + | ||
| 83 | +/* | ||
| 84 | + * POSTGRES backend dependent Constants. | ||
| 85 | + */ | ||
| 86 | +#define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */ | ||
| 87 | + | ||
| 88 | +/* | ||
| 89 | + * PGresult and the subsidiary types PGresAttDesc, PGresAttValue | ||
| 90 | + * represent the result of a query (or more precisely, of a single SQL | ||
| 91 | + * command --- a query string given to PQexec can contain multiple commands). | ||
| 92 | + * Note we assume that a single command can return at most one tuple group, | ||
| 93 | + * hence there is no need for multiple descriptor sets. | ||
| 94 | + */ | ||
| 95 | + | ||
| 96 | +/* Subsidiary-storage management structure for PGresult. | ||
| 97 | + * See space management routines in fe-exec.c for details. | ||
| 98 | + * Note that space[k] refers to the k'th byte starting from the physical | ||
| 99 | + * head of the block --- it's a union, not a struct! | ||
| 100 | + */ | ||
| 101 | +typedef union pgresult_data PGresult_data; | ||
| 102 | + | ||
| 103 | +union pgresult_data | ||
| 104 | +{ | ||
| 105 | + PGresult_data *next; /* link to next block, or NULL */ | ||
| 106 | + char space[1]; /* dummy for accessing block as bytes */ | ||
| 107 | +}; | ||
| 108 | + | ||
| 109 | +/* Data about a single parameter of a prepared statement */ | ||
| 110 | +typedef struct pgresParamDesc | ||
| 111 | +{ | ||
| 112 | + Oid typid; /* type id */ | ||
| 113 | +} PGresParamDesc; | ||
| 114 | + | ||
| 115 | +/* | ||
| 116 | + * Data for a single attribute of a single tuple | ||
| 117 | + * | ||
| 118 | + * We use char* for Attribute values. | ||
| 119 | + * | ||
| 120 | + * The value pointer always points to a null-terminated area; we add a | ||
| 121 | + * null (zero) byte after whatever the backend sends us. This is only | ||
| 122 | + * particularly useful for text values ... with a binary value, the | ||
| 123 | + * value might have embedded nulls, so the application can't use C string | ||
| 124 | + * operators on it. But we add a null anyway for consistency. | ||
| 125 | + * Note that the value itself does not contain a length word. | ||
| 126 | + * | ||
| 127 | + * A NULL attribute is a special case in two ways: its len field is NULL_LEN | ||
| 128 | + * and its value field points to null_field in the owning PGresult. All the | ||
| 129 | + * NULL attributes in a query result point to the same place (there's no need | ||
| 130 | + * to store a null string separately for each one). | ||
| 131 | + */ | ||
| 132 | + | ||
| 133 | +#define NULL_LEN (-1) /* pg_result len for NULL value */ | ||
| 134 | + | ||
| 135 | +typedef struct pgresAttValue | ||
| 136 | +{ | ||
| 137 | + int len; /* length in bytes of the value */ | ||
| 138 | + char *value; /* actual value, plus terminating zero byte */ | ||
| 139 | +} PGresAttValue; | ||
| 140 | + | ||
| 141 | +/* Typedef for message-field list entries */ | ||
| 142 | +typedef struct pgMessageField | ||
| 143 | +{ | ||
| 144 | + struct pgMessageField *next; /* list link */ | ||
| 145 | + char code; /* field code */ | ||
| 146 | + char contents[FLEXIBLE_ARRAY_MEMBER]; /* value, nul-terminated */ | ||
| 147 | +} PGMessageField; | ||
| 148 | + | ||
| 149 | +/* Fields needed for notice handling */ | ||
| 150 | +typedef struct | ||
| 151 | +{ | ||
| 152 | + PQnoticeReceiver noticeRec; /* notice message receiver */ | ||
| 153 | + void *noticeRecArg; | ||
| 154 | + PQnoticeProcessor noticeProc; /* notice message processor */ | ||
| 155 | + void *noticeProcArg; | ||
| 156 | +} PGNoticeHooks; | ||
| 157 | + | ||
| 158 | +typedef struct PGEvent | ||
| 159 | +{ | ||
| 160 | + PGEventProc proc; /* the function to call on events */ | ||
| 161 | + char *name; /* used only for error messages */ | ||
| 162 | + void *passThrough; /* pointer supplied at registration time */ | ||
| 163 | + void *data; /* optional state (instance) data */ | ||
| 164 | + bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */ | ||
| 165 | +} PGEvent; | ||
| 166 | + | ||
| 167 | +struct pg_result | ||
| 168 | +{ | ||
| 169 | + int ntups; | ||
| 170 | + int numAttributes; | ||
| 171 | + PGresAttDesc *attDescs; | ||
| 172 | + PGresAttValue **tuples; /* each PGresTuple is an array of | ||
| 173 | + * PGresAttValue's */ | ||
| 174 | + int tupArrSize; /* allocated size of tuples array */ | ||
| 175 | + int numParameters; | ||
| 176 | + PGresParamDesc *paramDescs; | ||
| 177 | + ExecStatusType resultStatus; | ||
| 178 | + char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */ | ||
| 179 | + int binary; /* binary tuple values if binary == 1, | ||
| 180 | + * otherwise text */ | ||
| 181 | + | ||
| 182 | + /* | ||
| 183 | + * These fields are copied from the originating PGconn, so that operations | ||
| 184 | + * on the PGresult don't have to reference the PGconn. | ||
| 185 | + */ | ||
| 186 | + PGNoticeHooks noticeHooks; | ||
| 187 | + PGEvent *events; | ||
| 188 | + int nEvents; | ||
| 189 | + int client_encoding; /* encoding id */ | ||
| 190 | + | ||
| 191 | + /* | ||
| 192 | + * Error information (all NULL if not an error result). errMsg is the | ||
| 193 | + * "overall" error message returned by PQresultErrorMessage. If we have | ||
| 194 | + * per-field info then it is stored in a linked list. | ||
| 195 | + */ | ||
| 196 | + char *errMsg; /* error message, or NULL if no error */ | ||
| 197 | + PGMessageField *errFields; /* message broken into fields */ | ||
| 198 | + char *errQuery; /* text of triggering query, if available */ | ||
| 199 | + | ||
| 200 | + /* All NULL attributes in the query result point to this null string */ | ||
| 201 | + char null_field[1]; | ||
| 202 | + | ||
| 203 | + /* | ||
| 204 | + * Space management information. Note that attDescs and error stuff, if | ||
| 205 | + * not null, point into allocated blocks. But tuples points to a | ||
| 206 | + * separately malloc'd block, so that we can realloc it. | ||
| 207 | + */ | ||
| 208 | + PGresult_data *curBlock; /* most recently allocated block */ | ||
| 209 | + int curOffset; /* start offset of free space in block */ | ||
| 210 | + int spaceLeft; /* number of free bytes remaining in block */ | ||
| 211 | +}; | ||
| 212 | + | ||
| 213 | +/* PGAsyncStatusType defines the state of the query-execution state machine */ | ||
| 214 | +typedef enum | ||
| 215 | +{ | ||
| 216 | + PGASYNC_IDLE, /* nothing's happening, dude */ | ||
| 217 | + PGASYNC_BUSY, /* query in progress */ | ||
| 218 | + PGASYNC_READY, /* result ready for PQgetResult */ | ||
| 219 | + PGASYNC_COPY_IN, /* Copy In data transfer in progress */ | ||
| 220 | + PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */ | ||
| 221 | + PGASYNC_COPY_BOTH /* Copy In/Out data transfer in progress */ | ||
| 222 | +} PGAsyncStatusType; | ||
| 223 | + | ||
| 224 | +/* PGQueryClass tracks which query protocol we are now executing */ | ||
| 225 | +typedef enum | ||
| 226 | +{ | ||
| 227 | + PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */ | ||
| 228 | + PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */ | ||
| 229 | + PGQUERY_PREPARE, /* Parse only (PQprepare) */ | ||
| 230 | + PGQUERY_DESCRIBE /* Describe Statement or Portal */ | ||
| 231 | +} PGQueryClass; | ||
| 232 | + | ||
| 233 | +/* PGSetenvStatusType defines the state of the PQSetenv state machine */ | ||
| 234 | +/* (this is used only for 2.0-protocol connections) */ | ||
| 235 | +typedef enum | ||
| 236 | +{ | ||
| 237 | + SETENV_STATE_CLIENT_ENCODING_SEND, /* About to send an Environment Option */ | ||
| 238 | + SETENV_STATE_CLIENT_ENCODING_WAIT, /* Waiting for above send to complete */ | ||
| 239 | + SETENV_STATE_OPTION_SEND, /* About to send an Environment Option */ | ||
| 240 | + SETENV_STATE_OPTION_WAIT, /* Waiting for above send to complete */ | ||
| 241 | + SETENV_STATE_QUERY1_SEND, /* About to send a status query */ | ||
| 242 | + SETENV_STATE_QUERY1_WAIT, /* Waiting for query to complete */ | ||
| 243 | + SETENV_STATE_QUERY2_SEND, /* About to send a status query */ | ||
| 244 | + SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */ | ||
| 245 | + SETENV_STATE_IDLE | ||
| 246 | +} PGSetenvStatusType; | ||
| 247 | + | ||
| 248 | +/* Typedef for the EnvironmentOptions[] array */ | ||
| 249 | +typedef struct PQEnvironmentOption | ||
| 250 | +{ | ||
| 251 | + const char *envName, /* name of an environment variable */ | ||
| 252 | + *pgName; /* name of corresponding SET variable */ | ||
| 253 | +} PQEnvironmentOption; | ||
| 254 | + | ||
| 255 | +/* Typedef for parameter-status list entries */ | ||
| 256 | +typedef struct pgParameterStatus | ||
| 257 | +{ | ||
| 258 | + struct pgParameterStatus *next; /* list link */ | ||
| 259 | + char *name; /* parameter name */ | ||
| 260 | + char *value; /* parameter value */ | ||
| 261 | + /* Note: name and value are stored in same malloc block as struct is */ | ||
| 262 | +} pgParameterStatus; | ||
| 263 | + | ||
| 264 | +/* large-object-access data ... allocated only if large-object code is used. */ | ||
| 265 | +typedef struct pgLobjfuncs | ||
| 266 | +{ | ||
| 267 | + Oid fn_lo_open; /* OID of backend function lo_open */ | ||
| 268 | + Oid fn_lo_close; /* OID of backend function lo_close */ | ||
| 269 | + Oid fn_lo_creat; /* OID of backend function lo_creat */ | ||
| 270 | + Oid fn_lo_create; /* OID of backend function lo_create */ | ||
| 271 | + Oid fn_lo_unlink; /* OID of backend function lo_unlink */ | ||
| 272 | + Oid fn_lo_lseek; /* OID of backend function lo_lseek */ | ||
| 273 | + Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */ | ||
| 274 | + Oid fn_lo_tell; /* OID of backend function lo_tell */ | ||
| 275 | + Oid fn_lo_tell64; /* OID of backend function lo_tell64 */ | ||
| 276 | + Oid fn_lo_truncate; /* OID of backend function lo_truncate */ | ||
| 277 | + Oid fn_lo_truncate64; /* OID of function lo_truncate64 */ | ||
| 278 | + Oid fn_lo_read; /* OID of backend function LOread */ | ||
| 279 | + Oid fn_lo_write; /* OID of backend function LOwrite */ | ||
| 280 | +} PGlobjfuncs; | ||
| 281 | + | ||
| 282 | +/* PGdataValue represents a data field value being passed to a row processor. | ||
| 283 | + * It could be either text or binary data; text data is not zero-terminated. | ||
| 284 | + * A SQL NULL is represented by len < 0; then value is still valid but there | ||
| 285 | + * are no data bytes there. | ||
| 286 | + */ | ||
| 287 | +typedef struct pgDataValue | ||
| 288 | +{ | ||
| 289 | + int len; /* data length in bytes, or <0 if NULL */ | ||
| 290 | + const char *value; /* data value, without zero-termination */ | ||
| 291 | +} PGdataValue; | ||
| 292 | + | ||
| 293 | +/* Host address type enum for struct pg_conn_host */ | ||
| 294 | +typedef enum pg_conn_host_type | ||
| 295 | +{ | ||
| 296 | + CHT_HOST_NAME, | ||
| 297 | + CHT_HOST_ADDRESS, | ||
| 298 | + CHT_UNIX_SOCKET | ||
| 299 | +} pg_conn_host_type; | ||
| 300 | + | ||
| 301 | +/* | ||
| 302 | + * pg_conn_host stores all information about each of possibly several hosts | ||
| 303 | + * mentioned in the connection string. Most fields are derived by splitting | ||
| 304 | + * the relevant connection parameter (e.g., pghost) at commas. | ||
| 305 | + */ | ||
| 306 | +typedef struct pg_conn_host | ||
| 307 | +{ | ||
| 308 | + pg_conn_host_type type; /* type of host address */ | ||
| 309 | + char *host; /* host name or socket path */ | ||
| 310 | + char *hostaddr; /* host numeric IP address */ | ||
| 311 | + char *port; /* port number (always provided) */ | ||
| 312 | + char *password; /* password for this host, read from the | ||
| 313 | + * password file; NULL if not sought or not | ||
| 314 | + * found in password file. */ | ||
| 315 | + struct addrinfo *was_addrlist; /* dummy for ABI compatibility */ | ||
| 316 | +} pg_conn_host; | ||
| 317 | + | ||
| 318 | +/* | ||
| 319 | + * PGconn stores all the state data associated with a single connection | ||
| 320 | + * to a backend. | ||
| 321 | + */ | ||
| 322 | +struct pg_conn | ||
| 323 | +{ | ||
| 324 | + /* Saved values of connection options */ | ||
| 325 | + char *pghost; /* the machine on which the server is running, | ||
| 326 | + * or a path to a UNIX-domain socket, or a | ||
| 327 | + * comma-separated list of machines and/or | ||
| 328 | + * paths; if NULL, use DEFAULT_PGSOCKET_DIR */ | ||
| 329 | + char *pghostaddr; /* the numeric IP address of the machine on | ||
| 330 | + * which the server is running, or a | ||
| 331 | + * comma-separated list of same. Takes | ||
| 332 | + * precedence over pghost. */ | ||
| 333 | + char *pgport; /* the server's communication port number, or | ||
| 334 | + * a comma-separated list of ports */ | ||
| 335 | + char *pgtty; /* tty on which the backend messages is | ||
| 336 | + * displayed (OBSOLETE, NOT USED) */ | ||
| 337 | + char *connect_timeout; /* connection timeout (numeric string) */ | ||
| 338 | + char *client_encoding_initial; /* encoding to use */ | ||
| 339 | + char *pgoptions; /* options to start the backend with */ | ||
| 340 | + char *appname; /* application name */ | ||
| 341 | + char *fbappname; /* fallback application name */ | ||
| 342 | + char *dbName; /* database name */ | ||
| 343 | + char *replication; /* connect as the replication standby? */ | ||
| 344 | + char *pguser; /* Postgres username and password, if any */ | ||
| 345 | + char *pgpass; | ||
| 346 | + char *pgpassfile; /* path to a file containing password(s) */ | ||
| 347 | + char *keepalives; /* use TCP keepalives? */ | ||
| 348 | + char *keepalives_idle; /* time between TCP keepalives */ | ||
| 349 | + char *keepalives_interval; /* time between TCP keepalive | ||
| 350 | + * retransmits */ | ||
| 351 | + char *keepalives_count; /* maximum number of TCP keepalive | ||
| 352 | + * retransmits */ | ||
| 353 | + char *sslmode; /* SSL mode (require,prefer,allow,disable) */ | ||
| 354 | + char *sslcompression; /* SSL compression (0 or 1) */ | ||
| 355 | + char *sslkey; /* client key filename */ | ||
| 356 | + char *sslcert; /* client certificate filename */ | ||
| 357 | + char *sslrootcert; /* root certificate filename */ | ||
| 358 | + char *sslcrl; /* certificate revocation list filename */ | ||
| 359 | + char *requirepeer; /* required peer credentials for local sockets */ | ||
| 360 | + | ||
| 361 | +#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) | ||
| 362 | + char *krbsrvname; /* Kerberos service name */ | ||
| 363 | +#endif | ||
| 364 | + | ||
| 365 | + /* Type of connection to make. Possible values: any, read-write. */ | ||
| 366 | + char *target_session_attrs; | ||
| 367 | + | ||
| 368 | + /* Optional file to write trace info to */ | ||
| 369 | + FILE *Pfdebug; | ||
| 370 | + | ||
| 371 | + /* Callback procedures for notice message processing */ | ||
| 372 | + PGNoticeHooks noticeHooks; | ||
| 373 | + | ||
| 374 | + /* Event procs registered via PQregisterEventProc */ | ||
| 375 | + PGEvent *events; /* expandable array of event data */ | ||
| 376 | + int nEvents; /* number of active events */ | ||
| 377 | + int eventArraySize; /* allocated array size */ | ||
| 378 | + | ||
| 379 | + /* Status indicators */ | ||
| 380 | + ConnStatusType status; | ||
| 381 | + PGAsyncStatusType asyncStatus; | ||
| 382 | + PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ | ||
| 383 | + PGQueryClass queryclass; | ||
| 384 | + char *last_query; /* last SQL command, or NULL if unknown */ | ||
| 385 | + char last_sqlstate[6]; /* last reported SQLSTATE */ | ||
| 386 | + bool options_valid; /* true if OK to attempt connection */ | ||
| 387 | + bool nonblocking; /* whether this connection is using nonblock | ||
| 388 | + * sending semantics */ | ||
| 389 | + bool singleRowMode; /* return current query result row-by-row? */ | ||
| 390 | + char copy_is_binary; /* 1 = copy binary, 0 = copy text */ | ||
| 391 | + int copy_already_done; /* # bytes already returned in COPY OUT */ | ||
| 392 | + PGnotify *notifyHead; /* oldest unreported Notify msg */ | ||
| 393 | + PGnotify *notifyTail; /* newest unreported Notify msg */ | ||
| 394 | + | ||
| 395 | + /* Support for multiple hosts in connection string */ | ||
| 396 | + int nconnhost; /* # of hosts named in conn string */ | ||
| 397 | + int whichhost; /* host we're currently trying/connected to */ | ||
| 398 | + pg_conn_host *connhost; /* details about each named host */ | ||
| 399 | + | ||
| 400 | + /* Connection data */ | ||
| 401 | + pgsocket sock; /* FD for socket, PGINVALID_SOCKET if | ||
| 402 | + * unconnected */ | ||
| 403 | + SockAddr laddr; /* Local address */ | ||
| 404 | + SockAddr raddr; /* Remote address */ | ||
| 405 | + ProtocolVersion pversion; /* FE/BE protocol version in use */ | ||
| 406 | + int sversion; /* server version, e.g. 70401 for 7.4.1 */ | ||
| 407 | + bool auth_req_received; /* true if any type of auth req received */ | ||
| 408 | + bool password_needed; /* true if server demanded a password */ | ||
| 409 | + bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */ | ||
| 410 | + bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */ | ||
| 411 | + | ||
| 412 | + /* Transient state needed while establishing connection */ | ||
| 413 | + bool try_next_addr; /* time to advance to next address/host? */ | ||
| 414 | + bool try_next_host; /* time to advance to next connhost[]? */ | ||
| 415 | + struct addrinfo *addr_cur; /* backend address currently being tried */ | ||
| 416 | + PGSetenvStatusType setenv_state; /* for 2.0 protocol only */ | ||
| 417 | + const PQEnvironmentOption *next_eo; | ||
| 418 | + bool send_appname; /* okay to send application_name? */ | ||
| 419 | + | ||
| 420 | + /* Miscellaneous stuff */ | ||
| 421 | + int be_pid; /* PID of backend --- needed for cancels */ | ||
| 422 | + int be_key; /* key of backend --- needed for cancels */ | ||
| 423 | + pgParameterStatus *pstatus; /* ParameterStatus data */ | ||
| 424 | + int client_encoding; /* encoding id */ | ||
| 425 | + bool std_strings; /* standard_conforming_strings */ | ||
| 426 | + PGVerbosity verbosity; /* error/notice message verbosity */ | ||
| 427 | + PGContextVisibility show_context; /* whether to show CONTEXT field */ | ||
| 428 | + PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ | ||
| 429 | + | ||
| 430 | + /* Buffer for data received from backend and not yet processed */ | ||
| 431 | + char *inBuffer; /* currently allocated buffer */ | ||
| 432 | + int inBufSize; /* allocated size of buffer */ | ||
| 433 | + int inStart; /* offset to first unconsumed data in buffer */ | ||
| 434 | + int inCursor; /* next byte to tentatively consume */ | ||
| 435 | + int inEnd; /* offset to first position after avail data */ | ||
| 436 | + | ||
| 437 | + /* Buffer for data not yet sent to backend */ | ||
| 438 | + char *outBuffer; /* currently allocated buffer */ | ||
| 439 | + int outBufSize; /* allocated size of buffer */ | ||
| 440 | + int outCount; /* number of chars waiting in buffer */ | ||
| 441 | + | ||
| 442 | + /* State for constructing messages in outBuffer */ | ||
| 443 | + int outMsgStart; /* offset to msg start (length word); if -1, | ||
| 444 | + * msg has no length word */ | ||
| 445 | + int outMsgEnd; /* offset to msg end (so far) */ | ||
| 446 | + | ||
| 447 | + /* Row processor interface workspace */ | ||
| 448 | + PGdataValue *rowBuf; /* array for passing values to rowProcessor */ | ||
| 449 | + int rowBufLen; /* number of entries allocated in rowBuf */ | ||
| 450 | + | ||
| 451 | + /* Status for asynchronous result construction */ | ||
| 452 | + PGresult *result; /* result being constructed */ | ||
| 453 | + PGresult *next_result; /* next result (used in single-row mode) */ | ||
| 454 | + | ||
| 455 | + /* Assorted state for SASL, SSL, GSS, etc */ | ||
| 456 | + void *sasl_state; | ||
| 457 | + | ||
| 458 | + /* SSL structures */ | ||
| 459 | + bool ssl_in_use; | ||
| 460 | + | ||
| 461 | +#ifdef USE_SSL | ||
| 462 | + bool allow_ssl_try; /* Allowed to try SSL negotiation */ | ||
| 463 | + bool wait_ssl_try; /* Delay SSL negotiation until after | ||
| 464 | + * attempting normal connection */ | ||
| 465 | +#ifdef USE_OPENSSL | ||
| 466 | + SSL *ssl; /* SSL status, if have SSL connection */ | ||
| 467 | + X509 *peer; /* X509 cert of server */ | ||
| 468 | +#ifdef USE_SSL_ENGINE | ||
| 469 | + ENGINE *engine; /* SSL engine, if any */ | ||
| 470 | +#else | ||
| 471 | + void *engine; /* dummy field to keep struct the same if | ||
| 472 | + * OpenSSL version changes */ | ||
| 473 | +#endif | ||
| 474 | +#endif /* USE_OPENSSL */ | ||
| 475 | +#endif /* USE_SSL */ | ||
| 476 | + | ||
| 477 | +#ifdef ENABLE_GSS | ||
| 478 | + gss_ctx_id_t gctx; /* GSS context */ | ||
| 479 | + gss_name_t gtarg_nam; /* GSS target name */ | ||
| 480 | +#endif | ||
| 481 | + | ||
| 482 | +#ifdef ENABLE_SSPI | ||
| 483 | +#ifdef ENABLE_GSS | ||
| 484 | + char *gsslib; /* What GSS library to use ("gssapi" or | ||
| 485 | + * "sspi") */ | ||
| 486 | +#endif | ||
| 487 | + CredHandle *sspicred; /* SSPI credentials handle */ | ||
| 488 | + CtxtHandle *sspictx; /* SSPI context */ | ||
| 489 | + char *sspitarget; /* SSPI target name */ | ||
| 490 | + int usesspi; /* Indicate if SSPI is in use on the | ||
| 491 | + * connection */ | ||
| 492 | +#endif | ||
| 493 | + | ||
| 494 | + /* Buffer for current error message */ | ||
| 495 | + PQExpBufferData errorMessage; /* expansible string */ | ||
| 496 | + | ||
| 497 | + /* Buffer for receiving various parts of messages */ | ||
| 498 | + PQExpBufferData workBuffer; /* expansible string */ | ||
| 499 | + | ||
| 500 | + /* Placed at the end, in this branch, to minimize ABI breakage */ | ||
| 501 | + struct addrinfo *addrlist; /* list of addresses for current connhost */ | ||
| 502 | + int addrlist_family; /* needed to know how to free addrlist */ | ||
| 503 | +}; | ||
| 504 | + | ||
| 505 | +/* PGcancel stores all data necessary to cancel a connection. A copy of this | ||
| 506 | + * data is required to safely cancel a connection running on a different | ||
| 507 | + * thread. | ||
| 508 | + */ | ||
| 509 | +struct pg_cancel | ||
| 510 | +{ | ||
| 511 | + SockAddr raddr; /* Remote address */ | ||
| 512 | + int be_pid; /* PID of backend --- needed for cancels */ | ||
| 513 | + int be_key; /* key of backend --- needed for cancels */ | ||
| 514 | +}; | ||
| 515 | + | ||
| 516 | + | ||
| 517 | +/* String descriptions of the ExecStatusTypes. | ||
| 518 | + * direct use of this array is deprecated; call PQresStatus() instead. | ||
| 519 | + */ | ||
| 520 | +extern char *const pgresStatus[]; | ||
| 521 | + | ||
| 522 | + | ||
| 523 | +#ifdef USE_SSL | ||
| 524 | + | ||
| 525 | +#ifndef WIN32 | ||
| 526 | +#define USER_CERT_FILE ".postgresql/postgresql.crt" | ||
| 527 | +#define USER_KEY_FILE ".postgresql/postgresql.key" | ||
| 528 | +#define ROOT_CERT_FILE ".postgresql/root.crt" | ||
| 529 | +#define ROOT_CRL_FILE ".postgresql/root.crl" | ||
| 530 | +#else | ||
| 531 | +/* On Windows, the "home" directory is already PostgreSQL-specific */ | ||
| 532 | +#define USER_CERT_FILE "postgresql.crt" | ||
| 533 | +#define USER_KEY_FILE "postgresql.key" | ||
| 534 | +#define ROOT_CERT_FILE "root.crt" | ||
| 535 | +#define ROOT_CRL_FILE "root.crl" | ||
| 536 | +#endif | ||
| 537 | + | ||
| 538 | +#endif /* USE_SSL */ | ||
| 539 | + | ||
| 540 | +/* ---------------- | ||
| 541 | + * Internal functions of libpq | ||
| 542 | + * Functions declared here need to be visible across files of libpq, | ||
| 543 | + * but are not intended to be called by applications. We use the | ||
| 544 | + * convention "pqXXX" for internal functions, vs. the "PQxxx" names | ||
| 545 | + * used for application-visible routines. | ||
| 546 | + * ---------------- | ||
| 547 | + */ | ||
| 548 | + | ||
| 549 | +/* === in fe-connect.c === */ | ||
| 550 | + | ||
| 551 | +extern void pqDropConnection(PGconn *conn, bool flushInput); | ||
| 552 | +extern int pqPacketSend(PGconn *conn, char pack_type, | ||
| 553 | + const void *buf, size_t buf_len); | ||
| 554 | +extern bool pqGetHomeDirectory(char *buf, int bufsize); | ||
| 555 | + | ||
| 556 | +#ifdef ENABLE_THREAD_SAFETY | ||
| 557 | +extern pgthreadlock_t pg_g_threadlock; | ||
| 558 | + | ||
| 559 | +#define PGTHREAD_ERROR(msg) \ | ||
| 560 | + do { \ | ||
| 561 | + fprintf(stderr, "%s\n", msg); \ | ||
| 562 | + abort(); \ | ||
| 563 | + } while (0) | ||
| 564 | + | ||
| 565 | + | ||
| 566 | +#define pglock_thread() pg_g_threadlock(true) | ||
| 567 | +#define pgunlock_thread() pg_g_threadlock(false) | ||
| 568 | +#else | ||
| 569 | +#define pglock_thread() ((void) 0) | ||
| 570 | +#define pgunlock_thread() ((void) 0) | ||
| 571 | +#endif | ||
| 572 | + | ||
| 573 | +/* === in fe-exec.c === */ | ||
| 574 | + | ||
| 575 | +extern void pqSetResultError(PGresult *res, const char *msg); | ||
| 576 | +extern void pqCatenateResultError(PGresult *res, const char *msg); | ||
| 577 | +extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary); | ||
| 578 | +extern char *pqResultStrdup(PGresult *res, const char *str); | ||
| 579 | +extern void pqClearAsyncResult(PGconn *conn); | ||
| 580 | +extern void pqSaveErrorResult(PGconn *conn); | ||
| 581 | +extern PGresult *pqPrepareAsyncResult(PGconn *conn); | ||
| 582 | +extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3); | ||
| 583 | +extern void pqSaveMessageField(PGresult *res, char code, | ||
| 584 | + const char *value); | ||
| 585 | +extern void pqSaveParameterStatus(PGconn *conn, const char *name, | ||
| 586 | + const char *value); | ||
| 587 | +extern int pqRowProcessor(PGconn *conn, const char **errmsgp); | ||
| 588 | +extern void pqHandleSendFailure(PGconn *conn); | ||
| 589 | + | ||
| 590 | +/* === in fe-protocol2.c === */ | ||
| 591 | + | ||
| 592 | +extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn); | ||
| 593 | + | ||
| 594 | +extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen, | ||
| 595 | + const PQEnvironmentOption *options); | ||
| 596 | +extern void pqParseInput2(PGconn *conn); | ||
| 597 | +extern int pqGetCopyData2(PGconn *conn, char **buffer, int async); | ||
| 598 | +extern int pqGetline2(PGconn *conn, char *s, int maxlen); | ||
| 599 | +extern int pqGetlineAsync2(PGconn *conn, char *buffer, int bufsize); | ||
| 600 | +extern int pqEndcopy2(PGconn *conn); | ||
| 601 | +extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid, | ||
| 602 | + int *result_buf, int *actual_result_len, | ||
| 603 | + int result_is_int, | ||
| 604 | + const PQArgBlock *args, int nargs); | ||
| 605 | + | ||
| 606 | +/* === in fe-protocol3.c === */ | ||
| 607 | + | ||
| 608 | +extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, | ||
| 609 | + const PQEnvironmentOption *options); | ||
| 610 | +extern void pqParseInput3(PGconn *conn); | ||
| 611 | +extern int pqGetErrorNotice3(PGconn *conn, bool isError); | ||
| 612 | +extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, | ||
| 613 | + PGVerbosity verbosity, PGContextVisibility show_context); | ||
| 614 | +extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); | ||
| 615 | +extern int pqGetline3(PGconn *conn, char *s, int maxlen); | ||
| 616 | +extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize); | ||
| 617 | +extern int pqEndcopy3(PGconn *conn); | ||
| 618 | +extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, | ||
| 619 | + int *result_buf, int *actual_result_len, | ||
| 620 | + int result_is_int, | ||
| 621 | + const PQArgBlock *args, int nargs); | ||
| 622 | + | ||
| 623 | +/* === in fe-misc.c === */ | ||
| 624 | + | ||
| 625 | + /* | ||
| 626 | + * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for | ||
| 627 | + * Get, EOF merely means the buffer is exhausted, not that there is | ||
| 628 | + * necessarily any error. | ||
| 629 | + */ | ||
| 630 | +extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn); | ||
| 631 | +extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn); | ||
| 632 | +extern int pqGetc(char *result, PGconn *conn); | ||
| 633 | +extern int pqPutc(char c, PGconn *conn); | ||
| 634 | +extern int pqGets(PQExpBuffer buf, PGconn *conn); | ||
| 635 | +extern int pqGets_append(PQExpBuffer buf, PGconn *conn); | ||
| 636 | +extern int pqPuts(const char *s, PGconn *conn); | ||
| 637 | +extern int pqGetnchar(char *s, size_t len, PGconn *conn); | ||
| 638 | +extern int pqSkipnchar(size_t len, PGconn *conn); | ||
| 639 | +extern int pqPutnchar(const char *s, size_t len, PGconn *conn); | ||
| 640 | +extern int pqGetInt(int *result, size_t bytes, PGconn *conn); | ||
| 641 | +extern int pqPutInt(int value, size_t bytes, PGconn *conn); | ||
| 642 | +extern int pqPutMsgStart(char msg_type, bool force_len, PGconn *conn); | ||
| 643 | +extern int pqPutMsgEnd(PGconn *conn); | ||
| 644 | +extern int pqReadData(PGconn *conn); | ||
| 645 | +extern int pqFlush(PGconn *conn); | ||
| 646 | +extern int pqWait(int forRead, int forWrite, PGconn *conn); | ||
| 647 | +extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, | ||
| 648 | + time_t finish_time); | ||
| 649 | +extern int pqReadReady(PGconn *conn); | ||
| 650 | +extern int pqWriteReady(PGconn *conn); | ||
| 651 | + | ||
| 652 | +/* === in fe-secure.c === */ | ||
| 653 | + | ||
| 654 | +extern int pqsecure_initialize(PGconn *); | ||
| 655 | +extern void pqsecure_destroy(void); | ||
| 656 | +extern PostgresPollingStatusType pqsecure_open_client(PGconn *); | ||
| 657 | +extern void pqsecure_close(PGconn *); | ||
| 658 | +extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); | ||
| 659 | +extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); | ||
| 660 | +extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); | ||
| 661 | +extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); | ||
| 662 | + | ||
| 663 | +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) | ||
| 664 | +extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); | ||
| 665 | +extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, | ||
| 666 | + bool got_epipe); | ||
| 667 | +#endif | ||
| 668 | + | ||
| 669 | +/* === SSL === */ | ||
| 670 | + | ||
| 671 | +/* | ||
| 672 | + * The SSL implementation provides these functions. | ||
| 673 | + */ | ||
| 674 | + | ||
| 675 | +/* | ||
| 676 | + * Implementation of PQinitSSL(). | ||
| 677 | + */ | ||
| 678 | +extern void pgtls_init_library(bool do_ssl, int do_crypto); | ||
| 679 | + | ||
| 680 | +/* | ||
| 681 | + * Initialize SSL library. | ||
| 682 | + * | ||
| 683 | + * The conn parameter is only used to be able to pass back an error | ||
| 684 | + * message - no connection-local setup is made here. | ||
| 685 | + * | ||
| 686 | + * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage). | ||
| 687 | + */ | ||
| 688 | +extern int pgtls_init(PGconn *conn); | ||
| 689 | + | ||
| 690 | +/* | ||
| 691 | + * Begin or continue negotiating a secure session. | ||
| 692 | + */ | ||
| 693 | +extern PostgresPollingStatusType pgtls_open_client(PGconn *conn); | ||
| 694 | + | ||
| 695 | +/* | ||
| 696 | + * Close SSL connection. | ||
| 697 | + */ | ||
| 698 | +extern void pgtls_close(PGconn *conn); | ||
| 699 | + | ||
| 700 | +/* | ||
| 701 | + * Read data from a secure connection. | ||
| 702 | + * | ||
| 703 | + * On failure, this function is responsible for putting a suitable message | ||
| 704 | + * into conn->errorMessage. The caller must still inspect errno, but only | ||
| 705 | + * to determine whether to continue/retry after error. | ||
| 706 | + */ | ||
| 707 | +extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); | ||
| 708 | + | ||
| 709 | +/* | ||
| 710 | + * Is there unread data waiting in the SSL read buffer? | ||
| 711 | + */ | ||
| 712 | +extern bool pgtls_read_pending(PGconn *conn); | ||
| 713 | + | ||
| 714 | +/* | ||
| 715 | + * Write data to a secure connection. | ||
| 716 | + * | ||
| 717 | + * On failure, this function is responsible for putting a suitable message | ||
| 718 | + * into conn->errorMessage. The caller must still inspect errno, but only | ||
| 719 | + * to determine whether to continue/retry after error. | ||
| 720 | + */ | ||
| 721 | +extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len); | ||
| 722 | + | ||
| 723 | +/* | ||
| 724 | + * Get the hash of the server certificate, for SCRAM channel binding type | ||
| 725 | + * tls-server-end-point. | ||
| 726 | + * | ||
| 727 | + * NULL is sent back to the caller in the event of an error, with an | ||
| 728 | + * error message for the caller to consume. | ||
| 729 | + * | ||
| 730 | + * This is not supported with old versions of OpenSSL that don't have | ||
| 731 | + * the X509_get_signature_nid() function. | ||
| 732 | + */ | ||
| 733 | +#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID) | ||
| 734 | +#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH | ||
| 735 | +extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); | ||
| 736 | +#endif | ||
| 737 | + | ||
| 738 | +/* | ||
| 739 | + * Verify that the server certificate matches the host name we connected to. | ||
| 740 | + * | ||
| 741 | + * The certificate's Common Name and Subject Alternative Names are considered. | ||
| 742 | + * | ||
| 743 | + * Returns 1 if the name matches, and 0 if it does not. On error, returns | ||
| 744 | + * -1, and sets the libpq error message. | ||
| 745 | + * | ||
| 746 | + */ | ||
| 747 | +extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, | ||
| 748 | + int *names_examined, | ||
| 749 | + char **first_name); | ||
| 750 | + | ||
| 751 | +/* === miscellaneous macros === */ | ||
| 752 | + | ||
| 753 | +/* | ||
| 754 | + * this is so that we can check if a connection is non-blocking internally | ||
| 755 | + * without the overhead of a function call | ||
| 756 | + */ | ||
| 757 | +#define pqIsnonblocking(conn) ((conn)->nonblocking) | ||
| 758 | + | ||
| 759 | +#ifdef ENABLE_NLS | ||
| 760 | +extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); | ||
| 761 | +extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2); | ||
| 762 | +#else | ||
| 763 | +#define libpq_gettext(x) (x) | ||
| 764 | +#define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p)) | ||
| 765 | +#endif | ||
| 766 | + | ||
| 767 | +/* | ||
| 768 | + * These macros are needed to let error-handling code be portable between | ||
| 769 | + * Unix and Windows. (ugh) | ||
| 770 | + */ | ||
| 771 | +#ifdef WIN32 | ||
| 772 | +#define SOCK_ERRNO (WSAGetLastError()) | ||
| 773 | +#define SOCK_STRERROR winsock_strerror | ||
| 774 | +#define SOCK_ERRNO_SET(e) WSASetLastError(e) | ||
| 775 | +#else | ||
| 776 | +#define SOCK_ERRNO errno | ||
| 777 | +#define SOCK_STRERROR pqStrerror | ||
| 778 | +#define SOCK_ERRNO_SET(e) (errno = (e)) | ||
| 779 | +#endif | ||
| 780 | + | ||
| 781 | +#endif /* LIBPQ_INT_H */ |
pgsql/include/internal/libpq/pqcomm.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * pqcomm.h | ||
| 4 | + * Definitions common to frontends and backends. | ||
| 5 | + * | ||
| 6 | + * NOTE: for historical reasons, this does not correspond to pqcomm.c. | ||
| 7 | + * pqcomm.c's routines are declared in libpq.h. | ||
| 8 | + * | ||
| 9 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 10 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 11 | + * | ||
| 12 | + * src/include/libpq/pqcomm.h | ||
| 13 | + * | ||
| 14 | + *------------------------------------------------------------------------- | ||
| 15 | + */ | ||
| 16 | +#ifndef PQCOMM_H | ||
| 17 | +#define PQCOMM_H | ||
| 18 | + | ||
| 19 | +#include <sys/socket.h> | ||
| 20 | +#include <netdb.h> | ||
| 21 | +#ifdef HAVE_SYS_UN_H | ||
| 22 | +#include <sys/un.h> | ||
| 23 | +#endif | ||
| 24 | +#include <netinet/in.h> | ||
| 25 | + | ||
| 26 | +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE | ||
| 27 | + | ||
| 28 | +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY | ||
| 29 | +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY | ||
| 30 | +#define ss_family __ss_family | ||
| 31 | +#else | ||
| 32 | +#error struct sockaddr_storage does not provide an ss_family member | ||
| 33 | +#endif | ||
| 34 | +#endif | ||
| 35 | + | ||
| 36 | +#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN | ||
| 37 | +#define ss_len __ss_len | ||
| 38 | +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 | ||
| 39 | +#endif | ||
| 40 | +#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ | ||
| 41 | + | ||
| 42 | +/* Define a struct sockaddr_storage if we don't have one. */ | ||
| 43 | + | ||
| 44 | +struct sockaddr_storage | ||
| 45 | +{ | ||
| 46 | + union | ||
| 47 | + { | ||
| 48 | + struct sockaddr sa; /* get the system-dependent fields */ | ||
| 49 | + int64 ss_align; /* ensures struct is properly aligned */ | ||
| 50 | + char ss_pad[128]; /* ensures struct has desired size */ | ||
| 51 | + } ss_stuff; | ||
| 52 | +}; | ||
| 53 | + | ||
| 54 | +#define ss_family ss_stuff.sa.sa_family | ||
| 55 | +/* It should have an ss_len field if sockaddr has sa_len. */ | ||
| 56 | +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN | ||
| 57 | +#define ss_len ss_stuff.sa.sa_len | ||
| 58 | +#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 | ||
| 59 | +#endif | ||
| 60 | +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ | ||
| 61 | + | ||
| 62 | +typedef struct | ||
| 63 | +{ | ||
| 64 | + struct sockaddr_storage addr; | ||
| 65 | + ACCEPT_TYPE_ARG3 salen; | ||
| 66 | +} SockAddr; | ||
| 67 | + | ||
| 68 | +/* Configure the UNIX socket location for the well known port. */ | ||
| 69 | + | ||
| 70 | +#define UNIXSOCK_PATH(path, port, sockdir) \ | ||
| 71 | + snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \ | ||
| 72 | + ((sockdir) && *(sockdir) != '\0') ? (sockdir) : \ | ||
| 73 | + DEFAULT_PGSOCKET_DIR, \ | ||
| 74 | + (port)) | ||
| 75 | + | ||
| 76 | +/* | ||
| 77 | + * The maximum workable length of a socket path is what will fit into | ||
| 78 | + * struct sockaddr_un. This is usually only 100 or so bytes :-(. | ||
| 79 | + * | ||
| 80 | + * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), | ||
| 81 | + * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. | ||
| 82 | + * (Because the standard API for getaddrinfo doesn't allow it to complain in | ||
| 83 | + * a useful way when the socket pathname is too long, we have to test for | ||
| 84 | + * this explicitly, instead of just letting the subroutine return an error.) | ||
| 85 | + */ | ||
| 86 | +#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) | ||
| 87 | + | ||
| 88 | + | ||
| 89 | +/* | ||
| 90 | + * These manipulate the frontend/backend protocol version number. | ||
| 91 | + * | ||
| 92 | + * The major number should be incremented for incompatible changes. The minor | ||
| 93 | + * number should be incremented for compatible changes (eg. additional | ||
| 94 | + * functionality). | ||
| 95 | + * | ||
| 96 | + * If a backend supports version m.n of the protocol it must actually support | ||
| 97 | + * versions m.[0..n]. Backend support for version m-1 can be dropped after a | ||
| 98 | + * `reasonable' length of time. | ||
| 99 | + * | ||
| 100 | + * A frontend isn't required to support anything other than the current | ||
| 101 | + * version. | ||
| 102 | + */ | ||
| 103 | + | ||
| 104 | +#define PG_PROTOCOL_MAJOR(v) ((v) >> 16) | ||
| 105 | +#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) | ||
| 106 | +#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) | ||
| 107 | + | ||
| 108 | +/* The earliest and latest frontend/backend protocol version supported. */ | ||
| 109 | + | ||
| 110 | +#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(2,0) | ||
| 111 | +#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) | ||
| 112 | + | ||
| 113 | +typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ | ||
| 114 | + | ||
| 115 | +typedef ProtocolVersion MsgType; | ||
| 116 | + | ||
| 117 | + | ||
| 118 | +/* | ||
| 119 | + * Packet lengths are 4 bytes in network byte order. | ||
| 120 | + * | ||
| 121 | + * The initial length is omitted from the packet layouts appearing below. | ||
| 122 | + */ | ||
| 123 | + | ||
| 124 | +typedef uint32 PacketLen; | ||
| 125 | + | ||
| 126 | + | ||
| 127 | +/* | ||
| 128 | + * Old-style startup packet layout with fixed-width fields. This is used in | ||
| 129 | + * protocol 1.0 and 2.0, but not in later versions. Note that the fields | ||
| 130 | + * in this layout are '\0' terminated only if there is room. | ||
| 131 | + */ | ||
| 132 | + | ||
| 133 | +#define SM_DATABASE 64 | ||
| 134 | +#define SM_USER 32 | ||
| 135 | +/* We append database name if db_user_namespace true. */ | ||
| 136 | +#define SM_DATABASE_USER (SM_DATABASE+SM_USER+1) /* +1 for @ */ | ||
| 137 | +#define SM_OPTIONS 64 | ||
| 138 | +#define SM_UNUSED 64 | ||
| 139 | +#define SM_TTY 64 | ||
| 140 | + | ||
| 141 | +typedef struct StartupPacket | ||
| 142 | +{ | ||
| 143 | + ProtocolVersion protoVersion; /* Protocol version */ | ||
| 144 | + char database[SM_DATABASE]; /* Database name */ | ||
| 145 | + /* Db_user_namespace appends dbname */ | ||
| 146 | + char user[SM_USER]; /* User name */ | ||
| 147 | + char options[SM_OPTIONS]; /* Optional additional args */ | ||
| 148 | + char unused[SM_UNUSED]; /* Unused */ | ||
| 149 | + char tty[SM_TTY]; /* Tty for debug output */ | ||
| 150 | +} StartupPacket; | ||
| 151 | + | ||
| 152 | +extern bool Db_user_namespace; | ||
| 153 | + | ||
| 154 | +/* | ||
| 155 | + * In protocol 3.0 and later, the startup packet length is not fixed, but | ||
| 156 | + * we set an arbitrary limit on it anyway. This is just to prevent simple | ||
| 157 | + * denial-of-service attacks via sending enough data to run the server | ||
| 158 | + * out of memory. | ||
| 159 | + */ | ||
| 160 | +#define MAX_STARTUP_PACKET_LENGTH 10000 | ||
| 161 | + | ||
| 162 | + | ||
| 163 | +/* These are the authentication request codes sent by the backend. */ | ||
| 164 | + | ||
| 165 | +#define AUTH_REQ_OK 0 /* User is authenticated */ | ||
| 166 | +#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ | ||
| 167 | +#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ | ||
| 168 | +#define AUTH_REQ_PASSWORD 3 /* Password */ | ||
| 169 | +#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ | ||
| 170 | +#define AUTH_REQ_MD5 5 /* md5 password */ | ||
| 171 | +#define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */ | ||
| 172 | +#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ | ||
| 173 | +#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ | ||
| 174 | +#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ | ||
| 175 | +#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ | ||
| 176 | +#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ | ||
| 177 | +#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ | ||
| 178 | + | ||
| 179 | +typedef uint32 AuthRequest; | ||
| 180 | + | ||
| 181 | + | ||
| 182 | +/* | ||
| 183 | + * A client can also send a cancel-current-operation request to the postmaster. | ||
| 184 | + * This is uglier than sending it directly to the client's backend, but it | ||
| 185 | + * avoids depending on out-of-band communication facilities. | ||
| 186 | + * | ||
| 187 | + * The cancel request code must not match any protocol version number | ||
| 188 | + * we're ever likely to use. This random choice should do. | ||
| 189 | + */ | ||
| 190 | +#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) | ||
| 191 | + | ||
| 192 | +typedef struct CancelRequestPacket | ||
| 193 | +{ | ||
| 194 | + /* Note that each field is stored in network byte order! */ | ||
| 195 | + MsgType cancelRequestCode; /* code to identify a cancel request */ | ||
| 196 | + uint32 backendPID; /* PID of client's backend */ | ||
| 197 | + uint32 cancelAuthCode; /* secret key to authorize cancel */ | ||
| 198 | +} CancelRequestPacket; | ||
| 199 | + | ||
| 200 | + | ||
| 201 | +/* | ||
| 202 | + * A client can also start by sending a SSL negotiation request, to get a | ||
| 203 | + * secure channel. | ||
| 204 | + */ | ||
| 205 | +#define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) | ||
| 206 | + | ||
| 207 | +#endif /* PQCOMM_H */ |
pgsql/include/internal/port.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * port.h | ||
| 4 | + * Header for src/port/ compatibility functions. | ||
| 5 | + * | ||
| 6 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 7 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 8 | + * | ||
| 9 | + * src/include/port.h | ||
| 10 | + * | ||
| 11 | + *------------------------------------------------------------------------- | ||
| 12 | + */ | ||
| 13 | +#ifndef PG_PORT_H | ||
| 14 | +#define PG_PORT_H | ||
| 15 | + | ||
| 16 | +#include <ctype.h> | ||
| 17 | +#include <netdb.h> | ||
| 18 | +#include <pwd.h> | ||
| 19 | + | ||
| 20 | +/* | ||
| 21 | + * Windows has enough specialized port stuff that we push most of it off | ||
| 22 | + * into another file. | ||
| 23 | + * Note: Some CYGWIN includes might #define WIN32. | ||
| 24 | + */ | ||
| 25 | +#if defined(WIN32) && !defined(__CYGWIN__) | ||
| 26 | +#include "port/win32_port.h" | ||
| 27 | +#endif | ||
| 28 | + | ||
| 29 | +/* socket has a different definition on WIN32 */ | ||
| 30 | +#ifndef WIN32 | ||
| 31 | +typedef int pgsocket; | ||
| 32 | + | ||
| 33 | +#define PGINVALID_SOCKET (-1) | ||
| 34 | +#else | ||
| 35 | +typedef SOCKET pgsocket; | ||
| 36 | + | ||
| 37 | +#define PGINVALID_SOCKET INVALID_SOCKET | ||
| 38 | +#endif | ||
| 39 | + | ||
| 40 | +/* non-blocking */ | ||
| 41 | +extern bool pg_set_noblock(pgsocket sock); | ||
| 42 | +extern bool pg_set_block(pgsocket sock); | ||
| 43 | + | ||
| 44 | +/* Portable path handling for Unix/Win32 (in path.c) */ | ||
| 45 | + | ||
| 46 | +extern bool has_drive_prefix(const char *filename); | ||
| 47 | +extern char *first_dir_separator(const char *filename); | ||
| 48 | +extern char *last_dir_separator(const char *filename); | ||
| 49 | +extern char *first_path_var_separator(const char *pathlist); | ||
| 50 | +extern void join_path_components(char *ret_path, | ||
| 51 | + const char *head, const char *tail); | ||
| 52 | +extern void canonicalize_path(char *path); | ||
| 53 | +extern void make_native_path(char *path); | ||
| 54 | +extern void cleanup_path(char *path); | ||
| 55 | +extern bool path_contains_parent_reference(const char *path); | ||
| 56 | +extern bool path_is_relative_and_below_cwd(const char *path); | ||
| 57 | +extern bool path_is_prefix_of_path(const char *path1, const char *path2); | ||
| 58 | +extern char *make_absolute_path(const char *path); | ||
| 59 | +extern const char *get_progname(const char *argv0); | ||
| 60 | +extern void get_share_path(const char *my_exec_path, char *ret_path); | ||
| 61 | +extern void get_etc_path(const char *my_exec_path, char *ret_path); | ||
| 62 | +extern void get_include_path(const char *my_exec_path, char *ret_path); | ||
| 63 | +extern void get_pkginclude_path(const char *my_exec_path, char *ret_path); | ||
| 64 | +extern void get_includeserver_path(const char *my_exec_path, char *ret_path); | ||
| 65 | +extern void get_lib_path(const char *my_exec_path, char *ret_path); | ||
| 66 | +extern void get_pkglib_path(const char *my_exec_path, char *ret_path); | ||
| 67 | +extern void get_locale_path(const char *my_exec_path, char *ret_path); | ||
| 68 | +extern void get_doc_path(const char *my_exec_path, char *ret_path); | ||
| 69 | +extern void get_html_path(const char *my_exec_path, char *ret_path); | ||
| 70 | +extern void get_man_path(const char *my_exec_path, char *ret_path); | ||
| 71 | +extern bool get_home_path(char *ret_path); | ||
| 72 | +extern void get_parent_directory(char *path); | ||
| 73 | + | ||
| 74 | +/* common/pgfnames.c */ | ||
| 75 | +extern char **pgfnames(const char *path); | ||
| 76 | +extern void pgfnames_cleanup(char **filenames); | ||
| 77 | + | ||
| 78 | +/* | ||
| 79 | + * is_absolute_path | ||
| 80 | + * | ||
| 81 | + * By making this a macro we avoid needing to include path.c in libpq. | ||
| 82 | + */ | ||
| 83 | +#ifndef WIN32 | ||
| 84 | +#define IS_DIR_SEP(ch) ((ch) == '/') | ||
| 85 | + | ||
| 86 | +#define is_absolute_path(filename) \ | ||
| 87 | +( \ | ||
| 88 | + IS_DIR_SEP((filename)[0]) \ | ||
| 89 | +) | ||
| 90 | +#else | ||
| 91 | +#define IS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') | ||
| 92 | + | ||
| 93 | +/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ | ||
| 94 | +#define is_absolute_path(filename) \ | ||
| 95 | +( \ | ||
| 96 | + IS_DIR_SEP((filename)[0]) || \ | ||
| 97 | + (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ | ||
| 98 | + IS_DIR_SEP((filename)[2])) \ | ||
| 99 | +) | ||
| 100 | +#endif | ||
| 101 | + | ||
| 102 | +/* Portable locale initialization (in exec.c) */ | ||
| 103 | +extern void set_pglocale_pgservice(const char *argv0, const char *app); | ||
| 104 | + | ||
| 105 | +/* Portable way to find binaries (in exec.c) */ | ||
| 106 | +extern int find_my_exec(const char *argv0, char *retpath); | ||
| 107 | +extern int find_other_exec(const char *argv0, const char *target, | ||
| 108 | + const char *versionstr, char *retpath); | ||
| 109 | + | ||
| 110 | +/* Doesn't belong here, but this is used with find_other_exec(), so... */ | ||
| 111 | +#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" | ||
| 112 | + | ||
| 113 | + | ||
| 114 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 115 | +#define EXE ".exe" | ||
| 116 | +#else | ||
| 117 | +#define EXE "" | ||
| 118 | +#endif | ||
| 119 | + | ||
| 120 | +#if defined(WIN32) && !defined(__CYGWIN__) | ||
| 121 | +#define DEVNULL "nul" | ||
| 122 | +#else | ||
| 123 | +#define DEVNULL "/dev/null" | ||
| 124 | +#endif | ||
| 125 | + | ||
| 126 | +/* Portable delay handling */ | ||
| 127 | +extern void pg_usleep(long microsec); | ||
| 128 | + | ||
| 129 | +/* Portable SQL-like case-independent comparisons and conversions */ | ||
| 130 | +extern int pg_strcasecmp(const char *s1, const char *s2); | ||
| 131 | +extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); | ||
| 132 | +extern unsigned char pg_toupper(unsigned char ch); | ||
| 133 | +extern unsigned char pg_tolower(unsigned char ch); | ||
| 134 | +extern unsigned char pg_ascii_toupper(unsigned char ch); | ||
| 135 | +extern unsigned char pg_ascii_tolower(unsigned char ch); | ||
| 136 | + | ||
| 137 | +#ifdef USE_REPL_SNPRINTF | ||
| 138 | + | ||
| 139 | +/* | ||
| 140 | + * Versions of libintl >= 0.13 try to replace printf() and friends with | ||
| 141 | + * macros to their own versions that understand the %$ format. We do the | ||
| 142 | + * same, so disable their macros, if they exist. | ||
| 143 | + */ | ||
| 144 | +#ifdef vsnprintf | ||
| 145 | +#undef vsnprintf | ||
| 146 | +#endif | ||
| 147 | +#ifdef snprintf | ||
| 148 | +#undef snprintf | ||
| 149 | +#endif | ||
| 150 | +#ifdef sprintf | ||
| 151 | +#undef sprintf | ||
| 152 | +#endif | ||
| 153 | +#ifdef vfprintf | ||
| 154 | +#undef vfprintf | ||
| 155 | +#endif | ||
| 156 | +#ifdef fprintf | ||
| 157 | +#undef fprintf | ||
| 158 | +#endif | ||
| 159 | +#ifdef printf | ||
| 160 | +#undef printf | ||
| 161 | +#endif | ||
| 162 | + | ||
| 163 | +extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); | ||
| 164 | +extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); | ||
| 165 | +extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); | ||
| 166 | +extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args); | ||
| 167 | +extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); | ||
| 168 | +extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); | ||
| 169 | + | ||
| 170 | +/* | ||
| 171 | + * The GCC-specific code below prevents the pg_attribute_printf above from | ||
| 172 | + * being replaced, and this is required because gcc doesn't know anything | ||
| 173 | + * about pg_printf. | ||
| 174 | + */ | ||
| 175 | +#ifdef __GNUC__ | ||
| 176 | +#define vsnprintf(...) pg_vsnprintf(__VA_ARGS__) | ||
| 177 | +#define snprintf(...) pg_snprintf(__VA_ARGS__) | ||
| 178 | +#define sprintf(...) pg_sprintf(__VA_ARGS__) | ||
| 179 | +#define vfprintf(...) pg_vfprintf(__VA_ARGS__) | ||
| 180 | +#define fprintf(...) pg_fprintf(__VA_ARGS__) | ||
| 181 | +#define printf(...) pg_printf(__VA_ARGS__) | ||
| 182 | +#else | ||
| 183 | +#define vsnprintf pg_vsnprintf | ||
| 184 | +#define snprintf pg_snprintf | ||
| 185 | +#define sprintf pg_sprintf | ||
| 186 | +#define vfprintf pg_vfprintf | ||
| 187 | +#define fprintf pg_fprintf | ||
| 188 | +#define printf pg_printf | ||
| 189 | +#endif | ||
| 190 | +#endif /* USE_REPL_SNPRINTF */ | ||
| 191 | + | ||
| 192 | +/* Portable prompt handling */ | ||
| 193 | +extern void simple_prompt(const char *prompt, char *destination, size_t destlen, | ||
| 194 | + bool echo); | ||
| 195 | + | ||
| 196 | +extern int pclose_check(FILE *stream); | ||
| 197 | + | ||
| 198 | +/* Global variable holding time zone information. */ | ||
| 199 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 200 | +#define TIMEZONE_GLOBAL _timezone | ||
| 201 | +#define TZNAME_GLOBAL _tzname | ||
| 202 | +#else | ||
| 203 | +#define TIMEZONE_GLOBAL timezone | ||
| 204 | +#define TZNAME_GLOBAL tzname | ||
| 205 | +#endif | ||
| 206 | + | ||
| 207 | +#if defined(WIN32) || defined(__CYGWIN__) | ||
| 208 | +/* | ||
| 209 | + * Win32 doesn't have reliable rename/unlink during concurrent access. | ||
| 210 | + */ | ||
| 211 | +extern int pgrename(const char *from, const char *to); | ||
| 212 | +extern int pgunlink(const char *path); | ||
| 213 | + | ||
| 214 | +/* Include this first so later includes don't see these defines */ | ||
| 215 | +#ifdef _MSC_VER | ||
| 216 | +#include <io.h> | ||
| 217 | +#endif | ||
| 218 | + | ||
| 219 | +#define rename(from, to) pgrename(from, to) | ||
| 220 | +#define unlink(path) pgunlink(path) | ||
| 221 | +#endif /* defined(WIN32) || defined(__CYGWIN__) */ | ||
| 222 | + | ||
| 223 | +/* | ||
| 224 | + * Win32 also doesn't have symlinks, but we can emulate them with | ||
| 225 | + * junction points on newer Win32 versions. | ||
| 226 | + * | ||
| 227 | + * Cygwin has its own symlinks which work on Win95/98/ME where | ||
| 228 | + * junction points don't, so use those instead. We have no way of | ||
| 229 | + * knowing what type of system Cygwin binaries will be run on. | ||
| 230 | + * Note: Some CYGWIN includes might #define WIN32. | ||
| 231 | + */ | ||
| 232 | +#if defined(WIN32) && !defined(__CYGWIN__) | ||
| 233 | +extern int pgsymlink(const char *oldpath, const char *newpath); | ||
| 234 | +extern int pgreadlink(const char *path, char *buf, size_t size); | ||
| 235 | +extern bool pgwin32_is_junction(const char *path); | ||
| 236 | + | ||
| 237 | +#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) | ||
| 238 | +#define readlink(path, buf, size) pgreadlink(path, buf, size) | ||
| 239 | +#endif | ||
| 240 | + | ||
| 241 | +extern bool rmtree(const char *path, bool rmtopdir); | ||
| 242 | + | ||
| 243 | +#if defined(WIN32) && !defined(__CYGWIN__) | ||
| 244 | + | ||
| 245 | +/* | ||
| 246 | + * open() and fopen() replacements to allow deletion of open files and | ||
| 247 | + * passing of other special options. | ||
| 248 | + */ | ||
| 249 | +#define O_DIRECT 0x80000000 | ||
| 250 | +extern int pgwin32_open(const char *, int,...); | ||
| 251 | +extern FILE *pgwin32_fopen(const char *, const char *); | ||
| 252 | + | ||
| 253 | +#ifndef FRONTEND | ||
| 254 | +#define open(a,b,c) pgwin32_open(a,b,c) | ||
| 255 | +#define fopen(a,b) pgwin32_fopen(a,b) | ||
| 256 | +#endif | ||
| 257 | + | ||
| 258 | +/* | ||
| 259 | + * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want | ||
| 260 | + * to use our popen wrapper, rather than plain _popen, so override that. For | ||
| 261 | + * consistency, use our version of pclose, too. | ||
| 262 | + */ | ||
| 263 | +#ifdef popen | ||
| 264 | +#undef popen | ||
| 265 | +#endif | ||
| 266 | +#ifdef pclose | ||
| 267 | +#undef pclose | ||
| 268 | +#endif | ||
| 269 | + | ||
| 270 | +/* | ||
| 271 | + * system() and popen() replacements to enclose the command in an extra | ||
| 272 | + * pair of quotes. | ||
| 273 | + */ | ||
| 274 | +extern int pgwin32_system(const char *command); | ||
| 275 | +extern FILE *pgwin32_popen(const char *command, const char *type); | ||
| 276 | + | ||
| 277 | +#define system(a) pgwin32_system(a) | ||
| 278 | +#define popen(a,b) pgwin32_popen(a,b) | ||
| 279 | +#define pclose(a) _pclose(a) | ||
| 280 | + | ||
| 281 | +/* New versions of MingW have gettimeofday, old mingw and msvc don't */ | ||
| 282 | +#ifndef HAVE_GETTIMEOFDAY | ||
| 283 | +/* Last parameter not used */ | ||
| 284 | +extern int gettimeofday(struct timeval *tp, struct timezone *tzp); | ||
| 285 | +#endif | ||
| 286 | +#else /* !WIN32 */ | ||
| 287 | + | ||
| 288 | +/* | ||
| 289 | + * Win32 requires a special close for sockets and pipes, while on Unix | ||
| 290 | + * close() does them all. | ||
| 291 | + */ | ||
| 292 | +#define closesocket close | ||
| 293 | +#endif /* WIN32 */ | ||
| 294 | + | ||
| 295 | +/* | ||
| 296 | + * On Windows, setvbuf() does not support _IOLBF mode, and interprets that | ||
| 297 | + * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) | ||
| 298 | + * crashes outright if "parameter validation" is enabled. Therefore, in | ||
| 299 | + * places where we'd like to select line-buffered mode, we fall back to | ||
| 300 | + * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF | ||
| 301 | + * directly in order to implement this behavior. | ||
| 302 | + */ | ||
| 303 | +#ifndef WIN32 | ||
| 304 | +#define PG_IOLBF _IOLBF | ||
| 305 | +#else | ||
| 306 | +#define PG_IOLBF _IONBF | ||
| 307 | +#endif | ||
| 308 | + | ||
| 309 | +/* | ||
| 310 | + * Default "extern" declarations or macro substitutes for library routines. | ||
| 311 | + * When necessary, these routines are provided by files in src/port/. | ||
| 312 | + */ | ||
| 313 | +#ifndef HAVE_CRYPT | ||
| 314 | +extern char *crypt(const char *key, const char *setting); | ||
| 315 | +#endif | ||
| 316 | + | ||
| 317 | +/* WIN32 handled in port/win32_port.h */ | ||
| 318 | +#ifndef WIN32 | ||
| 319 | +#define pgoff_t off_t | ||
| 320 | +#ifdef __NetBSD__ | ||
| 321 | +extern int fseeko(FILE *stream, off_t offset, int whence); | ||
| 322 | +extern off_t ftello(FILE *stream); | ||
| 323 | +#endif | ||
| 324 | +#endif | ||
| 325 | + | ||
| 326 | +extern double pg_erand48(unsigned short xseed[3]); | ||
| 327 | +extern long pg_lrand48(void); | ||
| 328 | +extern long pg_jrand48(unsigned short xseed[3]); | ||
| 329 | +extern void pg_srand48(long seed); | ||
| 330 | + | ||
| 331 | +#ifndef HAVE_FLS | ||
| 332 | +extern int fls(int mask); | ||
| 333 | +#endif | ||
| 334 | + | ||
| 335 | +#ifndef HAVE_FSEEKO | ||
| 336 | +#define fseeko(a, b, c) fseek(a, b, c) | ||
| 337 | +#define ftello(a) ftell(a) | ||
| 338 | +#endif | ||
| 339 | + | ||
| 340 | +#if !defined(HAVE_GETPEEREID) && !defined(WIN32) | ||
| 341 | +extern int getpeereid(int sock, uid_t *uid, gid_t *gid); | ||
| 342 | +#endif | ||
| 343 | + | ||
| 344 | +#ifndef HAVE_ISINF | ||
| 345 | +extern int isinf(double x); | ||
| 346 | +#else | ||
| 347 | +/* | ||
| 348 | + * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version | ||
| 349 | + * newer than the gcc compatibility clang claims to have. This would cause a | ||
| 350 | + * *lot* of superfluous function calls, therefore revert when using clang. In | ||
| 351 | + * C++ there's issues with libc++ (not libstdc++), so disable as well. | ||
| 352 | + */ | ||
| 353 | +#if defined(__clang__) && !defined(__cplusplus) | ||
| 354 | +/* needs to be separate to not confuse other compilers */ | ||
| 355 | +#if __has_builtin(__builtin_isinf) | ||
| 356 | +/* need to include before, to avoid getting overwritten */ | ||
| 357 | +#include <math.h> | ||
| 358 | +#undef isinf | ||
| 359 | +#define isinf __builtin_isinf | ||
| 360 | +#endif /* __has_builtin(isinf) */ | ||
| 361 | +#endif /* __clang__ && !__cplusplus*/ | ||
| 362 | +#endif /* !HAVE_ISINF */ | ||
| 363 | + | ||
| 364 | +#ifndef HAVE_MKDTEMP | ||
| 365 | +extern char *mkdtemp(char *path); | ||
| 366 | +#endif | ||
| 367 | + | ||
| 368 | +#ifndef HAVE_RINT | ||
| 369 | +extern double rint(double x); | ||
| 370 | +#endif | ||
| 371 | + | ||
| 372 | +#ifndef HAVE_INET_ATON | ||
| 373 | +#include <netinet/in.h> | ||
| 374 | +#include <arpa/inet.h> | ||
| 375 | +extern int inet_aton(const char *cp, struct in_addr *addr); | ||
| 376 | +#endif | ||
| 377 | + | ||
| 378 | +#if !HAVE_DECL_STRLCAT | ||
| 379 | +extern size_t strlcat(char *dst, const char *src, size_t siz); | ||
| 380 | +#endif | ||
| 381 | + | ||
| 382 | +#if !HAVE_DECL_STRLCPY | ||
| 383 | +extern size_t strlcpy(char *dst, const char *src, size_t siz); | ||
| 384 | +#endif | ||
| 385 | + | ||
| 386 | +#if !HAVE_DECL_STRNLEN | ||
| 387 | +extern size_t strnlen(const char *str, size_t maxlen); | ||
| 388 | +#endif | ||
| 389 | + | ||
| 390 | +#if !defined(HAVE_RANDOM) | ||
| 391 | +extern long random(void); | ||
| 392 | +#endif | ||
| 393 | + | ||
| 394 | +#ifndef HAVE_UNSETENV | ||
| 395 | +extern void unsetenv(const char *name); | ||
| 396 | +#endif | ||
| 397 | + | ||
| 398 | +#ifndef HAVE_SRANDOM | ||
| 399 | +extern void srandom(unsigned int seed); | ||
| 400 | +#endif | ||
| 401 | + | ||
| 402 | +#ifndef HAVE_SSL_GET_CURRENT_COMPRESSION | ||
| 403 | +#define SSL_get_current_compression(x) 0 | ||
| 404 | +#endif | ||
| 405 | + | ||
| 406 | +/* thread.h */ | ||
| 407 | +extern char *pqStrerror(int errnum, char *strerrbuf, size_t buflen); | ||
| 408 | + | ||
| 409 | +#ifndef WIN32 | ||
| 410 | +extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, | ||
| 411 | + size_t buflen, struct passwd **result); | ||
| 412 | +#endif | ||
| 413 | + | ||
| 414 | +extern int pqGethostbyname(const char *name, | ||
| 415 | + struct hostent *resultbuf, | ||
| 416 | + char *buffer, size_t buflen, | ||
| 417 | + struct hostent **result, | ||
| 418 | + int *herrno); | ||
| 419 | + | ||
| 420 | +extern void pg_qsort(void *base, size_t nel, size_t elsize, | ||
| 421 | + int (*cmp) (const void *, const void *)); | ||
| 422 | +extern int pg_qsort_strcmp(const void *a, const void *b); | ||
| 423 | + | ||
| 424 | +#define qsort(a,b,c,d) pg_qsort(a,b,c,d) | ||
| 425 | + | ||
| 426 | +typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); | ||
| 427 | + | ||
| 428 | +extern void qsort_arg(void *base, size_t nel, size_t elsize, | ||
| 429 | + qsort_arg_comparator cmp, void *arg); | ||
| 430 | + | ||
| 431 | +/* port/chklocale.c */ | ||
| 432 | +extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); | ||
| 433 | + | ||
| 434 | +#if defined(WIN32) && !defined(FRONTEND) | ||
| 435 | +extern int pg_codepage_to_encoding(UINT cp); | ||
| 436 | +#endif | ||
| 437 | + | ||
| 438 | +/* port/inet_net_ntop.c */ | ||
| 439 | +extern char *inet_net_ntop(int af, const void *src, int bits, | ||
| 440 | + char *dst, size_t size); | ||
| 441 | + | ||
| 442 | +/* port/pg_strong_random.c */ | ||
| 443 | +#ifdef HAVE_STRONG_RANDOM | ||
| 444 | +extern bool pg_strong_random(void *buf, size_t len); | ||
| 445 | +#endif | ||
| 446 | + | ||
| 447 | +/* port/pgcheckdir.c */ | ||
| 448 | +extern int pg_check_dir(const char *dir); | ||
| 449 | + | ||
| 450 | +/* port/pgmkdirp.c */ | ||
| 451 | +extern int pg_mkdir_p(char *path, int omode); | ||
| 452 | + | ||
| 453 | +/* port/pqsignal.c */ | ||
| 454 | +typedef void (*pqsigfunc) (int signo); | ||
| 455 | +extern pqsigfunc pqsignal(int signo, pqsigfunc func); | ||
| 456 | +#ifndef WIN32 | ||
| 457 | +extern pqsigfunc pqsignal_no_restart(int signo, pqsigfunc func); | ||
| 458 | +#else | ||
| 459 | +#define pqsignal_no_restart(signo, func) pqsignal(signo, func) | ||
| 460 | +#endif | ||
| 461 | + | ||
| 462 | +/* port/quotes.c */ | ||
| 463 | +extern char *escape_single_quotes_ascii(const char *src); | ||
| 464 | + | ||
| 465 | +/* port/wait_error.c */ | ||
| 466 | +extern char *wait_result_to_str(int exit_status); | ||
| 467 | + | ||
| 468 | +#endif /* PG_PORT_H */ |
pgsql/include/internal/postgres_fe.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * postgres_fe.h | ||
| 4 | + * Primary include file for PostgreSQL client-side .c files | ||
| 5 | + * | ||
| 6 | + * This should be the first file included by PostgreSQL client libraries and | ||
| 7 | + * application programs --- but not by backend modules, which should include | ||
| 8 | + * postgres.h. | ||
| 9 | + * | ||
| 10 | + * | ||
| 11 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 12 | + * Portions Copyright (c) 1995, Regents of the University of California | ||
| 13 | + * | ||
| 14 | + * src/include/postgres_fe.h | ||
| 15 | + * | ||
| 16 | + *------------------------------------------------------------------------- | ||
| 17 | + */ | ||
| 18 | +#ifndef POSTGRES_FE_H | ||
| 19 | +#define POSTGRES_FE_H | ||
| 20 | + | ||
| 21 | +#ifndef FRONTEND | ||
| 22 | +#define FRONTEND 1 | ||
| 23 | +#endif | ||
| 24 | + | ||
| 25 | +#include "c.h" | ||
| 26 | + | ||
| 27 | +#include "common/fe_memutils.h" | ||
| 28 | + | ||
| 29 | +#endif /* POSTGRES_FE_H */ |
pgsql/include/internal/pqexpbuffer.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * pqexpbuffer.h | ||
| 4 | + * Declarations/definitions for "PQExpBuffer" functions. | ||
| 5 | + * | ||
| 6 | + * PQExpBuffer provides an indefinitely-extensible string data type. | ||
| 7 | + * It can be used to buffer either ordinary C strings (null-terminated text) | ||
| 8 | + * or arbitrary binary data. All storage is allocated with malloc(). | ||
| 9 | + * | ||
| 10 | + * This module is essentially the same as the backend's StringInfo data type, | ||
| 11 | + * but it is intended for use in frontend libpq and client applications. | ||
| 12 | + * Thus, it does not rely on palloc() nor elog(). | ||
| 13 | + * | ||
| 14 | + * It does rely on vsnprintf(); if configure finds that libc doesn't provide | ||
| 15 | + * a usable vsnprintf(), then a copy of our own implementation of it will | ||
| 16 | + * be linked into libpq. | ||
| 17 | + * | ||
| 18 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 19 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 20 | + * | ||
| 21 | + * src/interfaces/libpq/pqexpbuffer.h | ||
| 22 | + * | ||
| 23 | + *------------------------------------------------------------------------- | ||
| 24 | + */ | ||
| 25 | +#ifndef PQEXPBUFFER_H | ||
| 26 | +#define PQEXPBUFFER_H | ||
| 27 | + | ||
| 28 | +/*------------------------- | ||
| 29 | + * PQExpBufferData holds information about an extensible string. | ||
| 30 | + * data is the current buffer for the string (allocated with malloc). | ||
| 31 | + * len is the current string length. There is guaranteed to be | ||
| 32 | + * a terminating '\0' at data[len], although this is not very | ||
| 33 | + * useful when the string holds binary data rather than text. | ||
| 34 | + * maxlen is the allocated size in bytes of 'data', i.e. the maximum | ||
| 35 | + * string size (including the terminating '\0' char) that we can | ||
| 36 | + * currently store in 'data' without having to reallocate | ||
| 37 | + * more space. We must always have maxlen > len. | ||
| 38 | + * | ||
| 39 | + * An exception occurs if we failed to allocate enough memory for the string | ||
| 40 | + * buffer. In that case data points to a statically allocated empty string, | ||
| 41 | + * and len = maxlen = 0. | ||
| 42 | + *------------------------- | ||
| 43 | + */ | ||
| 44 | +typedef struct PQExpBufferData | ||
| 45 | +{ | ||
| 46 | + char *data; | ||
| 47 | + size_t len; | ||
| 48 | + size_t maxlen; | ||
| 49 | +} PQExpBufferData; | ||
| 50 | + | ||
| 51 | +typedef PQExpBufferData *PQExpBuffer; | ||
| 52 | + | ||
| 53 | +/*------------------------ | ||
| 54 | + * Test for a broken (out of memory) PQExpBuffer. | ||
| 55 | + * When a buffer is "broken", all operations except resetting or deleting it | ||
| 56 | + * are no-ops. | ||
| 57 | + *------------------------ | ||
| 58 | + */ | ||
| 59 | +#define PQExpBufferBroken(str) \ | ||
| 60 | + ((str) == NULL || (str)->maxlen == 0) | ||
| 61 | + | ||
| 62 | +/*------------------------ | ||
| 63 | + * Same, but for use when using a static or local PQExpBufferData struct. | ||
| 64 | + * For that, a null-pointer test is useless and may draw compiler warnings. | ||
| 65 | + *------------------------ | ||
| 66 | + */ | ||
| 67 | +#define PQExpBufferDataBroken(buf) \ | ||
| 68 | + ((buf).maxlen == 0) | ||
| 69 | + | ||
| 70 | +/*------------------------ | ||
| 71 | + * Initial size of the data buffer in a PQExpBuffer. | ||
| 72 | + * NB: this must be large enough to hold error messages that might | ||
| 73 | + * be returned by PQrequestCancel(). | ||
| 74 | + *------------------------ | ||
| 75 | + */ | ||
| 76 | +#define INITIAL_EXPBUFFER_SIZE 256 | ||
| 77 | + | ||
| 78 | +/*------------------------ | ||
| 79 | + * There are two ways to create a PQExpBuffer object initially: | ||
| 80 | + * | ||
| 81 | + * PQExpBuffer stringptr = createPQExpBuffer(); | ||
| 82 | + * Both the PQExpBufferData and the data buffer are malloc'd. | ||
| 83 | + * | ||
| 84 | + * PQExpBufferData string; | ||
| 85 | + * initPQExpBuffer(&string); | ||
| 86 | + * The data buffer is malloc'd but the PQExpBufferData is presupplied. | ||
| 87 | + * This is appropriate if the PQExpBufferData is a field of another | ||
| 88 | + * struct. | ||
| 89 | + *------------------------- | ||
| 90 | + */ | ||
| 91 | + | ||
| 92 | +/*------------------------ | ||
| 93 | + * createPQExpBuffer | ||
| 94 | + * Create an empty 'PQExpBufferData' & return a pointer to it. | ||
| 95 | + */ | ||
| 96 | +extern PQExpBuffer createPQExpBuffer(void); | ||
| 97 | + | ||
| 98 | +/*------------------------ | ||
| 99 | + * initPQExpBuffer | ||
| 100 | + * Initialize a PQExpBufferData struct (with previously undefined contents) | ||
| 101 | + * to describe an empty string. | ||
| 102 | + */ | ||
| 103 | +extern void initPQExpBuffer(PQExpBuffer str); | ||
| 104 | + | ||
| 105 | +/*------------------------ | ||
| 106 | + * To destroy a PQExpBuffer, use either: | ||
| 107 | + * | ||
| 108 | + * destroyPQExpBuffer(str); | ||
| 109 | + * free()s both the data buffer and the PQExpBufferData. | ||
| 110 | + * This is the inverse of createPQExpBuffer(). | ||
| 111 | + * | ||
| 112 | + * termPQExpBuffer(str) | ||
| 113 | + * free()s the data buffer but not the PQExpBufferData itself. | ||
| 114 | + * This is the inverse of initPQExpBuffer(). | ||
| 115 | + * | ||
| 116 | + * NOTE: some routines build up a string using PQExpBuffer, and then | ||
| 117 | + * release the PQExpBufferData but return the data string itself to their | ||
| 118 | + * caller. At that point the data string looks like a plain malloc'd | ||
| 119 | + * string. | ||
| 120 | + */ | ||
| 121 | +extern void destroyPQExpBuffer(PQExpBuffer str); | ||
| 122 | +extern void termPQExpBuffer(PQExpBuffer str); | ||
| 123 | + | ||
| 124 | +/*------------------------ | ||
| 125 | + * resetPQExpBuffer | ||
| 126 | + * Reset a PQExpBuffer to empty | ||
| 127 | + * | ||
| 128 | + * Note: if possible, a "broken" PQExpBuffer is returned to normal. | ||
| 129 | + */ | ||
| 130 | +extern void resetPQExpBuffer(PQExpBuffer str); | ||
| 131 | + | ||
| 132 | +/*------------------------ | ||
| 133 | + * enlargePQExpBuffer | ||
| 134 | + * Make sure there is enough space for 'needed' more bytes in the buffer | ||
| 135 | + * ('needed' does not include the terminating null). | ||
| 136 | + * | ||
| 137 | + * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case | ||
| 138 | + * the buffer is left in "broken" state.) | ||
| 139 | + */ | ||
| 140 | +extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed); | ||
| 141 | + | ||
| 142 | +/*------------------------ | ||
| 143 | + * printfPQExpBuffer | ||
| 144 | + * Format text data under the control of fmt (an sprintf-like format string) | ||
| 145 | + * and insert it into str. More space is allocated to str if necessary. | ||
| 146 | + * This is a convenience routine that does the same thing as | ||
| 147 | + * resetPQExpBuffer() followed by appendPQExpBuffer(). | ||
| 148 | + */ | ||
| 149 | +extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); | ||
| 150 | + | ||
| 151 | +/*------------------------ | ||
| 152 | + * appendPQExpBuffer | ||
| 153 | + * Format text data under the control of fmt (an sprintf-like format string) | ||
| 154 | + * and append it to whatever is already in str. More space is allocated | ||
| 155 | + * to str if necessary. This is sort of like a combination of sprintf and | ||
| 156 | + * strcat. | ||
| 157 | + */ | ||
| 158 | +extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); | ||
| 159 | + | ||
| 160 | +/*------------------------ | ||
| 161 | + * appendPQExpBufferStr | ||
| 162 | + * Append the given string to a PQExpBuffer, allocating more space | ||
| 163 | + * if necessary. | ||
| 164 | + */ | ||
| 165 | +extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); | ||
| 166 | + | ||
| 167 | +/*------------------------ | ||
| 168 | + * appendPQExpBufferChar | ||
| 169 | + * Append a single byte to str. | ||
| 170 | + * Like appendPQExpBuffer(str, "%c", ch) but much faster. | ||
| 171 | + */ | ||
| 172 | +extern void appendPQExpBufferChar(PQExpBuffer str, char ch); | ||
| 173 | + | ||
| 174 | +/*------------------------ | ||
| 175 | + * appendBinaryPQExpBuffer | ||
| 176 | + * Append arbitrary binary data to a PQExpBuffer, allocating more space | ||
| 177 | + * if necessary. | ||
| 178 | + */ | ||
| 179 | +extern void appendBinaryPQExpBuffer(PQExpBuffer str, | ||
| 180 | + const char *data, size_t datalen); | ||
| 181 | + | ||
| 182 | +#endif /* PQEXPBUFFER_H */ |
pgsql/include/libpq-events.h
0 → 100644
| 1 | +/*------------------------------------------------------------------------- | ||
| 2 | + * | ||
| 3 | + * libpq-events.h | ||
| 4 | + * This file contains definitions that are useful to applications | ||
| 5 | + * that invoke the libpq "events" API, but are not interesting to | ||
| 6 | + * ordinary users of libpq. | ||
| 7 | + * | ||
| 8 | + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group | ||
| 9 | + * Portions Copyright (c) 1994, Regents of the University of California | ||
| 10 | + * | ||
| 11 | + * src/interfaces/libpq/libpq-events.h | ||
| 12 | + * | ||
| 13 | + *------------------------------------------------------------------------- | ||
| 14 | + */ | ||
| 15 | + | ||
| 16 | +#ifndef LIBPQ_EVENTS_H | ||
| 17 | +#define LIBPQ_EVENTS_H | ||
| 18 | + | ||
| 19 | +#include "libpq-fe.h" | ||
| 20 | + | ||
| 21 | +#ifdef __cplusplus | ||
| 22 | +extern "C" | ||
| 23 | +{ | ||
| 24 | +#endif | ||
| 25 | + | ||
| 26 | +/* Callback Event Ids */ | ||
| 27 | +typedef enum | ||
| 28 | +{ | ||
| 29 | + PGEVT_REGISTER, | ||
| 30 | + PGEVT_CONNRESET, | ||
| 31 | + PGEVT_CONNDESTROY, | ||
| 32 | + PGEVT_RESULTCREATE, | ||
| 33 | + PGEVT_RESULTCOPY, | ||
| 34 | + PGEVT_RESULTDESTROY | ||
| 35 | +} PGEventId; | ||
| 36 | + | ||
| 37 | +typedef struct | ||
| 38 | +{ | ||
| 39 | + PGconn *conn; | ||
| 40 | +} PGEventRegister; | ||
| 41 | + | ||
| 42 | +typedef struct | ||
| 43 | +{ | ||
| 44 | + PGconn *conn; | ||
| 45 | +} PGEventConnReset; | ||
| 46 | + | ||
| 47 | +typedef struct | ||
| 48 | +{ | ||
| 49 | + PGconn *conn; | ||
| 50 | +} PGEventConnDestroy; | ||
| 51 | + | ||
| 52 | +typedef struct | ||
| 53 | +{ | ||
| 54 | + PGconn *conn; | ||
| 55 | + PGresult *result; | ||
| 56 | +} PGEventResultCreate; | ||
| 57 | + | ||
| 58 | +typedef struct | ||
| 59 | +{ | ||
| 60 | + const PGresult *src; | ||
| 61 | + PGresult *dest; | ||
| 62 | +} PGEventResultCopy; | ||
| 63 | + | ||
| 64 | +typedef struct | ||
| 65 | +{ | ||
| 66 | + PGresult *result; | ||
| 67 | +} PGEventResultDestroy; | ||
| 68 | + | ||
| 69 | +typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); | ||
| 70 | + | ||
| 71 | +/* Registers an event proc with the given PGconn. */ | ||
| 72 | +extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, | ||
| 73 | + const char *name, void *passThrough); | ||
| 74 | + | ||
| 75 | +/* Sets the PGconn instance data for the provided proc to data. */ | ||
| 76 | +extern int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); | ||
| 77 | + | ||
| 78 | +/* Gets the PGconn instance data for the provided proc. */ | ||
| 79 | +extern void *PQinstanceData(const PGconn *conn, PGEventProc proc); | ||
| 80 | + | ||
| 81 | +/* Sets the PGresult instance data for the provided proc to data. */ | ||
| 82 | +extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data); | ||
| 83 | + | ||
| 84 | +/* Gets the PGresult instance data for the provided proc. */ | ||
| 85 | +extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); | ||
| 86 | + | ||
| 87 | +/* Fires RESULTCREATE events for an application-created PGresult. */ | ||
| 88 | +extern int PQfireResultCreateEvents(PGconn *conn, PGresult *res); | ||
| 89 | + | ||
| 90 | +#ifdef __cplusplus | ||
| 91 | +} | ||
| 92 | +#endif | ||
| 93 | + | ||
| 94 | +#endif /* LIBPQ_EVENTS_H */ |
请
注册
或
登录
后发表评论