正在显示
63 个修改的文件
包含
4632 行增加
和
0 行删除
.gitignore
0 → 100644
1 | +build/* | |
\ No newline at end of file | ... | ... |
.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 | +} | |
\ No newline at end of file | ... | ... |
.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 | +} | |
\ No newline at end of file | ... | ... |
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) | |
\ No newline at end of file | ... | ... |
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 | +} | |
\ No newline at end of file | ... | ... |
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 | + ) | |
\ No newline at end of file | ... | ... |
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 */ | ... | ... |
请
注册
或
登录
后发表评论