diff options
author | Alexander Smirnov <alex@ydb.tech> | 2024-04-16 09:11:59 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2024-04-16 09:11:59 +0000 |
commit | 25de1d521ca218e2b040739fea77a39e9fc543e9 (patch) | |
tree | 21521d8866cf1462dbd52c071cf369974c29650e /contrib/libs/libpq/src | |
parent | bf444b8ed4d0f6bf17fd753e2cf88f9440012e87 (diff) | |
parent | 0a63d9ddc516f206f2b8745ce5e5dfa60190d755 (diff) | |
download | ydb-25de1d521ca218e2b040739fea77a39e9fc543e9.tar.gz |
Merge branch 'rightlib' into mergelibs-240416-0910
Diffstat (limited to 'contrib/libs/libpq/src')
214 files changed, 0 insertions, 77746 deletions
diff --git a/contrib/libs/libpq/src/backend/catalog/pg_tablespace_d.h b/contrib/libs/libpq/src/backend/catalog/pg_tablespace_d.h deleted file mode 100644 index 064e58d758..0000000000 --- a/contrib/libs/libpq/src/backend/catalog/pg_tablespace_d.h +++ /dev/null @@ -1,38 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_tablespace_d.h - * Macro definitions for pg_tablespace - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * NOTES - * ****************************** - * *** DO NOT EDIT THIS FILE! *** - * ****************************** - * - * It has been GENERATED by src/backend/catalog/genbki.pl - * - *------------------------------------------------------------------------- - */ -#ifndef PG_TABLESPACE_D_H -#define PG_TABLESPACE_D_H - -#define TableSpaceRelationId 1213 -#define PgTablespaceToastTable 4185 -#define PgTablespaceToastIndex 4186 -#define TablespaceOidIndexId 2697 -#define TablespaceNameIndexId 2698 - -#define Anum_pg_tablespace_oid 1 -#define Anum_pg_tablespace_spcname 2 -#define Anum_pg_tablespace_spcowner 3 -#define Anum_pg_tablespace_spcacl 4 -#define Anum_pg_tablespace_spcoptions 5 - -#define Natts_pg_tablespace 5 - -#define DEFAULTTABLESPACE_OID 1663 -#define GLOBALTABLESPACE_OID 1664 - -#endif /* PG_TABLESPACE_D_H */ diff --git a/contrib/libs/libpq/src/backend/utils/README.Gen_dummy_probes b/contrib/libs/libpq/src/backend/utils/README.Gen_dummy_probes deleted file mode 100644 index e17060ef24..0000000000 --- a/contrib/libs/libpq/src/backend/utils/README.Gen_dummy_probes +++ /dev/null @@ -1,27 +0,0 @@ -# Generating dummy probes - -If Postgres isn't configured with dtrace enabled, we need to generate -dummy probes for the entries in probes.d, that do nothing. - -This is accomplished in Unix via the sed script `Gen_dummy_probes.sed`. We -used to use this in MSVC builds using the perl utility `psed`, which mimicked -sed. However, that utility disappeared from Windows perl distributions and so -we converted the sed script to a perl script to be used in MSVC builds. - -We still keep the sed script as the authoritative source for generating -these dummy probes because except on Windows perl is not a hard requirement -when building from a tarball. - -So, if you need to change the way dummy probes are generated, first change -the sed script, and when it's working generate the perl script. This can -be accomplished by using the perl utility s2p. - -s2p is no longer part of the perl core, so it might not be on your system, -but it is available on CPAN and also in many package systems. e.g. -on Fedora it can be installed using `cpan App::s2p` or -`dnf install perl-App-s2p`. - -The Makefile contains a recipe for regenerating Gen_dummy_probes.pl, so all -you need to do is once you have s2p installed is `make Gen_dummy_probes.pl` -Note that in a VPATH build this will generate the file in the vpath tree, -not the source tree. diff --git a/contrib/libs/libpq/src/backend/utils/errcodes.h b/contrib/libs/libpq/src/backend/utils/errcodes.h deleted file mode 100644 index a2f604c2fa..0000000000 --- a/contrib/libs/libpq/src/backend/utils/errcodes.h +++ /dev/null @@ -1,354 +0,0 @@ -/* autogenerated from src/backend/utils/errcodes.txt, do not edit */ -/* there is deliberately not an #ifndef ERRCODES_H here */ - -/* Class 00 - Successful Completion */ -#define ERRCODE_SUCCESSFUL_COMPLETION MAKE_SQLSTATE('0','0','0','0','0') - -/* Class 01 - Warning */ -#define ERRCODE_WARNING MAKE_SQLSTATE('0','1','0','0','0') -#define ERRCODE_WARNING_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','1','0','0','C') -#define ERRCODE_WARNING_IMPLICIT_ZERO_BIT_PADDING MAKE_SQLSTATE('0','1','0','0','8') -#define ERRCODE_WARNING_NULL_VALUE_ELIMINATED_IN_SET_FUNCTION MAKE_SQLSTATE('0','1','0','0','3') -#define ERRCODE_WARNING_PRIVILEGE_NOT_GRANTED MAKE_SQLSTATE('0','1','0','0','7') -#define ERRCODE_WARNING_PRIVILEGE_NOT_REVOKED MAKE_SQLSTATE('0','1','0','0','6') -#define ERRCODE_WARNING_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('0','1','0','0','4') -#define ERRCODE_WARNING_DEPRECATED_FEATURE MAKE_SQLSTATE('0','1','P','0','1') - -/* Class 02 - No Data (this is also a warning class per the SQL standard) */ -#define ERRCODE_NO_DATA MAKE_SQLSTATE('0','2','0','0','0') -#define ERRCODE_NO_ADDITIONAL_DYNAMIC_RESULT_SETS_RETURNED MAKE_SQLSTATE('0','2','0','0','1') - -/* Class 03 - SQL Statement Not Yet Complete */ -#define ERRCODE_SQL_STATEMENT_NOT_YET_COMPLETE MAKE_SQLSTATE('0','3','0','0','0') - -/* Class 08 - Connection Exception */ -#define ERRCODE_CONNECTION_EXCEPTION MAKE_SQLSTATE('0','8','0','0','0') -#define ERRCODE_CONNECTION_DOES_NOT_EXIST MAKE_SQLSTATE('0','8','0','0','3') -#define ERRCODE_CONNECTION_FAILURE MAKE_SQLSTATE('0','8','0','0','6') -#define ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','1') -#define ERRCODE_SQLSERVER_REJECTED_ESTABLISHMENT_OF_SQLCONNECTION MAKE_SQLSTATE('0','8','0','0','4') -#define ERRCODE_TRANSACTION_RESOLUTION_UNKNOWN MAKE_SQLSTATE('0','8','0','0','7') -#define ERRCODE_PROTOCOL_VIOLATION MAKE_SQLSTATE('0','8','P','0','1') - -/* Class 09 - Triggered Action Exception */ -#define ERRCODE_TRIGGERED_ACTION_EXCEPTION MAKE_SQLSTATE('0','9','0','0','0') - -/* Class 0A - Feature Not Supported */ -#define ERRCODE_FEATURE_NOT_SUPPORTED MAKE_SQLSTATE('0','A','0','0','0') - -/* Class 0B - Invalid Transaction Initiation */ -#define ERRCODE_INVALID_TRANSACTION_INITIATION MAKE_SQLSTATE('0','B','0','0','0') - -/* Class 0F - Locator Exception */ -#define ERRCODE_LOCATOR_EXCEPTION MAKE_SQLSTATE('0','F','0','0','0') -#define ERRCODE_L_E_INVALID_SPECIFICATION MAKE_SQLSTATE('0','F','0','0','1') - -/* Class 0L - Invalid Grantor */ -#define ERRCODE_INVALID_GRANTOR MAKE_SQLSTATE('0','L','0','0','0') -#define ERRCODE_INVALID_GRANT_OPERATION MAKE_SQLSTATE('0','L','P','0','1') - -/* Class 0P - Invalid Role Specification */ -#define ERRCODE_INVALID_ROLE_SPECIFICATION MAKE_SQLSTATE('0','P','0','0','0') - -/* Class 0Z - Diagnostics Exception */ -#define ERRCODE_DIAGNOSTICS_EXCEPTION MAKE_SQLSTATE('0','Z','0','0','0') -#define ERRCODE_STACKED_DIAGNOSTICS_ACCESSED_WITHOUT_ACTIVE_HANDLER MAKE_SQLSTATE('0','Z','0','0','2') - -/* Class 20 - Case Not Found */ -#define ERRCODE_CASE_NOT_FOUND MAKE_SQLSTATE('2','0','0','0','0') - -/* Class 21 - Cardinality Violation */ -#define ERRCODE_CARDINALITY_VIOLATION MAKE_SQLSTATE('2','1','0','0','0') - -/* Class 22 - Data Exception */ -#define ERRCODE_DATA_EXCEPTION MAKE_SQLSTATE('2','2','0','0','0') -#define ERRCODE_ARRAY_ELEMENT_ERROR MAKE_SQLSTATE('2','2','0','2','E') -#define ERRCODE_ARRAY_SUBSCRIPT_ERROR MAKE_SQLSTATE('2','2','0','2','E') -#define ERRCODE_CHARACTER_NOT_IN_REPERTOIRE MAKE_SQLSTATE('2','2','0','2','1') -#define ERRCODE_DATETIME_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','0','8') -#define ERRCODE_DATETIME_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','8') -#define ERRCODE_DIVISION_BY_ZERO MAKE_SQLSTATE('2','2','0','1','2') -#define ERRCODE_ERROR_IN_ASSIGNMENT MAKE_SQLSTATE('2','2','0','0','5') -#define ERRCODE_ESCAPE_CHARACTER_CONFLICT MAKE_SQLSTATE('2','2','0','0','B') -#define ERRCODE_INDICATOR_OVERFLOW MAKE_SQLSTATE('2','2','0','2','2') -#define ERRCODE_INTERVAL_FIELD_OVERFLOW MAKE_SQLSTATE('2','2','0','1','5') -#define ERRCODE_INVALID_ARGUMENT_FOR_LOG MAKE_SQLSTATE('2','2','0','1','E') -#define ERRCODE_INVALID_ARGUMENT_FOR_NTILE MAKE_SQLSTATE('2','2','0','1','4') -#define ERRCODE_INVALID_ARGUMENT_FOR_NTH_VALUE MAKE_SQLSTATE('2','2','0','1','6') -#define ERRCODE_INVALID_ARGUMENT_FOR_POWER_FUNCTION MAKE_SQLSTATE('2','2','0','1','F') -#define ERRCODE_INVALID_ARGUMENT_FOR_WIDTH_BUCKET_FUNCTION MAKE_SQLSTATE('2','2','0','1','G') -#define ERRCODE_INVALID_CHARACTER_VALUE_FOR_CAST MAKE_SQLSTATE('2','2','0','1','8') -#define ERRCODE_INVALID_DATETIME_FORMAT MAKE_SQLSTATE('2','2','0','0','7') -#define ERRCODE_INVALID_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','1','9') -#define ERRCODE_INVALID_ESCAPE_OCTET MAKE_SQLSTATE('2','2','0','0','D') -#define ERRCODE_INVALID_ESCAPE_SEQUENCE MAKE_SQLSTATE('2','2','0','2','5') -#define ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','P','0','6') -#define ERRCODE_INVALID_INDICATOR_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','1','0') -#define ERRCODE_INVALID_PARAMETER_VALUE MAKE_SQLSTATE('2','2','0','2','3') -#define ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE MAKE_SQLSTATE('2','2','0','1','3') -#define ERRCODE_INVALID_REGULAR_EXPRESSION MAKE_SQLSTATE('2','2','0','1','B') -#define ERRCODE_INVALID_ROW_COUNT_IN_LIMIT_CLAUSE MAKE_SQLSTATE('2','2','0','1','W') -#define ERRCODE_INVALID_ROW_COUNT_IN_RESULT_OFFSET_CLAUSE MAKE_SQLSTATE('2','2','0','1','X') -#define ERRCODE_INVALID_TABLESAMPLE_ARGUMENT MAKE_SQLSTATE('2','2','0','2','H') -#define ERRCODE_INVALID_TABLESAMPLE_REPEAT MAKE_SQLSTATE('2','2','0','2','G') -#define ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE MAKE_SQLSTATE('2','2','0','0','9') -#define ERRCODE_INVALID_USE_OF_ESCAPE_CHARACTER MAKE_SQLSTATE('2','2','0','0','C') -#define ERRCODE_MOST_SPECIFIC_TYPE_MISMATCH MAKE_SQLSTATE('2','2','0','0','G') -#define ERRCODE_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('2','2','0','0','4') -#define ERRCODE_NULL_VALUE_NO_INDICATOR_PARAMETER MAKE_SQLSTATE('2','2','0','0','2') -#define ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE MAKE_SQLSTATE('2','2','0','0','3') -#define ERRCODE_SEQUENCE_GENERATOR_LIMIT_EXCEEDED MAKE_SQLSTATE('2','2','0','0','H') -#define ERRCODE_STRING_DATA_LENGTH_MISMATCH MAKE_SQLSTATE('2','2','0','2','6') -#define ERRCODE_STRING_DATA_RIGHT_TRUNCATION MAKE_SQLSTATE('2','2','0','0','1') -#define ERRCODE_SUBSTRING_ERROR MAKE_SQLSTATE('2','2','0','1','1') -#define ERRCODE_TRIM_ERROR MAKE_SQLSTATE('2','2','0','2','7') -#define ERRCODE_UNTERMINATED_C_STRING MAKE_SQLSTATE('2','2','0','2','4') -#define ERRCODE_ZERO_LENGTH_CHARACTER_STRING MAKE_SQLSTATE('2','2','0','0','F') -#define ERRCODE_FLOATING_POINT_EXCEPTION MAKE_SQLSTATE('2','2','P','0','1') -#define ERRCODE_INVALID_TEXT_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','2') -#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2','P','0','3') -#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2','P','0','4') -#define ERRCODE_UNTRANSLATABLE_CHARACTER MAKE_SQLSTATE('2','2','P','0','5') -#define ERRCODE_NOT_AN_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','L') -#define ERRCODE_INVALID_XML_DOCUMENT MAKE_SQLSTATE('2','2','0','0','M') -#define ERRCODE_INVALID_XML_CONTENT MAKE_SQLSTATE('2','2','0','0','N') -#define ERRCODE_INVALID_XML_COMMENT MAKE_SQLSTATE('2','2','0','0','S') -#define ERRCODE_INVALID_XML_PROCESSING_INSTRUCTION MAKE_SQLSTATE('2','2','0','0','T') -#define ERRCODE_DUPLICATE_JSON_OBJECT_KEY_VALUE MAKE_SQLSTATE('2','2','0','3','0') -#define ERRCODE_INVALID_ARGUMENT_FOR_SQL_JSON_DATETIME_FUNCTION MAKE_SQLSTATE('2','2','0','3','1') -#define ERRCODE_INVALID_JSON_TEXT MAKE_SQLSTATE('2','2','0','3','2') -#define ERRCODE_INVALID_SQL_JSON_SUBSCRIPT MAKE_SQLSTATE('2','2','0','3','3') -#define ERRCODE_MORE_THAN_ONE_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','4') -#define ERRCODE_NO_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','5') -#define ERRCODE_NON_NUMERIC_SQL_JSON_ITEM MAKE_SQLSTATE('2','2','0','3','6') -#define ERRCODE_NON_UNIQUE_KEYS_IN_A_JSON_OBJECT MAKE_SQLSTATE('2','2','0','3','7') -#define ERRCODE_SINGLETON_SQL_JSON_ITEM_REQUIRED MAKE_SQLSTATE('2','2','0','3','8') -#define ERRCODE_SQL_JSON_ARRAY_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','9') -#define ERRCODE_SQL_JSON_MEMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','A') -#define ERRCODE_SQL_JSON_NUMBER_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','B') -#define ERRCODE_SQL_JSON_OBJECT_NOT_FOUND MAKE_SQLSTATE('2','2','0','3','C') -#define ERRCODE_TOO_MANY_JSON_ARRAY_ELEMENTS MAKE_SQLSTATE('2','2','0','3','D') -#define ERRCODE_TOO_MANY_JSON_OBJECT_MEMBERS MAKE_SQLSTATE('2','2','0','3','E') -#define ERRCODE_SQL_JSON_SCALAR_REQUIRED MAKE_SQLSTATE('2','2','0','3','F') -#define ERRCODE_SQL_JSON_ITEM_CANNOT_BE_CAST_TO_TARGET_TYPE MAKE_SQLSTATE('2','2','0','3','G') - -/* Class 23 - Integrity Constraint Violation */ -#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3','0','0','0') -#define ERRCODE_RESTRICT_VIOLATION MAKE_SQLSTATE('2','3','0','0','1') -#define ERRCODE_NOT_NULL_VIOLATION MAKE_SQLSTATE('2','3','5','0','2') -#define ERRCODE_FOREIGN_KEY_VIOLATION MAKE_SQLSTATE('2','3','5','0','3') -#define ERRCODE_UNIQUE_VIOLATION MAKE_SQLSTATE('2','3','5','0','5') -#define ERRCODE_CHECK_VIOLATION MAKE_SQLSTATE('2','3','5','1','4') -#define ERRCODE_EXCLUSION_VIOLATION MAKE_SQLSTATE('2','3','P','0','1') - -/* Class 24 - Invalid Cursor State */ -#define ERRCODE_INVALID_CURSOR_STATE MAKE_SQLSTATE('2','4','0','0','0') - -/* Class 25 - Invalid Transaction State */ -#define ERRCODE_INVALID_TRANSACTION_STATE MAKE_SQLSTATE('2','5','0','0','0') -#define ERRCODE_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','1') -#define ERRCODE_BRANCH_TRANSACTION_ALREADY_ACTIVE MAKE_SQLSTATE('2','5','0','0','2') -#define ERRCODE_HELD_CURSOR_REQUIRES_SAME_ISOLATION_LEVEL MAKE_SQLSTATE('2','5','0','0','8') -#define ERRCODE_INAPPROPRIATE_ACCESS_MODE_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','3') -#define ERRCODE_INAPPROPRIATE_ISOLATION_LEVEL_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','4') -#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION_FOR_BRANCH_TRANSACTION MAKE_SQLSTATE('2','5','0','0','5') -#define ERRCODE_READ_ONLY_SQL_TRANSACTION MAKE_SQLSTATE('2','5','0','0','6') -#define ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED MAKE_SQLSTATE('2','5','0','0','7') -#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','1') -#define ERRCODE_IN_FAILED_SQL_TRANSACTION MAKE_SQLSTATE('2','5','P','0','2') -#define ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT MAKE_SQLSTATE('2','5','P','0','3') - -/* Class 26 - Invalid SQL Statement Name */ -#define ERRCODE_INVALID_SQL_STATEMENT_NAME MAKE_SQLSTATE('2','6','0','0','0') - -/* Class 27 - Triggered Data Change Violation */ -#define ERRCODE_TRIGGERED_DATA_CHANGE_VIOLATION MAKE_SQLSTATE('2','7','0','0','0') - -/* Class 28 - Invalid Authorization Specification */ -#define ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION MAKE_SQLSTATE('2','8','0','0','0') -#define ERRCODE_INVALID_PASSWORD MAKE_SQLSTATE('2','8','P','0','1') - -/* Class 2B - Dependent Privilege Descriptors Still Exist */ -#define ERRCODE_DEPENDENT_PRIVILEGE_DESCRIPTORS_STILL_EXIST MAKE_SQLSTATE('2','B','0','0','0') -#define ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST MAKE_SQLSTATE('2','B','P','0','1') - -/* Class 2D - Invalid Transaction Termination */ -#define ERRCODE_INVALID_TRANSACTION_TERMINATION MAKE_SQLSTATE('2','D','0','0','0') - -/* Class 2F - SQL Routine Exception */ -#define ERRCODE_SQL_ROUTINE_EXCEPTION MAKE_SQLSTATE('2','F','0','0','0') -#define ERRCODE_S_R_E_FUNCTION_EXECUTED_NO_RETURN_STATEMENT MAKE_SQLSTATE('2','F','0','0','5') -#define ERRCODE_S_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','2') -#define ERRCODE_S_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('2','F','0','0','3') -#define ERRCODE_S_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('2','F','0','0','4') - -/* Class 34 - Invalid Cursor Name */ -#define ERRCODE_INVALID_CURSOR_NAME MAKE_SQLSTATE('3','4','0','0','0') - -/* Class 38 - External Routine Exception */ -#define ERRCODE_EXTERNAL_ROUTINE_EXCEPTION MAKE_SQLSTATE('3','8','0','0','0') -#define ERRCODE_E_R_E_CONTAINING_SQL_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','1') -#define ERRCODE_E_R_E_MODIFYING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','2') -#define ERRCODE_E_R_E_PROHIBITED_SQL_STATEMENT_ATTEMPTED MAKE_SQLSTATE('3','8','0','0','3') -#define ERRCODE_E_R_E_READING_SQL_DATA_NOT_PERMITTED MAKE_SQLSTATE('3','8','0','0','4') - -/* Class 39 - External Routine Invocation Exception */ -#define ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION MAKE_SQLSTATE('3','9','0','0','0') -#define ERRCODE_E_R_I_E_INVALID_SQLSTATE_RETURNED MAKE_SQLSTATE('3','9','0','0','1') -#define ERRCODE_E_R_I_E_NULL_VALUE_NOT_ALLOWED MAKE_SQLSTATE('3','9','0','0','4') -#define ERRCODE_E_R_I_E_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','1') -#define ERRCODE_E_R_I_E_SRF_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','2') -#define ERRCODE_E_R_I_E_EVENT_TRIGGER_PROTOCOL_VIOLATED MAKE_SQLSTATE('3','9','P','0','3') - -/* Class 3B - Savepoint Exception */ -#define ERRCODE_SAVEPOINT_EXCEPTION MAKE_SQLSTATE('3','B','0','0','0') -#define ERRCODE_S_E_INVALID_SPECIFICATION MAKE_SQLSTATE('3','B','0','0','1') - -/* Class 3D - Invalid Catalog Name */ -#define ERRCODE_INVALID_CATALOG_NAME MAKE_SQLSTATE('3','D','0','0','0') - -/* Class 3F - Invalid Schema Name */ -#define ERRCODE_INVALID_SCHEMA_NAME MAKE_SQLSTATE('3','F','0','0','0') - -/* Class 40 - Transaction Rollback */ -#define ERRCODE_TRANSACTION_ROLLBACK MAKE_SQLSTATE('4','0','0','0','0') -#define ERRCODE_T_R_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('4','0','0','0','2') -#define ERRCODE_T_R_SERIALIZATION_FAILURE MAKE_SQLSTATE('4','0','0','0','1') -#define ERRCODE_T_R_STATEMENT_COMPLETION_UNKNOWN MAKE_SQLSTATE('4','0','0','0','3') -#define ERRCODE_T_R_DEADLOCK_DETECTED MAKE_SQLSTATE('4','0','P','0','1') - -/* Class 42 - Syntax Error or Access Rule Violation */ -#define ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION MAKE_SQLSTATE('4','2','0','0','0') -#define ERRCODE_SYNTAX_ERROR MAKE_SQLSTATE('4','2','6','0','1') -#define ERRCODE_INSUFFICIENT_PRIVILEGE MAKE_SQLSTATE('4','2','5','0','1') -#define ERRCODE_CANNOT_COERCE MAKE_SQLSTATE('4','2','8','4','6') -#define ERRCODE_GROUPING_ERROR MAKE_SQLSTATE('4','2','8','0','3') -#define ERRCODE_WINDOWING_ERROR MAKE_SQLSTATE('4','2','P','2','0') -#define ERRCODE_INVALID_RECURSION MAKE_SQLSTATE('4','2','P','1','9') -#define ERRCODE_INVALID_FOREIGN_KEY MAKE_SQLSTATE('4','2','8','3','0') -#define ERRCODE_INVALID_NAME MAKE_SQLSTATE('4','2','6','0','2') -#define ERRCODE_NAME_TOO_LONG MAKE_SQLSTATE('4','2','6','2','2') -#define ERRCODE_RESERVED_NAME MAKE_SQLSTATE('4','2','9','3','9') -#define ERRCODE_DATATYPE_MISMATCH MAKE_SQLSTATE('4','2','8','0','4') -#define ERRCODE_INDETERMINATE_DATATYPE MAKE_SQLSTATE('4','2','P','1','8') -#define ERRCODE_COLLATION_MISMATCH MAKE_SQLSTATE('4','2','P','2','1') -#define ERRCODE_INDETERMINATE_COLLATION MAKE_SQLSTATE('4','2','P','2','2') -#define ERRCODE_WRONG_OBJECT_TYPE MAKE_SQLSTATE('4','2','8','0','9') -#define ERRCODE_GENERATED_ALWAYS MAKE_SQLSTATE('4','2','8','C','9') -#define ERRCODE_UNDEFINED_COLUMN MAKE_SQLSTATE('4','2','7','0','3') -#define ERRCODE_UNDEFINED_CURSOR MAKE_SQLSTATE('3','4','0','0','0') -#define ERRCODE_UNDEFINED_DATABASE MAKE_SQLSTATE('3','D','0','0','0') -#define ERRCODE_UNDEFINED_FUNCTION MAKE_SQLSTATE('4','2','8','8','3') -#define ERRCODE_UNDEFINED_PSTATEMENT MAKE_SQLSTATE('2','6','0','0','0') -#define ERRCODE_UNDEFINED_SCHEMA MAKE_SQLSTATE('3','F','0','0','0') -#define ERRCODE_UNDEFINED_TABLE MAKE_SQLSTATE('4','2','P','0','1') -#define ERRCODE_UNDEFINED_PARAMETER MAKE_SQLSTATE('4','2','P','0','2') -#define ERRCODE_UNDEFINED_OBJECT MAKE_SQLSTATE('4','2','7','0','4') -#define ERRCODE_DUPLICATE_COLUMN MAKE_SQLSTATE('4','2','7','0','1') -#define ERRCODE_DUPLICATE_CURSOR MAKE_SQLSTATE('4','2','P','0','3') -#define ERRCODE_DUPLICATE_DATABASE MAKE_SQLSTATE('4','2','P','0','4') -#define ERRCODE_DUPLICATE_FUNCTION MAKE_SQLSTATE('4','2','7','2','3') -#define ERRCODE_DUPLICATE_PSTATEMENT MAKE_SQLSTATE('4','2','P','0','5') -#define ERRCODE_DUPLICATE_SCHEMA MAKE_SQLSTATE('4','2','P','0','6') -#define ERRCODE_DUPLICATE_TABLE MAKE_SQLSTATE('4','2','P','0','7') -#define ERRCODE_DUPLICATE_ALIAS MAKE_SQLSTATE('4','2','7','1','2') -#define ERRCODE_DUPLICATE_OBJECT MAKE_SQLSTATE('4','2','7','1','0') -#define ERRCODE_AMBIGUOUS_COLUMN MAKE_SQLSTATE('4','2','7','0','2') -#define ERRCODE_AMBIGUOUS_FUNCTION MAKE_SQLSTATE('4','2','7','2','5') -#define ERRCODE_AMBIGUOUS_PARAMETER MAKE_SQLSTATE('4','2','P','0','8') -#define ERRCODE_AMBIGUOUS_ALIAS MAKE_SQLSTATE('4','2','P','0','9') -#define ERRCODE_INVALID_COLUMN_REFERENCE MAKE_SQLSTATE('4','2','P','1','0') -#define ERRCODE_INVALID_COLUMN_DEFINITION MAKE_SQLSTATE('4','2','6','1','1') -#define ERRCODE_INVALID_CURSOR_DEFINITION MAKE_SQLSTATE('4','2','P','1','1') -#define ERRCODE_INVALID_DATABASE_DEFINITION MAKE_SQLSTATE('4','2','P','1','2') -#define ERRCODE_INVALID_FUNCTION_DEFINITION MAKE_SQLSTATE('4','2','P','1','3') -#define ERRCODE_INVALID_PSTATEMENT_DEFINITION MAKE_SQLSTATE('4','2','P','1','4') -#define ERRCODE_INVALID_SCHEMA_DEFINITION MAKE_SQLSTATE('4','2','P','1','5') -#define ERRCODE_INVALID_TABLE_DEFINITION MAKE_SQLSTATE('4','2','P','1','6') -#define ERRCODE_INVALID_OBJECT_DEFINITION MAKE_SQLSTATE('4','2','P','1','7') - -/* Class 44 - WITH CHECK OPTION Violation */ -#define ERRCODE_WITH_CHECK_OPTION_VIOLATION MAKE_SQLSTATE('4','4','0','0','0') - -/* Class 53 - Insufficient Resources */ -#define ERRCODE_INSUFFICIENT_RESOURCES MAKE_SQLSTATE('5','3','0','0','0') -#define ERRCODE_DISK_FULL MAKE_SQLSTATE('5','3','1','0','0') -#define ERRCODE_OUT_OF_MEMORY MAKE_SQLSTATE('5','3','2','0','0') -#define ERRCODE_TOO_MANY_CONNECTIONS MAKE_SQLSTATE('5','3','3','0','0') -#define ERRCODE_CONFIGURATION_LIMIT_EXCEEDED MAKE_SQLSTATE('5','3','4','0','0') - -/* Class 54 - Program Limit Exceeded */ -#define ERRCODE_PROGRAM_LIMIT_EXCEEDED MAKE_SQLSTATE('5','4','0','0','0') -#define ERRCODE_STATEMENT_TOO_COMPLEX MAKE_SQLSTATE('5','4','0','0','1') -#define ERRCODE_TOO_MANY_COLUMNS MAKE_SQLSTATE('5','4','0','1','1') -#define ERRCODE_TOO_MANY_ARGUMENTS MAKE_SQLSTATE('5','4','0','2','3') - -/* Class 55 - Object Not In Prerequisite State */ -#define ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE MAKE_SQLSTATE('5','5','0','0','0') -#define ERRCODE_OBJECT_IN_USE MAKE_SQLSTATE('5','5','0','0','6') -#define ERRCODE_CANT_CHANGE_RUNTIME_PARAM MAKE_SQLSTATE('5','5','P','0','2') -#define ERRCODE_LOCK_NOT_AVAILABLE MAKE_SQLSTATE('5','5','P','0','3') -#define ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE MAKE_SQLSTATE('5','5','P','0','4') - -/* Class 57 - Operator Intervention */ -#define ERRCODE_OPERATOR_INTERVENTION MAKE_SQLSTATE('5','7','0','0','0') -#define ERRCODE_QUERY_CANCELED MAKE_SQLSTATE('5','7','0','1','4') -#define ERRCODE_ADMIN_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','1') -#define ERRCODE_CRASH_SHUTDOWN MAKE_SQLSTATE('5','7','P','0','2') -#define ERRCODE_CANNOT_CONNECT_NOW MAKE_SQLSTATE('5','7','P','0','3') -#define ERRCODE_DATABASE_DROPPED MAKE_SQLSTATE('5','7','P','0','4') -#define ERRCODE_IDLE_SESSION_TIMEOUT MAKE_SQLSTATE('5','7','P','0','5') - -/* Class 58 - System Error (errors external to PostgreSQL itself) */ -#define ERRCODE_SYSTEM_ERROR MAKE_SQLSTATE('5','8','0','0','0') -#define ERRCODE_IO_ERROR MAKE_SQLSTATE('5','8','0','3','0') -#define ERRCODE_UNDEFINED_FILE MAKE_SQLSTATE('5','8','P','0','1') -#define ERRCODE_DUPLICATE_FILE MAKE_SQLSTATE('5','8','P','0','2') - -/* Class 72 - Snapshot Failure */ -#define ERRCODE_SNAPSHOT_TOO_OLD MAKE_SQLSTATE('7','2','0','0','0') - -/* Class F0 - Configuration File Error */ -#define ERRCODE_CONFIG_FILE_ERROR MAKE_SQLSTATE('F','0','0','0','0') -#define ERRCODE_LOCK_FILE_EXISTS MAKE_SQLSTATE('F','0','0','0','1') - -/* Class HV - Foreign Data Wrapper Error (SQL/MED) */ -#define ERRCODE_FDW_ERROR MAKE_SQLSTATE('H','V','0','0','0') -#define ERRCODE_FDW_COLUMN_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','5') -#define ERRCODE_FDW_DYNAMIC_PARAMETER_VALUE_NEEDED MAKE_SQLSTATE('H','V','0','0','2') -#define ERRCODE_FDW_FUNCTION_SEQUENCE_ERROR MAKE_SQLSTATE('H','V','0','1','0') -#define ERRCODE_FDW_INCONSISTENT_DESCRIPTOR_INFORMATION MAKE_SQLSTATE('H','V','0','2','1') -#define ERRCODE_FDW_INVALID_ATTRIBUTE_VALUE MAKE_SQLSTATE('H','V','0','2','4') -#define ERRCODE_FDW_INVALID_COLUMN_NAME MAKE_SQLSTATE('H','V','0','0','7') -#define ERRCODE_FDW_INVALID_COLUMN_NUMBER MAKE_SQLSTATE('H','V','0','0','8') -#define ERRCODE_FDW_INVALID_DATA_TYPE MAKE_SQLSTATE('H','V','0','0','4') -#define ERRCODE_FDW_INVALID_DATA_TYPE_DESCRIPTORS MAKE_SQLSTATE('H','V','0','0','6') -#define ERRCODE_FDW_INVALID_DESCRIPTOR_FIELD_IDENTIFIER MAKE_SQLSTATE('H','V','0','9','1') -#define ERRCODE_FDW_INVALID_HANDLE MAKE_SQLSTATE('H','V','0','0','B') -#define ERRCODE_FDW_INVALID_OPTION_INDEX MAKE_SQLSTATE('H','V','0','0','C') -#define ERRCODE_FDW_INVALID_OPTION_NAME MAKE_SQLSTATE('H','V','0','0','D') -#define ERRCODE_FDW_INVALID_STRING_LENGTH_OR_BUFFER_LENGTH MAKE_SQLSTATE('H','V','0','9','0') -#define ERRCODE_FDW_INVALID_STRING_FORMAT MAKE_SQLSTATE('H','V','0','0','A') -#define ERRCODE_FDW_INVALID_USE_OF_NULL_POINTER MAKE_SQLSTATE('H','V','0','0','9') -#define ERRCODE_FDW_TOO_MANY_HANDLES MAKE_SQLSTATE('H','V','0','1','4') -#define ERRCODE_FDW_OUT_OF_MEMORY MAKE_SQLSTATE('H','V','0','0','1') -#define ERRCODE_FDW_NO_SCHEMAS MAKE_SQLSTATE('H','V','0','0','P') -#define ERRCODE_FDW_OPTION_NAME_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','J') -#define ERRCODE_FDW_REPLY_HANDLE MAKE_SQLSTATE('H','V','0','0','K') -#define ERRCODE_FDW_SCHEMA_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','Q') -#define ERRCODE_FDW_TABLE_NOT_FOUND MAKE_SQLSTATE('H','V','0','0','R') -#define ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION MAKE_SQLSTATE('H','V','0','0','L') -#define ERRCODE_FDW_UNABLE_TO_CREATE_REPLY MAKE_SQLSTATE('H','V','0','0','M') -#define ERRCODE_FDW_UNABLE_TO_ESTABLISH_CONNECTION MAKE_SQLSTATE('H','V','0','0','N') - -/* Class P0 - PL/pgSQL Error */ -#define ERRCODE_PLPGSQL_ERROR MAKE_SQLSTATE('P','0','0','0','0') -#define ERRCODE_RAISE_EXCEPTION MAKE_SQLSTATE('P','0','0','0','1') -#define ERRCODE_NO_DATA_FOUND MAKE_SQLSTATE('P','0','0','0','2') -#define ERRCODE_TOO_MANY_ROWS MAKE_SQLSTATE('P','0','0','0','3') -#define ERRCODE_ASSERT_FAILURE MAKE_SQLSTATE('P','0','0','0','4') - -/* Class XX - Internal Error */ -#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X','0','0','0') -#define ERRCODE_DATA_CORRUPTED MAKE_SQLSTATE('X','X','0','0','1') -#define ERRCODE_INDEX_CORRUPTED MAKE_SQLSTATE('X','X','0','0','2') diff --git a/contrib/libs/libpq/src/common/archive.c b/contrib/libs/libpq/src/common/archive.c deleted file mode 100644 index 641a58ee88..0000000000 --- a/contrib/libs/libpq/src/common/archive.c +++ /dev/null @@ -1,60 +0,0 @@ -/*------------------------------------------------------------------------- - * - * archive.c - * Common WAL archive routines - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/archive.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/archive.h" -#include "common/percentrepl.h" - -/* - * BuildRestoreCommand - * - * Builds a restore command to retrieve a file from WAL archives, replacing - * the supported aliases with values supplied by the caller as defined by - * the GUC parameter restore_command: xlogpath for %p, xlogfname for %f and - * lastRestartPointFname for %r. - * - * The result is a palloc'd string for the restore command built. The - * caller is responsible for freeing it. If any of the required arguments - * is NULL and that the corresponding alias is found in the command given - * by the caller, then an error is thrown. - */ -char * -BuildRestoreCommand(const char *restoreCommand, - const char *xlogpath, - const char *xlogfname, - const char *lastRestartPointFname) -{ - char *nativePath = NULL; - char *result; - - if (xlogpath) - { - nativePath = pstrdup(xlogpath); - make_native_path(nativePath); - } - - result = replace_percent_placeholders(restoreCommand, "restore_command", "frp", - xlogfname, lastRestartPointFname, nativePath); - - if (nativePath) - pfree(nativePath); - - return result; -} diff --git a/contrib/libs/libpq/src/common/base64.c b/contrib/libs/libpq/src/common/base64.c deleted file mode 100644 index ec4eb49382..0000000000 --- a/contrib/libs/libpq/src/common/base64.c +++ /dev/null @@ -1,242 +0,0 @@ -/*------------------------------------------------------------------------- - * - * base64.c - * Encoding and decoding routines for base64 without whitespace. - * - * Copyright (c) 2001-2023, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/common/base64.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/base64.h" - -/* - * BASE64 - */ - -static const char _base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static const int8 b64lookup[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -}; - -/* - * pg_b64_encode - * - * Encode into base64 the given string. Returns the length of the encoded - * string, and -1 in the event of an error with the result buffer zeroed - * for safety. - */ -int -pg_b64_encode(const char *src, int len, char *dst, int dstlen) -{ - char *p; - const char *s, - *end = src + len; - int pos = 2; - uint32 buf = 0; - - s = src; - p = dst; - - while (s < end) - { - buf |= (unsigned char) *s << (pos << 3); - pos--; - s++; - - /* write it out */ - if (pos < 0) - { - /* - * Leave if there is an overflow in the area allocated for the - * encoded string. - */ - if ((p - dst + 4) > dstlen) - goto error; - - *p++ = _base64[(buf >> 18) & 0x3f]; - *p++ = _base64[(buf >> 12) & 0x3f]; - *p++ = _base64[(buf >> 6) & 0x3f]; - *p++ = _base64[buf & 0x3f]; - - pos = 2; - buf = 0; - } - } - if (pos != 2) - { - /* - * Leave if there is an overflow in the area allocated for the encoded - * string. - */ - if ((p - dst + 4) > dstlen) - goto error; - - *p++ = _base64[(buf >> 18) & 0x3f]; - *p++ = _base64[(buf >> 12) & 0x3f]; - *p++ = (pos == 0) ? _base64[(buf >> 6) & 0x3f] : '='; - *p++ = '='; - } - - Assert((p - dst) <= dstlen); - return p - dst; - -error: - memset(dst, 0, dstlen); - return -1; -} - -/* - * pg_b64_decode - * - * Decode the given base64 string. Returns the length of the decoded - * string on success, and -1 in the event of an error with the result - * buffer zeroed for safety. - */ -int -pg_b64_decode(const char *src, int len, char *dst, int dstlen) -{ - const char *srcend = src + len, - *s = src; - char *p = dst; - char c; - int b = 0; - uint32 buf = 0; - int pos = 0, - end = 0; - - while (s < srcend) - { - c = *s++; - - /* Leave if a whitespace is found */ - if (c == ' ' || c == '\t' || c == '\n' || c == '\r') - goto error; - - if (c == '=') - { - /* end sequence */ - if (!end) - { - if (pos == 2) - end = 1; - else if (pos == 3) - end = 2; - else - { - /* - * Unexpected "=" character found while decoding base64 - * sequence. - */ - goto error; - } - } - b = 0; - } - else - { - b = -1; - if (c > 0 && c < 127) - b = b64lookup[(unsigned char) c]; - if (b < 0) - { - /* invalid symbol found */ - goto error; - } - } - /* add it to buffer */ - buf = (buf << 6) + b; - pos++; - if (pos == 4) - { - /* - * Leave if there is an overflow in the area allocated for the - * decoded string. - */ - if ((p - dst + 1) > dstlen) - goto error; - *p++ = (buf >> 16) & 255; - - if (end == 0 || end > 1) - { - /* overflow check */ - if ((p - dst + 1) > dstlen) - goto error; - *p++ = (buf >> 8) & 255; - } - if (end == 0 || end > 2) - { - /* overflow check */ - if ((p - dst + 1) > dstlen) - goto error; - *p++ = buf & 255; - } - buf = 0; - pos = 0; - } - } - - if (pos != 0) - { - /* - * base64 end sequence is invalid. Input data is missing padding, is - * truncated or is otherwise corrupted. - */ - goto error; - } - - Assert((p - dst) <= dstlen); - return p - dst; - -error: - memset(dst, 0, dstlen); - return -1; -} - -/* - * pg_b64_enc_len - * - * Returns to caller the length of the string if it were encoded with - * base64 based on the length provided by caller. This is useful to - * estimate how large a buffer allocation needs to be done before doing - * the actual encoding. - */ -int -pg_b64_enc_len(int srclen) -{ - /* 3 bytes will be converted to 4 */ - return (srclen + 2) / 3 * 4; -} - -/* - * pg_b64_dec_len - * - * Returns to caller the length of the string if it were to be decoded - * with base64, based on the length given by caller. This is useful to - * estimate how large a buffer allocation needs to be done before doing - * the actual decoding. - */ -int -pg_b64_dec_len(int srclen) -{ - return (srclen * 3) >> 2; -} diff --git a/contrib/libs/libpq/src/common/checksum_helper.c b/contrib/libs/libpq/src/common/checksum_helper.c deleted file mode 100644 index 21ff8954fd..0000000000 --- a/contrib/libs/libpq/src/common/checksum_helper.c +++ /dev/null @@ -1,232 +0,0 @@ -/*------------------------------------------------------------------------- - * - * checksum_helper.c - * Compute a checksum of any of various types using common routines - * - * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/checksum_helper.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/checksum_helper.h" - -/* - * If 'name' is a recognized checksum type, set *type to the corresponding - * constant and return true. Otherwise, set *type to CHECKSUM_TYPE_NONE and - * return false. - */ -bool -pg_checksum_parse_type(char *name, pg_checksum_type *type) -{ - pg_checksum_type result_type = CHECKSUM_TYPE_NONE; - bool result = true; - - if (pg_strcasecmp(name, "none") == 0) - result_type = CHECKSUM_TYPE_NONE; - else if (pg_strcasecmp(name, "crc32c") == 0) - result_type = CHECKSUM_TYPE_CRC32C; - else if (pg_strcasecmp(name, "sha224") == 0) - result_type = CHECKSUM_TYPE_SHA224; - else if (pg_strcasecmp(name, "sha256") == 0) - result_type = CHECKSUM_TYPE_SHA256; - else if (pg_strcasecmp(name, "sha384") == 0) - result_type = CHECKSUM_TYPE_SHA384; - else if (pg_strcasecmp(name, "sha512") == 0) - result_type = CHECKSUM_TYPE_SHA512; - else - result = false; - - *type = result_type; - return result; -} - -/* - * Get the canonical human-readable name corresponding to a checksum type. - */ -char * -pg_checksum_type_name(pg_checksum_type type) -{ - switch (type) - { - case CHECKSUM_TYPE_NONE: - return "NONE"; - case CHECKSUM_TYPE_CRC32C: - return "CRC32C"; - case CHECKSUM_TYPE_SHA224: - return "SHA224"; - case CHECKSUM_TYPE_SHA256: - return "SHA256"; - case CHECKSUM_TYPE_SHA384: - return "SHA384"; - case CHECKSUM_TYPE_SHA512: - return "SHA512"; - } - - Assert(false); - return "???"; -} - -/* - * Initialize a checksum context for checksums of the given type. - * Returns 0 for a success, -1 for a failure. - */ -int -pg_checksum_init(pg_checksum_context *context, pg_checksum_type type) -{ - context->type = type; - - switch (type) - { - case CHECKSUM_TYPE_NONE: - /* do nothing */ - break; - case CHECKSUM_TYPE_CRC32C: - INIT_CRC32C(context->raw_context.c_crc32c); - break; - case CHECKSUM_TYPE_SHA224: - context->raw_context.c_sha2 = pg_cryptohash_create(PG_SHA224); - if (context->raw_context.c_sha2 == NULL) - return -1; - if (pg_cryptohash_init(context->raw_context.c_sha2) < 0) - { - pg_cryptohash_free(context->raw_context.c_sha2); - return -1; - } - break; - case CHECKSUM_TYPE_SHA256: - context->raw_context.c_sha2 = pg_cryptohash_create(PG_SHA256); - if (context->raw_context.c_sha2 == NULL) - return -1; - if (pg_cryptohash_init(context->raw_context.c_sha2) < 0) - { - pg_cryptohash_free(context->raw_context.c_sha2); - return -1; - } - break; - case CHECKSUM_TYPE_SHA384: - context->raw_context.c_sha2 = pg_cryptohash_create(PG_SHA384); - if (context->raw_context.c_sha2 == NULL) - return -1; - if (pg_cryptohash_init(context->raw_context.c_sha2) < 0) - { - pg_cryptohash_free(context->raw_context.c_sha2); - return -1; - } - break; - case CHECKSUM_TYPE_SHA512: - context->raw_context.c_sha2 = pg_cryptohash_create(PG_SHA512); - if (context->raw_context.c_sha2 == NULL) - return -1; - if (pg_cryptohash_init(context->raw_context.c_sha2) < 0) - { - pg_cryptohash_free(context->raw_context.c_sha2); - return -1; - } - break; - } - - return 0; -} - -/* - * Update a checksum context with new data. - * Returns 0 for a success, -1 for a failure. - */ -int -pg_checksum_update(pg_checksum_context *context, const uint8 *input, - size_t len) -{ - switch (context->type) - { - case CHECKSUM_TYPE_NONE: - /* do nothing */ - break; - case CHECKSUM_TYPE_CRC32C: - COMP_CRC32C(context->raw_context.c_crc32c, input, len); - break; - case CHECKSUM_TYPE_SHA224: - case CHECKSUM_TYPE_SHA256: - case CHECKSUM_TYPE_SHA384: - case CHECKSUM_TYPE_SHA512: - if (pg_cryptohash_update(context->raw_context.c_sha2, input, len) < 0) - return -1; - break; - } - - return 0; -} - -/* - * Finalize a checksum computation and write the result to an output buffer. - * - * The caller must ensure that the buffer is at least PG_CHECKSUM_MAX_LENGTH - * bytes in length. The return value is the number of bytes actually written, - * or -1 for a failure. - */ -int -pg_checksum_final(pg_checksum_context *context, uint8 *output) -{ - int retval = 0; - - StaticAssertDecl(sizeof(pg_crc32c) <= PG_CHECKSUM_MAX_LENGTH, - "CRC-32C digest too big for PG_CHECKSUM_MAX_LENGTH"); - StaticAssertDecl(PG_SHA224_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH, - "SHA224 digest too big for PG_CHECKSUM_MAX_LENGTH"); - StaticAssertDecl(PG_SHA256_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH, - "SHA256 digest too big for PG_CHECKSUM_MAX_LENGTH"); - StaticAssertDecl(PG_SHA384_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH, - "SHA384 digest too big for PG_CHECKSUM_MAX_LENGTH"); - StaticAssertDecl(PG_SHA512_DIGEST_LENGTH <= PG_CHECKSUM_MAX_LENGTH, - "SHA512 digest too big for PG_CHECKSUM_MAX_LENGTH"); - - switch (context->type) - { - case CHECKSUM_TYPE_NONE: - break; - case CHECKSUM_TYPE_CRC32C: - FIN_CRC32C(context->raw_context.c_crc32c); - retval = sizeof(pg_crc32c); - memcpy(output, &context->raw_context.c_crc32c, retval); - break; - case CHECKSUM_TYPE_SHA224: - retval = PG_SHA224_DIGEST_LENGTH; - if (pg_cryptohash_final(context->raw_context.c_sha2, - output, retval) < 0) - return -1; - pg_cryptohash_free(context->raw_context.c_sha2); - break; - case CHECKSUM_TYPE_SHA256: - retval = PG_SHA256_DIGEST_LENGTH; - if (pg_cryptohash_final(context->raw_context.c_sha2, - output, retval) < 0) - return -1; - pg_cryptohash_free(context->raw_context.c_sha2); - break; - case CHECKSUM_TYPE_SHA384: - retval = PG_SHA384_DIGEST_LENGTH; - if (pg_cryptohash_final(context->raw_context.c_sha2, - output, retval) < 0) - return -1; - pg_cryptohash_free(context->raw_context.c_sha2); - break; - case CHECKSUM_TYPE_SHA512: - retval = PG_SHA512_DIGEST_LENGTH; - if (pg_cryptohash_final(context->raw_context.c_sha2, - output, retval) < 0) - return -1; - pg_cryptohash_free(context->raw_context.c_sha2); - break; - } - - Assert(retval <= PG_CHECKSUM_MAX_LENGTH); - return retval; -} diff --git a/contrib/libs/libpq/src/common/compression.c b/contrib/libs/libpq/src/common/compression.c deleted file mode 100644 index 47b18b8c60..0000000000 --- a/contrib/libs/libpq/src/common/compression.c +++ /dev/null @@ -1,476 +0,0 @@ -/*------------------------------------------------------------------------- - * - * compression.c - * - * Shared code for compression methods and specifications. - * - * A compression specification specifies the parameters that should be used - * when performing compression with a specific algorithm. The simplest - * possible compression specification is an integer, which sets the - * compression level. - * - * Otherwise, a compression specification is a comma-separated list of items, - * each having the form keyword or keyword=value. - * - * Currently, the supported keywords are "level", "long", and "workers". - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/compression.c - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#ifdef USE_ZSTD -#error #include <zstd.h> -#endif -#ifdef HAVE_LIBZ -#include <zlib.h> -#endif - -#include "common/compression.h" - -static int expect_integer_value(char *keyword, char *value, - pg_compress_specification *result); -static bool expect_boolean_value(char *keyword, char *value, - pg_compress_specification *result); - -/* - * Look up a compression algorithm by name. Returns true and sets *algorithm - * if the name is recognized. Otherwise returns false. - */ -bool -parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm) -{ - if (strcmp(name, "none") == 0) - *algorithm = PG_COMPRESSION_NONE; - else if (strcmp(name, "gzip") == 0) - *algorithm = PG_COMPRESSION_GZIP; - else if (strcmp(name, "lz4") == 0) - *algorithm = PG_COMPRESSION_LZ4; - else if (strcmp(name, "zstd") == 0) - *algorithm = PG_COMPRESSION_ZSTD; - else - return false; - return true; -} - -/* - * Get the human-readable name corresponding to a particular compression - * algorithm. - */ -const char * -get_compress_algorithm_name(pg_compress_algorithm algorithm) -{ - switch (algorithm) - { - case PG_COMPRESSION_NONE: - return "none"; - case PG_COMPRESSION_GZIP: - return "gzip"; - case PG_COMPRESSION_LZ4: - return "lz4"; - case PG_COMPRESSION_ZSTD: - return "zstd"; - /* no default, to provoke compiler warnings if values are added */ - } - Assert(false); - return "???"; /* placate compiler */ -} - -/* - * Parse a compression specification for a specified algorithm. - * - * See the file header comments for a brief description of what a compression - * specification is expected to look like. - * - * On return, all fields of the result object will be initialized. - * In particular, result->parse_error will be NULL if no errors occurred - * during parsing, and will otherwise contain an appropriate error message. - * The caller may free this error message string using pfree, if desired. - * Note, however, even if there's no parse error, the string might not make - * sense: e.g. for gzip, level=12 is not sensible, but it does parse OK. - * - * The compression level is assigned by default if not directly specified - * by the specification. - * - * Use validate_compress_specification() to find out whether a compression - * specification is semantically sensible. - */ -void -parse_compress_specification(pg_compress_algorithm algorithm, char *specification, - pg_compress_specification *result) -{ - int bare_level; - char *bare_level_endp; - - /* Initial setup of result object. */ - result->algorithm = algorithm; - result->options = 0; - result->parse_error = NULL; - - /* - * Assign a default level depending on the compression method. This may - * be enforced later. - */ - switch (result->algorithm) - { - case PG_COMPRESSION_NONE: - result->level = 0; - break; - case PG_COMPRESSION_LZ4: -#ifdef USE_LZ4 - result->level = 0; /* fast compression mode */ -#else - result->parse_error = - psprintf(_("this build does not support compression with %s"), - "LZ4"); -#endif - break; - case PG_COMPRESSION_ZSTD: -#ifdef USE_ZSTD - result->level = ZSTD_CLEVEL_DEFAULT; -#else - result->parse_error = - psprintf(_("this build does not support compression with %s"), - "ZSTD"); -#endif - break; - case PG_COMPRESSION_GZIP: -#ifdef HAVE_LIBZ - result->level = Z_DEFAULT_COMPRESSION; -#else - result->parse_error = - psprintf(_("this build does not support compression with %s"), - "gzip"); -#endif - break; - } - - /* If there is no specification, we're done already. */ - if (specification == NULL) - return; - - /* As a special case, the specification can be a bare integer. */ - bare_level = strtol(specification, &bare_level_endp, 10); - if (specification != bare_level_endp && *bare_level_endp == '\0') - { - result->level = bare_level; - return; - } - - /* Look for comma-separated keyword or keyword=value entries. */ - while (1) - { - char *kwstart; - char *kwend; - char *vstart; - char *vend; - int kwlen; - int vlen; - bool has_value; - char *keyword; - char *value; - - /* Figure start, end, and length of next keyword and any value. */ - kwstart = kwend = specification; - while (*kwend != '\0' && *kwend != ',' && *kwend != '=') - ++kwend; - kwlen = kwend - kwstart; - if (*kwend != '=') - { - vstart = vend = NULL; - vlen = 0; - has_value = false; - } - else - { - vstart = vend = kwend + 1; - while (*vend != '\0' && *vend != ',') - ++vend; - vlen = vend - vstart; - has_value = true; - } - - /* Reject empty keyword. */ - if (kwlen == 0) - { - result->parse_error = - pstrdup(_("found empty string where a compression option was expected")); - break; - } - - /* Extract keyword and value as separate C strings. */ - keyword = palloc(kwlen + 1); - memcpy(keyword, kwstart, kwlen); - keyword[kwlen] = '\0'; - if (!has_value) - value = NULL; - else - { - value = palloc(vlen + 1); - memcpy(value, vstart, vlen); - value[vlen] = '\0'; - } - - /* Handle whatever keyword we found. */ - if (strcmp(keyword, "level") == 0) - { - result->level = expect_integer_value(keyword, value, result); - - /* - * No need to set a flag in "options", there is a default level - * set at least thanks to the logic above. - */ - } - else if (strcmp(keyword, "workers") == 0) - { - result->workers = expect_integer_value(keyword, value, result); - result->options |= PG_COMPRESSION_OPTION_WORKERS; - } - else if (strcmp(keyword, "long") == 0) - { - result->long_distance = expect_boolean_value(keyword, value, result); - result->options |= PG_COMPRESSION_OPTION_LONG_DISTANCE; - } - else - result->parse_error = - psprintf(_("unrecognized compression option: \"%s\""), keyword); - - /* Release memory, just to be tidy. */ - pfree(keyword); - if (value != NULL) - pfree(value); - - /* - * If we got an error or have reached the end of the string, stop. - * - * If there is no value, then the end of the keyword might have been - * the end of the string. If there is a value, then the end of the - * keyword cannot have been the end of the string, but the end of the - * value might have been. - */ - if (result->parse_error != NULL || - (vend == NULL ? *kwend == '\0' : *vend == '\0')) - break; - - /* Advance to next entry and loop around. */ - specification = vend == NULL ? kwend + 1 : vend + 1; - } -} - -/* - * Parse 'value' as an integer and return the result. - * - * If parsing fails, set result->parse_error to an appropriate message - * and return -1. - */ -static int -expect_integer_value(char *keyword, char *value, pg_compress_specification *result) -{ - int ivalue; - char *ivalue_endp; - - if (value == NULL) - { - result->parse_error = - psprintf(_("compression option \"%s\" requires a value"), - keyword); - return -1; - } - - ivalue = strtol(value, &ivalue_endp, 10); - if (ivalue_endp == value || *ivalue_endp != '\0') - { - result->parse_error = - psprintf(_("value for compression option \"%s\" must be an integer"), - keyword); - return -1; - } - return ivalue; -} - -/* - * Parse 'value' as a boolean and return the result. - * - * If parsing fails, set result->parse_error to an appropriate message - * and return -1. The caller must check result->parse_error to determine if - * the call was successful. - * - * Valid values are: yes, no, on, off, 1, 0. - * - * Inspired by ParseVariableBool(). - */ -static bool -expect_boolean_value(char *keyword, char *value, pg_compress_specification *result) -{ - if (value == NULL) - return true; - - if (pg_strcasecmp(value, "yes") == 0) - return true; - if (pg_strcasecmp(value, "on") == 0) - return true; - if (pg_strcasecmp(value, "1") == 0) - return true; - - if (pg_strcasecmp(value, "no") == 0) - return false; - if (pg_strcasecmp(value, "off") == 0) - return false; - if (pg_strcasecmp(value, "0") == 0) - return false; - - result->parse_error = - psprintf(_("value for compression option \"%s\" must be a Boolean value"), - keyword); - return false; -} - -/* - * Returns NULL if the compression specification string was syntactically - * valid and semantically sensible. Otherwise, returns an error message. - * - * Does not test whether this build of PostgreSQL supports the requested - * compression method. - */ -char * -validate_compress_specification(pg_compress_specification *spec) -{ - int min_level = 1; - int max_level = 1; - int default_level = 0; - - /* If it didn't even parse OK, it's definitely no good. */ - if (spec->parse_error != NULL) - return spec->parse_error; - - /* - * Check that the algorithm expects a compression level and it is within - * the legal range for the algorithm. - */ - switch (spec->algorithm) - { - case PG_COMPRESSION_GZIP: - max_level = 9; -#ifdef HAVE_LIBZ - default_level = Z_DEFAULT_COMPRESSION; -#endif - break; - case PG_COMPRESSION_LZ4: - max_level = 12; - default_level = 0; /* fast mode */ - break; - case PG_COMPRESSION_ZSTD: -#ifdef USE_ZSTD - max_level = ZSTD_maxCLevel(); - min_level = ZSTD_minCLevel(); - default_level = ZSTD_CLEVEL_DEFAULT; -#endif - break; - case PG_COMPRESSION_NONE: - if (spec->level != 0) - return psprintf(_("compression algorithm \"%s\" does not accept a compression level"), - get_compress_algorithm_name(spec->algorithm)); - break; - } - - if ((spec->level < min_level || spec->level > max_level) && - spec->level != default_level) - return psprintf(_("compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"), - get_compress_algorithm_name(spec->algorithm), - min_level, max_level, default_level); - - /* - * Of the compression algorithms that we currently support, only zstd - * allows parallel workers. - */ - if ((spec->options & PG_COMPRESSION_OPTION_WORKERS) != 0 && - (spec->algorithm != PG_COMPRESSION_ZSTD)) - { - return psprintf(_("compression algorithm \"%s\" does not accept a worker count"), - get_compress_algorithm_name(spec->algorithm)); - } - - /* - * Of the compression algorithms that we currently support, only zstd - * supports long-distance mode. - */ - if ((spec->options & PG_COMPRESSION_OPTION_LONG_DISTANCE) != 0 && - (spec->algorithm != PG_COMPRESSION_ZSTD)) - { - return psprintf(_("compression algorithm \"%s\" does not support long-distance mode"), - get_compress_algorithm_name(spec->algorithm)); - } - - return NULL; -} - -#ifdef FRONTEND - -/* - * Basic parsing of a value specified through a command-line option, commonly - * -Z/--compress. - * - * The parsing consists of a METHOD:DETAIL string fed later to - * parse_compress_specification(). This only extracts METHOD and DETAIL. - * If only an integer is found, the method is implied by the value specified. - */ -void -parse_compress_options(const char *option, char **algorithm, char **detail) -{ - char *sep; - char *endp; - long result; - - /* - * Check whether the compression specification consists of a bare integer. - * - * For backward-compatibility, assume "none" if the integer found is zero - * and "gzip" otherwise. - */ - result = strtol(option, &endp, 10); - if (*endp == '\0') - { - if (result == 0) - { - *algorithm = pstrdup("none"); - *detail = NULL; - } - else - { - *algorithm = pstrdup("gzip"); - *detail = pstrdup(option); - } - return; - } - - /* - * Check whether there is a compression detail following the algorithm - * name. - */ - sep = strchr(option, ':'); - if (sep == NULL) - { - *algorithm = pstrdup(option); - *detail = NULL; - } - else - { - char *alg; - - alg = palloc((sep - option) + 1); - memcpy(alg, option, sep - option); - alg[sep - option] = '\0'; - - *algorithm = alg; - *detail = pstrdup(sep + 1); - } -} -#endif /* FRONTEND */ diff --git a/contrib/libs/libpq/src/common/config_info.c b/contrib/libs/libpq/src/common/config_info.c deleted file mode 100644 index 09e78a6efb..0000000000 --- a/contrib/libs/libpq/src/common/config_info.c +++ /dev/null @@ -1,201 +0,0 @@ -/*------------------------------------------------------------------------- - * - * config_info.c - * Common code for pg_config output - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/config_info.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/config_info.h" - - -/* - * get_configdata(const char *my_exec_path, size_t *configdata_len) - * - * Get configure-time constants. The caller is responsible - * for pfreeing the result. - */ -ConfigData * -get_configdata(const char *my_exec_path, size_t *configdata_len) -{ - ConfigData *configdata; - char path[MAXPGPATH]; - char *lastsep; - int i = 0; - - /* Adjust this to match the number of items filled below */ - *configdata_len = 23; - configdata = palloc_array(ConfigData, *configdata_len); - - configdata[i].name = pstrdup("BINDIR"); - strlcpy(path, my_exec_path, sizeof(path)); - lastsep = strrchr(path, '/'); - if (lastsep) - *lastsep = '\0'; - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("DOCDIR"); - get_doc_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("HTMLDIR"); - get_html_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("INCLUDEDIR"); - get_include_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("PKGINCLUDEDIR"); - get_pkginclude_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("INCLUDEDIR-SERVER"); - get_includeserver_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("LIBDIR"); - get_lib_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("PKGLIBDIR"); - get_pkglib_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("LOCALEDIR"); - get_locale_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("MANDIR"); - get_man_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("SHAREDIR"); - get_share_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("SYSCONFDIR"); - get_etc_path(my_exec_path, path); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("PGXS"); - get_pkglib_path(my_exec_path, path); - strlcat(path, "/pgxs/src/makefiles/pgxs.mk", sizeof(path)); - cleanup_path(path); - configdata[i].setting = pstrdup(path); - i++; - - configdata[i].name = pstrdup("CONFIGURE"); - configdata[i].setting = pstrdup(CONFIGURE_ARGS); - i++; - - configdata[i].name = pstrdup("CC"); -#ifdef VAL_CC - configdata[i].setting = pstrdup(VAL_CC); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("CPPFLAGS"); -#ifdef VAL_CPPFLAGS - configdata[i].setting = pstrdup(VAL_CPPFLAGS); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("CFLAGS"); -#ifdef VAL_CFLAGS - configdata[i].setting = pstrdup(VAL_CFLAGS); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("CFLAGS_SL"); -#ifdef VAL_CFLAGS_SL - configdata[i].setting = pstrdup(VAL_CFLAGS_SL); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("LDFLAGS"); -#ifdef VAL_LDFLAGS - configdata[i].setting = pstrdup(VAL_LDFLAGS); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("LDFLAGS_EX"); -#ifdef VAL_LDFLAGS_EX - configdata[i].setting = pstrdup(VAL_LDFLAGS_EX); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("LDFLAGS_SL"); -#ifdef VAL_LDFLAGS_SL - configdata[i].setting = pstrdup(VAL_LDFLAGS_SL); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("LIBS"); -#ifdef VAL_LIBS - configdata[i].setting = pstrdup(VAL_LIBS); -#else - configdata[i].setting = pstrdup(_("not recorded")); -#endif - i++; - - configdata[i].name = pstrdup("VERSION"); - configdata[i].setting = pstrdup("PostgreSQL " PG_VERSION); - i++; - - Assert(i == *configdata_len); - - return configdata; -} diff --git a/contrib/libs/libpq/src/common/controldata_utils.c b/contrib/libs/libpq/src/common/controldata_utils.c deleted file mode 100644 index 19305fa07a..0000000000 --- a/contrib/libs/libpq/src/common/controldata_utils.c +++ /dev/null @@ -1,269 +0,0 @@ -/*------------------------------------------------------------------------- - * - * controldata_utils.c - * Common code for control data file output. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/controldata_utils.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <unistd.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <time.h> - -#include "access/xlog_internal.h" -#include "catalog/pg_control.h" -#include "common/controldata_utils.h" -#include "common/file_perm.h" -#ifdef FRONTEND -#include "common/logging.h" -#endif -#include "port/pg_crc32c.h" - -#ifndef FRONTEND -#error #include "pgstat.h" -#error #include "storage/fd.h" -#endif - -/* - * get_controlfile() - * - * Get controlfile values. The result is returned as a palloc'd copy of the - * control file data. - * - * crc_ok_p can be used by the caller to see whether the CRC of the control - * file data is correct. - */ -ControlFileData * -get_controlfile(const char *DataDir, bool *crc_ok_p) -{ - ControlFileData *ControlFile; - int fd; - char ControlFilePath[MAXPGPATH]; - pg_crc32c crc; - int r; -#ifdef FRONTEND - pg_crc32c last_crc; - int retries = 0; -#endif - - Assert(crc_ok_p); - - ControlFile = palloc_object(ControlFileData); - snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); - -#ifdef FRONTEND - INIT_CRC32C(last_crc); - -retry: -#endif - -#ifndef FRONTEND - if ((fd = OpenTransientFile(ControlFilePath, O_RDONLY | PG_BINARY)) == -1) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not open file \"%s\" for reading: %m", - ControlFilePath))); -#else - if ((fd = open(ControlFilePath, O_RDONLY | PG_BINARY, 0)) == -1) - pg_fatal("could not open file \"%s\" for reading: %m", - ControlFilePath); -#endif - - r = read(fd, ControlFile, sizeof(ControlFileData)); - if (r != sizeof(ControlFileData)) - { - if (r < 0) -#ifndef FRONTEND - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not read file \"%s\": %m", ControlFilePath))); -#else - pg_fatal("could not read file \"%s\": %m", ControlFilePath); -#endif - else -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("could not read file \"%s\": read %d of %zu", - ControlFilePath, r, sizeof(ControlFileData)))); -#else - pg_fatal("could not read file \"%s\": read %d of %zu", - ControlFilePath, r, sizeof(ControlFileData)); -#endif - } - -#ifndef FRONTEND - if (CloseTransientFile(fd) != 0) - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not close file \"%s\": %m", - ControlFilePath))); -#else - if (close(fd) != 0) - pg_fatal("could not close file \"%s\": %m", ControlFilePath); -#endif - - /* Check the CRC. */ - INIT_CRC32C(crc); - COMP_CRC32C(crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(crc); - - *crc_ok_p = EQ_CRC32C(crc, ControlFile->crc); - -#ifdef FRONTEND - - /* - * If the server was writing at the same time, it is possible that we read - * partially updated contents on some systems. If the CRC doesn't match, - * retry a limited number of times until we compute the same bad CRC twice - * in a row with a short sleep in between. Then the failure is unlikely - * to be due to a concurrent write. - */ - if (!*crc_ok_p && - (retries == 0 || !EQ_CRC32C(crc, last_crc)) && - retries < 10) - { - retries++; - last_crc = crc; - pg_usleep(10000); - goto retry; - } -#endif - - /* Make sure the control file is valid byte order. */ - if (ControlFile->pg_control_version % 65536 == 0 && - ControlFile->pg_control_version / 65536 != 0) -#ifndef FRONTEND - elog(ERROR, _("byte ordering mismatch")); -#else - pg_log_warning("possible byte ordering mismatch\n" - "The byte ordering used to store the pg_control file might not match the one\n" - "used by this program. In that case the results below would be incorrect, and\n" - "the PostgreSQL installation would be incompatible with this data directory."); -#endif - - return ControlFile; -} - -/* - * update_controlfile() - * - * Update controlfile values with the contents given by caller. The - * contents to write are included in "ControlFile". "do_sync" can be - * optionally used to flush the updated control file. Note that it is up - * to the caller to properly lock ControlFileLock when calling this - * routine in the backend. - */ -void -update_controlfile(const char *DataDir, - ControlFileData *ControlFile, bool do_sync) -{ - int fd; - char buffer[PG_CONTROL_FILE_SIZE]; - char ControlFilePath[MAXPGPATH]; - - /* Update timestamp */ - ControlFile->time = (pg_time_t) time(NULL); - - /* Recalculate CRC of control file */ - INIT_CRC32C(ControlFile->crc); - COMP_CRC32C(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(ControlFile->crc); - - /* - * Write out PG_CONTROL_FILE_SIZE bytes into pg_control by zero-padding - * the excess over sizeof(ControlFileData), to avoid premature EOF related - * errors when reading it. - */ - memset(buffer, 0, PG_CONTROL_FILE_SIZE); - memcpy(buffer, ControlFile, sizeof(ControlFileData)); - - snprintf(ControlFilePath, sizeof(ControlFilePath), "%s/%s", DataDir, XLOG_CONTROL_FILE); - -#ifndef FRONTEND - - /* - * All errors issue a PANIC, so no need to use OpenTransientFile() and to - * worry about file descriptor leaks. - */ - if ((fd = BasicOpenFile(ControlFilePath, O_RDWR | PG_BINARY)) < 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", - ControlFilePath))); -#else - if ((fd = open(ControlFilePath, O_WRONLY | PG_BINARY, - pg_file_create_mode)) == -1) - pg_fatal("could not open file \"%s\": %m", ControlFilePath); -#endif - - errno = 0; -#ifndef FRONTEND - pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE); -#endif - if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - -#ifndef FRONTEND - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not write file \"%s\": %m", - ControlFilePath))); -#else - pg_fatal("could not write file \"%s\": %m", ControlFilePath); -#endif - } -#ifndef FRONTEND - pgstat_report_wait_end(); -#endif - - if (do_sync) - { -#ifndef FRONTEND - pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE); - if (pg_fsync(fd) != 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not fsync file \"%s\": %m", - ControlFilePath))); - pgstat_report_wait_end(); -#else - if (fsync(fd) != 0) - pg_fatal("could not fsync file \"%s\": %m", ControlFilePath); -#endif - } - - if (close(fd) != 0) - { -#ifndef FRONTEND - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not close file \"%s\": %m", - ControlFilePath))); -#else - pg_fatal("could not close file \"%s\": %m", ControlFilePath); -#endif - } -} diff --git a/contrib/libs/libpq/src/common/cryptohash_openssl.c b/contrib/libs/libpq/src/common/cryptohash_openssl.c deleted file mode 100644 index ac2cff0759..0000000000 --- a/contrib/libs/libpq/src/common/cryptohash_openssl.c +++ /dev/null @@ -1,353 +0,0 @@ -/*------------------------------------------------------------------------- - * - * cryptohash_openssl.c - * Set of wrapper routines on top of OpenSSL to support cryptographic - * hash functions. - * - * This should only be used if code is compiled with OpenSSL support. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/cryptohash_openssl.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <openssl/err.h> -#include <openssl/evp.h> - -#include "common/cryptohash.h" -#include "common/md5.h" -#include "common/sha1.h" -#include "common/sha2.h" -#ifndef FRONTEND -#error #include "utils/memutils.h" -#error #include "utils/resowner.h" -#error #include "utils/resowner_private.h" -#endif - -/* - * In the backend, use an allocation in TopMemoryContext to count for - * resowner cleanup handling. In the frontend, use malloc to be able - * to return a failure status back to the caller. - */ -#ifndef FRONTEND -#define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size) -#define FREE(ptr) pfree(ptr) -#else -#define ALLOC(size) malloc(size) -#define FREE(ptr) free(ptr) -#endif - -/* Set of error states */ -typedef enum pg_cryptohash_errno -{ - PG_CRYPTOHASH_ERROR_NONE = 0, - PG_CRYPTOHASH_ERROR_DEST_LEN, - PG_CRYPTOHASH_ERROR_OPENSSL -} pg_cryptohash_errno; - -/* - * Internal pg_cryptohash_ctx structure. - * - * This tracks the resource owner associated to each EVP context data - * for the backend. - */ -struct pg_cryptohash_ctx -{ - pg_cryptohash_type type; - pg_cryptohash_errno error; - const char *errreason; - - EVP_MD_CTX *evpctx; - -#ifndef FRONTEND - ResourceOwner resowner; -#endif -}; - -static const char * -SSLerrmessage(unsigned long ecode) -{ - if (ecode == 0) - return NULL; - - /* - * This may return NULL, but we would fall back to a default error path if - * that were the case. - */ - return ERR_reason_error_string(ecode); -} - -/* - * pg_cryptohash_create - * - * Allocate a hash context. Returns NULL on failure for an OOM. The - * backend issues an error, without returning. - */ -pg_cryptohash_ctx * -pg_cryptohash_create(pg_cryptohash_type type) -{ - pg_cryptohash_ctx *ctx; - - /* - * Make sure that the resource owner has space to remember this reference. - * This can error out with "out of memory", so do this before any other - * allocation to avoid leaking. - */ -#ifndef FRONTEND - ResourceOwnerEnlargeCryptoHash(CurrentResourceOwner); -#endif - - ctx = ALLOC(sizeof(pg_cryptohash_ctx)); - if (ctx == NULL) - return NULL; - memset(ctx, 0, sizeof(pg_cryptohash_ctx)); - ctx->type = type; - ctx->error = PG_CRYPTOHASH_ERROR_NONE; - ctx->errreason = NULL; - - /* - * Initialization takes care of assigning the correct type for OpenSSL. - * Also ensure that there aren't any unconsumed errors in the queue from - * previous runs. - */ - ERR_clear_error(); - ctx->evpctx = EVP_MD_CTX_create(); - - if (ctx->evpctx == NULL) - { - explicit_bzero(ctx, sizeof(pg_cryptohash_ctx)); - FREE(ctx); -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#else - return NULL; -#endif - } - -#ifndef FRONTEND - ctx->resowner = CurrentResourceOwner; - ResourceOwnerRememberCryptoHash(CurrentResourceOwner, - PointerGetDatum(ctx)); -#endif - - return ctx; -} - -/* - * pg_cryptohash_init - * - * Initialize a hash context. Returns 0 on success, and -1 on failure. - */ -int -pg_cryptohash_init(pg_cryptohash_ctx *ctx) -{ - int status = 0; - - if (ctx == NULL) - return -1; - - switch (ctx->type) - { - case PG_MD5: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_md5(), NULL); - break; - case PG_SHA1: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha1(), NULL); - break; - case PG_SHA224: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha224(), NULL); - break; - case PG_SHA256: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha256(), NULL); - break; - case PG_SHA384: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha384(), NULL); - break; - case PG_SHA512: - status = EVP_DigestInit_ex(ctx->evpctx, EVP_sha512(), NULL); - break; - } - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_CRYPTOHASH_ERROR_OPENSSL; - - /* - * The OpenSSL error queue should normally be empty since we've - * consumed an error, but cipher initialization can in FIPS-enabled - * OpenSSL builds generate two errors so clear the queue here as well. - */ - ERR_clear_error(); - return -1; - } - return 0; -} - -/* - * pg_cryptohash_update - * - * Update a hash context. Returns 0 on success, and -1 on failure. - */ -int -pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len) -{ - int status = 0; - - if (ctx == NULL) - return -1; - - status = EVP_DigestUpdate(ctx->evpctx, data, len); - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_CRYPTOHASH_ERROR_OPENSSL; - return -1; - } - return 0; -} - -/* - * pg_cryptohash_final - * - * Finalize a hash context. Returns 0 on success, and -1 on failure. - */ -int -pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len) -{ - int status = 0; - - if (ctx == NULL) - return -1; - - switch (ctx->type) - { - case PG_MD5: - if (len < MD5_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA1: - if (len < SHA1_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA224: - if (len < PG_SHA224_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA256: - if (len < PG_SHA256_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA384: - if (len < PG_SHA384_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA512: - if (len < PG_SHA512_DIGEST_LENGTH) - { - ctx->error = PG_CRYPTOHASH_ERROR_DEST_LEN; - return -1; - } - break; - } - - status = EVP_DigestFinal_ex(ctx->evpctx, dest, 0); - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_CRYPTOHASH_ERROR_OPENSSL; - return -1; - } - return 0; -} - -/* - * pg_cryptohash_free - * - * Free a hash context. - */ -void -pg_cryptohash_free(pg_cryptohash_ctx *ctx) -{ - if (ctx == NULL) - return; - - EVP_MD_CTX_destroy(ctx->evpctx); - -#ifndef FRONTEND - ResourceOwnerForgetCryptoHash(ctx->resowner, - PointerGetDatum(ctx)); -#endif - - explicit_bzero(ctx, sizeof(pg_cryptohash_ctx)); - FREE(ctx); -} - -/* - * pg_cryptohash_error - * - * Returns a static string providing details about an error that - * happened during a computation. - */ -const char * -pg_cryptohash_error(pg_cryptohash_ctx *ctx) -{ - /* - * This implementation would never fail because of an out-of-memory error, - * except when creating the context. - */ - if (ctx == NULL) - return _("out of memory"); - - /* - * If a reason is provided, rely on it, else fallback to any error code - * set. - */ - if (ctx->errreason) - return ctx->errreason; - - switch (ctx->error) - { - case PG_CRYPTOHASH_ERROR_NONE: - return _("success"); - case PG_CRYPTOHASH_ERROR_DEST_LEN: - return _("destination buffer too small"); - case PG_CRYPTOHASH_ERROR_OPENSSL: - return _("OpenSSL failure"); - } - - Assert(false); /* cannot be reached */ - return _("success"); -} diff --git a/contrib/libs/libpq/src/common/d2s.c b/contrib/libs/libpq/src/common/d2s.c deleted file mode 100644 index 614e98192a..0000000000 --- a/contrib/libs/libpq/src/common/d2s.c +++ /dev/null @@ -1,1076 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Ryu floating-point output for double precision. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/d2s.c - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ - -/* - * Runtime compiler options: - * - * -DRYU_ONLY_64_BIT_OPS Avoid using uint128 or 64-bit intrinsics. Slower, - * depending on your compiler. - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/shortest_dec.h" - -/* - * For consistency, we use 128-bit types if and only if the rest of PG also - * does, even though we could use them here without worrying about the - * alignment concerns that apply elsewhere. - */ -#if !defined(HAVE_INT128) && defined(_MSC_VER) \ - && !defined(RYU_ONLY_64_BIT_OPS) && defined(_M_X64) -#define HAS_64_BIT_INTRINSICS -#endif - -#include "ryu_common.h" -#include "digit_table.h" -#include "d2s_full_table.h" -#include "d2s_intrinsics.h" - -#define DOUBLE_MANTISSA_BITS 52 -#define DOUBLE_EXPONENT_BITS 11 -#define DOUBLE_BIAS 1023 - -#define DOUBLE_POW5_INV_BITCOUNT 122 -#define DOUBLE_POW5_BITCOUNT 121 - - -static inline uint32 -pow5Factor(uint64 value) -{ - uint32 count = 0; - - for (;;) - { - Assert(value != 0); - const uint64 q = div5(value); - const uint32 r = (uint32) (value - 5 * q); - - if (r != 0) - break; - - value = q; - ++count; - } - return count; -} - -/* Returns true if value is divisible by 5^p. */ -static inline bool -multipleOfPowerOf5(const uint64 value, const uint32 p) -{ - /* - * I tried a case distinction on p, but there was no performance - * difference. - */ - return pow5Factor(value) >= p; -} - -/* Returns true if value is divisible by 2^p. */ -static inline bool -multipleOfPowerOf2(const uint64 value, const uint32 p) -{ - /* return __builtin_ctzll(value) >= p; */ - return (value & ((UINT64CONST(1) << p) - 1)) == 0; -} - -/* - * We need a 64x128-bit multiplication and a subsequent 128-bit shift. - * - * Multiplication: - * - * The 64-bit factor is variable and passed in, the 128-bit factor comes - * from a lookup table. We know that the 64-bit factor only has 55 - * significant bits (i.e., the 9 topmost bits are zeros). The 128-bit - * factor only has 124 significant bits (i.e., the 4 topmost bits are - * zeros). - * - * Shift: - * - * In principle, the multiplication result requires 55 + 124 = 179 bits to - * represent. However, we then shift this value to the right by j, which is - * at least j >= 115, so the result is guaranteed to fit into 179 - 115 = - * 64 bits. This means that we only need the topmost 64 significant bits of - * the 64x128-bit multiplication. - * - * There are several ways to do this: - * - * 1. Best case: the compiler exposes a 128-bit type. - * We perform two 64x64-bit multiplications, add the higher 64 bits of the - * lower result to the higher result, and shift by j - 64 bits. - * - * We explicitly cast from 64-bit to 128-bit, so the compiler can tell - * that these are only 64-bit inputs, and can map these to the best - * possible sequence of assembly instructions. x86-64 machines happen to - * have matching assembly instructions for 64x64-bit multiplications and - * 128-bit shifts. - * - * 2. Second best case: the compiler exposes intrinsics for the x86-64 - * assembly instructions mentioned in 1. - * - * 3. We only have 64x64 bit instructions that return the lower 64 bits of - * the result, i.e., we have to use plain C. - * - * Our inputs are less than the full width, so we have three options: - * a. Ignore this fact and just implement the intrinsics manually. - * b. Split both into 31-bit pieces, which guarantees no internal - * overflow, but requires extra work upfront (unless we change the - * lookup table). - * c. Split only the first factor into 31-bit pieces, which also - * guarantees no internal overflow, but requires extra work since the - * intermediate results are not perfectly aligned. - */ -#if defined(HAVE_INT128) - -/* Best case: use 128-bit type. */ -static inline uint64 -mulShift(const uint64 m, const uint64 *const mul, const int32 j) -{ - const uint128 b0 = ((uint128) m) * mul[0]; - const uint128 b2 = ((uint128) m) * mul[1]; - - return (uint64) (((b0 >> 64) + b2) >> (j - 64)); -} - -static inline uint64 -mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j, - uint64 *const vp, uint64 *const vm, const uint32 mmShift) -{ - *vp = mulShift(4 * m + 2, mul, j); - *vm = mulShift(4 * m - 1 - mmShift, mul, j); - return mulShift(4 * m, mul, j); -} - -#elif defined(HAS_64_BIT_INTRINSICS) - -static inline uint64 -mulShift(const uint64 m, const uint64 *const mul, const int32 j) -{ - /* m is maximum 55 bits */ - uint64 high1; - - /* 128 */ - const uint64 low1 = umul128(m, mul[1], &high1); - - /* 64 */ - uint64 high0; - uint64 sum; - - /* 64 */ - umul128(m, mul[0], &high0); - /* 0 */ - sum = high0 + low1; - - if (sum < high0) - { - ++high1; - /* overflow into high1 */ - } - return shiftright128(sum, high1, j - 64); -} - -static inline uint64 -mulShiftAll(const uint64 m, const uint64 *const mul, const int32 j, - uint64 *const vp, uint64 *const vm, const uint32 mmShift) -{ - *vp = mulShift(4 * m + 2, mul, j); - *vm = mulShift(4 * m - 1 - mmShift, mul, j); - return mulShift(4 * m, mul, j); -} - -#else /* // !defined(HAVE_INT128) && - * !defined(HAS_64_BIT_INTRINSICS) */ - -static inline uint64 -mulShiftAll(uint64 m, const uint64 *const mul, const int32 j, - uint64 *const vp, uint64 *const vm, const uint32 mmShift) -{ - m <<= 1; /* m is maximum 55 bits */ - - uint64 tmp; - const uint64 lo = umul128(m, mul[0], &tmp); - uint64 hi; - const uint64 mid = tmp + umul128(m, mul[1], &hi); - - hi += mid < tmp; /* overflow into hi */ - - const uint64 lo2 = lo + mul[0]; - const uint64 mid2 = mid + mul[1] + (lo2 < lo); - const uint64 hi2 = hi + (mid2 < mid); - - *vp = shiftright128(mid2, hi2, j - 64 - 1); - - if (mmShift == 1) - { - const uint64 lo3 = lo - mul[0]; - const uint64 mid3 = mid - mul[1] - (lo3 > lo); - const uint64 hi3 = hi - (mid3 > mid); - - *vm = shiftright128(mid3, hi3, j - 64 - 1); - } - else - { - const uint64 lo3 = lo + lo; - const uint64 mid3 = mid + mid + (lo3 < lo); - const uint64 hi3 = hi + hi + (mid3 < mid); - const uint64 lo4 = lo3 - mul[0]; - const uint64 mid4 = mid3 - mul[1] - (lo4 > lo3); - const uint64 hi4 = hi3 - (mid4 > mid3); - - *vm = shiftright128(mid4, hi4, j - 64); - } - - return shiftright128(mid, hi, j - 64 - 1); -} - -#endif /* // HAS_64_BIT_INTRINSICS */ - -static inline uint32 -decimalLength(const uint64 v) -{ - /* This is slightly faster than a loop. */ - /* The average output length is 16.38 digits, so we check high-to-low. */ - /* Function precondition: v is not an 18, 19, or 20-digit number. */ - /* (17 digits are sufficient for round-tripping.) */ - Assert(v < 100000000000000000L); - if (v >= 10000000000000000L) - { - return 17; - } - if (v >= 1000000000000000L) - { - return 16; - } - if (v >= 100000000000000L) - { - return 15; - } - if (v >= 10000000000000L) - { - return 14; - } - if (v >= 1000000000000L) - { - return 13; - } - if (v >= 100000000000L) - { - return 12; - } - if (v >= 10000000000L) - { - return 11; - } - if (v >= 1000000000L) - { - return 10; - } - if (v >= 100000000L) - { - return 9; - } - if (v >= 10000000L) - { - return 8; - } - if (v >= 1000000L) - { - return 7; - } - if (v >= 100000L) - { - return 6; - } - if (v >= 10000L) - { - return 5; - } - if (v >= 1000L) - { - return 4; - } - if (v >= 100L) - { - return 3; - } - if (v >= 10L) - { - return 2; - } - return 1; -} - -/* A floating decimal representing m * 10^e. */ -typedef struct floating_decimal_64 -{ - uint64 mantissa; - int32 exponent; -} floating_decimal_64; - -static inline floating_decimal_64 -d2d(const uint64 ieeeMantissa, const uint32 ieeeExponent) -{ - int32 e2; - uint64 m2; - - if (ieeeExponent == 0) - { - /* We subtract 2 so that the bounds computation has 2 additional bits. */ - e2 = 1 - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; - m2 = ieeeMantissa; - } - else - { - e2 = ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS - 2; - m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa; - } - -#if STRICTLY_SHORTEST - const bool even = (m2 & 1) == 0; - const bool acceptBounds = even; -#else - const bool acceptBounds = false; -#endif - - /* Step 2: Determine the interval of legal decimal representations. */ - const uint64 mv = 4 * m2; - - /* Implicit bool -> int conversion. True is 1, false is 0. */ - const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; - - /* We would compute mp and mm like this: */ - /* uint64 mp = 4 * m2 + 2; */ - /* uint64 mm = mv - 1 - mmShift; */ - - /* Step 3: Convert to a decimal power base using 128-bit arithmetic. */ - uint64 vr, - vp, - vm; - int32 e10; - bool vmIsTrailingZeros = false; - bool vrIsTrailingZeros = false; - - if (e2 >= 0) - { - /* - * I tried special-casing q == 0, but there was no effect on - * performance. - * - * This expr is slightly faster than max(0, log10Pow2(e2) - 1). - */ - const uint32 q = log10Pow2(e2) - (e2 > 3); - const int32 k = DOUBLE_POW5_INV_BITCOUNT + pow5bits(q) - 1; - const int32 i = -e2 + q + k; - - e10 = q; - - vr = mulShiftAll(m2, DOUBLE_POW5_INV_SPLIT[q], i, &vp, &vm, mmShift); - - if (q <= 21) - { - /* - * This should use q <= 22, but I think 21 is also safe. Smaller - * values may still be safe, but it's more difficult to reason - * about them. - * - * Only one of mp, mv, and mm can be a multiple of 5, if any. - */ - const uint32 mvMod5 = (uint32) (mv - 5 * div5(mv)); - - if (mvMod5 == 0) - { - vrIsTrailingZeros = multipleOfPowerOf5(mv, q); - } - else if (acceptBounds) - { - /*---- - * Same as min(e2 + (~mm & 1), pow5Factor(mm)) >= q - * <=> e2 + (~mm & 1) >= q && pow5Factor(mm) >= q - * <=> true && pow5Factor(mm) >= q, since e2 >= q. - *---- - */ - vmIsTrailingZeros = multipleOfPowerOf5(mv - 1 - mmShift, q); - } - else - { - /* Same as min(e2 + 1, pow5Factor(mp)) >= q. */ - vp -= multipleOfPowerOf5(mv + 2, q); - } - } - } - else - { - /* - * This expression is slightly faster than max(0, log10Pow5(-e2) - 1). - */ - const uint32 q = log10Pow5(-e2) - (-e2 > 1); - const int32 i = -e2 - q; - const int32 k = pow5bits(i) - DOUBLE_POW5_BITCOUNT; - const int32 j = q - k; - - e10 = q + e2; - - vr = mulShiftAll(m2, DOUBLE_POW5_SPLIT[i], j, &vp, &vm, mmShift); - - if (q <= 1) - { - /* - * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q - * trailing 0 bits. - */ - /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ - vrIsTrailingZeros = true; - if (acceptBounds) - { - /* - * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff - * mmShift == 1. - */ - vmIsTrailingZeros = mmShift == 1; - } - else - { - /* - * mp = mv + 2, so it always has at least one trailing 0 bit. - */ - --vp; - } - } - else if (q < 63) - { - /* TODO(ulfjack):Use a tighter bound here. */ - /* - * We need to compute min(ntz(mv), pow5Factor(mv) - e2) >= q - 1 - */ - /* <=> ntz(mv) >= q - 1 && pow5Factor(mv) - e2 >= q - 1 */ - /* <=> ntz(mv) >= q - 1 (e2 is negative and -e2 >= q) */ - /* <=> (mv & ((1 << (q - 1)) - 1)) == 0 */ - - /* - * We also need to make sure that the left shift does not - * overflow. - */ - vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); - } - } - - /* - * Step 4: Find the shortest decimal representation in the interval of - * legal representations. - */ - uint32 removed = 0; - uint8 lastRemovedDigit = 0; - uint64 output; - - /* On average, we remove ~2 digits. */ - if (vmIsTrailingZeros || vrIsTrailingZeros) - { - /* General case, which happens rarely (~0.7%). */ - for (;;) - { - const uint64 vpDiv10 = div10(vp); - const uint64 vmDiv10 = div10(vm); - - if (vpDiv10 <= vmDiv10) - break; - - const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10); - const uint64 vrDiv10 = div10(vr); - const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); - - vmIsTrailingZeros &= vmMod10 == 0; - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) vrMod10; - vr = vrDiv10; - vp = vpDiv10; - vm = vmDiv10; - ++removed; - } - - if (vmIsTrailingZeros) - { - for (;;) - { - const uint64 vmDiv10 = div10(vm); - const uint32 vmMod10 = (uint32) (vm - 10 * vmDiv10); - - if (vmMod10 != 0) - break; - - const uint64 vpDiv10 = div10(vp); - const uint64 vrDiv10 = div10(vr); - const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); - - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) vrMod10; - vr = vrDiv10; - vp = vpDiv10; - vm = vmDiv10; - ++removed; - } - } - - if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) - { - /* Round even if the exact number is .....50..0. */ - lastRemovedDigit = 4; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); - } - else - { - /* - * Specialized for the common case (~99.3%). Percentages below are - * relative to this. - */ - bool roundUp = false; - const uint64 vpDiv100 = div100(vp); - const uint64 vmDiv100 = div100(vm); - - if (vpDiv100 > vmDiv100) - { - /* Optimization:remove two digits at a time(~86.2 %). */ - const uint64 vrDiv100 = div100(vr); - const uint32 vrMod100 = (uint32) (vr - 100 * vrDiv100); - - roundUp = vrMod100 >= 50; - vr = vrDiv100; - vp = vpDiv100; - vm = vmDiv100; - removed += 2; - } - - /*---- - * Loop iterations below (approximately), without optimization - * above: - * - * 0: 0.03%, 1: 13.8%, 2: 70.6%, 3: 14.0%, 4: 1.40%, 5: 0.14%, - * 6+: 0.02% - * - * Loop iterations below (approximately), with optimization - * above: - * - * 0: 70.6%, 1: 27.8%, 2: 1.40%, 3: 0.14%, 4+: 0.02% - *---- - */ - for (;;) - { - const uint64 vpDiv10 = div10(vp); - const uint64 vmDiv10 = div10(vm); - - if (vpDiv10 <= vmDiv10) - break; - - const uint64 vrDiv10 = div10(vr); - const uint32 vrMod10 = (uint32) (vr - 10 * vrDiv10); - - roundUp = vrMod10 >= 5; - vr = vrDiv10; - vp = vpDiv10; - vm = vmDiv10; - ++removed; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + (vr == vm || roundUp); - } - - const int32 exp = e10 + removed; - - floating_decimal_64 fd; - - fd.exponent = exp; - fd.mantissa = output; - return fd; -} - -static inline int -to_chars_df(const floating_decimal_64 v, const uint32 olength, char *const result) -{ - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint64 output = v.mantissa; - int32 exp = v.exponent; - - /*---- - * On entry, mantissa * 10^exp is the result to be output. - * Caller has already done the - sign if needed. - * - * We want to insert the point somewhere depending on the output length - * and exponent, which might mean adding zeros: - * - * exp | format - * 1+ | ddddddddd000000 - * 0 | ddddddddd - * -1 .. -len+1 | dddddddd.d to d.ddddddddd - * -len ... | 0.ddddddddd to 0.000dddddd - */ - uint32 i = 0; - int32 nexp = exp + olength; - - if (nexp <= 0) - { - /* -nexp is number of 0s to add after '.' */ - Assert(nexp >= -3); - /* 0.000ddddd */ - index = 2 - nexp; - /* won't need more than this many 0s */ - memcpy(result, "0.000000", 8); - } - else if (exp < 0) - { - /* - * dddd.dddd; leave space at the start and move the '.' in after - */ - index = 1; - } - else - { - /* - * We can save some code later by pre-filling with zeros. We know that - * there can be no more than 16 output digits in this form, otherwise - * we would not choose fixed-point output. - */ - Assert(exp < 16 && exp + olength <= 16); - memset(result, '0', 16); - } - - /* - * We prefer 32-bit operations, even on 64-bit platforms. We have at most - * 17 digits, and uint32 can store 9 digits. If output doesn't fit into - * uint32, we cut off 8 digits, so the rest will fit into uint32. - */ - if ((output >> 32) != 0) - { - /* Expensive 64-bit division. */ - const uint64 q = div1e8(output); - uint32 output2 = (uint32) (output - 100000000 * q); - const uint32 c = output2 % 10000; - - output = q; - output2 /= 10000; - - const uint32 d = output2 % 10000; - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - const uint32 d0 = (d % 100) << 1; - const uint32 d1 = (d / 100) << 1; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); - memcpy(result + index + olength - i - 6, DIGIT_TABLE + d0, 2); - memcpy(result + index + olength - i - 8, DIGIT_TABLE + d1, 2); - i += 8; - } - - uint32 output2 = (uint32) output; - - while (output2 >= 10000) - { - const uint32 c = output2 - 10000 * (output2 / 10000); - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - output2 /= 10000; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output2 >= 100) - { - const uint32 c = (output2 % 100) << 1; - - output2 /= 100; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - i += 2; - } - if (output2 >= 10) - { - const uint32 c = output2 << 1; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - } - else - { - result[index] = (char) ('0' + output2); - } - - if (index == 1) - { - /* - * nexp is 1..15 here, representing the number of digits before the - * point. A value of 16 is not possible because we switch to - * scientific notation when the display exponent reaches 15. - */ - Assert(nexp < 16); - /* gcc only seems to want to optimize memmove for small 2^n */ - if (nexp & 8) - { - memmove(result + index - 1, result + index, 8); - index += 8; - } - if (nexp & 4) - { - memmove(result + index - 1, result + index, 4); - index += 4; - } - if (nexp & 2) - { - memmove(result + index - 1, result + index, 2); - index += 2; - } - if (nexp & 1) - { - result[index - 1] = result[index]; - } - result[nexp] = '.'; - index = olength + 1; - } - else if (exp >= 0) - { - /* we supplied the trailing zeros earlier, now just set the length. */ - index = olength + exp; - } - else - { - index = olength + (2 - nexp); - } - - return index; -} - -static inline int -to_chars(floating_decimal_64 v, const bool sign, char *const result) -{ - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint64 output = v.mantissa; - uint32 olength = decimalLength(output); - int32 exp = v.exponent + olength - 1; - - if (sign) - { - result[index++] = '-'; - } - - /* - * The thresholds for fixed-point output are chosen to match printf - * defaults. Beware that both the code of to_chars_df and the value of - * DOUBLE_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. - */ - if (exp >= -4 && exp < 15) - return to_chars_df(v, olength, result + index) + sign; - - /* - * If v.exponent is exactly 0, we might have reached here via the small - * integer fast path, in which case v.mantissa might contain trailing - * (decimal) zeros. For scientific notation we need to move these zeros - * into the exponent. (For fixed point this doesn't matter, which is why - * we do this here rather than above.) - * - * Since we already calculated the display exponent (exp) above based on - * the old decimal length, that value does not change here. Instead, we - * just reduce the display length for each digit removed. - * - * If we didn't get here via the fast path, the raw exponent will not - * usually be 0, and there will be no trailing zeros, so we pay no more - * than one div10/multiply extra cost. We claw back half of that by - * checking for divisibility by 2 before dividing by 10. - */ - if (v.exponent == 0) - { - while ((output & 1) == 0) - { - const uint64 q = div10(output); - const uint32 r = (uint32) (output - 10 * q); - - if (r != 0) - break; - output = q; - --olength; - } - } - - /*---- - * Print the decimal digits. - * - * The following code is equivalent to: - * - * for (uint32 i = 0; i < olength - 1; ++i) { - * const uint32 c = output % 10; output /= 10; - * result[index + olength - i] = (char) ('0' + c); - * } - * result[index] = '0' + output % 10; - *---- - */ - - uint32 i = 0; - - /* - * We prefer 32-bit operations, even on 64-bit platforms. We have at most - * 17 digits, and uint32 can store 9 digits. If output doesn't fit into - * uint32, we cut off 8 digits, so the rest will fit into uint32. - */ - if ((output >> 32) != 0) - { - /* Expensive 64-bit division. */ - const uint64 q = div1e8(output); - uint32 output2 = (uint32) (output - 100000000 * q); - - output = q; - - const uint32 c = output2 % 10000; - - output2 /= 10000; - - const uint32 d = output2 % 10000; - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - const uint32 d0 = (d % 100) << 1; - const uint32 d1 = (d / 100) << 1; - - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); - memcpy(result + index + olength - i - 5, DIGIT_TABLE + d0, 2); - memcpy(result + index + olength - i - 7, DIGIT_TABLE + d1, 2); - i += 8; - } - - uint32 output2 = (uint32) output; - - while (output2 >= 10000) - { - const uint32 c = output2 - 10000 * (output2 / 10000); - - output2 /= 10000; - - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output2 >= 100) - { - const uint32 c = (output2 % 100) << 1; - - output2 /= 100; - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); - i += 2; - } - if (output2 >= 10) - { - const uint32 c = output2 << 1; - - /* - * We can't use memcpy here: the decimal dot goes between these two - * digits. - */ - result[index + olength - i] = DIGIT_TABLE[c + 1]; - result[index] = DIGIT_TABLE[c]; - } - else - { - result[index] = (char) ('0' + output2); - } - - /* Print decimal point if needed. */ - if (olength > 1) - { - result[index + 1] = '.'; - index += olength + 1; - } - else - { - ++index; - } - - /* Print the exponent. */ - result[index++] = 'e'; - if (exp < 0) - { - result[index++] = '-'; - exp = -exp; - } - else - result[index++] = '+'; - - if (exp >= 100) - { - const int32 c = exp % 10; - - memcpy(result + index, DIGIT_TABLE + 2 * (exp / 10), 2); - result[index + 2] = (char) ('0' + c); - index += 3; - } - else - { - memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); - index += 2; - } - - return index; -} - -static inline bool -d2d_small_int(const uint64 ieeeMantissa, - const uint32 ieeeExponent, - floating_decimal_64 *v) -{ - const int32 e2 = (int32) ieeeExponent - DOUBLE_BIAS - DOUBLE_MANTISSA_BITS; - - /* - * Avoid using multiple "return false;" here since it tends to provoke the - * compiler into inlining multiple copies of d2d, which is undesirable. - */ - - if (e2 >= -DOUBLE_MANTISSA_BITS && e2 <= 0) - { - /*---- - * Since 2^52 <= m2 < 2^53 and 0 <= -e2 <= 52: - * 1 <= f = m2 / 2^-e2 < 2^53. - * - * Test if the lower -e2 bits of the significand are 0, i.e. whether - * the fraction is 0. We can use ieeeMantissa here, since the implied - * 1 bit can never be tested by this; the implied 1 can only be part - * of a fraction if e2 < -DOUBLE_MANTISSA_BITS which we already - * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -53) - */ - const uint64 mask = (UINT64CONST(1) << -e2) - 1; - const uint64 fraction = ieeeMantissa & mask; - - if (fraction == 0) - { - /*---- - * f is an integer in the range [1, 2^53). - * Note: mantissa might contain trailing (decimal) 0's. - * Note: since 2^53 < 10^16, there is no need to adjust - * decimalLength(). - */ - const uint64 m2 = (UINT64CONST(1) << DOUBLE_MANTISSA_BITS) | ieeeMantissa; - - v->mantissa = m2 >> -e2; - v->exponent = 0; - return true; - } - } - - return false; -} - -/* - * Store the shortest decimal representation of the given double as an - * UNTERMINATED string in the caller's supplied buffer (which must be at least - * DOUBLE_SHORTEST_DECIMAL_LEN-1 bytes long). - * - * Returns the number of bytes stored. - */ -int -double_to_shortest_decimal_bufn(double f, char *result) -{ - /* - * Step 1: Decode the floating-point number, and unify normalized and - * subnormal cases. - */ - const uint64 bits = double_to_bits(f); - - /* Decode bits into sign, mantissa, and exponent. */ - const bool ieeeSign = ((bits >> (DOUBLE_MANTISSA_BITS + DOUBLE_EXPONENT_BITS)) & 1) != 0; - const uint64 ieeeMantissa = bits & ((UINT64CONST(1) << DOUBLE_MANTISSA_BITS) - 1); - const uint32 ieeeExponent = (uint32) ((bits >> DOUBLE_MANTISSA_BITS) & ((1u << DOUBLE_EXPONENT_BITS) - 1)); - - /* Case distinction; exit early for the easy cases. */ - if (ieeeExponent == ((1u << DOUBLE_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) - { - return copy_special_str(result, ieeeSign, (ieeeExponent != 0), (ieeeMantissa != 0)); - } - - floating_decimal_64 v; - const bool isSmallInt = d2d_small_int(ieeeMantissa, ieeeExponent, &v); - - if (!isSmallInt) - { - v = d2d(ieeeMantissa, ieeeExponent); - } - - return to_chars(v, ieeeSign, result); -} - -/* - * Store the shortest decimal representation of the given double as a - * null-terminated string in the caller's supplied buffer (which must be at - * least DOUBLE_SHORTEST_DECIMAL_LEN bytes long). - * - * Returns the string length. - */ -int -double_to_shortest_decimal_buf(double f, char *result) -{ - const int index = double_to_shortest_decimal_bufn(f, result); - - /* Terminate the string. */ - Assert(index < DOUBLE_SHORTEST_DECIMAL_LEN); - result[index] = '\0'; - return index; -} - -/* - * Return the shortest decimal representation as a null-terminated palloc'd - * string (outside the backend, uses malloc() instead). - * - * Caller is responsible for freeing the result. - */ -char * -double_to_shortest_decimal(double f) -{ - char *const result = (char *) palloc(DOUBLE_SHORTEST_DECIMAL_LEN); - - double_to_shortest_decimal_buf(f, result); - return result; -} diff --git a/contrib/libs/libpq/src/common/d2s_full_table.h b/contrib/libs/libpq/src/common/d2s_full_table.h deleted file mode 100644 index 23f5e9a45e..0000000000 --- a/contrib/libs/libpq/src/common/d2s_full_table.h +++ /dev/null @@ -1,358 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Ryu floating-point output for double precision. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/d2s_full_table.h - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ - -#ifndef RYU_D2S_FULL_TABLE_H -#define RYU_D2S_FULL_TABLE_H - -/* - * These tables are generated (by the upstream) using PrintDoubleLookupTable - * from the upstream sources at github.com/ulfjack/ryu, and then modified (by - * us) by adding UINT64CONST. - */ -static const uint64 DOUBLE_POW5_INV_SPLIT[292][2] = { - {UINT64CONST(1), UINT64CONST(288230376151711744)}, {UINT64CONST(3689348814741910324), UINT64CONST(230584300921369395)}, - {UINT64CONST(2951479051793528259), UINT64CONST(184467440737095516)}, {UINT64CONST(17118578500402463900), UINT64CONST(147573952589676412)}, - {UINT64CONST(12632330341676300947), UINT64CONST(236118324143482260)}, {UINT64CONST(10105864273341040758), UINT64CONST(188894659314785808)}, - {UINT64CONST(15463389048156653253), UINT64CONST(151115727451828646)}, {UINT64CONST(17362724847566824558), UINT64CONST(241785163922925834)}, - {UINT64CONST(17579528692795369969), UINT64CONST(193428131138340667)}, {UINT64CONST(6684925324752475329), UINT64CONST(154742504910672534)}, - {UINT64CONST(18074578149087781173), UINT64CONST(247588007857076054)}, {UINT64CONST(18149011334012135262), UINT64CONST(198070406285660843)}, - {UINT64CONST(3451162622983977240), UINT64CONST(158456325028528675)}, {UINT64CONST(5521860196774363583), UINT64CONST(253530120045645880)}, - {UINT64CONST(4417488157419490867), UINT64CONST(202824096036516704)}, {UINT64CONST(7223339340677503017), UINT64CONST(162259276829213363)}, - {UINT64CONST(7867994130342094503), UINT64CONST(259614842926741381)}, {UINT64CONST(2605046489531765280), UINT64CONST(207691874341393105)}, - {UINT64CONST(2084037191625412224), UINT64CONST(166153499473114484)}, {UINT64CONST(10713157136084480204), UINT64CONST(265845599156983174)}, - {UINT64CONST(12259874523609494487), UINT64CONST(212676479325586539)}, {UINT64CONST(13497248433629505913), UINT64CONST(170141183460469231)}, - {UINT64CONST(14216899864323388813), UINT64CONST(272225893536750770)}, {UINT64CONST(11373519891458711051), UINT64CONST(217780714829400616)}, - {UINT64CONST(5409467098425058518), UINT64CONST(174224571863520493)}, {UINT64CONST(4965798542738183305), UINT64CONST(278759314981632789)}, - {UINT64CONST(7661987648932456967), UINT64CONST(223007451985306231)}, {UINT64CONST(2440241304404055250), UINT64CONST(178405961588244985)}, - {UINT64CONST(3904386087046488400), UINT64CONST(285449538541191976)}, {UINT64CONST(17880904128604832013), UINT64CONST(228359630832953580)}, - {UINT64CONST(14304723302883865611), UINT64CONST(182687704666362864)}, {UINT64CONST(15133127457049002812), UINT64CONST(146150163733090291)}, - {UINT64CONST(16834306301794583852), UINT64CONST(233840261972944466)}, {UINT64CONST(9778096226693756759), UINT64CONST(187072209578355573)}, - {UINT64CONST(15201174610838826053), UINT64CONST(149657767662684458)}, {UINT64CONST(2185786488890659746), UINT64CONST(239452428260295134)}, - {UINT64CONST(5437978005854438120), UINT64CONST(191561942608236107)}, {UINT64CONST(15418428848909281466), UINT64CONST(153249554086588885)}, - {UINT64CONST(6222742084545298729), UINT64CONST(245199286538542217)}, {UINT64CONST(16046240111861969953), UINT64CONST(196159429230833773)}, - {UINT64CONST(1768945645263844993), UINT64CONST(156927543384667019)}, {UINT64CONST(10209010661905972635), UINT64CONST(251084069415467230)}, - {UINT64CONST(8167208529524778108), UINT64CONST(200867255532373784)}, {UINT64CONST(10223115638361732810), UINT64CONST(160693804425899027)}, - {UINT64CONST(1599589762411131202), UINT64CONST(257110087081438444)}, {UINT64CONST(4969020624670815285), UINT64CONST(205688069665150755)}, - {UINT64CONST(3975216499736652228), UINT64CONST(164550455732120604)}, {UINT64CONST(13739044029062464211), UINT64CONST(263280729171392966)}, - {UINT64CONST(7301886408508061046), UINT64CONST(210624583337114373)}, {UINT64CONST(13220206756290269483), UINT64CONST(168499666669691498)}, - {UINT64CONST(17462981995322520850), UINT64CONST(269599466671506397)}, {UINT64CONST(6591687966774196033), UINT64CONST(215679573337205118)}, - {UINT64CONST(12652048002903177473), UINT64CONST(172543658669764094)}, {UINT64CONST(9175230360419352987), UINT64CONST(276069853871622551)}, - {UINT64CONST(3650835473593572067), UINT64CONST(220855883097298041)}, {UINT64CONST(17678063637842498946), UINT64CONST(176684706477838432)}, - {UINT64CONST(13527506561580357021), UINT64CONST(282695530364541492)}, {UINT64CONST(3443307619780464970), UINT64CONST(226156424291633194)}, - {UINT64CONST(6443994910566282300), UINT64CONST(180925139433306555)}, {UINT64CONST(5155195928453025840), UINT64CONST(144740111546645244)}, - {UINT64CONST(15627011115008661990), UINT64CONST(231584178474632390)}, {UINT64CONST(12501608892006929592), UINT64CONST(185267342779705912)}, - {UINT64CONST(2622589484121723027), UINT64CONST(148213874223764730)}, {UINT64CONST(4196143174594756843), UINT64CONST(237142198758023568)}, - {UINT64CONST(10735612169159626121), UINT64CONST(189713759006418854)}, {UINT64CONST(12277838550069611220), UINT64CONST(151771007205135083)}, - {UINT64CONST(15955192865369467629), UINT64CONST(242833611528216133)}, {UINT64CONST(1696107848069843133), UINT64CONST(194266889222572907)}, - {UINT64CONST(12424932722681605476), UINT64CONST(155413511378058325)}, {UINT64CONST(1433148282581017146), UINT64CONST(248661618204893321)}, - {UINT64CONST(15903913885032455010), UINT64CONST(198929294563914656)}, {UINT64CONST(9033782293284053685), UINT64CONST(159143435651131725)}, - {UINT64CONST(14454051669254485895), UINT64CONST(254629497041810760)}, {UINT64CONST(11563241335403588716), UINT64CONST(203703597633448608)}, - {UINT64CONST(16629290697806691620), UINT64CONST(162962878106758886)}, {UINT64CONST(781423413297334329), UINT64CONST(260740604970814219)}, - {UINT64CONST(4314487545379777786), UINT64CONST(208592483976651375)}, {UINT64CONST(3451590036303822229), UINT64CONST(166873987181321100)}, - {UINT64CONST(5522544058086115566), UINT64CONST(266998379490113760)}, {UINT64CONST(4418035246468892453), UINT64CONST(213598703592091008)}, - {UINT64CONST(10913125826658934609), UINT64CONST(170878962873672806)}, {UINT64CONST(10082303693170474728), UINT64CONST(273406340597876490)}, - {UINT64CONST(8065842954536379782), UINT64CONST(218725072478301192)}, {UINT64CONST(17520720807854834795), UINT64CONST(174980057982640953)}, - {UINT64CONST(5897060404116273733), UINT64CONST(279968092772225526)}, {UINT64CONST(1028299508551108663), UINT64CONST(223974474217780421)}, - {UINT64CONST(15580034865808528224), UINT64CONST(179179579374224336)}, {UINT64CONST(17549358155809824511), UINT64CONST(286687326998758938)}, - {UINT64CONST(2971440080422128639), UINT64CONST(229349861599007151)}, {UINT64CONST(17134547323305344204), UINT64CONST(183479889279205720)}, - {UINT64CONST(13707637858644275364), UINT64CONST(146783911423364576)}, {UINT64CONST(14553522944347019935), UINT64CONST(234854258277383322)}, - {UINT64CONST(4264120725993795302), UINT64CONST(187883406621906658)}, {UINT64CONST(10789994210278856888), UINT64CONST(150306725297525326)}, - {UINT64CONST(9885293106962350374), UINT64CONST(240490760476040522)}, {UINT64CONST(529536856086059653), UINT64CONST(192392608380832418)}, - {UINT64CONST(7802327114352668369), UINT64CONST(153914086704665934)}, {UINT64CONST(1415676938738538420), UINT64CONST(246262538727465495)}, - {UINT64CONST(1132541550990830736), UINT64CONST(197010030981972396)}, {UINT64CONST(15663428499760305882), UINT64CONST(157608024785577916)}, - {UINT64CONST(17682787970132668764), UINT64CONST(252172839656924666)}, {UINT64CONST(10456881561364224688), UINT64CONST(201738271725539733)}, - {UINT64CONST(15744202878575200397), UINT64CONST(161390617380431786)}, {UINT64CONST(17812026976236499989), UINT64CONST(258224987808690858)}, - {UINT64CONST(3181575136763469022), UINT64CONST(206579990246952687)}, {UINT64CONST(13613306553636506187), UINT64CONST(165263992197562149)}, - {UINT64CONST(10713244041592678929), UINT64CONST(264422387516099439)}, {UINT64CONST(12259944048016053467), UINT64CONST(211537910012879551)}, - {UINT64CONST(6118606423670932450), UINT64CONST(169230328010303641)}, {UINT64CONST(2411072648389671274), UINT64CONST(270768524816485826)}, - {UINT64CONST(16686253377679378312), UINT64CONST(216614819853188660)}, {UINT64CONST(13349002702143502650), UINT64CONST(173291855882550928)}, - {UINT64CONST(17669055508687693916), UINT64CONST(277266969412081485)}, {UINT64CONST(14135244406950155133), UINT64CONST(221813575529665188)}, - {UINT64CONST(240149081334393137), UINT64CONST(177450860423732151)}, {UINT64CONST(11452284974360759988), UINT64CONST(283921376677971441)}, - {UINT64CONST(5472479164746697667), UINT64CONST(227137101342377153)}, {UINT64CONST(11756680961281178780), UINT64CONST(181709681073901722)}, - {UINT64CONST(2026647139541122378), UINT64CONST(145367744859121378)}, {UINT64CONST(18000030682233437097), UINT64CONST(232588391774594204)}, - {UINT64CONST(18089373360528660001), UINT64CONST(186070713419675363)}, {UINT64CONST(3403452244197197031), UINT64CONST(148856570735740291)}, - {UINT64CONST(16513570034941246220), UINT64CONST(238170513177184465)}, {UINT64CONST(13210856027952996976), UINT64CONST(190536410541747572)}, - {UINT64CONST(3189987192878576934), UINT64CONST(152429128433398058)}, {UINT64CONST(1414630693863812771), UINT64CONST(243886605493436893)}, - {UINT64CONST(8510402184574870864), UINT64CONST(195109284394749514)}, {UINT64CONST(10497670562401807014), UINT64CONST(156087427515799611)}, - {UINT64CONST(9417575270359070576), UINT64CONST(249739884025279378)}, {UINT64CONST(14912757845771077107), UINT64CONST(199791907220223502)}, - {UINT64CONST(4551508647133041040), UINT64CONST(159833525776178802)}, {UINT64CONST(10971762650154775986), UINT64CONST(255733641241886083)}, - {UINT64CONST(16156107749607641435), UINT64CONST(204586912993508866)}, {UINT64CONST(9235537384944202825), UINT64CONST(163669530394807093)}, - {UINT64CONST(11087511001168814197), UINT64CONST(261871248631691349)}, {UINT64CONST(12559357615676961681), UINT64CONST(209496998905353079)}, - {UINT64CONST(13736834907283479668), UINT64CONST(167597599124282463)}, {UINT64CONST(18289587036911657145), UINT64CONST(268156158598851941)}, - {UINT64CONST(10942320814787415393), UINT64CONST(214524926879081553)}, {UINT64CONST(16132554281313752961), UINT64CONST(171619941503265242)}, - {UINT64CONST(11054691591134363444), UINT64CONST(274591906405224388)}, {UINT64CONST(16222450902391311402), UINT64CONST(219673525124179510)}, - {UINT64CONST(12977960721913049122), UINT64CONST(175738820099343608)}, {UINT64CONST(17075388340318968271), UINT64CONST(281182112158949773)}, - {UINT64CONST(2592264228029443648), UINT64CONST(224945689727159819)}, {UINT64CONST(5763160197165465241), UINT64CONST(179956551781727855)}, - {UINT64CONST(9221056315464744386), UINT64CONST(287930482850764568)}, {UINT64CONST(14755542681855616155), UINT64CONST(230344386280611654)}, - {UINT64CONST(15493782960226403247), UINT64CONST(184275509024489323)}, {UINT64CONST(1326979923955391628), UINT64CONST(147420407219591459)}, - {UINT64CONST(9501865507812447252), UINT64CONST(235872651551346334)}, {UINT64CONST(11290841220991868125), UINT64CONST(188698121241077067)}, - {UINT64CONST(1653975347309673853), UINT64CONST(150958496992861654)}, {UINT64CONST(10025058185179298811), UINT64CONST(241533595188578646)}, - {UINT64CONST(4330697733401528726), UINT64CONST(193226876150862917)}, {UINT64CONST(14532604630946953951), UINT64CONST(154581500920690333)}, - {UINT64CONST(1116074521063664381), UINT64CONST(247330401473104534)}, {UINT64CONST(4582208431592841828), UINT64CONST(197864321178483627)}, - {UINT64CONST(14733813189500004432), UINT64CONST(158291456942786901)}, {UINT64CONST(16195403473716186445), UINT64CONST(253266331108459042)}, - {UINT64CONST(5577625149489128510), UINT64CONST(202613064886767234)}, {UINT64CONST(8151448934333213131), UINT64CONST(162090451909413787)}, - {UINT64CONST(16731667109675051333), UINT64CONST(259344723055062059)}, {UINT64CONST(17074682502481951390), UINT64CONST(207475778444049647)}, - {UINT64CONST(6281048372501740465), UINT64CONST(165980622755239718)}, {UINT64CONST(6360328581260874421), UINT64CONST(265568996408383549)}, - {UINT64CONST(8777611679750609860), UINT64CONST(212455197126706839)}, {UINT64CONST(10711438158542398211), UINT64CONST(169964157701365471)}, - {UINT64CONST(9759603424184016492), UINT64CONST(271942652322184754)}, {UINT64CONST(11497031554089123517), UINT64CONST(217554121857747803)}, - {UINT64CONST(16576322872755119460), UINT64CONST(174043297486198242)}, {UINT64CONST(11764721337440549842), UINT64CONST(278469275977917188)}, - {UINT64CONST(16790474699436260520), UINT64CONST(222775420782333750)}, {UINT64CONST(13432379759549008416), UINT64CONST(178220336625867000)}, - {UINT64CONST(3045063541568861850), UINT64CONST(285152538601387201)}, {UINT64CONST(17193446092222730773), UINT64CONST(228122030881109760)}, - {UINT64CONST(13754756873778184618), UINT64CONST(182497624704887808)}, {UINT64CONST(18382503128506368341), UINT64CONST(145998099763910246)}, - {UINT64CONST(3586563302416817083), UINT64CONST(233596959622256395)}, {UINT64CONST(2869250641933453667), UINT64CONST(186877567697805116)}, - {UINT64CONST(17052795772514404226), UINT64CONST(149502054158244092)}, {UINT64CONST(12527077977055405469), UINT64CONST(239203286653190548)}, - {UINT64CONST(17400360011128145022), UINT64CONST(191362629322552438)}, {UINT64CONST(2852241564676785048), UINT64CONST(153090103458041951)}, - {UINT64CONST(15631632947708587046), UINT64CONST(244944165532867121)}, {UINT64CONST(8815957543424959314), UINT64CONST(195955332426293697)}, - {UINT64CONST(18120812478965698421), UINT64CONST(156764265941034957)}, {UINT64CONST(14235904707377476180), UINT64CONST(250822825505655932)}, - {UINT64CONST(4010026136418160298), UINT64CONST(200658260404524746)}, {UINT64CONST(17965416168102169531), UINT64CONST(160526608323619796)}, - {UINT64CONST(2919224165770098987), UINT64CONST(256842573317791675)}, {UINT64CONST(2335379332616079190), UINT64CONST(205474058654233340)}, - {UINT64CONST(1868303466092863352), UINT64CONST(164379246923386672)}, {UINT64CONST(6678634360490491686), UINT64CONST(263006795077418675)}, - {UINT64CONST(5342907488392393349), UINT64CONST(210405436061934940)}, {UINT64CONST(4274325990713914679), UINT64CONST(168324348849547952)}, - {UINT64CONST(10528270399884173809), UINT64CONST(269318958159276723)}, {UINT64CONST(15801313949391159694), UINT64CONST(215455166527421378)}, - {UINT64CONST(1573004715287196786), UINT64CONST(172364133221937103)}, {UINT64CONST(17274202803427156150), UINT64CONST(275782613155099364)}, - {UINT64CONST(17508711057483635243), UINT64CONST(220626090524079491)}, {UINT64CONST(10317620031244997871), UINT64CONST(176500872419263593)}, - {UINT64CONST(12818843235250086271), UINT64CONST(282401395870821749)}, {UINT64CONST(13944423402941979340), UINT64CONST(225921116696657399)}, - {UINT64CONST(14844887537095493795), UINT64CONST(180736893357325919)}, {UINT64CONST(15565258844418305359), UINT64CONST(144589514685860735)}, - {UINT64CONST(6457670077359736959), UINT64CONST(231343223497377177)}, {UINT64CONST(16234182506113520537), UINT64CONST(185074578797901741)}, - {UINT64CONST(9297997190148906106), UINT64CONST(148059663038321393)}, {UINT64CONST(11187446689496339446), UINT64CONST(236895460861314229)}, - {UINT64CONST(12639306166338981880), UINT64CONST(189516368689051383)}, {UINT64CONST(17490142562555006151), UINT64CONST(151613094951241106)}, - {UINT64CONST(2158786396894637579), UINT64CONST(242580951921985771)}, {UINT64CONST(16484424376483351356), UINT64CONST(194064761537588616)}, - {UINT64CONST(9498190686444770762), UINT64CONST(155251809230070893)}, {UINT64CONST(11507756283569722895), UINT64CONST(248402894768113429)}, - {UINT64CONST(12895553841597688639), UINT64CONST(198722315814490743)}, {UINT64CONST(17695140702761971558), UINT64CONST(158977852651592594)}, - {UINT64CONST(17244178680193423523), UINT64CONST(254364564242548151)}, {UINT64CONST(10105994129412828495), UINT64CONST(203491651394038521)}, - {UINT64CONST(4395446488788352473), UINT64CONST(162793321115230817)}, {UINT64CONST(10722063196803274280), UINT64CONST(260469313784369307)}, - {UINT64CONST(1198952927958798777), UINT64CONST(208375451027495446)}, {UINT64CONST(15716557601334680315), UINT64CONST(166700360821996356)}, - {UINT64CONST(17767794532651667857), UINT64CONST(266720577315194170)}, {UINT64CONST(14214235626121334286), UINT64CONST(213376461852155336)}, - {UINT64CONST(7682039686155157106), UINT64CONST(170701169481724269)}, {UINT64CONST(1223217053622520399), UINT64CONST(273121871170758831)}, - {UINT64CONST(15735968901865657612), UINT64CONST(218497496936607064)}, {UINT64CONST(16278123936234436413), UINT64CONST(174797997549285651)}, - {UINT64CONST(219556594781725998), UINT64CONST(279676796078857043)}, {UINT64CONST(7554342905309201445), UINT64CONST(223741436863085634)}, - {UINT64CONST(9732823138989271479), UINT64CONST(178993149490468507)}, {UINT64CONST(815121763415193074), UINT64CONST(286389039184749612)}, - {UINT64CONST(11720143854957885429), UINT64CONST(229111231347799689)}, {UINT64CONST(13065463898708218666), UINT64CONST(183288985078239751)}, - {UINT64CONST(6763022304224664610), UINT64CONST(146631188062591801)}, {UINT64CONST(3442138057275642729), UINT64CONST(234609900900146882)}, - {UINT64CONST(13821756890046245153), UINT64CONST(187687920720117505)}, {UINT64CONST(11057405512036996122), UINT64CONST(150150336576094004)}, - {UINT64CONST(6623802375033462826), UINT64CONST(240240538521750407)}, {UINT64CONST(16367088344252501231), UINT64CONST(192192430817400325)}, - {UINT64CONST(13093670675402000985), UINT64CONST(153753944653920260)}, {UINT64CONST(2503129006933649959), UINT64CONST(246006311446272417)}, - {UINT64CONST(13070549649772650937), UINT64CONST(196805049157017933)}, {UINT64CONST(17835137349301941396), UINT64CONST(157444039325614346)}, - {UINT64CONST(2710778055689733971), UINT64CONST(251910462920982955)}, {UINT64CONST(2168622444551787177), UINT64CONST(201528370336786364)}, - {UINT64CONST(5424246770383340065), UINT64CONST(161222696269429091)}, {UINT64CONST(1300097203129523457), UINT64CONST(257956314031086546)}, - {UINT64CONST(15797473021471260058), UINT64CONST(206365051224869236)}, {UINT64CONST(8948629602435097724), UINT64CONST(165092040979895389)}, - {UINT64CONST(3249760919670425388), UINT64CONST(264147265567832623)}, {UINT64CONST(9978506365220160957), UINT64CONST(211317812454266098)}, - {UINT64CONST(15361502721659949412), UINT64CONST(169054249963412878)}, {UINT64CONST(2442311466204457120), UINT64CONST(270486799941460606)}, - {UINT64CONST(16711244431931206989), UINT64CONST(216389439953168484)}, {UINT64CONST(17058344360286875914), UINT64CONST(173111551962534787)}, - {UINT64CONST(12535955717491360170), UINT64CONST(276978483140055660)}, {UINT64CONST(10028764573993088136), UINT64CONST(221582786512044528)}, - {UINT64CONST(15401709288678291155), UINT64CONST(177266229209635622)}, {UINT64CONST(9885339602917624555), UINT64CONST(283625966735416996)}, - {UINT64CONST(4218922867592189321), UINT64CONST(226900773388333597)}, {UINT64CONST(14443184738299482427), UINT64CONST(181520618710666877)}, - {UINT64CONST(4175850161155765295), UINT64CONST(145216494968533502)}, {UINT64CONST(10370709072591134795), UINT64CONST(232346391949653603)}, - {UINT64CONST(15675264887556728482), UINT64CONST(185877113559722882)}, {UINT64CONST(5161514280561562140), UINT64CONST(148701690847778306)}, - {UINT64CONST(879725219414678777), UINT64CONST(237922705356445290)}, {UINT64CONST(703780175531743021), UINT64CONST(190338164285156232)}, - {UINT64CONST(11631070584651125387), UINT64CONST(152270531428124985)}, {UINT64CONST(162968861732249003), UINT64CONST(243632850284999977)}, - {UINT64CONST(11198421533611530172), UINT64CONST(194906280227999981)}, {UINT64CONST(5269388412147313814), UINT64CONST(155925024182399985)}, - {UINT64CONST(8431021459435702103), UINT64CONST(249480038691839976)}, {UINT64CONST(3055468352806651359), UINT64CONST(199584030953471981)}, - {UINT64CONST(17201769941212962380), UINT64CONST(159667224762777584)}, {UINT64CONST(16454785461715008838), UINT64CONST(255467559620444135)}, - {UINT64CONST(13163828369372007071), UINT64CONST(204374047696355308)}, {UINT64CONST(17909760324981426303), UINT64CONST(163499238157084246)}, - {UINT64CONST(2830174816776909822), UINT64CONST(261598781051334795)}, {UINT64CONST(2264139853421527858), UINT64CONST(209279024841067836)}, - {UINT64CONST(16568707141704863579), UINT64CONST(167423219872854268)}, {UINT64CONST(4373838538276319787), UINT64CONST(267877151796566830)}, - {UINT64CONST(3499070830621055830), UINT64CONST(214301721437253464)}, {UINT64CONST(6488605479238754987), UINT64CONST(171441377149802771)}, - {UINT64CONST(3003071137298187333), UINT64CONST(274306203439684434)}, {UINT64CONST(6091805724580460189), UINT64CONST(219444962751747547)}, - {UINT64CONST(15941491023890099121), UINT64CONST(175555970201398037)}, {UINT64CONST(10748990379256517301), UINT64CONST(280889552322236860)}, - {UINT64CONST(8599192303405213841), UINT64CONST(224711641857789488)}, {UINT64CONST(14258051472207991719), UINT64CONST(179769313486231590)} -}; - -static const uint64 DOUBLE_POW5_SPLIT[326][2] = { - {UINT64CONST(0), UINT64CONST(72057594037927936)}, {UINT64CONST(0), UINT64CONST(90071992547409920)}, - {UINT64CONST(0), UINT64CONST(112589990684262400)}, {UINT64CONST(0), UINT64CONST(140737488355328000)}, - {UINT64CONST(0), UINT64CONST(87960930222080000)}, {UINT64CONST(0), UINT64CONST(109951162777600000)}, - {UINT64CONST(0), UINT64CONST(137438953472000000)}, {UINT64CONST(0), UINT64CONST(85899345920000000)}, - {UINT64CONST(0), UINT64CONST(107374182400000000)}, {UINT64CONST(0), UINT64CONST(134217728000000000)}, - {UINT64CONST(0), UINT64CONST(83886080000000000)}, {UINT64CONST(0), UINT64CONST(104857600000000000)}, - {UINT64CONST(0), UINT64CONST(131072000000000000)}, {UINT64CONST(0), UINT64CONST(81920000000000000)}, - {UINT64CONST(0), UINT64CONST(102400000000000000)}, {UINT64CONST(0), UINT64CONST(128000000000000000)}, - {UINT64CONST(0), UINT64CONST(80000000000000000)}, {UINT64CONST(0), UINT64CONST(100000000000000000)}, - {UINT64CONST(0), UINT64CONST(125000000000000000)}, {UINT64CONST(0), UINT64CONST(78125000000000000)}, - {UINT64CONST(0), UINT64CONST(97656250000000000)}, {UINT64CONST(0), UINT64CONST(122070312500000000)}, - {UINT64CONST(0), UINT64CONST(76293945312500000)}, {UINT64CONST(0), UINT64CONST(95367431640625000)}, - {UINT64CONST(0), UINT64CONST(119209289550781250)}, {UINT64CONST(4611686018427387904), UINT64CONST(74505805969238281)}, - {UINT64CONST(10376293541461622784), UINT64CONST(93132257461547851)}, {UINT64CONST(8358680908399640576), UINT64CONST(116415321826934814)}, - {UINT64CONST(612489549322387456), UINT64CONST(72759576141834259)}, {UINT64CONST(14600669991935148032), UINT64CONST(90949470177292823)}, - {UINT64CONST(13639151471491547136), UINT64CONST(113686837721616029)}, {UINT64CONST(3213881284082270208), UINT64CONST(142108547152020037)}, - {UINT64CONST(4314518811765112832), UINT64CONST(88817841970012523)}, {UINT64CONST(781462496279003136), UINT64CONST(111022302462515654)}, - {UINT64CONST(10200200157203529728), UINT64CONST(138777878078144567)}, {UINT64CONST(13292654125893287936), UINT64CONST(86736173798840354)}, - {UINT64CONST(7392445620511834112), UINT64CONST(108420217248550443)}, {UINT64CONST(4628871007212404736), UINT64CONST(135525271560688054)}, - {UINT64CONST(16728102434789916672), UINT64CONST(84703294725430033)}, {UINT64CONST(7075069988205232128), UINT64CONST(105879118406787542)}, - {UINT64CONST(18067209522111315968), UINT64CONST(132348898008484427)}, {UINT64CONST(8986162942105878528), UINT64CONST(82718061255302767)}, - {UINT64CONST(6621017659204960256), UINT64CONST(103397576569128459)}, {UINT64CONST(3664586055578812416), UINT64CONST(129246970711410574)}, - {UINT64CONST(16125424340018921472), UINT64CONST(80779356694631608)}, {UINT64CONST(1710036351314100224), UINT64CONST(100974195868289511)}, - {UINT64CONST(15972603494424788992), UINT64CONST(126217744835361888)}, {UINT64CONST(9982877184015493120), UINT64CONST(78886090522101180)}, - {UINT64CONST(12478596480019366400), UINT64CONST(98607613152626475)}, {UINT64CONST(10986559581596820096), UINT64CONST(123259516440783094)}, - {UINT64CONST(2254913720070624656), UINT64CONST(77037197775489434)}, {UINT64CONST(12042014186943056628), UINT64CONST(96296497219361792)}, - {UINT64CONST(15052517733678820785), UINT64CONST(120370621524202240)}, {UINT64CONST(9407823583549262990), UINT64CONST(75231638452626400)}, - {UINT64CONST(11759779479436578738), UINT64CONST(94039548065783000)}, {UINT64CONST(14699724349295723422), UINT64CONST(117549435082228750)}, - {UINT64CONST(4575641699882439235), UINT64CONST(73468396926392969)}, {UINT64CONST(10331238143280436948), UINT64CONST(91835496157991211)}, - {UINT64CONST(8302361660673158281), UINT64CONST(114794370197489014)}, {UINT64CONST(1154580038986672043), UINT64CONST(143492962746861268)}, - {UINT64CONST(9944984561221445835), UINT64CONST(89683101716788292)}, {UINT64CONST(12431230701526807293), UINT64CONST(112103877145985365)}, - {UINT64CONST(1703980321626345405), UINT64CONST(140129846432481707)}, {UINT64CONST(17205888765512323542), UINT64CONST(87581154020301066)}, - {UINT64CONST(12283988920035628619), UINT64CONST(109476442525376333)}, {UINT64CONST(1519928094762372062), UINT64CONST(136845553156720417)}, - {UINT64CONST(12479170105294952299), UINT64CONST(85528470722950260)}, {UINT64CONST(15598962631618690374), UINT64CONST(106910588403687825)}, - {UINT64CONST(5663645234241199255), UINT64CONST(133638235504609782)}, {UINT64CONST(17374836326682913246), UINT64CONST(83523897190381113)}, - {UINT64CONST(7883487353071477846), UINT64CONST(104404871487976392)}, {UINT64CONST(9854359191339347308), UINT64CONST(130506089359970490)}, - {UINT64CONST(10770660513014479971), UINT64CONST(81566305849981556)}, {UINT64CONST(13463325641268099964), UINT64CONST(101957882312476945)}, - {UINT64CONST(2994098996302961243), UINT64CONST(127447352890596182)}, {UINT64CONST(15706369927971514489), UINT64CONST(79654595556622613)}, - {UINT64CONST(5797904354682229399), UINT64CONST(99568244445778267)}, {UINT64CONST(2635694424925398845), UINT64CONST(124460305557222834)}, - {UINT64CONST(6258995034005762182), UINT64CONST(77787690973264271)}, {UINT64CONST(3212057774079814824), UINT64CONST(97234613716580339)}, - {UINT64CONST(17850130272881932242), UINT64CONST(121543267145725423)}, {UINT64CONST(18073860448192289507), UINT64CONST(75964541966078389)}, - {UINT64CONST(8757267504958198172), UINT64CONST(94955677457597987)}, {UINT64CONST(6334898362770359811), UINT64CONST(118694596821997484)}, - {UINT64CONST(13182683513586250689), UINT64CONST(74184123013748427)}, {UINT64CONST(11866668373555425458), UINT64CONST(92730153767185534)}, - {UINT64CONST(5609963430089506015), UINT64CONST(115912692208981918)}, {UINT64CONST(17341285199088104971), UINT64CONST(72445432630613698)}, - {UINT64CONST(12453234462005355406), UINT64CONST(90556790788267123)}, {UINT64CONST(10954857059079306353), UINT64CONST(113195988485333904)}, - {UINT64CONST(13693571323849132942), UINT64CONST(141494985606667380)}, {UINT64CONST(17781854114260483896), UINT64CONST(88434366004167112)}, - {UINT64CONST(3780573569116053255), UINT64CONST(110542957505208891)}, {UINT64CONST(114030942967678664), UINT64CONST(138178696881511114)}, - {UINT64CONST(4682955357782187069), UINT64CONST(86361685550944446)}, {UINT64CONST(15077066234082509644), UINT64CONST(107952106938680557)}, - {UINT64CONST(5011274737320973344), UINT64CONST(134940133673350697)}, {UINT64CONST(14661261756894078100), UINT64CONST(84337583545844185)}, - {UINT64CONST(4491519140835433913), UINT64CONST(105421979432305232)}, {UINT64CONST(5614398926044292391), UINT64CONST(131777474290381540)}, - {UINT64CONST(12732371365632458552), UINT64CONST(82360921431488462)}, {UINT64CONST(6692092170185797382), UINT64CONST(102951151789360578)}, - {UINT64CONST(17588487249587022536), UINT64CONST(128688939736700722)}, {UINT64CONST(15604490549419276989), UINT64CONST(80430587335437951)}, - {UINT64CONST(14893927168346708332), UINT64CONST(100538234169297439)}, {UINT64CONST(14005722942005997511), UINT64CONST(125672792711621799)}, - {UINT64CONST(15671105866394830300), UINT64CONST(78545495444763624)}, {UINT64CONST(1142138259283986260), UINT64CONST(98181869305954531)}, - {UINT64CONST(15262730879387146537), UINT64CONST(122727336632443163)}, {UINT64CONST(7233363790403272633), UINT64CONST(76704585395276977)}, - {UINT64CONST(13653390756431478696), UINT64CONST(95880731744096221)}, {UINT64CONST(3231680390257184658), UINT64CONST(119850914680120277)}, - {UINT64CONST(4325643253124434363), UINT64CONST(74906821675075173)}, {UINT64CONST(10018740084832930858), UINT64CONST(93633527093843966)}, - {UINT64CONST(3300053069186387764), UINT64CONST(117041908867304958)}, {UINT64CONST(15897591223523656064), UINT64CONST(73151193042065598)}, - {UINT64CONST(10648616992549794273), UINT64CONST(91438991302581998)}, {UINT64CONST(4087399203832467033), UINT64CONST(114298739128227498)}, - {UINT64CONST(14332621041645359599), UINT64CONST(142873423910284372)}, {UINT64CONST(18181260187883125557), UINT64CONST(89295889943927732)}, - {UINT64CONST(4279831161144355331), UINT64CONST(111619862429909666)}, {UINT64CONST(14573160988285219972), UINT64CONST(139524828037387082)}, - {UINT64CONST(13719911636105650386), UINT64CONST(87203017523366926)}, {UINT64CONST(7926517508277287175), UINT64CONST(109003771904208658)}, - {UINT64CONST(684774848491833161), UINT64CONST(136254714880260823)}, {UINT64CONST(7345513307948477581), UINT64CONST(85159196800163014)}, - {UINT64CONST(18405263671790372785), UINT64CONST(106448996000203767)}, {UINT64CONST(18394893571310578077), UINT64CONST(133061245000254709)}, - {UINT64CONST(13802651491282805250), UINT64CONST(83163278125159193)}, {UINT64CONST(3418256308821342851), UINT64CONST(103954097656448992)}, - {UINT64CONST(4272820386026678563), UINT64CONST(129942622070561240)}, {UINT64CONST(2670512741266674102), UINT64CONST(81214138794100775)}, - {UINT64CONST(17173198981865506339), UINT64CONST(101517673492625968)}, {UINT64CONST(3019754653622331308), UINT64CONST(126897091865782461)}, - {UINT64CONST(4193189667727651020), UINT64CONST(79310682416114038)}, {UINT64CONST(14464859121514339583), UINT64CONST(99138353020142547)}, - {UINT64CONST(13469387883465536574), UINT64CONST(123922941275178184)}, {UINT64CONST(8418367427165960359), UINT64CONST(77451838296986365)}, - {UINT64CONST(15134645302384838353), UINT64CONST(96814797871232956)}, {UINT64CONST(471562554271496325), UINT64CONST(121018497339041196)}, - {UINT64CONST(9518098633274461011), UINT64CONST(75636560836900747)}, {UINT64CONST(7285937273165688360), UINT64CONST(94545701046125934)}, - {UINT64CONST(18330793628311886258), UINT64CONST(118182126307657417)}, {UINT64CONST(4539216990053847055), UINT64CONST(73863828942285886)}, - {UINT64CONST(14897393274422084627), UINT64CONST(92329786177857357)}, {UINT64CONST(4786683537745442072), UINT64CONST(115412232722321697)}, - {UINT64CONST(14520892257159371055), UINT64CONST(72132645451451060)}, {UINT64CONST(18151115321449213818), UINT64CONST(90165806814313825)}, - {UINT64CONST(8853836096529353561), UINT64CONST(112707258517892282)}, {UINT64CONST(1843923083806916143), UINT64CONST(140884073147365353)}, - {UINT64CONST(12681666973447792349), UINT64CONST(88052545717103345)}, {UINT64CONST(2017025661527576725), UINT64CONST(110065682146379182)}, - {UINT64CONST(11744654113764246714), UINT64CONST(137582102682973977)}, {UINT64CONST(422879793461572340), UINT64CONST(85988814176858736)}, - {UINT64CONST(528599741826965425), UINT64CONST(107486017721073420)}, {UINT64CONST(660749677283706782), UINT64CONST(134357522151341775)}, - {UINT64CONST(7330497575943398595), UINT64CONST(83973451344588609)}, {UINT64CONST(13774807988356636147), UINT64CONST(104966814180735761)}, - {UINT64CONST(3383451930163631472), UINT64CONST(131208517725919702)}, {UINT64CONST(15949715511634433382), UINT64CONST(82005323578699813)}, - {UINT64CONST(6102086334260878016), UINT64CONST(102506654473374767)}, {UINT64CONST(3015921899398709616), UINT64CONST(128133318091718459)}, - {UINT64CONST(18025852251620051174), UINT64CONST(80083323807324036)}, {UINT64CONST(4085571240815512351), UINT64CONST(100104154759155046)}, - {UINT64CONST(14330336087874166247), UINT64CONST(125130193448943807)}, {UINT64CONST(15873989082562435760), UINT64CONST(78206370905589879)}, - {UINT64CONST(15230800334775656796), UINT64CONST(97757963631987349)}, {UINT64CONST(5203442363187407284), UINT64CONST(122197454539984187)}, - {UINT64CONST(946308467778435600), UINT64CONST(76373409087490117)}, {UINT64CONST(5794571603150432404), UINT64CONST(95466761359362646)}, - {UINT64CONST(16466586540792816313), UINT64CONST(119333451699203307)}, {UINT64CONST(7985773578781816244), UINT64CONST(74583407312002067)}, - {UINT64CONST(5370530955049882401), UINT64CONST(93229259140002584)}, {UINT64CONST(6713163693812353001), UINT64CONST(116536573925003230)}, - {UINT64CONST(18030785363914884337), UINT64CONST(72835358703127018)}, {UINT64CONST(13315109668038829614), UINT64CONST(91044198378908773)}, - {UINT64CONST(2808829029766373305), UINT64CONST(113805247973635967)}, {UINT64CONST(17346094342490130344), UINT64CONST(142256559967044958)}, - {UINT64CONST(6229622945628943561), UINT64CONST(88910349979403099)}, {UINT64CONST(3175342663608791547), UINT64CONST(111137937474253874)}, - {UINT64CONST(13192550366365765242), UINT64CONST(138922421842817342)}, {UINT64CONST(3633657960551215372), UINT64CONST(86826513651760839)}, - {UINT64CONST(18377130505971182927), UINT64CONST(108533142064701048)}, {UINT64CONST(4524669058754427043), UINT64CONST(135666427580876311)}, - {UINT64CONST(9745447189362598758), UINT64CONST(84791517238047694)}, {UINT64CONST(2958436949848472639), UINT64CONST(105989396547559618)}, - {UINT64CONST(12921418224165366607), UINT64CONST(132486745684449522)}, {UINT64CONST(12687572408530742033), UINT64CONST(82804216052780951)}, - {UINT64CONST(11247779492236039638), UINT64CONST(103505270065976189)}, {UINT64CONST(224666310012885835), UINT64CONST(129381587582470237)}, - {UINT64CONST(2446259452971747599), UINT64CONST(80863492239043898)}, {UINT64CONST(12281196353069460307), UINT64CONST(101079365298804872)}, - {UINT64CONST(15351495441336825384), UINT64CONST(126349206623506090)}, {UINT64CONST(14206370669262903769), UINT64CONST(78968254139691306)}, - {UINT64CONST(8534591299723853903), UINT64CONST(98710317674614133)}, {UINT64CONST(15279925143082205283), UINT64CONST(123387897093267666)}, - {UINT64CONST(14161639232853766206), UINT64CONST(77117435683292291)}, {UINT64CONST(13090363022639819853), UINT64CONST(96396794604115364)}, - {UINT64CONST(16362953778299774816), UINT64CONST(120495993255144205)}, {UINT64CONST(12532689120651053212), UINT64CONST(75309995784465128)}, - {UINT64CONST(15665861400813816515), UINT64CONST(94137494730581410)}, {UINT64CONST(10358954714162494836), UINT64CONST(117671868413226763)}, - {UINT64CONST(4168503687137865320), UINT64CONST(73544917758266727)}, {UINT64CONST(598943590494943747), UINT64CONST(91931147197833409)}, - {UINT64CONST(5360365506546067587), UINT64CONST(114913933997291761)}, {UINT64CONST(11312142901609972388), UINT64CONST(143642417496614701)}, - {UINT64CONST(9375932322719926695), UINT64CONST(89776510935384188)}, {UINT64CONST(11719915403399908368), UINT64CONST(112220638669230235)}, - {UINT64CONST(10038208235822497557), UINT64CONST(140275798336537794)}, {UINT64CONST(10885566165816448877), UINT64CONST(87672373960336121)}, - {UINT64CONST(18218643725697949000), UINT64CONST(109590467450420151)}, {UINT64CONST(18161618638695048346), UINT64CONST(136988084313025189)}, - {UINT64CONST(13656854658398099168), UINT64CONST(85617552695640743)}, {UINT64CONST(12459382304570236056), UINT64CONST(107021940869550929)}, - {UINT64CONST(1739169825430631358), UINT64CONST(133777426086938662)}, {UINT64CONST(14922039196176308311), UINT64CONST(83610891304336663)}, - {UINT64CONST(14040862976792997485), UINT64CONST(104513614130420829)}, {UINT64CONST(3716020665709083144), UINT64CONST(130642017663026037)}, - {UINT64CONST(4628355925281870917), UINT64CONST(81651261039391273)}, {UINT64CONST(10397130925029726550), UINT64CONST(102064076299239091)}, - {UINT64CONST(8384727637859770284), UINT64CONST(127580095374048864)}, {UINT64CONST(5240454773662356427), UINT64CONST(79737559608780540)}, - {UINT64CONST(6550568467077945534), UINT64CONST(99671949510975675)}, {UINT64CONST(3576524565420044014), UINT64CONST(124589936888719594)}, - {UINT64CONST(6847013871814915412), UINT64CONST(77868710555449746)}, {UINT64CONST(17782139376623420074), UINT64CONST(97335888194312182)}, - {UINT64CONST(13004302183924499284), UINT64CONST(121669860242890228)}, {UINT64CONST(17351060901807587860), UINT64CONST(76043662651806392)}, - {UINT64CONST(3242082053549933210), UINT64CONST(95054578314757991)}, {UINT64CONST(17887660622219580224), UINT64CONST(118818222893447488)}, - {UINT64CONST(11179787888887237640), UINT64CONST(74261389308404680)}, {UINT64CONST(13974734861109047050), UINT64CONST(92826736635505850)}, - {UINT64CONST(8245046539531533005), UINT64CONST(116033420794382313)}, {UINT64CONST(16682369133275677888), UINT64CONST(72520887996488945)}, - {UINT64CONST(7017903361312433648), UINT64CONST(90651109995611182)}, {UINT64CONST(17995751238495317868), UINT64CONST(113313887494513977)}, - {UINT64CONST(8659630992836983623), UINT64CONST(141642359368142472)}, {UINT64CONST(5412269370523114764), UINT64CONST(88526474605089045)}, - {UINT64CONST(11377022731581281359), UINT64CONST(110658093256361306)}, {UINT64CONST(4997906377621825891), UINT64CONST(138322616570451633)}, - {UINT64CONST(14652906532082110942), UINT64CONST(86451635356532270)}, {UINT64CONST(9092761128247862869), UINT64CONST(108064544195665338)}, - {UINT64CONST(2142579373455052779), UINT64CONST(135080680244581673)}, {UINT64CONST(12868327154477877747), UINT64CONST(84425425152863545)}, - {UINT64CONST(2250350887815183471), UINT64CONST(105531781441079432)}, {UINT64CONST(2812938609768979339), UINT64CONST(131914726801349290)}, - {UINT64CONST(6369772649532999991), UINT64CONST(82446704250843306)}, {UINT64CONST(17185587848771025797), UINT64CONST(103058380313554132)}, - {UINT64CONST(3035240737254230630), UINT64CONST(128822975391942666)}, {UINT64CONST(6508711479211282048), UINT64CONST(80514359619964166)}, - {UINT64CONST(17359261385868878368), UINT64CONST(100642949524955207)}, {UINT64CONST(17087390713908710056), UINT64CONST(125803686906194009)}, - {UINT64CONST(3762090168551861929), UINT64CONST(78627304316371256)}, {UINT64CONST(4702612710689827411), UINT64CONST(98284130395464070)}, - {UINT64CONST(15101637925217060072), UINT64CONST(122855162994330087)}, {UINT64CONST(16356052730901744401), UINT64CONST(76784476871456304)}, - {UINT64CONST(1998321839917628885), UINT64CONST(95980596089320381)}, {UINT64CONST(7109588318324424010), UINT64CONST(119975745111650476)}, - {UINT64CONST(13666864735807540814), UINT64CONST(74984840694781547)}, {UINT64CONST(12471894901332038114), UINT64CONST(93731050868476934)}, - {UINT64CONST(6366496589810271835), UINT64CONST(117163813585596168)}, {UINT64CONST(3979060368631419896), UINT64CONST(73227383490997605)}, - {UINT64CONST(9585511479216662775), UINT64CONST(91534229363747006)}, {UINT64CONST(2758517312166052660), UINT64CONST(114417786704683758)}, - {UINT64CONST(12671518677062341634), UINT64CONST(143022233380854697)}, {UINT64CONST(1002170145522881665), UINT64CONST(89388895863034186)}, - {UINT64CONST(10476084718758377889), UINT64CONST(111736119828792732)}, {UINT64CONST(13095105898447972362), UINT64CONST(139670149785990915)}, - {UINT64CONST(5878598177316288774), UINT64CONST(87293843616244322)}, {UINT64CONST(16571619758500136775), UINT64CONST(109117304520305402)}, - {UINT64CONST(11491152661270395161), UINT64CONST(136396630650381753)}, {UINT64CONST(264441385652915120), UINT64CONST(85247894156488596)}, - {UINT64CONST(330551732066143900), UINT64CONST(106559867695610745)}, {UINT64CONST(5024875683510067779), UINT64CONST(133199834619513431)}, - {UINT64CONST(10058076329834874218), UINT64CONST(83249896637195894)}, {UINT64CONST(3349223375438816964), UINT64CONST(104062370796494868)}, - {UINT64CONST(4186529219298521205), UINT64CONST(130077963495618585)}, {UINT64CONST(14145795808130045513), UINT64CONST(81298727184761615)}, - {UINT64CONST(13070558741735168987), UINT64CONST(101623408980952019)}, {UINT64CONST(11726512408741573330), UINT64CONST(127029261226190024)}, - {UINT64CONST(7329070255463483331), UINT64CONST(79393288266368765)}, {UINT64CONST(13773023837756742068), UINT64CONST(99241610332960956)}, - {UINT64CONST(17216279797195927585), UINT64CONST(124052012916201195)}, {UINT64CONST(8454331864033760789), UINT64CONST(77532508072625747)}, - {UINT64CONST(5956228811614813082), UINT64CONST(96915635090782184)}, {UINT64CONST(7445286014518516353), UINT64CONST(121144543863477730)}, - {UINT64CONST(9264989777501460624), UINT64CONST(75715339914673581)}, {UINT64CONST(16192923240304213684), UINT64CONST(94644174893341976)}, - {UINT64CONST(1794409976670715490), UINT64CONST(118305218616677471)}, {UINT64CONST(8039035263060279037), UINT64CONST(73940761635423419)}, - {UINT64CONST(5437108060397960892), UINT64CONST(92425952044279274)}, {UINT64CONST(16019757112352226923), UINT64CONST(115532440055349092)}, - {UINT64CONST(788976158365366019), UINT64CONST(72207775034593183)}, {UINT64CONST(14821278253238871236), UINT64CONST(90259718793241478)}, - {UINT64CONST(9303225779693813237), UINT64CONST(112824648491551848)}, {UINT64CONST(11629032224617266546), UINT64CONST(141030810614439810)}, - {UINT64CONST(11879831158813179495), UINT64CONST(88144256634024881)}, {UINT64CONST(1014730893234310657), UINT64CONST(110180320792531102)}, - {UINT64CONST(10491785653397664129), UINT64CONST(137725400990663877)}, {UINT64CONST(8863209042587234033), UINT64CONST(86078375619164923)}, - {UINT64CONST(6467325284806654637), UINT64CONST(107597969523956154)}, {UINT64CONST(17307528642863094104), UINT64CONST(134497461904945192)}, - {UINT64CONST(10817205401789433815), UINT64CONST(84060913690590745)}, {UINT64CONST(18133192770664180173), UINT64CONST(105076142113238431)}, - {UINT64CONST(18054804944902837312), UINT64CONST(131345177641548039)}, {UINT64CONST(18201782118205355176), UINT64CONST(82090736025967524)}, - {UINT64CONST(4305483574047142354), UINT64CONST(102613420032459406)}, {UINT64CONST(14605226504413703751), UINT64CONST(128266775040574257)}, - {UINT64CONST(2210737537617482988), UINT64CONST(80166734400358911)}, {UINT64CONST(16598479977304017447), UINT64CONST(100208418000448638)}, - {UINT64CONST(11524727934775246001), UINT64CONST(125260522500560798)}, {UINT64CONST(2591268940807140847), UINT64CONST(78287826562850499)}, - {UINT64CONST(17074144231291089770), UINT64CONST(97859783203563123)}, {UINT64CONST(16730994270686474309), UINT64CONST(122324729004453904)}, - {UINT64CONST(10456871419179046443), UINT64CONST(76452955627783690)}, {UINT64CONST(3847717237119032246), UINT64CONST(95566194534729613)}, - {UINT64CONST(9421332564826178211), UINT64CONST(119457743168412016)}, {UINT64CONST(5888332853016361382), UINT64CONST(74661089480257510)}, - {UINT64CONST(16583788103125227536), UINT64CONST(93326361850321887)}, {UINT64CONST(16118049110479146516), UINT64CONST(116657952312902359)}, - {UINT64CONST(16991309721690548428), UINT64CONST(72911220195563974)}, {UINT64CONST(12015765115258409727), UINT64CONST(91139025244454968)}, - {UINT64CONST(15019706394073012159), UINT64CONST(113923781555568710)}, {UINT64CONST(9551260955736489391), UINT64CONST(142404726944460888)}, - {UINT64CONST(5969538097335305869), UINT64CONST(89002954340288055)}, {UINT64CONST(2850236603241744433), UINT64CONST(111253692925360069)} -}; - -#endif /* RYU_D2S_FULL_TABLE_H */ diff --git a/contrib/libs/libpq/src/common/d2s_intrinsics.h b/contrib/libs/libpq/src/common/d2s_intrinsics.h deleted file mode 100644 index ae0f28dbb2..0000000000 --- a/contrib/libs/libpq/src/common/d2s_intrinsics.h +++ /dev/null @@ -1,202 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Ryu floating-point output for double precision. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/d2s_intrinsics.h - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ -#ifndef RYU_D2S_INTRINSICS_H -#define RYU_D2S_INTRINSICS_H - -#if defined(HAS_64_BIT_INTRINSICS) - -#include <intrin.h> - -static inline uint64 -umul128(const uint64 a, const uint64 b, uint64 *const productHi) -{ - return _umul128(a, b, productHi); -} - -static inline uint64 -shiftright128(const uint64 lo, const uint64 hi, const uint32 dist) -{ - /* - * For the __shiftright128 intrinsic, the shift value is always modulo 64. - * In the current implementation of the double-precision version of Ryu, - * the shift value is always < 64. (In the case RYU_OPTIMIZE_SIZE == 0, - * the shift value is in the range [49, 58]. Otherwise in the range [2, - * 59].) Check this here in case a future change requires larger shift - * values. In this case this function needs to be adjusted. - */ - Assert(dist < 64); - return __shiftright128(lo, hi, (unsigned char) dist); -} - -#else /* defined(HAS_64_BIT_INTRINSICS) */ - -static inline uint64 -umul128(const uint64 a, const uint64 b, uint64 *const productHi) -{ - /* - * The casts here help MSVC to avoid calls to the __allmul library - * function. - */ - const uint32 aLo = (uint32) a; - const uint32 aHi = (uint32) (a >> 32); - const uint32 bLo = (uint32) b; - const uint32 bHi = (uint32) (b >> 32); - - const uint64 b00 = (uint64) aLo * bLo; - const uint64 b01 = (uint64) aLo * bHi; - const uint64 b10 = (uint64) aHi * bLo; - const uint64 b11 = (uint64) aHi * bHi; - - const uint32 b00Lo = (uint32) b00; - const uint32 b00Hi = (uint32) (b00 >> 32); - - const uint64 mid1 = b10 + b00Hi; - const uint32 mid1Lo = (uint32) (mid1); - const uint32 mid1Hi = (uint32) (mid1 >> 32); - - const uint64 mid2 = b01 + mid1Lo; - const uint32 mid2Lo = (uint32) (mid2); - const uint32 mid2Hi = (uint32) (mid2 >> 32); - - const uint64 pHi = b11 + mid1Hi + mid2Hi; - const uint64 pLo = ((uint64) mid2Lo << 32) + b00Lo; - - *productHi = pHi; - return pLo; -} - -static inline uint64 -shiftright128(const uint64 lo, const uint64 hi, const uint32 dist) -{ - /* We don't need to handle the case dist >= 64 here (see above). */ - Assert(dist < 64); -#if !defined(RYU_32_BIT_PLATFORM) - Assert(dist > 0); - return (hi << (64 - dist)) | (lo >> dist); -#else - /* Avoid a 64-bit shift by taking advantage of the range of shift values. */ - Assert(dist >= 32); - return (hi << (64 - dist)) | ((uint32) (lo >> 32) >> (dist - 32)); -#endif -} - -#endif /* // defined(HAS_64_BIT_INTRINSICS) */ - -#ifdef RYU_32_BIT_PLATFORM - -/* Returns the high 64 bits of the 128-bit product of a and b. */ -static inline uint64 -umulh(const uint64 a, const uint64 b) -{ - /* - * Reuse the umul128 implementation. Optimizers will likely eliminate the - * instructions used to compute the low part of the product. - */ - uint64 hi; - - umul128(a, b, &hi); - return hi; -} - -/*---- - * On 32-bit platforms, compilers typically generate calls to library - * functions for 64-bit divisions, even if the divisor is a constant. - * - * E.g.: - * https://bugs.llvm.org/show_bug.cgi?id=37932 - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17958 - * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=37443 - * - * The functions here perform division-by-constant using multiplications - * in the same way as 64-bit compilers would do. - * - * NB: - * The multipliers and shift values are the ones generated by clang x64 - * for expressions like x/5, x/10, etc. - *---- - */ - -static inline uint64 -div5(const uint64 x) -{ - return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 2; -} - -static inline uint64 -div10(const uint64 x) -{ - return umulh(x, UINT64CONST(0xCCCCCCCCCCCCCCCD)) >> 3; -} - -static inline uint64 -div100(const uint64 x) -{ - return umulh(x >> 2, UINT64CONST(0x28F5C28F5C28F5C3)) >> 2; -} - -static inline uint64 -div1e8(const uint64 x) -{ - return umulh(x, UINT64CONST(0xABCC77118461CEFD)) >> 26; -} - -#else /* RYU_32_BIT_PLATFORM */ - -static inline uint64 -div5(const uint64 x) -{ - return x / 5; -} - -static inline uint64 -div10(const uint64 x) -{ - return x / 10; -} - -static inline uint64 -div100(const uint64 x) -{ - return x / 100; -} - -static inline uint64 -div1e8(const uint64 x) -{ - return x / 100000000; -} - -#endif /* RYU_32_BIT_PLATFORM */ - -#endif /* RYU_D2S_INTRINSICS_H */ diff --git a/contrib/libs/libpq/src/common/digit_table.h b/contrib/libs/libpq/src/common/digit_table.h deleted file mode 100644 index 483aa17142..0000000000 --- a/contrib/libs/libpq/src/common/digit_table.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef RYU_DIGIT_TABLE_H -#define RYU_DIGIT_TABLE_H - -/* - * A table of all two-digit numbers. This is used to speed up decimal digit - * generation by copying pairs of digits into the final output. - */ -static const char DIGIT_TABLE[200] = { - '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', - '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', - '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', - '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', - '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', - '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', - '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', - '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', - '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', - '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9' -}; - -#endif /* RYU_DIGIT_TABLE_H */ diff --git a/contrib/libs/libpq/src/common/encnames.c b/contrib/libs/libpq/src/common/encnames.c deleted file mode 100644 index 0412a8220e..0000000000 --- a/contrib/libs/libpq/src/common/encnames.c +++ /dev/null @@ -1,598 +0,0 @@ -/*------------------------------------------------------------------------- - * - * encnames.c - * Encoding names and routines for working with them. - * - * Portions Copyright (c) 2001-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/encnames.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include <ctype.h> -#include <unistd.h> - -#include "mb/pg_wchar.h" - - -/* ---------- - * All encoding names, sorted: *** A L P H A B E T I C *** - * - * All names must be without irrelevant chars, search routines use - * isalnum() chars only. It means ISO-8859-1, iso_8859-1 and Iso8859_1 - * are always converted to 'iso88591'. All must be lower case. - * - * The table doesn't contain 'cs' aliases (like csISOLatin1). It's needed? - * - * Karel Zak, Aug 2001 - * ---------- - */ -typedef struct pg_encname -{ - const char *name; - pg_enc encoding; -} pg_encname; - -static const pg_encname pg_encname_tbl[] = -{ - { - "abc", PG_WIN1258 - }, /* alias for WIN1258 */ - { - "alt", PG_WIN866 - }, /* IBM866 */ - { - "big5", PG_BIG5 - }, /* Big5; Chinese for Taiwan multibyte set */ - { - "euccn", PG_EUC_CN - }, /* EUC-CN; Extended Unix Code for simplified - * Chinese */ - { - "eucjis2004", PG_EUC_JIS_2004 - }, /* EUC-JIS-2004; Extended UNIX Code fixed - * Width for Japanese, standard JIS X 0213 */ - { - "eucjp", PG_EUC_JP - }, /* EUC-JP; Extended UNIX Code fixed Width for - * Japanese, standard OSF */ - { - "euckr", PG_EUC_KR - }, /* EUC-KR; Extended Unix Code for Korean , KS - * X 1001 standard */ - { - "euctw", PG_EUC_TW - }, /* EUC-TW; Extended Unix Code for - * - * traditional Chinese */ - { - "gb18030", PG_GB18030 - }, /* GB18030;GB18030 */ - { - "gbk", PG_GBK - }, /* GBK; Chinese Windows CodePage 936 - * simplified Chinese */ - { - "iso88591", PG_LATIN1 - }, /* ISO-8859-1; RFC1345,KXS2 */ - { - "iso885910", PG_LATIN6 - }, /* ISO-8859-10; RFC1345,KXS2 */ - { - "iso885913", PG_LATIN7 - }, /* ISO-8859-13; RFC1345,KXS2 */ - { - "iso885914", PG_LATIN8 - }, /* ISO-8859-14; RFC1345,KXS2 */ - { - "iso885915", PG_LATIN9 - }, /* ISO-8859-15; RFC1345,KXS2 */ - { - "iso885916", PG_LATIN10 - }, /* ISO-8859-16; RFC1345,KXS2 */ - { - "iso88592", PG_LATIN2 - }, /* ISO-8859-2; RFC1345,KXS2 */ - { - "iso88593", PG_LATIN3 - }, /* ISO-8859-3; RFC1345,KXS2 */ - { - "iso88594", PG_LATIN4 - }, /* ISO-8859-4; RFC1345,KXS2 */ - { - "iso88595", PG_ISO_8859_5 - }, /* ISO-8859-5; RFC1345,KXS2 */ - { - "iso88596", PG_ISO_8859_6 - }, /* ISO-8859-6; RFC1345,KXS2 */ - { - "iso88597", PG_ISO_8859_7 - }, /* ISO-8859-7; RFC1345,KXS2 */ - { - "iso88598", PG_ISO_8859_8 - }, /* ISO-8859-8; RFC1345,KXS2 */ - { - "iso88599", PG_LATIN5 - }, /* ISO-8859-9; RFC1345,KXS2 */ - { - "johab", PG_JOHAB - }, /* JOHAB; Extended Unix Code for simplified - * Chinese */ - { - "koi8", PG_KOI8R - }, /* _dirty_ alias for KOI8-R (backward - * compatibility) */ - { - "koi8r", PG_KOI8R - }, /* KOI8-R; RFC1489 */ - { - "koi8u", PG_KOI8U - }, /* KOI8-U; RFC2319 */ - { - "latin1", PG_LATIN1 - }, /* alias for ISO-8859-1 */ - { - "latin10", PG_LATIN10 - }, /* alias for ISO-8859-16 */ - { - "latin2", PG_LATIN2 - }, /* alias for ISO-8859-2 */ - { - "latin3", PG_LATIN3 - }, /* alias for ISO-8859-3 */ - { - "latin4", PG_LATIN4 - }, /* alias for ISO-8859-4 */ - { - "latin5", PG_LATIN5 - }, /* alias for ISO-8859-9 */ - { - "latin6", PG_LATIN6 - }, /* alias for ISO-8859-10 */ - { - "latin7", PG_LATIN7 - }, /* alias for ISO-8859-13 */ - { - "latin8", PG_LATIN8 - }, /* alias for ISO-8859-14 */ - { - "latin9", PG_LATIN9 - }, /* alias for ISO-8859-15 */ - { - "mskanji", PG_SJIS - }, /* alias for Shift_JIS */ - { - "muleinternal", PG_MULE_INTERNAL - }, - { - "shiftjis", PG_SJIS - }, /* Shift_JIS; JIS X 0202-1991 */ - - { - "shiftjis2004", PG_SHIFT_JIS_2004 - }, /* SHIFT-JIS-2004; Shift JIS for Japanese, - * standard JIS X 0213 */ - { - "sjis", PG_SJIS - }, /* alias for Shift_JIS */ - { - "sqlascii", PG_SQL_ASCII - }, - { - "tcvn", PG_WIN1258 - }, /* alias for WIN1258 */ - { - "tcvn5712", PG_WIN1258 - }, /* alias for WIN1258 */ - { - "uhc", PG_UHC - }, /* UHC; Korean Windows CodePage 949 */ - { - "unicode", PG_UTF8 - }, /* alias for UTF8 */ - { - "utf8", PG_UTF8 - }, /* alias for UTF8 */ - { - "vscii", PG_WIN1258 - }, /* alias for WIN1258 */ - { - "win", PG_WIN1251 - }, /* _dirty_ alias for windows-1251 (backward - * compatibility) */ - { - "win1250", PG_WIN1250 - }, /* alias for Windows-1250 */ - { - "win1251", PG_WIN1251 - }, /* alias for Windows-1251 */ - { - "win1252", PG_WIN1252 - }, /* alias for Windows-1252 */ - { - "win1253", PG_WIN1253 - }, /* alias for Windows-1253 */ - { - "win1254", PG_WIN1254 - }, /* alias for Windows-1254 */ - { - "win1255", PG_WIN1255 - }, /* alias for Windows-1255 */ - { - "win1256", PG_WIN1256 - }, /* alias for Windows-1256 */ - { - "win1257", PG_WIN1257 - }, /* alias for Windows-1257 */ - { - "win1258", PG_WIN1258 - }, /* alias for Windows-1258 */ - { - "win866", PG_WIN866 - }, /* IBM866 */ - { - "win874", PG_WIN874 - }, /* alias for Windows-874 */ - { - "win932", PG_SJIS - }, /* alias for Shift_JIS */ - { - "win936", PG_GBK - }, /* alias for GBK */ - { - "win949", PG_UHC - }, /* alias for UHC */ - { - "win950", PG_BIG5 - }, /* alias for BIG5 */ - { - "windows1250", PG_WIN1250 - }, /* Windows-1251; Microsoft */ - { - "windows1251", PG_WIN1251 - }, /* Windows-1251; Microsoft */ - { - "windows1252", PG_WIN1252 - }, /* Windows-1252; Microsoft */ - { - "windows1253", PG_WIN1253 - }, /* Windows-1253; Microsoft */ - { - "windows1254", PG_WIN1254 - }, /* Windows-1254; Microsoft */ - { - "windows1255", PG_WIN1255 - }, /* Windows-1255; Microsoft */ - { - "windows1256", PG_WIN1256 - }, /* Windows-1256; Microsoft */ - { - "windows1257", PG_WIN1257 - }, /* Windows-1257; Microsoft */ - { - "windows1258", PG_WIN1258 - }, /* Windows-1258; Microsoft */ - { - "windows866", PG_WIN866 - }, /* IBM866 */ - { - "windows874", PG_WIN874 - }, /* Windows-874; Microsoft */ - { - "windows932", PG_SJIS - }, /* alias for Shift_JIS */ - { - "windows936", PG_GBK - }, /* alias for GBK */ - { - "windows949", PG_UHC - }, /* alias for UHC */ - { - "windows950", PG_BIG5 - } /* alias for BIG5 */ -}; - -/* ---------- - * These are "official" encoding names. - * XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h) - * ---------- - */ -#ifndef WIN32 -#define DEF_ENC2NAME(name, codepage) { #name, PG_##name } -#else -#define DEF_ENC2NAME(name, codepage) { #name, PG_##name, codepage } -#endif - -const pg_enc2name pg_enc2name_tbl[] = -{ - DEF_ENC2NAME(SQL_ASCII, 0), - DEF_ENC2NAME(EUC_JP, 20932), - DEF_ENC2NAME(EUC_CN, 20936), - DEF_ENC2NAME(EUC_KR, 51949), - DEF_ENC2NAME(EUC_TW, 0), - DEF_ENC2NAME(EUC_JIS_2004, 20932), - DEF_ENC2NAME(UTF8, 65001), - DEF_ENC2NAME(MULE_INTERNAL, 0), - DEF_ENC2NAME(LATIN1, 28591), - DEF_ENC2NAME(LATIN2, 28592), - DEF_ENC2NAME(LATIN3, 28593), - DEF_ENC2NAME(LATIN4, 28594), - DEF_ENC2NAME(LATIN5, 28599), - DEF_ENC2NAME(LATIN6, 0), - DEF_ENC2NAME(LATIN7, 0), - DEF_ENC2NAME(LATIN8, 0), - DEF_ENC2NAME(LATIN9, 28605), - DEF_ENC2NAME(LATIN10, 0), - DEF_ENC2NAME(WIN1256, 1256), - DEF_ENC2NAME(WIN1258, 1258), - DEF_ENC2NAME(WIN866, 866), - DEF_ENC2NAME(WIN874, 874), - DEF_ENC2NAME(KOI8R, 20866), - DEF_ENC2NAME(WIN1251, 1251), - DEF_ENC2NAME(WIN1252, 1252), - DEF_ENC2NAME(ISO_8859_5, 28595), - DEF_ENC2NAME(ISO_8859_6, 28596), - DEF_ENC2NAME(ISO_8859_7, 28597), - DEF_ENC2NAME(ISO_8859_8, 28598), - DEF_ENC2NAME(WIN1250, 1250), - DEF_ENC2NAME(WIN1253, 1253), - DEF_ENC2NAME(WIN1254, 1254), - DEF_ENC2NAME(WIN1255, 1255), - DEF_ENC2NAME(WIN1257, 1257), - DEF_ENC2NAME(KOI8U, 21866), - DEF_ENC2NAME(SJIS, 932), - DEF_ENC2NAME(BIG5, 950), - DEF_ENC2NAME(GBK, 936), - DEF_ENC2NAME(UHC, 949), - DEF_ENC2NAME(GB18030, 54936), - DEF_ENC2NAME(JOHAB, 0), - DEF_ENC2NAME(SHIFT_JIS_2004, 932) -}; - -/* ---------- - * These are encoding names for gettext. - * - * This covers all encodings except MULE_INTERNAL, which is alien to gettext. - * ---------- - */ -const pg_enc2gettext pg_enc2gettext_tbl[] = -{ - {PG_SQL_ASCII, "US-ASCII"}, - {PG_UTF8, "UTF-8"}, - {PG_LATIN1, "LATIN1"}, - {PG_LATIN2, "LATIN2"}, - {PG_LATIN3, "LATIN3"}, - {PG_LATIN4, "LATIN4"}, - {PG_ISO_8859_5, "ISO-8859-5"}, - {PG_ISO_8859_6, "ISO_8859-6"}, - {PG_ISO_8859_7, "ISO-8859-7"}, - {PG_ISO_8859_8, "ISO-8859-8"}, - {PG_LATIN5, "LATIN5"}, - {PG_LATIN6, "LATIN6"}, - {PG_LATIN7, "LATIN7"}, - {PG_LATIN8, "LATIN8"}, - {PG_LATIN9, "LATIN-9"}, - {PG_LATIN10, "LATIN10"}, - {PG_KOI8R, "KOI8-R"}, - {PG_KOI8U, "KOI8-U"}, - {PG_WIN1250, "CP1250"}, - {PG_WIN1251, "CP1251"}, - {PG_WIN1252, "CP1252"}, - {PG_WIN1253, "CP1253"}, - {PG_WIN1254, "CP1254"}, - {PG_WIN1255, "CP1255"}, - {PG_WIN1256, "CP1256"}, - {PG_WIN1257, "CP1257"}, - {PG_WIN1258, "CP1258"}, - {PG_WIN866, "CP866"}, - {PG_WIN874, "CP874"}, - {PG_EUC_CN, "EUC-CN"}, - {PG_EUC_JP, "EUC-JP"}, - {PG_EUC_KR, "EUC-KR"}, - {PG_EUC_TW, "EUC-TW"}, - {PG_EUC_JIS_2004, "EUC-JP"}, - {PG_SJIS, "SHIFT-JIS"}, - {PG_BIG5, "BIG5"}, - {PG_GBK, "GBK"}, - {PG_UHC, "UHC"}, - {PG_GB18030, "GB18030"}, - {PG_JOHAB, "JOHAB"}, - {PG_SHIFT_JIS_2004, "SHIFT_JISX0213"}, - {0, NULL} -}; - - -/* - * Table of encoding names for ICU (currently covers backend encodings only) - * - * Reference: <https://ssl.icu-project.org/icu-bin/convexp> - * - * NULL entries are not supported by ICU, or their mapping is unclear. - */ -static const char *const pg_enc2icu_tbl[] = -{ - NULL, /* PG_SQL_ASCII */ - "EUC-JP", /* PG_EUC_JP */ - "EUC-CN", /* PG_EUC_CN */ - "EUC-KR", /* PG_EUC_KR */ - "EUC-TW", /* PG_EUC_TW */ - NULL, /* PG_EUC_JIS_2004 */ - "UTF-8", /* PG_UTF8 */ - NULL, /* PG_MULE_INTERNAL */ - "ISO-8859-1", /* PG_LATIN1 */ - "ISO-8859-2", /* PG_LATIN2 */ - "ISO-8859-3", /* PG_LATIN3 */ - "ISO-8859-4", /* PG_LATIN4 */ - "ISO-8859-9", /* PG_LATIN5 */ - "ISO-8859-10", /* PG_LATIN6 */ - "ISO-8859-13", /* PG_LATIN7 */ - "ISO-8859-14", /* PG_LATIN8 */ - "ISO-8859-15", /* PG_LATIN9 */ - NULL, /* PG_LATIN10 */ - "CP1256", /* PG_WIN1256 */ - "CP1258", /* PG_WIN1258 */ - "CP866", /* PG_WIN866 */ - NULL, /* PG_WIN874 */ - "KOI8-R", /* PG_KOI8R */ - "CP1251", /* PG_WIN1251 */ - "CP1252", /* PG_WIN1252 */ - "ISO-8859-5", /* PG_ISO_8859_5 */ - "ISO-8859-6", /* PG_ISO_8859_6 */ - "ISO-8859-7", /* PG_ISO_8859_7 */ - "ISO-8859-8", /* PG_ISO_8859_8 */ - "CP1250", /* PG_WIN1250 */ - "CP1253", /* PG_WIN1253 */ - "CP1254", /* PG_WIN1254 */ - "CP1255", /* PG_WIN1255 */ - "CP1257", /* PG_WIN1257 */ - "KOI8-U", /* PG_KOI8U */ -}; - -StaticAssertDecl(lengthof(pg_enc2icu_tbl) == PG_ENCODING_BE_LAST + 1, - "pg_enc2icu_tbl incomplete"); - - -/* - * Is this encoding supported by ICU? - */ -bool -is_encoding_supported_by_icu(int encoding) -{ - if (!PG_VALID_BE_ENCODING(encoding)) - return false; - return (pg_enc2icu_tbl[encoding] != NULL); -} - -/* - * Returns ICU's name for encoding, or NULL if not supported - */ -const char * -get_encoding_name_for_icu(int encoding) -{ - if (!PG_VALID_BE_ENCODING(encoding)) - return NULL; - return pg_enc2icu_tbl[encoding]; -} - - -/* ---------- - * Encoding checks, for error returns -1 else encoding id - * ---------- - */ -int -pg_valid_client_encoding(const char *name) -{ - int enc; - - if ((enc = pg_char_to_encoding(name)) < 0) - return -1; - - if (!PG_VALID_FE_ENCODING(enc)) - return -1; - - return enc; -} - -int -pg_valid_server_encoding(const char *name) -{ - int enc; - - if ((enc = pg_char_to_encoding(name)) < 0) - return -1; - - if (!PG_VALID_BE_ENCODING(enc)) - return -1; - - return enc; -} - -int -pg_valid_server_encoding_id(int encoding) -{ - return PG_VALID_BE_ENCODING(encoding); -} - -/* - * Remove irrelevant chars from encoding name, store at *newkey - * - * (Caller's responsibility to provide a large enough buffer) - */ -static char * -clean_encoding_name(const char *key, char *newkey) -{ - const char *p; - char *np; - - for (p = key, np = newkey; *p != '\0'; p++) - { - if (isalnum((unsigned char) *p)) - { - if (*p >= 'A' && *p <= 'Z') - *np++ = *p + 'a' - 'A'; - else - *np++ = *p; - } - } - *np = '\0'; - return newkey; -} - -/* - * Search encoding by encoding name - * - * Returns encoding ID, or -1 if not recognized - */ -int -pg_char_to_encoding(const char *name) -{ - unsigned int nel = lengthof(pg_encname_tbl); - const pg_encname *base = pg_encname_tbl, - *last = base + nel - 1, - *position; - int result; - char buff[NAMEDATALEN], - *key; - - if (name == NULL || *name == '\0') - return -1; - - if (strlen(name) >= NAMEDATALEN) - return -1; /* it's certainly not in the table */ - - key = clean_encoding_name(name, buff); - - while (last >= base) - { - position = base + ((last - base) >> 1); - result = key[0] - position->name[0]; - - if (result == 0) - { - result = strcmp(key, position->name); - if (result == 0) - return position->encoding; - } - if (result < 0) - last = position - 1; - else - base = position + 1; - } - return -1; -} - -const char * -pg_encoding_to_char(int encoding) -{ - if (PG_VALID_ENCODING(encoding)) - { - const pg_enc2name *p = &pg_enc2name_tbl[encoding]; - - Assert(encoding == p->encoding); - return p->name; - } - return ""; -} diff --git a/contrib/libs/libpq/src/common/exec.c b/contrib/libs/libpq/src/common/exec.c deleted file mode 100644 index d3a967baa4..0000000000 --- a/contrib/libs/libpq/src/common/exec.c +++ /dev/null @@ -1,719 +0,0 @@ -/*------------------------------------------------------------------------- - * - * exec.c - * Functions for finding and validating executable files - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/exec.c - * - *------------------------------------------------------------------------- - */ - -/* - * On macOS, "man realpath" avers: - * Defining _DARWIN_C_SOURCE or _DARWIN_BETTER_REALPATH before including - * stdlib.h will cause the provided implementation of realpath() to use - * F_GETPATH from fcntl(2) to discover the path. - * This should be harmless everywhere else. - */ -#define _DARWIN_BETTER_REALPATH - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <signal.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <unistd.h> - -#ifdef EXEC_BACKEND -#if defined(HAVE_SYS_PERSONALITY_H) -#include <sys/personality.h> -#elif defined(HAVE_SYS_PROCCTL_H) -#error #include <sys/procctl.h> -#endif -#endif - -/* Inhibit mingw CRT's auto-globbing of command line arguments */ -#if defined(WIN32) && !defined(_MSC_VER) -extern int _CRT_glob = 0; /* 0 turns off globbing; 1 turns it on */ -#endif - -/* - * Hacky solution to allow expressing both frontend and backend error reports - * in one macro call. First argument of log_error is an errcode() call of - * some sort (ignored if FRONTEND); the rest are errmsg_internal() arguments, - * i.e. message string and any parameters for it. - * - * Caller must provide the gettext wrapper around the message string, if - * appropriate, so that it gets translated in the FRONTEND case; this - * motivates using errmsg_internal() not errmsg(). We handle appending a - * newline, if needed, inside the macro, so that there's only one translatable - * string per call not two. - */ -#ifndef FRONTEND -#define log_error(errcodefn, ...) \ - ereport(LOG, (errcodefn, errmsg_internal(__VA_ARGS__))) -#else -#define log_error(errcodefn, ...) \ - (fprintf(stderr, __VA_ARGS__), fputc('\n', stderr)) -#endif - -static int normalize_exec_path(char *path); -static char *pg_realpath(const char *fname); - -#ifdef WIN32 -static BOOL GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser); -#endif - -/* - * validate_exec -- validate "path" as an executable file - * - * returns 0 if the file is found and no error is encountered. - * -1 if the regular file "path" does not exist or cannot be executed. - * -2 if the file is otherwise valid but cannot be read. - * in the failure cases, errno is set appropriately - */ -int -validate_exec(const char *path) -{ - struct stat buf; - int is_r; - int is_x; - -#ifdef WIN32 - char path_exe[MAXPGPATH + sizeof(".exe") - 1]; - - /* Win32 requires a .exe suffix for stat() */ - if (strlen(path) < strlen(".exe") || - pg_strcasecmp(path + strlen(path) - strlen(".exe"), ".exe") != 0) - { - strlcpy(path_exe, path, sizeof(path_exe) - 4); - strcat(path_exe, ".exe"); - path = path_exe; - } -#endif - - /* - * Ensure that the file exists and is a regular file. - * - * XXX if you have a broken system where stat() looks at the symlink - * instead of the underlying file, you lose. - */ - if (stat(path, &buf) < 0) - return -1; - - if (!S_ISREG(buf.st_mode)) - { - /* - * POSIX offers no errno code that's simply "not a regular file". If - * it's a directory we can use EISDIR. Otherwise, it's most likely a - * device special file, and EPERM (Operation not permitted) isn't too - * horribly off base. - */ - errno = S_ISDIR(buf.st_mode) ? EISDIR : EPERM; - return -1; - } - - /* - * Ensure that the file is both executable and readable (required for - * dynamic loading). - */ -#ifndef WIN32 - is_r = (access(path, R_OK) == 0); - is_x = (access(path, X_OK) == 0); - /* access() will set errno if it returns -1 */ -#else - is_r = buf.st_mode & S_IRUSR; - is_x = buf.st_mode & S_IXUSR; - errno = EACCES; /* appropriate thing if we return nonzero */ -#endif - return is_x ? (is_r ? 0 : -2) : -1; -} - - -/* - * find_my_exec -- find an absolute path to this program's executable - * - * argv0 is the name passed on the command line - * retpath is the output area (must be of size MAXPGPATH) - * Returns 0 if OK, -1 if error. - * - * The reason we have to work so hard to find an absolute path is that - * on some platforms we can't do dynamic loading unless we know the - * executable's location. Also, we need an absolute path not a relative - * path because we may later change working directory. Finally, we want - * a true path not a symlink location, so that we can locate other files - * that are part of our installation relative to the executable. - */ -int -find_my_exec(const char *argv0, char *retpath) -{ - char *path; - - /* - * If argv0 contains a separator, then PATH wasn't used. - */ - strlcpy(retpath, argv0, MAXPGPATH); - if (first_dir_separator(retpath) != NULL) - { - if (validate_exec(retpath) == 0) - return normalize_exec_path(retpath); - - log_error(errcode(ERRCODE_WRONG_OBJECT_TYPE), - _("invalid binary \"%s\": %m"), retpath); - return -1; - } - -#ifdef WIN32 - /* Win32 checks the current directory first for names without slashes */ - if (validate_exec(retpath) == 0) - return normalize_exec_path(retpath); -#endif - - /* - * Since no explicit path was supplied, the user must have been relying on - * PATH. We'll search the same PATH. - */ - if ((path = getenv("PATH")) && *path) - { - char *startp = NULL, - *endp = NULL; - - do - { - if (!startp) - startp = path; - else - startp = endp + 1; - - endp = first_path_var_separator(startp); - if (!endp) - endp = startp + strlen(startp); /* point to end */ - - strlcpy(retpath, startp, Min(endp - startp + 1, MAXPGPATH)); - - join_path_components(retpath, retpath, argv0); - canonicalize_path(retpath); - - switch (validate_exec(retpath)) - { - case 0: /* found ok */ - return normalize_exec_path(retpath); - case -1: /* wasn't even a candidate, keep looking */ - break; - case -2: /* found but disqualified */ - log_error(errcode(ERRCODE_WRONG_OBJECT_TYPE), - _("could not read binary \"%s\": %m"), - retpath); - break; - } - } while (*endp); - } - - log_error(errcode(ERRCODE_UNDEFINED_FILE), - _("could not find a \"%s\" to execute"), argv0); - return -1; -} - - -/* - * normalize_exec_path - resolve symlinks and convert to absolute path - * - * Given a path that refers to an executable, chase through any symlinks - * to find the real file location; then convert that to an absolute path. - * - * On success, replaces the contents of "path" with the absolute path. - * ("path" is assumed to be of size MAXPGPATH.) - * Returns 0 if OK, -1 if error. - */ -static int -normalize_exec_path(char *path) -{ - /* - * We used to do a lot of work ourselves here, but now we just let - * realpath(3) do all the heavy lifting. - */ - char *abspath = pg_realpath(path); - - if (abspath == NULL) - { - log_error(errcode_for_file_access(), - _("could not resolve path \"%s\" to absolute form: %m"), - path); - return -1; - } - strlcpy(path, abspath, MAXPGPATH); - free(abspath); - -#ifdef WIN32 - /* On Windows, be sure to convert '\' to '/' */ - canonicalize_path(path); -#endif - - return 0; -} - - -/* - * pg_realpath() - realpath(3) with POSIX.1-2008 semantics - * - * This is equivalent to realpath(fname, NULL), in that it returns a - * malloc'd buffer containing the absolute path equivalent to fname. - * On error, returns NULL with errno set. - * - * On Windows, what you get is spelled per platform conventions, - * so you probably want to apply canonicalize_path() to the result. - * - * For now, this is needed only here so mark it static. If you choose to - * move it into its own file, move the _DARWIN_BETTER_REALPATH #define too! - */ -static char * -pg_realpath(const char *fname) -{ - char *path; - -#ifndef WIN32 - path = realpath(fname, NULL); - if (path == NULL && errno == EINVAL) - { - /* - * Cope with old-POSIX systems that require a user-provided buffer. - * Assume MAXPGPATH is enough room on all such systems. - */ - char *buf = malloc(MAXPGPATH); - - if (buf == NULL) - return NULL; /* assume errno is set */ - path = realpath(fname, buf); - if (path == NULL) /* don't leak memory */ - { - int save_errno = errno; - - free(buf); - errno = save_errno; - } - } -#else /* WIN32 */ - - /* - * Microsoft is resolutely non-POSIX, but _fullpath() does the same thing. - * The documentation claims it reports errors by setting errno, which is a - * bit surprising for Microsoft, but we'll believe that until it's proven - * wrong. Clear errno first, though, so we can at least tell if a failure - * occurs and doesn't set it. - */ - errno = 0; - path = _fullpath(NULL, fname, 0); -#endif - - return path; -} - - -/* - * Find another program in our binary's directory, - * then make sure it is the proper version. - */ -int -find_other_exec(const char *argv0, const char *target, - const char *versionstr, char *retpath) -{ - char cmd[MAXPGPATH]; - char line[MAXPGPATH]; - - if (find_my_exec(argv0, retpath) < 0) - return -1; - - /* Trim off program name and keep just directory */ - *last_dir_separator(retpath) = '\0'; - canonicalize_path(retpath); - - /* Now append the other program's name */ - snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath), - "/%s%s", target, EXE); - - if (validate_exec(retpath) != 0) - return -1; - - snprintf(cmd, sizeof(cmd), "\"%s\" -V", retpath); - - if (!pipe_read_line(cmd, line, sizeof(line))) - return -1; - - if (strcmp(line, versionstr) != 0) - return -2; - - return 0; -} - - -/* - * Execute a command in a pipe and read the first line from it. - */ -char * -pipe_read_line(char *cmd, char *line, int maxsize) -{ - FILE *pgver; - - fflush(NULL); - - errno = 0; - if ((pgver = popen(cmd, "r")) == NULL) - { - perror("popen failure"); - return NULL; - } - - errno = 0; - if (fgets(line, maxsize, pgver) == NULL) - { - if (feof(pgver)) - fprintf(stderr, "no data was returned by command \"%s\"\n", cmd); - else - perror("fgets failure"); - pclose(pgver); /* no error checking */ - return NULL; - } - - if (pclose_check(pgver)) - return NULL; - - return line; -} - - -/* - * pclose() plus useful error reporting - */ -int -pclose_check(FILE *stream) -{ - int exitstatus; - char *reason; - - exitstatus = pclose(stream); - - if (exitstatus == 0) - return 0; /* all is well */ - - if (exitstatus == -1) - { - /* pclose() itself failed, and hopefully set errno */ - log_error(errcode(ERRCODE_SYSTEM_ERROR), - _("%s() failed: %m"), "pclose"); - } - else - { - reason = wait_result_to_str(exitstatus); - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "%s", reason); - pfree(reason); - } - return exitstatus; -} - -/* - * set_pglocale_pgservice - * - * Set application-specific locale and service directory - * - * This function takes the value of argv[0] rather than a full path. - * - * (You may be wondering why this is in exec.c. It requires this module's - * services and doesn't introduce any new dependencies, so this seems as - * good as anyplace.) - */ -void -set_pglocale_pgservice(const char *argv0, const char *app) -{ - char path[MAXPGPATH]; - char my_exec_path[MAXPGPATH]; - - /* don't set LC_ALL in the backend */ - if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0) - { - setlocale(LC_ALL, ""); - - /* - * One could make a case for reproducing here PostmasterMain()'s test - * for whether the process is multithreaded. Unlike the postmaster, - * no frontend program calls sigprocmask() or otherwise provides for - * mutual exclusion between signal handlers. While frontends using - * fork(), if multithreaded, are formally exposed to undefined - * behavior, we have not witnessed a concrete bug. Therefore, - * complaining about multithreading here may be mere pedantry. - */ - } - - if (find_my_exec(argv0, my_exec_path) < 0) - return; - -#ifdef ENABLE_NLS - get_locale_path(my_exec_path, path); - bindtextdomain(app, path); - textdomain(app); - /* set for libpq to use, but don't override existing setting */ - setenv("PGLOCALEDIR", path, 0); -#endif - - if (getenv("PGSYSCONFDIR") == NULL) - { - get_etc_path(my_exec_path, path); - /* set for libpq to use */ - setenv("PGSYSCONFDIR", path, 0); - } -} - -#ifdef EXEC_BACKEND -/* - * For the benefit of PostgreSQL developers testing EXEC_BACKEND on Unix - * systems (code paths normally exercised only on Windows), provide a way to - * disable address space layout randomization, if we know how on this platform. - * Otherwise, backends may fail to attach to shared memory at the fixed address - * chosen by the postmaster. (See also the macOS-specific hack in - * sysv_shmem.c.) - */ -int -pg_disable_aslr(void) -{ -#if defined(HAVE_SYS_PERSONALITY_H) - return personality(ADDR_NO_RANDOMIZE); -#elif defined(HAVE_SYS_PROCCTL_H) && defined(PROC_ASLR_FORCE_DISABLE) - int data = PROC_ASLR_FORCE_DISABLE; - - return procctl(P_PID, 0, PROC_ASLR_CTL, &data); -#else - errno = ENOSYS; - return -1; -#endif -} -#endif - -#ifdef WIN32 - -/* - * AddUserToTokenDacl(HANDLE hToken) - * - * This function adds the current user account to the restricted - * token used when we create a restricted process. - * - * This is required because of some security changes in Windows - * that appeared in patches to XP/2K3 and in Vista/2008. - * - * On these machines, the Administrator account is not included in - * the default DACL - you just get Administrators + System. For - * regular users you get User + System. Because we strip Administrators - * when we create the restricted token, we are left with only System - * in the DACL which leads to access denied errors for later CreatePipe() - * and CreateProcess() calls when running as Administrator. - * - * This function fixes this problem by modifying the DACL of the - * token the process will use, and explicitly re-adding the current - * user account. This is still secure because the Administrator account - * inherits its privileges from the Administrators group - it doesn't - * have any of its own. - */ -BOOL -AddUserToTokenDacl(HANDLE hToken) -{ - int i; - ACL_SIZE_INFORMATION asi; - ACCESS_ALLOWED_ACE *pace; - DWORD dwNewAclSize; - DWORD dwSize = 0; - DWORD dwTokenInfoLength = 0; - PACL pacl = NULL; - PTOKEN_USER pTokenUser = NULL; - TOKEN_DEFAULT_DACL tddNew; - TOKEN_DEFAULT_DACL *ptdd = NULL; - TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl; - BOOL ret = FALSE; - - /* Figure out the buffer size for the DACL info */ - if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize)) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize); - if (ptdd == NULL) - { - log_error(errcode(ERRCODE_OUT_OF_MEMORY), - _("out of memory")); - goto cleanup; - } - - if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get token information: error code %lu", - GetLastError()); - goto cleanup; - } - } - else - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get token information buffer size: error code %lu", - GetLastError()); - goto cleanup; - } - } - - /* Get the ACL info */ - if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi, - (DWORD) sizeof(ACL_SIZE_INFORMATION), - AclSizeInformation)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get ACL information: error code %lu", - GetLastError()); - goto cleanup; - } - - /* Get the current user SID */ - if (!GetTokenUser(hToken, &pTokenUser)) - goto cleanup; /* callee printed a message */ - - /* Figure out the size of the new ACL */ - dwNewAclSize = asi.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + - GetLengthSid(pTokenUser->User.Sid) - sizeof(DWORD); - - /* Allocate the ACL buffer & initialize it */ - pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize); - if (pacl == NULL) - { - log_error(errcode(ERRCODE_OUT_OF_MEMORY), - _("out of memory")); - goto cleanup; - } - - if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not initialize ACL: error code %lu", GetLastError()); - goto cleanup; - } - - /* Loop through the existing ACEs, and build the new ACL */ - for (i = 0; i < (int) asi.AceCount; i++) - { - if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *) &pace)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get ACE: error code %lu", GetLastError()); - goto cleanup; - } - - if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not add ACE: error code %lu", GetLastError()); - goto cleanup; - } - } - - /* Add the new ACE for the current user */ - if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not add access allowed ACE: error code %lu", - GetLastError()); - goto cleanup; - } - - /* Set the new DACL in the token */ - tddNew.DefaultDacl = pacl; - - if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize)) - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not set token information: error code %lu", - GetLastError()); - goto cleanup; - } - - ret = TRUE; - -cleanup: - if (pTokenUser) - LocalFree((HLOCAL) pTokenUser); - - if (pacl) - LocalFree((HLOCAL) pacl); - - if (ptdd) - LocalFree((HLOCAL) ptdd); - - return ret; -} - -/* - * GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser) - * - * Get the users token information from a process token. - * - * The caller of this function is responsible for calling LocalFree() on the - * returned TOKEN_USER memory. - */ -static BOOL -GetTokenUser(HANDLE hToken, PTOKEN_USER *ppTokenUser) -{ - DWORD dwLength; - - *ppTokenUser = NULL; - - if (!GetTokenInformation(hToken, - TokenUser, - NULL, - 0, - &dwLength)) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - *ppTokenUser = (PTOKEN_USER) LocalAlloc(LPTR, dwLength); - - if (*ppTokenUser == NULL) - { - log_error(errcode(ERRCODE_OUT_OF_MEMORY), - _("out of memory")); - return FALSE; - } - } - else - { - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get token information buffer size: error code %lu", - GetLastError()); - return FALSE; - } - } - - if (!GetTokenInformation(hToken, - TokenUser, - *ppTokenUser, - dwLength, - &dwLength)) - { - LocalFree(*ppTokenUser); - *ppTokenUser = NULL; - - log_error(errcode(ERRCODE_SYSTEM_ERROR), - "could not get token information: error code %lu", - GetLastError()); - return FALSE; - } - - /* Memory in *ppTokenUser is LocalFree():d by the caller */ - return TRUE; -} - -#endif diff --git a/contrib/libs/libpq/src/common/f2s.c b/contrib/libs/libpq/src/common/f2s.c deleted file mode 100644 index ba08dcb6aa..0000000000 --- a/contrib/libs/libpq/src/common/f2s.c +++ /dev/null @@ -1,803 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Ryu floating-point output for single precision. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/f2s.c - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/shortest_dec.h" -#include "digit_table.h" -#include "ryu_common.h" - -#define FLOAT_MANTISSA_BITS 23 -#define FLOAT_EXPONENT_BITS 8 -#define FLOAT_BIAS 127 - -/* - * This table is generated (by the upstream) by PrintFloatLookupTable, - * and modified (by us) to add UINT64CONST. - */ -#define FLOAT_POW5_INV_BITCOUNT 59 -static const uint64 FLOAT_POW5_INV_SPLIT[31] = { - UINT64CONST(576460752303423489), UINT64CONST(461168601842738791), UINT64CONST(368934881474191033), UINT64CONST(295147905179352826), - UINT64CONST(472236648286964522), UINT64CONST(377789318629571618), UINT64CONST(302231454903657294), UINT64CONST(483570327845851670), - UINT64CONST(386856262276681336), UINT64CONST(309485009821345069), UINT64CONST(495176015714152110), UINT64CONST(396140812571321688), - UINT64CONST(316912650057057351), UINT64CONST(507060240091291761), UINT64CONST(405648192073033409), UINT64CONST(324518553658426727), - UINT64CONST(519229685853482763), UINT64CONST(415383748682786211), UINT64CONST(332306998946228969), UINT64CONST(531691198313966350), - UINT64CONST(425352958651173080), UINT64CONST(340282366920938464), UINT64CONST(544451787073501542), UINT64CONST(435561429658801234), - UINT64CONST(348449143727040987), UINT64CONST(557518629963265579), UINT64CONST(446014903970612463), UINT64CONST(356811923176489971), - UINT64CONST(570899077082383953), UINT64CONST(456719261665907162), UINT64CONST(365375409332725730) -}; -#define FLOAT_POW5_BITCOUNT 61 -static const uint64 FLOAT_POW5_SPLIT[47] = { - UINT64CONST(1152921504606846976), UINT64CONST(1441151880758558720), UINT64CONST(1801439850948198400), UINT64CONST(2251799813685248000), - UINT64CONST(1407374883553280000), UINT64CONST(1759218604441600000), UINT64CONST(2199023255552000000), UINT64CONST(1374389534720000000), - UINT64CONST(1717986918400000000), UINT64CONST(2147483648000000000), UINT64CONST(1342177280000000000), UINT64CONST(1677721600000000000), - UINT64CONST(2097152000000000000), UINT64CONST(1310720000000000000), UINT64CONST(1638400000000000000), UINT64CONST(2048000000000000000), - UINT64CONST(1280000000000000000), UINT64CONST(1600000000000000000), UINT64CONST(2000000000000000000), UINT64CONST(1250000000000000000), - UINT64CONST(1562500000000000000), UINT64CONST(1953125000000000000), UINT64CONST(1220703125000000000), UINT64CONST(1525878906250000000), - UINT64CONST(1907348632812500000), UINT64CONST(1192092895507812500), UINT64CONST(1490116119384765625), UINT64CONST(1862645149230957031), - UINT64CONST(1164153218269348144), UINT64CONST(1455191522836685180), UINT64CONST(1818989403545856475), UINT64CONST(2273736754432320594), - UINT64CONST(1421085471520200371), UINT64CONST(1776356839400250464), UINT64CONST(2220446049250313080), UINT64CONST(1387778780781445675), - UINT64CONST(1734723475976807094), UINT64CONST(2168404344971008868), UINT64CONST(1355252715606880542), UINT64CONST(1694065894508600678), - UINT64CONST(2117582368135750847), UINT64CONST(1323488980084844279), UINT64CONST(1654361225106055349), UINT64CONST(2067951531382569187), - UINT64CONST(1292469707114105741), UINT64CONST(1615587133892632177), UINT64CONST(2019483917365790221) -}; - -static inline uint32 -pow5Factor(uint32 value) -{ - uint32 count = 0; - - for (;;) - { - Assert(value != 0); - const uint32 q = value / 5; - const uint32 r = value % 5; - - if (r != 0) - break; - - value = q; - ++count; - } - return count; -} - -/* Returns true if value is divisible by 5^p. */ -static inline bool -multipleOfPowerOf5(const uint32 value, const uint32 p) -{ - return pow5Factor(value) >= p; -} - -/* Returns true if value is divisible by 2^p. */ -static inline bool -multipleOfPowerOf2(const uint32 value, const uint32 p) -{ - /* return __builtin_ctz(value) >= p; */ - return (value & ((1u << p) - 1)) == 0; -} - -/* - * It seems to be slightly faster to avoid uint128_t here, although the - * generated code for uint128_t looks slightly nicer. - */ -static inline uint32 -mulShift(const uint32 m, const uint64 factor, const int32 shift) -{ - /* - * The casts here help MSVC to avoid calls to the __allmul library - * function. - */ - const uint32 factorLo = (uint32) (factor); - const uint32 factorHi = (uint32) (factor >> 32); - const uint64 bits0 = (uint64) m * factorLo; - const uint64 bits1 = (uint64) m * factorHi; - - Assert(shift > 32); - -#ifdef RYU_32_BIT_PLATFORM - - /* - * On 32-bit platforms we can avoid a 64-bit shift-right since we only - * need the upper 32 bits of the result and the shift value is > 32. - */ - const uint32 bits0Hi = (uint32) (bits0 >> 32); - uint32 bits1Lo = (uint32) (bits1); - uint32 bits1Hi = (uint32) (bits1 >> 32); - - bits1Lo += bits0Hi; - bits1Hi += (bits1Lo < bits0Hi); - - const int32 s = shift - 32; - - return (bits1Hi << (32 - s)) | (bits1Lo >> s); - -#else /* RYU_32_BIT_PLATFORM */ - - const uint64 sum = (bits0 >> 32) + bits1; - const uint64 shiftedSum = sum >> (shift - 32); - - Assert(shiftedSum <= PG_UINT32_MAX); - return (uint32) shiftedSum; - -#endif /* RYU_32_BIT_PLATFORM */ -} - -static inline uint32 -mulPow5InvDivPow2(const uint32 m, const uint32 q, const int32 j) -{ - return mulShift(m, FLOAT_POW5_INV_SPLIT[q], j); -} - -static inline uint32 -mulPow5divPow2(const uint32 m, const uint32 i, const int32 j) -{ - return mulShift(m, FLOAT_POW5_SPLIT[i], j); -} - -static inline uint32 -decimalLength(const uint32 v) -{ - /* Function precondition: v is not a 10-digit number. */ - /* (9 digits are sufficient for round-tripping.) */ - Assert(v < 1000000000); - if (v >= 100000000) - { - return 9; - } - if (v >= 10000000) - { - return 8; - } - if (v >= 1000000) - { - return 7; - } - if (v >= 100000) - { - return 6; - } - if (v >= 10000) - { - return 5; - } - if (v >= 1000) - { - return 4; - } - if (v >= 100) - { - return 3; - } - if (v >= 10) - { - return 2; - } - return 1; -} - -/* A floating decimal representing m * 10^e. */ -typedef struct floating_decimal_32 -{ - uint32 mantissa; - int32 exponent; -} floating_decimal_32; - -static inline floating_decimal_32 -f2d(const uint32 ieeeMantissa, const uint32 ieeeExponent) -{ - int32 e2; - uint32 m2; - - if (ieeeExponent == 0) - { - /* We subtract 2 so that the bounds computation has 2 additional bits. */ - e2 = 1 - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; - m2 = ieeeMantissa; - } - else - { - e2 = ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS - 2; - m2 = (1u << FLOAT_MANTISSA_BITS) | ieeeMantissa; - } - -#if STRICTLY_SHORTEST - const bool even = (m2 & 1) == 0; - const bool acceptBounds = even; -#else - const bool acceptBounds = false; -#endif - - /* Step 2: Determine the interval of legal decimal representations. */ - const uint32 mv = 4 * m2; - const uint32 mp = 4 * m2 + 2; - - /* Implicit bool -> int conversion. True is 1, false is 0. */ - const uint32 mmShift = ieeeMantissa != 0 || ieeeExponent <= 1; - const uint32 mm = 4 * m2 - 1 - mmShift; - - /* Step 3: Convert to a decimal power base using 64-bit arithmetic. */ - uint32 vr, - vp, - vm; - int32 e10; - bool vmIsTrailingZeros = false; - bool vrIsTrailingZeros = false; - uint8 lastRemovedDigit = 0; - - if (e2 >= 0) - { - const uint32 q = log10Pow2(e2); - - e10 = q; - - const int32 k = FLOAT_POW5_INV_BITCOUNT + pow5bits(q) - 1; - const int32 i = -e2 + q + k; - - vr = mulPow5InvDivPow2(mv, q, i); - vp = mulPow5InvDivPow2(mp, q, i); - vm = mulPow5InvDivPow2(mm, q, i); - - if (q != 0 && (vp - 1) / 10 <= vm / 10) - { - /* - * We need to know one removed digit even if we are not going to - * loop below. We could use q = X - 1 above, except that would - * require 33 bits for the result, and we've found that 32-bit - * arithmetic is faster even on 64-bit machines. - */ - const int32 l = FLOAT_POW5_INV_BITCOUNT + pow5bits(q - 1) - 1; - - lastRemovedDigit = (uint8) (mulPow5InvDivPow2(mv, q - 1, -e2 + q - 1 + l) % 10); - } - if (q <= 9) - { - /* - * The largest power of 5 that fits in 24 bits is 5^10, but q <= 9 - * seems to be safe as well. - * - * Only one of mp, mv, and mm can be a multiple of 5, if any. - */ - if (mv % 5 == 0) - { - vrIsTrailingZeros = multipleOfPowerOf5(mv, q); - } - else if (acceptBounds) - { - vmIsTrailingZeros = multipleOfPowerOf5(mm, q); - } - else - { - vp -= multipleOfPowerOf5(mp, q); - } - } - } - else - { - const uint32 q = log10Pow5(-e2); - - e10 = q + e2; - - const int32 i = -e2 - q; - const int32 k = pow5bits(i) - FLOAT_POW5_BITCOUNT; - int32 j = q - k; - - vr = mulPow5divPow2(mv, i, j); - vp = mulPow5divPow2(mp, i, j); - vm = mulPow5divPow2(mm, i, j); - - if (q != 0 && (vp - 1) / 10 <= vm / 10) - { - j = q - 1 - (pow5bits(i + 1) - FLOAT_POW5_BITCOUNT); - lastRemovedDigit = (uint8) (mulPow5divPow2(mv, i + 1, j) % 10); - } - if (q <= 1) - { - /* - * {vr,vp,vm} is trailing zeros if {mv,mp,mm} has at least q - * trailing 0 bits. - */ - /* mv = 4 * m2, so it always has at least two trailing 0 bits. */ - vrIsTrailingZeros = true; - if (acceptBounds) - { - /* - * mm = mv - 1 - mmShift, so it has 1 trailing 0 bit iff - * mmShift == 1. - */ - vmIsTrailingZeros = mmShift == 1; - } - else - { - /* - * mp = mv + 2, so it always has at least one trailing 0 bit. - */ - --vp; - } - } - else if (q < 31) - { - /* TODO(ulfjack):Use a tighter bound here. */ - vrIsTrailingZeros = multipleOfPowerOf2(mv, q - 1); - } - } - - /* - * Step 4: Find the shortest decimal representation in the interval of - * legal representations. - */ - uint32 removed = 0; - uint32 output; - - if (vmIsTrailingZeros || vrIsTrailingZeros) - { - /* General case, which happens rarely (~4.0%). */ - while (vp / 10 > vm / 10) - { - vmIsTrailingZeros &= vm - (vm / 10) * 10 == 0; - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - if (vmIsTrailingZeros) - { - while (vm % 10 == 0) - { - vrIsTrailingZeros &= lastRemovedDigit == 0; - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - } - - if (vrIsTrailingZeros && lastRemovedDigit == 5 && vr % 2 == 0) - { - /* Round even if the exact number is .....50..0. */ - lastRemovedDigit = 4; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + ((vr == vm && (!acceptBounds || !vmIsTrailingZeros)) || lastRemovedDigit >= 5); - } - else - { - /* - * Specialized for the common case (~96.0%). Percentages below are - * relative to this. - * - * Loop iterations below (approximately): 0: 13.6%, 1: 70.7%, 2: - * 14.1%, 3: 1.39%, 4: 0.14%, 5+: 0.01% - */ - while (vp / 10 > vm / 10) - { - lastRemovedDigit = (uint8) (vr % 10); - vr /= 10; - vp /= 10; - vm /= 10; - ++removed; - } - - /* - * We need to take vr + 1 if vr is outside bounds or we need to round - * up. - */ - output = vr + (vr == vm || lastRemovedDigit >= 5); - } - - const int32 exp = e10 + removed; - - floating_decimal_32 fd; - - fd.exponent = exp; - fd.mantissa = output; - return fd; -} - -static inline int -to_chars_f(const floating_decimal_32 v, const uint32 olength, char *const result) -{ - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint32 output = v.mantissa; - int32 exp = v.exponent; - - /*---- - * On entry, mantissa * 10^exp is the result to be output. - * Caller has already done the - sign if needed. - * - * We want to insert the point somewhere depending on the output length - * and exponent, which might mean adding zeros: - * - * exp | format - * 1+ | ddddddddd000000 - * 0 | ddddddddd - * -1 .. -len+1 | dddddddd.d to d.ddddddddd - * -len ... | 0.ddddddddd to 0.000dddddd - */ - uint32 i = 0; - int32 nexp = exp + olength; - - if (nexp <= 0) - { - /* -nexp is number of 0s to add after '.' */ - Assert(nexp >= -3); - /* 0.000ddddd */ - index = 2 - nexp; - /* copy 8 bytes rather than 5 to let compiler optimize */ - memcpy(result, "0.000000", 8); - } - else if (exp < 0) - { - /* - * dddd.dddd; leave space at the start and move the '.' in after - */ - index = 1; - } - else - { - /* - * We can save some code later by pre-filling with zeros. We know that - * there can be no more than 6 output digits in this form, otherwise - * we would not choose fixed-point output. memset 8 rather than 6 - * bytes to let the compiler optimize it. - */ - Assert(exp < 6 && exp + olength <= 6); - memset(result, '0', 8); - } - - while (output >= 10000) - { - const uint32 c = output - 10000 * (output / 10000); - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - output /= 10000; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 4, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output >= 100) - { - const uint32 c = (output % 100) << 1; - - output /= 100; - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - i += 2; - } - if (output >= 10) - { - const uint32 c = output << 1; - - memcpy(result + index + olength - i - 2, DIGIT_TABLE + c, 2); - } - else - { - result[index] = (char) ('0' + output); - } - - if (index == 1) - { - /* - * nexp is 1..6 here, representing the number of digits before the - * point. A value of 7+ is not possible because we switch to - * scientific notation when the display exponent reaches 6. - */ - Assert(nexp < 7); - /* gcc only seems to want to optimize memmove for small 2^n */ - if (nexp & 4) - { - memmove(result + index - 1, result + index, 4); - index += 4; - } - if (nexp & 2) - { - memmove(result + index - 1, result + index, 2); - index += 2; - } - if (nexp & 1) - { - result[index - 1] = result[index]; - } - result[nexp] = '.'; - index = olength + 1; - } - else if (exp >= 0) - { - /* we supplied the trailing zeros earlier, now just set the length. */ - index = olength + exp; - } - else - { - index = olength + (2 - nexp); - } - - return index; -} - -static inline int -to_chars(const floating_decimal_32 v, const bool sign, char *const result) -{ - /* Step 5: Print the decimal representation. */ - int index = 0; - - uint32 output = v.mantissa; - uint32 olength = decimalLength(output); - int32 exp = v.exponent + olength - 1; - - if (sign) - result[index++] = '-'; - - /* - * The thresholds for fixed-point output are chosen to match printf - * defaults. Beware that both the code of to_chars_f and the value of - * FLOAT_SHORTEST_DECIMAL_LEN are sensitive to these thresholds. - */ - if (exp >= -4 && exp < 6) - return to_chars_f(v, olength, result + index) + sign; - - /* - * If v.exponent is exactly 0, we might have reached here via the small - * integer fast path, in which case v.mantissa might contain trailing - * (decimal) zeros. For scientific notation we need to move these zeros - * into the exponent. (For fixed point this doesn't matter, which is why - * we do this here rather than above.) - * - * Since we already calculated the display exponent (exp) above based on - * the old decimal length, that value does not change here. Instead, we - * just reduce the display length for each digit removed. - * - * If we didn't get here via the fast path, the raw exponent will not - * usually be 0, and there will be no trailing zeros, so we pay no more - * than one div10/multiply extra cost. We claw back half of that by - * checking for divisibility by 2 before dividing by 10. - */ - if (v.exponent == 0) - { - while ((output & 1) == 0) - { - const uint32 q = output / 10; - const uint32 r = output - 10 * q; - - if (r != 0) - break; - output = q; - --olength; - } - } - - /*---- - * Print the decimal digits. - * The following code is equivalent to: - * - * for (uint32 i = 0; i < olength - 1; ++i) { - * const uint32 c = output % 10; output /= 10; - * result[index + olength - i] = (char) ('0' + c); - * } - * result[index] = '0' + output % 10; - */ - uint32 i = 0; - - while (output >= 10000) - { - const uint32 c = output - 10000 * (output / 10000); - const uint32 c0 = (c % 100) << 1; - const uint32 c1 = (c / 100) << 1; - - output /= 10000; - - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c0, 2); - memcpy(result + index + olength - i - 3, DIGIT_TABLE + c1, 2); - i += 4; - } - if (output >= 100) - { - const uint32 c = (output % 100) << 1; - - output /= 100; - memcpy(result + index + olength - i - 1, DIGIT_TABLE + c, 2); - i += 2; - } - if (output >= 10) - { - const uint32 c = output << 1; - - /* - * We can't use memcpy here: the decimal dot goes between these two - * digits. - */ - result[index + olength - i] = DIGIT_TABLE[c + 1]; - result[index] = DIGIT_TABLE[c]; - } - else - { - result[index] = (char) ('0' + output); - } - - /* Print decimal point if needed. */ - if (olength > 1) - { - result[index + 1] = '.'; - index += olength + 1; - } - else - { - ++index; - } - - /* Print the exponent. */ - result[index++] = 'e'; - if (exp < 0) - { - result[index++] = '-'; - exp = -exp; - } - else - result[index++] = '+'; - - memcpy(result + index, DIGIT_TABLE + 2 * exp, 2); - index += 2; - - return index; -} - -static inline bool -f2d_small_int(const uint32 ieeeMantissa, - const uint32 ieeeExponent, - floating_decimal_32 *v) -{ - const int32 e2 = (int32) ieeeExponent - FLOAT_BIAS - FLOAT_MANTISSA_BITS; - - /* - * Avoid using multiple "return false;" here since it tends to provoke the - * compiler into inlining multiple copies of f2d, which is undesirable. - */ - - if (e2 >= -FLOAT_MANTISSA_BITS && e2 <= 0) - { - /*---- - * Since 2^23 <= m2 < 2^24 and 0 <= -e2 <= 23: - * 1 <= f = m2 / 2^-e2 < 2^24. - * - * Test if the lower -e2 bits of the significand are 0, i.e. whether - * the fraction is 0. We can use ieeeMantissa here, since the implied - * 1 bit can never be tested by this; the implied 1 can only be part - * of a fraction if e2 < -FLOAT_MANTISSA_BITS which we already - * checked. (e.g. 0.5 gives ieeeMantissa == 0 and e2 == -24) - */ - const uint32 mask = (1U << -e2) - 1; - const uint32 fraction = ieeeMantissa & mask; - - if (fraction == 0) - { - /*---- - * f is an integer in the range [1, 2^24). - * Note: mantissa might contain trailing (decimal) 0's. - * Note: since 2^24 < 10^9, there is no need to adjust - * decimalLength(). - */ - const uint32 m2 = (1U << FLOAT_MANTISSA_BITS) | ieeeMantissa; - - v->mantissa = m2 >> -e2; - v->exponent = 0; - return true; - } - } - - return false; -} - -/* - * Store the shortest decimal representation of the given float as an - * UNTERMINATED string in the caller's supplied buffer (which must be at least - * FLOAT_SHORTEST_DECIMAL_LEN-1 bytes long). - * - * Returns the number of bytes stored. - */ -int -float_to_shortest_decimal_bufn(float f, char *result) -{ - /* - * Step 1: Decode the floating-point number, and unify normalized and - * subnormal cases. - */ - const uint32 bits = float_to_bits(f); - - /* Decode bits into sign, mantissa, and exponent. */ - const bool ieeeSign = ((bits >> (FLOAT_MANTISSA_BITS + FLOAT_EXPONENT_BITS)) & 1) != 0; - const uint32 ieeeMantissa = bits & ((1u << FLOAT_MANTISSA_BITS) - 1); - const uint32 ieeeExponent = (bits >> FLOAT_MANTISSA_BITS) & ((1u << FLOAT_EXPONENT_BITS) - 1); - - /* Case distinction; exit early for the easy cases. */ - if (ieeeExponent == ((1u << FLOAT_EXPONENT_BITS) - 1u) || (ieeeExponent == 0 && ieeeMantissa == 0)) - { - return copy_special_str(result, ieeeSign, (ieeeExponent != 0), (ieeeMantissa != 0)); - } - - floating_decimal_32 v; - const bool isSmallInt = f2d_small_int(ieeeMantissa, ieeeExponent, &v); - - if (!isSmallInt) - { - v = f2d(ieeeMantissa, ieeeExponent); - } - - return to_chars(v, ieeeSign, result); -} - -/* - * Store the shortest decimal representation of the given float as a - * null-terminated string in the caller's supplied buffer (which must be at - * least FLOAT_SHORTEST_DECIMAL_LEN bytes long). - * - * Returns the string length. - */ -int -float_to_shortest_decimal_buf(float f, char *result) -{ - const int index = float_to_shortest_decimal_bufn(f, result); - - /* Terminate the string. */ - Assert(index < FLOAT_SHORTEST_DECIMAL_LEN); - result[index] = '\0'; - return index; -} - -/* - * Return the shortest decimal representation as a null-terminated palloc'd - * string (outside the backend, uses malloc() instead). - * - * Caller is responsible for freeing the result. - */ -char * -float_to_shortest_decimal(float f) -{ - char *const result = (char *) palloc(FLOAT_SHORTEST_DECIMAL_LEN); - - float_to_shortest_decimal_buf(f, result); - return result; -} diff --git a/contrib/libs/libpq/src/common/fe_memutils.c b/contrib/libs/libpq/src/common/fe_memutils.c deleted file mode 100644 index 3bad81eafc..0000000000 --- a/contrib/libs/libpq/src/common/fe_memutils.c +++ /dev/null @@ -1,175 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe_memutils.c - * memory management support for frontend code - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/fe_memutils.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#error "This file is not expected to be compiled for backend code" -#endif - -#include "postgres_fe.h" - -static inline void * -pg_malloc_internal(size_t size, int flags) -{ - void *tmp; - - /* Avoid unportable behavior of malloc(0) */ - if (size == 0) - size = 1; - tmp = malloc(size); - if (tmp == NULL) - { - if ((flags & MCXT_ALLOC_NO_OOM) == 0) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - return NULL; - } - - if ((flags & MCXT_ALLOC_ZERO) != 0) - MemSet(tmp, 0, size); - return tmp; -} - -void * -pg_malloc(size_t size) -{ - return pg_malloc_internal(size, 0); -} - -void * -pg_malloc0(size_t size) -{ - return pg_malloc_internal(size, MCXT_ALLOC_ZERO); -} - -void * -pg_malloc_extended(size_t size, int flags) -{ - return pg_malloc_internal(size, flags); -} - -void * -pg_realloc(void *ptr, size_t size) -{ - void *tmp; - - /* Avoid unportable behavior of realloc(NULL, 0) */ - if (ptr == NULL && size == 0) - size = 1; - tmp = realloc(ptr, size); - if (!tmp) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - return tmp; -} - -/* - * "Safe" wrapper around strdup(). - */ -char * -pg_strdup(const char *in) -{ - char *tmp; - - if (!in) - { - fprintf(stderr, - _("cannot duplicate null pointer (internal error)\n")); - exit(EXIT_FAILURE); - } - tmp = strdup(in); - if (!tmp) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - return tmp; -} - -void -pg_free(void *ptr) -{ - free(ptr); -} - -/* - * Frontend emulation of backend memory management functions. Useful for - * programs that compile backend files. - */ -void * -palloc(Size size) -{ - return pg_malloc_internal(size, 0); -} - -void * -palloc0(Size size) -{ - return pg_malloc_internal(size, MCXT_ALLOC_ZERO); -} - -void * -palloc_extended(Size size, int flags) -{ - return pg_malloc_internal(size, flags); -} - -void -pfree(void *pointer) -{ - pg_free(pointer); -} - -char * -pstrdup(const char *in) -{ - return pg_strdup(in); -} - -char * -pnstrdup(const char *in, Size size) -{ - char *tmp; - int len; - - if (!in) - { - fprintf(stderr, - _("cannot duplicate null pointer (internal error)\n")); - exit(EXIT_FAILURE); - } - - len = strnlen(in, size); - tmp = malloc(len + 1); - if (tmp == NULL) - { - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); - } - - memcpy(tmp, in, len); - tmp[len] = '\0'; - - return tmp; -} - -void * -repalloc(void *pointer, Size size) -{ - return pg_realloc(pointer, size); -} diff --git a/contrib/libs/libpq/src/common/file_perm.c b/contrib/libs/libpq/src/common/file_perm.c deleted file mode 100644 index 60f88d2caf..0000000000 --- a/contrib/libs/libpq/src/common/file_perm.c +++ /dev/null @@ -1,91 +0,0 @@ -/*------------------------------------------------------------------------- - * - * File and directory permission routines - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/common/file_perm.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "common/file_perm.h" - -/* Modes for creating directories and files in the data directory */ -int pg_dir_create_mode = PG_DIR_MODE_OWNER; -int pg_file_create_mode = PG_FILE_MODE_OWNER; - -/* - * Mode mask to pass to umask(). This is more of a preventative measure since - * all file/directory creates should be performed using the create modes above. - */ -int pg_mode_mask = PG_MODE_MASK_OWNER; - -/* - * Set create modes and mask to use when writing to PGDATA based on the data - * directory mode passed. If group read/execute are present in the mode, then - * create modes and mask will be relaxed to allow group read/execute on all - * newly created files and directories. - */ -void -SetDataDirectoryCreatePerm(int dataDirMode) -{ - /* If the data directory mode has group access */ - if ((PG_DIR_MODE_GROUP & dataDirMode) == PG_DIR_MODE_GROUP) - { - pg_dir_create_mode = PG_DIR_MODE_GROUP; - pg_file_create_mode = PG_FILE_MODE_GROUP; - pg_mode_mask = PG_MODE_MASK_GROUP; - } - /* Else use default permissions */ - else - { - pg_dir_create_mode = PG_DIR_MODE_OWNER; - pg_file_create_mode = PG_FILE_MODE_OWNER; - pg_mode_mask = PG_MODE_MASK_OWNER; - } -} - -#ifdef FRONTEND - -/* - * Get the create modes and mask to use when writing to PGDATA by examining the - * mode of the PGDATA directory and calling SetDataDirectoryCreatePerm(). - * - * Errors are not handled here and should be reported by the application when - * false is returned. - * - * Suppress when on Windows, because there may not be proper support for Unix-y - * file permissions. - */ -bool -GetDataDirectoryCreatePerm(const char *dataDir) -{ -#if !defined(WIN32) && !defined(__CYGWIN__) - struct stat statBuf; - - /* - * If an error occurs getting the mode then return false. The caller is - * responsible for generating an error, if appropriate, indicating that we - * were unable to access the data directory. - */ - if (stat(dataDir, &statBuf) == -1) - return false; - - /* Set permissions */ - SetDataDirectoryCreatePerm(statBuf.st_mode); - return true; -#else /* !defined(WIN32) && !defined(__CYGWIN__) */ - /* - * On Windows, we don't have anything to do here since they don't have - * Unix-y permissions. - */ - return true; -#endif -} - - -#endif /* FRONTEND */ diff --git a/contrib/libs/libpq/src/common/file_utils.c b/contrib/libs/libpq/src/common/file_utils.c deleted file mode 100644 index 74833c4acb..0000000000 --- a/contrib/libs/libpq/src/common/file_utils.c +++ /dev/null @@ -1,582 +0,0 @@ -/*------------------------------------------------------------------------- - * - * File-processing utility routines. - * - * Assorted utility functions to work on files. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/common/file_utils.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <dirent.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "common/file_utils.h" -#ifdef FRONTEND -#include "common/logging.h" -#endif -#include "port/pg_iovec.h" - -#ifdef FRONTEND - -/* Define PG_FLUSH_DATA_WORKS if we have an implementation for pg_flush_data */ -#if defined(HAVE_SYNC_FILE_RANGE) -#define PG_FLUSH_DATA_WORKS 1 -#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED) -#define PG_FLUSH_DATA_WORKS 1 -#endif - -/* - * pg_xlog has been renamed to pg_wal in version 10. - */ -#define MINIMUM_VERSION_FOR_PG_WAL 100000 - -#ifdef PG_FLUSH_DATA_WORKS -static int pre_sync_fname(const char *fname, bool isdir); -#endif -static void walkdir(const char *path, - int (*action) (const char *fname, bool isdir), - bool process_symlinks); - -/* - * Issue fsync recursively on PGDATA and all its contents. - * - * We fsync regular files and directories wherever they are, but we follow - * symlinks only for pg_wal (or pg_xlog) and immediately under pg_tblspc. - * Other symlinks are presumed to point at files we're not responsible for - * fsyncing, and might not have privileges to write at all. - * - * serverVersion indicates the version of the server to be fsync'd. - */ -void -fsync_pgdata(const char *pg_data, - int serverVersion) -{ - bool xlog_is_symlink; - char pg_wal[MAXPGPATH]; - char pg_tblspc[MAXPGPATH]; - - /* handle renaming of pg_xlog to pg_wal in post-10 clusters */ - snprintf(pg_wal, MAXPGPATH, "%s/%s", pg_data, - serverVersion < MINIMUM_VERSION_FOR_PG_WAL ? "pg_xlog" : "pg_wal"); - snprintf(pg_tblspc, MAXPGPATH, "%s/pg_tblspc", pg_data); - - /* - * If pg_wal is a symlink, we'll need to recurse into it separately, - * because the first walkdir below will ignore it. - */ - xlog_is_symlink = false; - - { - struct stat st; - - if (lstat(pg_wal, &st) < 0) - pg_log_error("could not stat file \"%s\": %m", pg_wal); - else if (S_ISLNK(st.st_mode)) - xlog_is_symlink = true; - } - - /* - * If possible, hint to the kernel that we're soon going to fsync the data - * directory and its contents. - */ -#ifdef PG_FLUSH_DATA_WORKS - walkdir(pg_data, pre_sync_fname, false); - if (xlog_is_symlink) - walkdir(pg_wal, pre_sync_fname, false); - walkdir(pg_tblspc, pre_sync_fname, true); -#endif - - /* - * Now we do the fsync()s in the same order. - * - * The main call ignores symlinks, so in addition to specially processing - * pg_wal if it's a symlink, pg_tblspc has to be visited separately with - * process_symlinks = true. Note that if there are any plain directories - * in pg_tblspc, they'll get fsync'd twice. That's not an expected case - * so we don't worry about optimizing it. - */ - walkdir(pg_data, fsync_fname, false); - if (xlog_is_symlink) - walkdir(pg_wal, fsync_fname, false); - walkdir(pg_tblspc, fsync_fname, true); -} - -/* - * Issue fsync recursively on the given directory and all its contents. - * - * This is a convenient wrapper on top of walkdir(). - */ -void -fsync_dir_recurse(const char *dir) -{ - /* - * If possible, hint to the kernel that we're soon going to fsync the data - * directory and its contents. - */ -#ifdef PG_FLUSH_DATA_WORKS - walkdir(dir, pre_sync_fname, false); -#endif - - walkdir(dir, fsync_fname, false); -} - -/* - * walkdir: recursively walk a directory, applying the action to each - * regular file and directory (including the named directory itself). - * - * If process_symlinks is true, the action and recursion are also applied - * to regular files and directories that are pointed to by symlinks in the - * given directory; otherwise symlinks are ignored. Symlinks are always - * ignored in subdirectories, ie we intentionally don't pass down the - * process_symlinks flag to recursive calls. - * - * Errors are reported but not considered fatal. - * - * See also walkdir in fd.c, which is a backend version of this logic. - */ -static void -walkdir(const char *path, - int (*action) (const char *fname, bool isdir), - bool process_symlinks) -{ - DIR *dir; - struct dirent *de; - - dir = opendir(path); - if (dir == NULL) - { - pg_log_error("could not open directory \"%s\": %m", path); - return; - } - - while (errno = 0, (de = readdir(dir)) != NULL) - { - char subpath[MAXPGPATH * 2]; - - if (strcmp(de->d_name, ".") == 0 || - strcmp(de->d_name, "..") == 0) - continue; - - snprintf(subpath, sizeof(subpath), "%s/%s", path, de->d_name); - - switch (get_dirent_type(subpath, de, process_symlinks, PG_LOG_ERROR)) - { - case PGFILETYPE_REG: - (*action) (subpath, false); - break; - case PGFILETYPE_DIR: - walkdir(subpath, action, false); - break; - default: - - /* - * Errors are already reported directly by get_dirent_type(), - * and any remaining symlinks and unknown file types are - * ignored. - */ - break; - } - } - - if (errno) - pg_log_error("could not read directory \"%s\": %m", path); - - (void) closedir(dir); - - /* - * It's important to fsync the destination directory itself as individual - * file fsyncs don't guarantee that the directory entry for the file is - * synced. Recent versions of ext4 have made the window much wider but - * it's been an issue for ext3 and other filesystems in the past. - */ - (*action) (path, true); -} - -/* - * Hint to the OS that it should get ready to fsync() this file. - * - * Ignores errors trying to open unreadable files, and reports other errors - * non-fatally. - */ -#ifdef PG_FLUSH_DATA_WORKS - -static int -pre_sync_fname(const char *fname, bool isdir) -{ - int fd; - - fd = open(fname, O_RDONLY | PG_BINARY, 0); - - if (fd < 0) - { - if (errno == EACCES || (isdir && errno == EISDIR)) - return 0; - pg_log_error("could not open file \"%s\": %m", fname); - return -1; - } - - /* - * We do what pg_flush_data() would do in the backend: prefer to use - * sync_file_range, but fall back to posix_fadvise. We ignore errors - * because this is only a hint. - */ -#if defined(HAVE_SYNC_FILE_RANGE) - (void) sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE); -#elif defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED) - (void) posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); -#else -#error PG_FLUSH_DATA_WORKS should not have been defined -#endif - - (void) close(fd); - return 0; -} - -#endif /* PG_FLUSH_DATA_WORKS */ - -/* - * fsync_fname -- Try to fsync a file or directory - * - * Ignores errors trying to open unreadable files, or trying to fsync - * directories on systems where that isn't allowed/required. All other errors - * are fatal. - */ -int -fsync_fname(const char *fname, bool isdir) -{ - int fd; - int flags; - int returncode; - - /* - * Some OSs require directories to be opened read-only whereas other - * systems don't allow us to fsync files opened read-only; so we need both - * cases here. Using O_RDWR will cause us to fail to fsync files that are - * not writable by our userid, but we assume that's OK. - */ - flags = PG_BINARY; - if (!isdir) - flags |= O_RDWR; - else - flags |= O_RDONLY; - - /* - * Open the file, silently ignoring errors about unreadable files (or - * unsupported operations, e.g. opening a directory under Windows), and - * logging others. - */ - fd = open(fname, flags, 0); - if (fd < 0) - { - if (errno == EACCES || (isdir && errno == EISDIR)) - return 0; - pg_log_error("could not open file \"%s\": %m", fname); - return -1; - } - - returncode = fsync(fd); - - /* - * Some OSes don't allow us to fsync directories at all, so we can ignore - * those errors. Anything else needs to be reported. - */ - if (returncode != 0 && !(isdir && (errno == EBADF || errno == EINVAL))) - { - pg_log_error("could not fsync file \"%s\": %m", fname); - (void) close(fd); - exit(EXIT_FAILURE); - } - - (void) close(fd); - return 0; -} - -/* - * fsync_parent_path -- fsync the parent path of a file or directory - * - * This is aimed at making file operations persistent on disk in case of - * an OS crash or power failure. - */ -int -fsync_parent_path(const char *fname) -{ - char parentpath[MAXPGPATH]; - - strlcpy(parentpath, fname, MAXPGPATH); - get_parent_directory(parentpath); - - /* - * get_parent_directory() returns an empty string if the input argument is - * just a file name (see comments in path.c), so handle that as being the - * current directory. - */ - if (strlen(parentpath) == 0) - strlcpy(parentpath, ".", MAXPGPATH); - - if (fsync_fname(parentpath, true) != 0) - return -1; - - return 0; -} - -/* - * durable_rename -- rename(2) wrapper, issuing fsyncs required for durability - * - * Wrapper around rename, similar to the backend version. - */ -int -durable_rename(const char *oldfile, const char *newfile) -{ - int fd; - - /* - * First fsync the old and target path (if it exists), to ensure that they - * are properly persistent on disk. Syncing the target file is not - * strictly necessary, but it makes it easier to reason about crashes; - * because it's then guaranteed that either source or target file exists - * after a crash. - */ - if (fsync_fname(oldfile, false) != 0) - return -1; - - fd = open(newfile, PG_BINARY | O_RDWR, 0); - if (fd < 0) - { - if (errno != ENOENT) - { - pg_log_error("could not open file \"%s\": %m", newfile); - return -1; - } - } - else - { - if (fsync(fd) != 0) - { - pg_log_error("could not fsync file \"%s\": %m", newfile); - close(fd); - exit(EXIT_FAILURE); - } - close(fd); - } - - /* Time to do the real deal... */ - if (rename(oldfile, newfile) != 0) - { - pg_log_error("could not rename file \"%s\" to \"%s\": %m", - oldfile, newfile); - return -1; - } - - /* - * To guarantee renaming the file is persistent, fsync the file with its - * new name, and its containing directory. - */ - if (fsync_fname(newfile, false) != 0) - return -1; - - if (fsync_parent_path(newfile) != 0) - return -1; - - return 0; -} - -#endif /* FRONTEND */ - -/* - * Return the type of a directory entry. - * - * In frontend code, elevel should be a level from logging.h; in backend code - * it should be a level from elog.h. - */ -PGFileType -get_dirent_type(const char *path, - const struct dirent *de, - bool look_through_symlinks, - int elevel) -{ - PGFileType result; - - /* - * Some systems tell us the type directly in the dirent struct, but that's - * a BSD and Linux extension not required by POSIX. Even when the - * interface is present, sometimes the type is unknown, depending on the - * filesystem. - */ -#if defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK) - if (de->d_type == DT_REG) - result = PGFILETYPE_REG; - else if (de->d_type == DT_DIR) - result = PGFILETYPE_DIR; - else if (de->d_type == DT_LNK && !look_through_symlinks) - result = PGFILETYPE_LNK; - else - result = PGFILETYPE_UNKNOWN; -#else - result = PGFILETYPE_UNKNOWN; -#endif - - if (result == PGFILETYPE_UNKNOWN) - { - struct stat fst; - int sret; - - - if (look_through_symlinks) - sret = stat(path, &fst); - else - sret = lstat(path, &fst); - - if (sret < 0) - { - result = PGFILETYPE_ERROR; -#ifdef FRONTEND - pg_log_generic(elevel, PG_LOG_PRIMARY, "could not stat file \"%s\": %m", path); -#else - ereport(elevel, - (errcode_for_file_access(), - errmsg("could not stat file \"%s\": %m", path))); -#endif - } - else if (S_ISREG(fst.st_mode)) - result = PGFILETYPE_REG; - else if (S_ISDIR(fst.st_mode)) - result = PGFILETYPE_DIR; - else if (S_ISLNK(fst.st_mode)) - result = PGFILETYPE_LNK; - } - - return result; -} - -/* - * pg_pwritev_with_retry - * - * Convenience wrapper for pg_pwritev() that retries on partial write. If an - * error is returned, it is unspecified how much has been written. - */ -ssize_t -pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset) -{ - struct iovec iov_copy[PG_IOV_MAX]; - ssize_t sum = 0; - ssize_t part; - - /* We'd better have space to make a copy, in case we need to retry. */ - if (iovcnt > PG_IOV_MAX) - { - errno = EINVAL; - return -1; - } - - for (;;) - { - /* Write as much as we can. */ - part = pg_pwritev(fd, iov, iovcnt, offset); - if (part < 0) - return -1; - -#ifdef SIMULATE_SHORT_WRITE - part = Min(part, 4096); -#endif - - /* Count our progress. */ - sum += part; - offset += part; - - /* Step over iovecs that are done. */ - while (iovcnt > 0 && iov->iov_len <= part) - { - part -= iov->iov_len; - ++iov; - --iovcnt; - } - - /* Are they all done? */ - if (iovcnt == 0) - { - /* We don't expect the kernel to write more than requested. */ - Assert(part == 0); - break; - } - - /* - * Move whatever's left to the front of our mutable copy and adjust - * the leading iovec. - */ - Assert(iovcnt > 0); - memmove(iov_copy, iov, sizeof(*iov) * iovcnt); - Assert(iov->iov_len > part); - iov_copy[0].iov_base = (char *) iov_copy[0].iov_base + part; - iov_copy[0].iov_len -= part; - iov = iov_copy; - } - - return sum; -} - -/* - * pg_pwrite_zeros - * - * Writes zeros to file worth "size" bytes at "offset" (from the start of the - * file), using vectored I/O. - * - * Returns the total amount of data written. On failure, a negative value - * is returned with errno set. - */ -ssize_t -pg_pwrite_zeros(int fd, size_t size, off_t offset) -{ - static const PGIOAlignedBlock zbuffer = {{0}}; /* worth BLCKSZ */ - void *zerobuf_addr = unconstify(PGIOAlignedBlock *, &zbuffer)->data; - struct iovec iov[PG_IOV_MAX]; - size_t remaining_size = size; - ssize_t total_written = 0; - - /* Loop, writing as many blocks as we can for each system call. */ - while (remaining_size > 0) - { - int iovcnt = 0; - ssize_t written; - - for (; iovcnt < PG_IOV_MAX && remaining_size > 0; iovcnt++) - { - size_t this_iov_size; - - iov[iovcnt].iov_base = zerobuf_addr; - - if (remaining_size < BLCKSZ) - this_iov_size = remaining_size; - else - this_iov_size = BLCKSZ; - - iov[iovcnt].iov_len = this_iov_size; - remaining_size -= this_iov_size; - } - - written = pg_pwritev_with_retry(fd, iov, iovcnt, offset); - - if (written < 0) - return written; - - offset += written; - total_written += written; - } - - Assert(total_written == size); - - return total_written; -} diff --git a/contrib/libs/libpq/src/common/hashfn.c b/contrib/libs/libpq/src/common/hashfn.c deleted file mode 100644 index 2490607eea..0000000000 --- a/contrib/libs/libpq/src/common/hashfn.c +++ /dev/null @@ -1,692 +0,0 @@ -/*------------------------------------------------------------------------- - * - * hashfn.c - * Generic hashing functions, and hash functions for use in dynahash.c - * hashtables - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/hashfn.c - * - * NOTES - * It is expected that every bit of a hash function's 32-bit result is - * as random as every other; failure to ensure this is likely to lead - * to poor performance of hash tables. In most cases a hash - * function should use hash_bytes() or its variant hash_bytes_uint32(), - * or the wrappers hash_any() and hash_uint32 defined in hashfn.h. - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "common/hashfn.h" -#include "port/pg_bitutils.h" - - -/* - * This hash function was written by Bob Jenkins - * (bob_jenkins@burtleburtle.net), and superficially adapted - * for PostgreSQL by Neil Conway. For more information on this - * hash function, see http://burtleburtle.net/bob/hash/doobs.html, - * or Bob's article in Dr. Dobb's Journal, Sept. 1997. - * - * In the current code, we have adopted Bob's 2006 update of his hash - * function to fetch the data a word at a time when it is suitably aligned. - * This makes for a useful speedup, at the cost of having to maintain - * four code paths (aligned vs unaligned, and little-endian vs big-endian). - * It also uses two separate mixing functions mix() and final(), instead - * of a slower multi-purpose function. - */ - -/* Get a bit mask of the bits set in non-uint32 aligned addresses */ -#define UINT32_ALIGN_MASK (sizeof(uint32) - 1) - -#define rot(x,k) pg_rotate_left32(x, k) - -/*---------- - * mix -- mix 3 32-bit values reversibly. - * - * This is reversible, so any information in (a,b,c) before mix() is - * still in (a,b,c) after mix(). - * - * If four pairs of (a,b,c) inputs are run through mix(), or through - * mix() in reverse, there are at least 32 bits of the output that - * are sometimes the same for one pair and different for another pair. - * This was tested for: - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * This does not achieve avalanche. There are input bits of (a,b,c) - * that fail to affect some output bits of (a,b,c), especially of a. The - * most thoroughly mixed value is c, but it doesn't really even achieve - * avalanche in c. - * - * This allows some parallelism. Read-after-writes are good at doubling - * the number of bits affected, so the goal of mixing pulls in the opposite - * direction from the goal of parallelism. I did what I could. Rotates - * seem to cost as much as shifts on every machine I could lay my hands on, - * and rotates are much kinder to the top and bottom bits, so I used rotates. - *---------- - */ -#define mix(a,b,c) \ -{ \ - a -= c; a ^= rot(c, 4); c += b; \ - b -= a; b ^= rot(a, 6); a += c; \ - c -= b; c ^= rot(b, 8); b += a; \ - a -= c; a ^= rot(c,16); c += b; \ - b -= a; b ^= rot(a,19); a += c; \ - c -= b; c ^= rot(b, 4); b += a; \ -} - -/*---------- - * final -- final mixing of 3 32-bit values (a,b,c) into c - * - * Pairs of (a,b,c) values differing in only a few bits will usually - * produce values of c that look totally different. This was tested for - * * pairs that differed by one bit, by two bits, in any combination - * of top bits of (a,b,c), or in any combination of bottom bits of - * (a,b,c). - * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed - * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as - * is commonly produced by subtraction) look like a single 1-bit - * difference. - * * the base values were pseudorandom, all zero but one bit set, or - * all zero plus a counter that starts at zero. - * - * The use of separate functions for mix() and final() allow for a - * substantial performance increase since final() does not need to - * do well in reverse, but is does need to affect all output bits. - * mix(), on the other hand, does not need to affect all output - * bits (affecting 32 bits is enough). The original hash function had - * a single mixing operation that had to satisfy both sets of requirements - * and was slower as a result. - *---------- - */ -#define final(a,b,c) \ -{ \ - c ^= b; c -= rot(b,14); \ - a ^= c; a -= rot(c,11); \ - b ^= a; b -= rot(a,25); \ - c ^= b; c -= rot(b,16); \ - a ^= c; a -= rot(c, 4); \ - b ^= a; b -= rot(a,14); \ - c ^= b; c -= rot(b,24); \ -} - -/* - * hash_bytes() -- hash a variable-length key into a 32-bit value - * k : the key (the unaligned variable-length array of bytes) - * len : the length of the key, counting by bytes - * - * Returns a uint32 value. Every bit of the key affects every bit of - * the return value. Every 1-bit and 2-bit delta achieves avalanche. - * About 6*len+35 instructions. The best hash table sizes are powers - * of 2. There is no need to do mod a prime (mod is sooo slow!). - * If you need less than 32 bits, use a bitmask. - * - * This procedure must never throw elog(ERROR); the ResourceOwner code - * relies on this not to fail. - * - * Note: we could easily change this function to return a 64-bit hash value - * by using the final values of both b and c. b is perhaps a little less - * well mixed than c, however. - */ -uint32 -hash_bytes(const unsigned char *k, int keylen) -{ - uint32 a, - b, - c, - len; - - /* Set up the internal state */ - len = keylen; - a = b = c = 0x9e3779b9 + len + 3923095; - - /* If the source pointer is word-aligned, we use word-wide fetches */ - if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) - { - /* Code path for aligned source data */ - const uint32 *ka = (const uint32 *) k; - - /* handle most of the key */ - while (len >= 12) - { - a += ka[0]; - b += ka[1]; - c += ka[2]; - mix(a, b, c); - ka += 3; - len -= 12; - } - - /* handle the last 11 bytes */ - k = (const unsigned char *) ka; -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - else - { - /* Code path for non-aligned source data */ - - /* handle most of the key */ - while (len >= 12) - { -#ifdef WORDS_BIGENDIAN - a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); - b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); - c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); -#else /* !WORDS_BIGENDIAN */ - a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); - b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); - c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); -#endif /* WORDS_BIGENDIAN */ - mix(a, b, c); - k += 12; - len -= 12; - } - - /* handle the last 11 bytes */ -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += k[7]; - /* fall through */ - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += k[3]; - /* fall through */ - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ((uint32) k[7] << 24); - /* fall through */ - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ((uint32) k[3] << 24); - /* fall through */ - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - - final(a, b, c); - - /* report the result */ - return c; -} - -/* - * hash_bytes_extended() -- hash into a 64-bit value, using an optional seed - * k : the key (the unaligned variable-length array of bytes) - * len : the length of the key, counting by bytes - * seed : a 64-bit seed (0 means no seed) - * - * Returns a uint64 value. Otherwise similar to hash_bytes. - */ -uint64 -hash_bytes_extended(const unsigned char *k, int keylen, uint64 seed) -{ - uint32 a, - b, - c, - len; - - /* Set up the internal state */ - len = keylen; - a = b = c = 0x9e3779b9 + len + 3923095; - - /* If the seed is non-zero, use it to perturb the internal state. */ - if (seed != 0) - { - /* - * In essence, the seed is treated as part of the data being hashed, - * but for simplicity, we pretend that it's padded with four bytes of - * zeroes so that the seed constitutes a 12-byte chunk. - */ - a += (uint32) (seed >> 32); - b += (uint32) seed; - mix(a, b, c); - } - - /* If the source pointer is word-aligned, we use word-wide fetches */ - if (((uintptr_t) k & UINT32_ALIGN_MASK) == 0) - { - /* Code path for aligned source data */ - const uint32 *ka = (const uint32 *) k; - - /* handle most of the key */ - while (len >= 12) - { - a += ka[0]; - b += ka[1]; - c += ka[2]; - mix(a, b, c); - ka += 3; - len -= 12; - } - - /* handle the last 11 bytes */ - k = (const unsigned char *) ka; -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ka[1]; - a += ka[0]; - break; - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ka[0]; - break; - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - else - { - /* Code path for non-aligned source data */ - - /* handle most of the key */ - while (len >= 12) - { -#ifdef WORDS_BIGENDIAN - a += (k[3] + ((uint32) k[2] << 8) + ((uint32) k[1] << 16) + ((uint32) k[0] << 24)); - b += (k[7] + ((uint32) k[6] << 8) + ((uint32) k[5] << 16) + ((uint32) k[4] << 24)); - c += (k[11] + ((uint32) k[10] << 8) + ((uint32) k[9] << 16) + ((uint32) k[8] << 24)); -#else /* !WORDS_BIGENDIAN */ - a += (k[0] + ((uint32) k[1] << 8) + ((uint32) k[2] << 16) + ((uint32) k[3] << 24)); - b += (k[4] + ((uint32) k[5] << 8) + ((uint32) k[6] << 16) + ((uint32) k[7] << 24)); - c += (k[8] + ((uint32) k[9] << 8) + ((uint32) k[10] << 16) + ((uint32) k[11] << 24)); -#endif /* WORDS_BIGENDIAN */ - mix(a, b, c); - k += 12; - len -= 12; - } - - /* handle the last 11 bytes */ -#ifdef WORDS_BIGENDIAN - switch (len) - { - case 11: - c += ((uint32) k[10] << 8); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 24); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += k[7]; - /* fall through */ - case 7: - b += ((uint32) k[6] << 8); - /* fall through */ - case 6: - b += ((uint32) k[5] << 16); - /* fall through */ - case 5: - b += ((uint32) k[4] << 24); - /* fall through */ - case 4: - a += k[3]; - /* fall through */ - case 3: - a += ((uint32) k[2] << 8); - /* fall through */ - case 2: - a += ((uint32) k[1] << 16); - /* fall through */ - case 1: - a += ((uint32) k[0] << 24); - /* case 0: nothing left to add */ - } -#else /* !WORDS_BIGENDIAN */ - switch (len) - { - case 11: - c += ((uint32) k[10] << 24); - /* fall through */ - case 10: - c += ((uint32) k[9] << 16); - /* fall through */ - case 9: - c += ((uint32) k[8] << 8); - /* fall through */ - case 8: - /* the lowest byte of c is reserved for the length */ - b += ((uint32) k[7] << 24); - /* fall through */ - case 7: - b += ((uint32) k[6] << 16); - /* fall through */ - case 6: - b += ((uint32) k[5] << 8); - /* fall through */ - case 5: - b += k[4]; - /* fall through */ - case 4: - a += ((uint32) k[3] << 24); - /* fall through */ - case 3: - a += ((uint32) k[2] << 16); - /* fall through */ - case 2: - a += ((uint32) k[1] << 8); - /* fall through */ - case 1: - a += k[0]; - /* case 0: nothing left to add */ - } -#endif /* WORDS_BIGENDIAN */ - } - - final(a, b, c); - - /* report the result */ - return ((uint64) b << 32) | c; -} - -/* - * hash_bytes_uint32() -- hash a 32-bit value to a 32-bit value - * - * This has the same result as - * hash_bytes(&k, sizeof(uint32)) - * but is faster and doesn't force the caller to store k into memory. - */ -uint32 -hash_bytes_uint32(uint32 k) -{ - uint32 a, - b, - c; - - a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; - a += k; - - final(a, b, c); - - /* report the result */ - return c; -} - -/* - * hash_bytes_uint32_extended() -- hash 32-bit value to 64-bit value, with seed - * - * Like hash_bytes_uint32, this is a convenience function. - */ -uint64 -hash_bytes_uint32_extended(uint32 k, uint64 seed) -{ - uint32 a, - b, - c; - - a = b = c = 0x9e3779b9 + (uint32) sizeof(uint32) + 3923095; - - if (seed != 0) - { - a += (uint32) (seed >> 32); - b += (uint32) seed; - mix(a, b, c); - } - - a += k; - - final(a, b, c); - - /* report the result */ - return ((uint64) b << 32) | c; -} - -/* - * string_hash: hash function for keys that are NUL-terminated strings. - * - * NOTE: this is the default hash function if none is specified. - */ -uint32 -string_hash(const void *key, Size keysize) -{ - /* - * If the string exceeds keysize-1 bytes, we want to hash only that many, - * because when it is copied into the hash table it will be truncated at - * that length. - */ - Size s_len = strlen((const char *) key); - - s_len = Min(s_len, keysize - 1); - return hash_bytes((const unsigned char *) key, (int) s_len); -} - -/* - * tag_hash: hash function for fixed-size tag values - */ -uint32 -tag_hash(const void *key, Size keysize) -{ - return hash_bytes((const unsigned char *) key, (int) keysize); -} - -/* - * uint32_hash: hash function for keys that are uint32 or int32 - * - * (tag_hash works for this case too, but is slower) - */ -uint32 -uint32_hash(const void *key, Size keysize) -{ - Assert(keysize == sizeof(uint32)); - return hash_bytes_uint32(*((const uint32 *) key)); -} diff --git a/contrib/libs/libpq/src/common/hmac_openssl.c b/contrib/libs/libpq/src/common/hmac_openssl.c deleted file mode 100644 index 9aadbb886c..0000000000 --- a/contrib/libs/libpq/src/common/hmac_openssl.c +++ /dev/null @@ -1,348 +0,0 @@ -/*------------------------------------------------------------------------- - * - * hmac_openssl.c - * Implementation of HMAC with OpenSSL. - * - * This should only be used if code is compiled with OpenSSL support. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/hmac_openssl.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - - -#include <openssl/err.h> -#include <openssl/hmac.h> - -#include "common/hmac.h" -#include "common/md5.h" -#include "common/sha1.h" -#include "common/sha2.h" -#ifndef FRONTEND -#error #include "utils/memutils.h" -#error #include "utils/resowner.h" -#error #include "utils/resowner_private.h" -#endif - -/* - * In backend, use an allocation in TopMemoryContext to count for resowner - * cleanup handling if necessary. For versions of OpenSSL where HMAC_CTX is - * known, just use palloc(). In frontend, use malloc to be able to return - * a failure status back to the caller. - */ -#ifndef FRONTEND -#ifdef HAVE_HMAC_CTX_NEW -#define ALLOC(size) MemoryContextAlloc(TopMemoryContext, size) -#else -#define ALLOC(size) palloc(size) -#endif -#define FREE(ptr) pfree(ptr) -#else /* FRONTEND */ -#define ALLOC(size) malloc(size) -#define FREE(ptr) free(ptr) -#endif /* FRONTEND */ - -/* Set of error states */ -typedef enum pg_hmac_errno -{ - PG_HMAC_ERROR_NONE = 0, - PG_HMAC_ERROR_DEST_LEN, - PG_HMAC_ERROR_OPENSSL -} pg_hmac_errno; - -/* Internal pg_hmac_ctx structure */ -struct pg_hmac_ctx -{ - HMAC_CTX *hmacctx; - pg_cryptohash_type type; - pg_hmac_errno error; - const char *errreason; - -#ifndef FRONTEND - ResourceOwner resowner; -#endif -}; - -static const char * -SSLerrmessage(unsigned long ecode) -{ - if (ecode == 0) - return NULL; - - /* - * This may return NULL, but we would fall back to a default error path if - * that were the case. - */ - return ERR_reason_error_string(ecode); -} - -/* - * pg_hmac_create - * - * Allocate a hash context. Returns NULL on failure for an OOM. The - * backend issues an error, without returning. - */ -pg_hmac_ctx * -pg_hmac_create(pg_cryptohash_type type) -{ - pg_hmac_ctx *ctx; - - ctx = ALLOC(sizeof(pg_hmac_ctx)); - if (ctx == NULL) - return NULL; - memset(ctx, 0, sizeof(pg_hmac_ctx)); - - ctx->type = type; - ctx->error = PG_HMAC_ERROR_NONE; - ctx->errreason = NULL; - - - /* - * Initialization takes care of assigning the correct type for OpenSSL. - * Also ensure that there aren't any unconsumed errors in the queue from - * previous runs. - */ - ERR_clear_error(); -#ifdef HAVE_HMAC_CTX_NEW -#ifndef FRONTEND - ResourceOwnerEnlargeHMAC(CurrentResourceOwner); -#endif - ctx->hmacctx = HMAC_CTX_new(); -#else - ctx->hmacctx = ALLOC(sizeof(HMAC_CTX)); -#endif - - if (ctx->hmacctx == NULL) - { - explicit_bzero(ctx, sizeof(pg_hmac_ctx)); - FREE(ctx); -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#endif - return NULL; - } - -#ifdef HAVE_HMAC_CTX_NEW -#ifndef FRONTEND - ctx->resowner = CurrentResourceOwner; - ResourceOwnerRememberHMAC(CurrentResourceOwner, PointerGetDatum(ctx)); -#endif -#else - memset(ctx->hmacctx, 0, sizeof(HMAC_CTX)); -#endif /* HAVE_HMAC_CTX_NEW */ - - return ctx; -} - -/* - * pg_hmac_init - * - * Initialize a HMAC context. Returns 0 on success, -1 on failure. - */ -int -pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len) -{ - int status = 0; - - if (ctx == NULL) - return -1; - - switch (ctx->type) - { - case PG_MD5: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_md5(), NULL); - break; - case PG_SHA1: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha1(), NULL); - break; - case PG_SHA224: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha224(), NULL); - break; - case PG_SHA256: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha256(), NULL); - break; - case PG_SHA384: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha384(), NULL); - break; - case PG_SHA512: - status = HMAC_Init_ex(ctx->hmacctx, key, len, EVP_sha512(), NULL); - break; - } - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_HMAC_ERROR_OPENSSL; - return -1; - } - - return 0; -} - -/* - * pg_hmac_update - * - * Update a HMAC context. Returns 0 on success, -1 on failure. - */ -int -pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len) -{ - int status = 0; - - if (ctx == NULL) - return -1; - - status = HMAC_Update(ctx->hmacctx, data, len); - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_HMAC_ERROR_OPENSSL; - return -1; - } - return 0; -} - -/* - * pg_hmac_final - * - * Finalize a HMAC context. Returns 0 on success, -1 on failure. - */ -int -pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len) -{ - int status = 0; - uint32 outlen; - - if (ctx == NULL) - return -1; - - switch (ctx->type) - { - case PG_MD5: - if (len < MD5_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA1: - if (len < SHA1_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA224: - if (len < PG_SHA224_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA256: - if (len < PG_SHA256_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA384: - if (len < PG_SHA384_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - case PG_SHA512: - if (len < PG_SHA512_DIGEST_LENGTH) - { - ctx->error = PG_HMAC_ERROR_DEST_LEN; - return -1; - } - break; - } - - status = HMAC_Final(ctx->hmacctx, dest, &outlen); - - /* OpenSSL internals return 1 on success, 0 on failure */ - if (status <= 0) - { - ctx->errreason = SSLerrmessage(ERR_get_error()); - ctx->error = PG_HMAC_ERROR_OPENSSL; - return -1; - } - return 0; -} - -/* - * pg_hmac_free - * - * Free a HMAC context. - */ -void -pg_hmac_free(pg_hmac_ctx *ctx) -{ - if (ctx == NULL) - return; - -#ifdef HAVE_HMAC_CTX_FREE - HMAC_CTX_free(ctx->hmacctx); -#ifndef FRONTEND - ResourceOwnerForgetHMAC(ctx->resowner, PointerGetDatum(ctx)); -#endif -#else - explicit_bzero(ctx->hmacctx, sizeof(HMAC_CTX)); - FREE(ctx->hmacctx); -#endif - - explicit_bzero(ctx, sizeof(pg_hmac_ctx)); - FREE(ctx); -} - -/* - * pg_hmac_error - * - * Returns a static string providing details about an error that happened - * during a HMAC computation. - */ -const char * -pg_hmac_error(pg_hmac_ctx *ctx) -{ - if (ctx == NULL) - return _("out of memory"); - - /* - * If a reason is provided, rely on it, else fallback to any error code - * set. - */ - if (ctx->errreason) - return ctx->errreason; - - switch (ctx->error) - { - case PG_HMAC_ERROR_NONE: - return _("success"); - case PG_HMAC_ERROR_DEST_LEN: - return _("destination buffer too small"); - case PG_HMAC_ERROR_OPENSSL: - return _("OpenSSL failure"); - } - - Assert(false); /* cannot be reached */ - return _("success"); -} diff --git a/contrib/libs/libpq/src/common/ip.c b/contrib/libs/libpq/src/common/ip.c deleted file mode 100644 index 9baad3a337..0000000000 --- a/contrib/libs/libpq/src/common/ip.c +++ /dev/null @@ -1,262 +0,0 @@ -/*------------------------------------------------------------------------- - * - * ip.c - * IPv6-aware network access. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/ip.c - * - * This file and the IPV6 implementation were initially provided by - * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design - * http://www.lbsd.net. - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <unistd.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#include <sys/file.h> - -#include "common/ip.h" - - - -static int getaddrinfo_unix(const char *path, - const struct addrinfo *hintsp, - struct addrinfo **result); - -static int getnameinfo_unix(const struct sockaddr_un *sa, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); - - -/* - * pg_getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets - */ -int -pg_getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo *hintp, struct addrinfo **result) -{ - int rc; - - /* not all versions of getaddrinfo() zero *result on failure */ - *result = NULL; - - if (hintp->ai_family == AF_UNIX) - return getaddrinfo_unix(servname, hintp, result); - - /* NULL has special meaning to getaddrinfo(). */ - rc = getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname, - servname, hintp, result); - - return rc; -} - - -/* - * pg_freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix - * - * Note: the ai_family field of the original hint structure must be passed - * so that we can tell whether the addrinfo struct was built by the system's - * getaddrinfo() routine or our own getaddrinfo_unix() routine. Some versions - * of getaddrinfo() might be willing to return AF_UNIX addresses, so it's - * not safe to look at ai_family in the addrinfo itself. - */ -void -pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai) -{ - if (hint_ai_family == AF_UNIX) - { - /* struct was built by getaddrinfo_unix (see pg_getaddrinfo_all) */ - while (ai != NULL) - { - struct addrinfo *p = ai; - - ai = ai->ai_next; - free(p->ai_addr); - free(p); - } - } - else - { - /* struct was built by getaddrinfo() */ - if (ai != NULL) - freeaddrinfo(ai); - } -} - - -/* - * pg_getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets - * - * The API of this routine differs from the standard getnameinfo() definition - * in two ways: first, the addr parameter is declared as sockaddr_storage - * rather than struct sockaddr, and second, the node and service fields are - * guaranteed to be filled with something even on failure return. - */ -int -pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags) -{ - int rc; - - if (addr && addr->ss_family == AF_UNIX) - rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen, - node, nodelen, - service, servicelen, - flags); - else - rc = getnameinfo((const struct sockaddr *) addr, salen, - node, nodelen, - service, servicelen, - flags); - - if (rc != 0) - { - if (node) - strlcpy(node, "???", nodelen); - if (service) - strlcpy(service, "???", servicelen); - } - - return rc; -} - - -/* ------- - * getaddrinfo_unix - get unix socket info using IPv6-compatible API - * - * Bugs: only one addrinfo is set even though hintsp is NULL or - * ai_socktype is 0 - * AI_CANONNAME is not supported. - * ------- - */ -static int -getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, - struct addrinfo **result) -{ - struct addrinfo hints = {0}; - struct addrinfo *aip; - struct sockaddr_un *unp; - - *result = NULL; - - if (strlen(path) >= sizeof(unp->sun_path)) - return EAI_FAIL; - - if (hintsp == NULL) - { - hints.ai_family = AF_UNIX; - hints.ai_socktype = SOCK_STREAM; - } - else - memcpy(&hints, hintsp, sizeof(hints)); - - if (hints.ai_socktype == 0) - hints.ai_socktype = SOCK_STREAM; - - if (hints.ai_family != AF_UNIX) - { - /* shouldn't have been called */ - return EAI_FAIL; - } - - aip = calloc(1, sizeof(struct addrinfo)); - if (aip == NULL) - return EAI_MEMORY; - - unp = calloc(1, sizeof(struct sockaddr_un)); - if (unp == NULL) - { - free(aip); - return EAI_MEMORY; - } - - aip->ai_family = AF_UNIX; - aip->ai_socktype = hints.ai_socktype; - aip->ai_protocol = hints.ai_protocol; - aip->ai_next = NULL; - aip->ai_canonname = NULL; - *result = aip; - - unp->sun_family = AF_UNIX; - aip->ai_addr = (struct sockaddr *) unp; - aip->ai_addrlen = sizeof(struct sockaddr_un); - - strcpy(unp->sun_path, path); - - /* - * If the supplied path starts with @, replace that with a zero byte for - * the internal representation. In that mode, the entire sun_path is the - * address, including trailing zero bytes. But we set the address length - * to only include the length of the original string. That way the - * trailing zero bytes won't show up in any network or socket lists of the - * operating system. This is just a convention, also followed by other - * packages. - */ - if (path[0] == '@') - { - unp->sun_path[0] = '\0'; - aip->ai_addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(path); - } - - return 0; -} - -/* - * Convert an address to a hostname. - */ -static int -getnameinfo_unix(const struct sockaddr_un *sa, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags) -{ - int ret; - - /* Invalid arguments. */ - if (sa == NULL || sa->sun_family != AF_UNIX || - (node == NULL && service == NULL)) - return EAI_FAIL; - - if (node) - { - ret = snprintf(node, nodelen, "%s", "[local]"); - if (ret < 0 || ret >= nodelen) - return EAI_MEMORY; - } - - if (service) - { - /* - * Check whether it looks like an abstract socket, but it could also - * just be an empty string. - */ - if (sa->sun_path[0] == '\0' && sa->sun_path[1] != '\0') - ret = snprintf(service, servicelen, "@%s", sa->sun_path + 1); - else - ret = snprintf(service, servicelen, "%s", sa->sun_path); - if (ret < 0 || ret >= servicelen) - return EAI_MEMORY; - } - - return 0; -} diff --git a/contrib/libs/libpq/src/common/jsonapi.c b/contrib/libs/libpq/src/common/jsonapi.c deleted file mode 100644 index bb8178e91d..0000000000 --- a/contrib/libs/libpq/src/common/jsonapi.c +++ /dev/null @@ -1,1206 +0,0 @@ -/*------------------------------------------------------------------------- - * - * jsonapi.c - * JSON parser and lexer interfaces - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/jsonapi.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/jsonapi.h" -#include "mb/pg_wchar.h" -#include "port/pg_lfind.h" - -#ifndef FRONTEND -#error #include "miscadmin.h" -#endif - -/* - * The context of the parser is maintained by the recursive descent - * mechanism, but is passed explicitly to the error reporting routine - * for better diagnostics. - */ -typedef enum /* contexts of JSON parser */ -{ - JSON_PARSE_VALUE, /* expecting a value */ - JSON_PARSE_STRING, /* expecting a string (for a field name) */ - JSON_PARSE_ARRAY_START, /* saw '[', expecting value or ']' */ - JSON_PARSE_ARRAY_NEXT, /* saw array element, expecting ',' or ']' */ - JSON_PARSE_OBJECT_START, /* saw '{', expecting label or '}' */ - JSON_PARSE_OBJECT_LABEL, /* saw object label, expecting ':' */ - JSON_PARSE_OBJECT_NEXT, /* saw object value, expecting ',' or '}' */ - JSON_PARSE_OBJECT_COMMA, /* saw object ',', expecting next label */ - JSON_PARSE_END /* saw the end of a document, expect nothing */ -} JsonParseContext; - -static inline JsonParseErrorType json_lex_string(JsonLexContext *lex); -static inline JsonParseErrorType json_lex_number(JsonLexContext *lex, char *s, - bool *num_err, int *total_len); -static inline JsonParseErrorType parse_scalar(JsonLexContext *lex, JsonSemAction *sem); -static JsonParseErrorType parse_object_field(JsonLexContext *lex, JsonSemAction *sem); -static JsonParseErrorType parse_object(JsonLexContext *lex, JsonSemAction *sem); -static JsonParseErrorType parse_array_element(JsonLexContext *lex, JsonSemAction *sem); -static JsonParseErrorType parse_array(JsonLexContext *lex, JsonSemAction *sem); -static JsonParseErrorType report_parse_error(JsonParseContext ctx, JsonLexContext *lex); - -/* the null action object used for pure validation */ -JsonSemAction nullSemAction = -{ - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL -}; - -/* Recursive Descent parser support routines */ - -/* - * lex_peek - * - * what is the current look_ahead token? -*/ -static inline JsonTokenType -lex_peek(JsonLexContext *lex) -{ - return lex->token_type; -} - -/* - * lex_expect - * - * move the lexer to the next token if the current look_ahead token matches - * the parameter token. Otherwise, report an error. - */ -static inline JsonParseErrorType -lex_expect(JsonParseContext ctx, JsonLexContext *lex, JsonTokenType token) -{ - if (lex_peek(lex) == token) - return json_lex(lex); - else - return report_parse_error(ctx, lex); -} - -/* chars to consider as part of an alphanumeric token */ -#define JSON_ALPHANUMERIC_CHAR(c) \ - (((c) >= 'a' && (c) <= 'z') || \ - ((c) >= 'A' && (c) <= 'Z') || \ - ((c) >= '0' && (c) <= '9') || \ - (c) == '_' || \ - IS_HIGHBIT_SET(c)) - -/* - * Utility function to check if a string is a valid JSON number. - * - * str is of length len, and need not be null-terminated. - */ -bool -IsValidJsonNumber(const char *str, int len) -{ - bool numeric_error; - int total_len; - JsonLexContext dummy_lex; - - if (len <= 0) - return false; - - /* - * json_lex_number expects a leading '-' to have been eaten already. - * - * having to cast away the constness of str is ugly, but there's not much - * easy alternative. - */ - if (*str == '-') - { - dummy_lex.input = unconstify(char *, str) + 1; - dummy_lex.input_length = len - 1; - } - else - { - dummy_lex.input = unconstify(char *, str); - dummy_lex.input_length = len; - } - - json_lex_number(&dummy_lex, dummy_lex.input, &numeric_error, &total_len); - - return (!numeric_error) && (total_len == dummy_lex.input_length); -} - -/* - * makeJsonLexContextCstringLen - * - * lex constructor, with or without StringInfo object for de-escaped lexemes. - * - * Without is better as it makes the processing faster, so only make one - * if really required. - */ -JsonLexContext * -makeJsonLexContextCstringLen(char *json, int len, int encoding, bool need_escapes) -{ - JsonLexContext *lex = palloc0(sizeof(JsonLexContext)); - - lex->input = lex->token_terminator = lex->line_start = json; - lex->line_number = 1; - lex->input_length = len; - lex->input_encoding = encoding; - if (need_escapes) - lex->strval = makeStringInfo(); - return lex; -} - -/* - * pg_parse_json - * - * Publicly visible entry point for the JSON parser. - * - * lex is a lexing context, set up for the json to be processed by calling - * makeJsonLexContext(). sem is a structure of function pointers to semantic - * action routines to be called at appropriate spots during parsing, and a - * pointer to a state object to be passed to those routines. - */ -JsonParseErrorType -pg_parse_json(JsonLexContext *lex, JsonSemAction *sem) -{ - JsonTokenType tok; - JsonParseErrorType result; - - /* get the initial token */ - result = json_lex(lex); - if (result != JSON_SUCCESS) - return result; - - tok = lex_peek(lex); - - /* parse by recursive descent */ - switch (tok) - { - case JSON_TOKEN_OBJECT_START: - result = parse_object(lex, sem); - break; - case JSON_TOKEN_ARRAY_START: - result = parse_array(lex, sem); - break; - default: - result = parse_scalar(lex, sem); /* json can be a bare scalar */ - } - - if (result == JSON_SUCCESS) - result = lex_expect(JSON_PARSE_END, lex, JSON_TOKEN_END); - - return result; -} - -/* - * json_count_array_elements - * - * Returns number of array elements in lex context at start of array token - * until end of array token at same nesting level. - * - * Designed to be called from array_start routines. - */ -JsonParseErrorType -json_count_array_elements(JsonLexContext *lex, int *elements) -{ - JsonLexContext copylex; - int count; - JsonParseErrorType result; - - /* - * It's safe to do this with a shallow copy because the lexical routines - * don't scribble on the input. They do scribble on the other pointers - * etc, so doing this with a copy makes that safe. - */ - memcpy(©lex, lex, sizeof(JsonLexContext)); - copylex.strval = NULL; /* not interested in values here */ - copylex.lex_level++; - - count = 0; - result = lex_expect(JSON_PARSE_ARRAY_START, ©lex, - JSON_TOKEN_ARRAY_START); - if (result != JSON_SUCCESS) - return result; - if (lex_peek(©lex) != JSON_TOKEN_ARRAY_END) - { - while (1) - { - count++; - result = parse_array_element(©lex, &nullSemAction); - if (result != JSON_SUCCESS) - return result; - if (copylex.token_type != JSON_TOKEN_COMMA) - break; - result = json_lex(©lex); - if (result != JSON_SUCCESS) - return result; - } - } - result = lex_expect(JSON_PARSE_ARRAY_NEXT, ©lex, - JSON_TOKEN_ARRAY_END); - if (result != JSON_SUCCESS) - return result; - - *elements = count; - return JSON_SUCCESS; -} - -/* - * Recursive Descent parse routines. There is one for each structural - * element in a json document: - * - scalar (string, number, true, false, null) - * - array ( [ ] ) - * - array element - * - object ( { } ) - * - object field - */ -static inline JsonParseErrorType -parse_scalar(JsonLexContext *lex, JsonSemAction *sem) -{ - char *val = NULL; - json_scalar_action sfunc = sem->scalar; - JsonTokenType tok = lex_peek(lex); - JsonParseErrorType result; - - /* a scalar must be a string, a number, true, false, or null */ - if (tok != JSON_TOKEN_STRING && tok != JSON_TOKEN_NUMBER && - tok != JSON_TOKEN_TRUE && tok != JSON_TOKEN_FALSE && - tok != JSON_TOKEN_NULL) - return report_parse_error(JSON_PARSE_VALUE, lex); - - /* if no semantic function, just consume the token */ - if (sfunc == NULL) - return json_lex(lex); - - /* extract the de-escaped string value, or the raw lexeme */ - if (lex_peek(lex) == JSON_TOKEN_STRING) - { - if (lex->strval != NULL) - val = pstrdup(lex->strval->data); - } - else - { - int len = (lex->token_terminator - lex->token_start); - - val = palloc(len + 1); - memcpy(val, lex->token_start, len); - val[len] = '\0'; - } - - /* consume the token */ - result = json_lex(lex); - if (result != JSON_SUCCESS) - return result; - - /* invoke the callback */ - result = (*sfunc) (sem->semstate, val, tok); - - return result; -} - -static JsonParseErrorType -parse_object_field(JsonLexContext *lex, JsonSemAction *sem) -{ - /* - * An object field is "fieldname" : value where value can be a scalar, - * object or array. Note: in user-facing docs and error messages, we - * generally call a field name a "key". - */ - - char *fname = NULL; /* keep compiler quiet */ - json_ofield_action ostart = sem->object_field_start; - json_ofield_action oend = sem->object_field_end; - bool isnull; - JsonTokenType tok; - JsonParseErrorType result; - - if (lex_peek(lex) != JSON_TOKEN_STRING) - return report_parse_error(JSON_PARSE_STRING, lex); - if ((ostart != NULL || oend != NULL) && lex->strval != NULL) - fname = pstrdup(lex->strval->data); - result = json_lex(lex); - if (result != JSON_SUCCESS) - return result; - - result = lex_expect(JSON_PARSE_OBJECT_LABEL, lex, JSON_TOKEN_COLON); - if (result != JSON_SUCCESS) - return result; - - tok = lex_peek(lex); - isnull = tok == JSON_TOKEN_NULL; - - if (ostart != NULL) - { - result = (*ostart) (sem->semstate, fname, isnull); - if (result != JSON_SUCCESS) - return result; - } - - switch (tok) - { - case JSON_TOKEN_OBJECT_START: - result = parse_object(lex, sem); - break; - case JSON_TOKEN_ARRAY_START: - result = parse_array(lex, sem); - break; - default: - result = parse_scalar(lex, sem); - } - if (result != JSON_SUCCESS) - return result; - - if (oend != NULL) - { - result = (*oend) (sem->semstate, fname, isnull); - if (result != JSON_SUCCESS) - return result; - } - - return JSON_SUCCESS; -} - -static JsonParseErrorType -parse_object(JsonLexContext *lex, JsonSemAction *sem) -{ - /* - * an object is a possibly empty sequence of object fields, separated by - * commas and surrounded by curly braces. - */ - json_struct_action ostart = sem->object_start; - json_struct_action oend = sem->object_end; - JsonTokenType tok; - JsonParseErrorType result; - -#ifndef FRONTEND - check_stack_depth(); -#endif - - if (ostart != NULL) - { - result = (*ostart) (sem->semstate); - if (result != JSON_SUCCESS) - return result; - } - - /* - * Data inside an object is at a higher nesting level than the object - * itself. Note that we increment this after we call the semantic routine - * for the object start and restore it before we call the routine for the - * object end. - */ - lex->lex_level++; - - Assert(lex_peek(lex) == JSON_TOKEN_OBJECT_START); - result = json_lex(lex); - if (result != JSON_SUCCESS) - return result; - - tok = lex_peek(lex); - switch (tok) - { - case JSON_TOKEN_STRING: - result = parse_object_field(lex, sem); - while (result == JSON_SUCCESS && lex_peek(lex) == JSON_TOKEN_COMMA) - { - result = json_lex(lex); - if (result != JSON_SUCCESS) - break; - result = parse_object_field(lex, sem); - } - break; - case JSON_TOKEN_OBJECT_END: - break; - default: - /* case of an invalid initial token inside the object */ - result = report_parse_error(JSON_PARSE_OBJECT_START, lex); - } - if (result != JSON_SUCCESS) - return result; - - result = lex_expect(JSON_PARSE_OBJECT_NEXT, lex, JSON_TOKEN_OBJECT_END); - if (result != JSON_SUCCESS) - return result; - - lex->lex_level--; - - if (oend != NULL) - { - result = (*oend) (sem->semstate); - if (result != JSON_SUCCESS) - return result; - } - - return JSON_SUCCESS; -} - -static JsonParseErrorType -parse_array_element(JsonLexContext *lex, JsonSemAction *sem) -{ - json_aelem_action astart = sem->array_element_start; - json_aelem_action aend = sem->array_element_end; - JsonTokenType tok = lex_peek(lex); - JsonParseErrorType result; - bool isnull; - - isnull = tok == JSON_TOKEN_NULL; - - if (astart != NULL) - { - result = (*astart) (sem->semstate, isnull); - if (result != JSON_SUCCESS) - return result; - } - - /* an array element is any object, array or scalar */ - switch (tok) - { - case JSON_TOKEN_OBJECT_START: - result = parse_object(lex, sem); - break; - case JSON_TOKEN_ARRAY_START: - result = parse_array(lex, sem); - break; - default: - result = parse_scalar(lex, sem); - } - - if (result != JSON_SUCCESS) - return result; - - if (aend != NULL) - { - result = (*aend) (sem->semstate, isnull); - if (result != JSON_SUCCESS) - return result; - } - - return JSON_SUCCESS; -} - -static JsonParseErrorType -parse_array(JsonLexContext *lex, JsonSemAction *sem) -{ - /* - * an array is a possibly empty sequence of array elements, separated by - * commas and surrounded by square brackets. - */ - json_struct_action astart = sem->array_start; - json_struct_action aend = sem->array_end; - JsonParseErrorType result; - -#ifndef FRONTEND - check_stack_depth(); -#endif - - if (astart != NULL) - { - result = (*astart) (sem->semstate); - if (result != JSON_SUCCESS) - return result; - } - - /* - * Data inside an array is at a higher nesting level than the array - * itself. Note that we increment this after we call the semantic routine - * for the array start and restore it before we call the routine for the - * array end. - */ - lex->lex_level++; - - result = lex_expect(JSON_PARSE_ARRAY_START, lex, JSON_TOKEN_ARRAY_START); - if (result == JSON_SUCCESS && lex_peek(lex) != JSON_TOKEN_ARRAY_END) - { - result = parse_array_element(lex, sem); - - while (result == JSON_SUCCESS && lex_peek(lex) == JSON_TOKEN_COMMA) - { - result = json_lex(lex); - if (result != JSON_SUCCESS) - break; - result = parse_array_element(lex, sem); - } - } - if (result != JSON_SUCCESS) - return result; - - result = lex_expect(JSON_PARSE_ARRAY_NEXT, lex, JSON_TOKEN_ARRAY_END); - if (result != JSON_SUCCESS) - return result; - - lex->lex_level--; - - if (aend != NULL) - { - result = (*aend) (sem->semstate); - if (result != JSON_SUCCESS) - return result; - } - - return JSON_SUCCESS; -} - -/* - * Lex one token from the input stream. - */ -JsonParseErrorType -json_lex(JsonLexContext *lex) -{ - char *s; - char *const end = lex->input + lex->input_length; - JsonParseErrorType result; - - /* Skip leading whitespace. */ - s = lex->token_terminator; - while (s < end && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')) - { - if (*s++ == '\n') - { - ++lex->line_number; - lex->line_start = s; - } - } - lex->token_start = s; - - /* Determine token type. */ - if (s >= end) - { - lex->token_start = NULL; - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s; - lex->token_type = JSON_TOKEN_END; - } - else - { - switch (*s) - { - /* Single-character token, some kind of punctuation mark. */ - case '{': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_OBJECT_START; - break; - case '}': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_OBJECT_END; - break; - case '[': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_ARRAY_START; - break; - case ']': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_ARRAY_END; - break; - case ',': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_COMMA; - break; - case ':': - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - lex->token_type = JSON_TOKEN_COLON; - break; - case '"': - /* string */ - result = json_lex_string(lex); - if (result != JSON_SUCCESS) - return result; - lex->token_type = JSON_TOKEN_STRING; - break; - case '-': - /* Negative number. */ - result = json_lex_number(lex, s + 1, NULL, NULL); - if (result != JSON_SUCCESS) - return result; - lex->token_type = JSON_TOKEN_NUMBER; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* Positive number. */ - result = json_lex_number(lex, s, NULL, NULL); - if (result != JSON_SUCCESS) - return result; - lex->token_type = JSON_TOKEN_NUMBER; - break; - default: - { - char *p; - - /* - * We're not dealing with a string, number, legal - * punctuation mark, or end of string. The only legal - * tokens we might find here are true, false, and null, - * but for error reporting purposes we scan until we see a - * non-alphanumeric character. That way, we can report - * the whole word as an unexpected token, rather than just - * some unintuitive prefix thereof. - */ - for (p = s; p < end && JSON_ALPHANUMERIC_CHAR(*p); p++) - /* skip */ ; - - /* - * We got some sort of unexpected punctuation or an - * otherwise unexpected character, so just complain about - * that one character. - */ - if (p == s) - { - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - return JSON_INVALID_TOKEN; - } - - /* - * We've got a real alphanumeric token here. If it - * happens to be true, false, or null, all is well. If - * not, error out. - */ - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = p; - if (p - s == 4) - { - if (memcmp(s, "true", 4) == 0) - lex->token_type = JSON_TOKEN_TRUE; - else if (memcmp(s, "null", 4) == 0) - lex->token_type = JSON_TOKEN_NULL; - else - return JSON_INVALID_TOKEN; - } - else if (p - s == 5 && memcmp(s, "false", 5) == 0) - lex->token_type = JSON_TOKEN_FALSE; - else - return JSON_INVALID_TOKEN; - } - } /* end of switch */ - } - - return JSON_SUCCESS; -} - -/* - * The next token in the input stream is known to be a string; lex it. - * - * If lex->strval isn't NULL, fill it with the decoded string. - * Set lex->token_terminator to the end of the decoded input, and in - * success cases, transfer its previous value to lex->prev_token_terminator. - * Return JSON_SUCCESS or an error code. - * - * Note: be careful that all error exits advance lex->token_terminator - * to the point after the character we detected the error on. - */ -static inline JsonParseErrorType -json_lex_string(JsonLexContext *lex) -{ - char *s; - char *const end = lex->input + lex->input_length; - int hi_surrogate = -1; - - /* Convenience macros for error exits */ -#define FAIL_AT_CHAR_START(code) \ - do { \ - lex->token_terminator = s; \ - return code; \ - } while (0) -#define FAIL_AT_CHAR_END(code) \ - do { \ - lex->token_terminator = \ - s + pg_encoding_mblen_bounded(lex->input_encoding, s); \ - return code; \ - } while (0) - - if (lex->strval != NULL) - resetStringInfo(lex->strval); - - Assert(lex->input_length > 0); - s = lex->token_start; - for (;;) - { - s++; - /* Premature end of the string. */ - if (s >= end) - FAIL_AT_CHAR_START(JSON_INVALID_TOKEN); - else if (*s == '"') - break; - else if (*s == '\\') - { - /* OK, we have an escape character. */ - s++; - if (s >= end) - FAIL_AT_CHAR_START(JSON_INVALID_TOKEN); - else if (*s == 'u') - { - int i; - int ch = 0; - - for (i = 1; i <= 4; i++) - { - s++; - if (s >= end) - FAIL_AT_CHAR_START(JSON_INVALID_TOKEN); - else if (*s >= '0' && *s <= '9') - ch = (ch * 16) + (*s - '0'); - else if (*s >= 'a' && *s <= 'f') - ch = (ch * 16) + (*s - 'a') + 10; - else if (*s >= 'A' && *s <= 'F') - ch = (ch * 16) + (*s - 'A') + 10; - else - FAIL_AT_CHAR_END(JSON_UNICODE_ESCAPE_FORMAT); - } - if (lex->strval != NULL) - { - /* - * Combine surrogate pairs. - */ - if (is_utf16_surrogate_first(ch)) - { - if (hi_surrogate != -1) - FAIL_AT_CHAR_END(JSON_UNICODE_HIGH_SURROGATE); - hi_surrogate = ch; - continue; - } - else if (is_utf16_surrogate_second(ch)) - { - if (hi_surrogate == -1) - FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE); - ch = surrogate_pair_to_codepoint(hi_surrogate, ch); - hi_surrogate = -1; - } - - if (hi_surrogate != -1) - FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE); - - /* - * Reject invalid cases. We can't have a value above - * 0xFFFF here (since we only accepted 4 hex digits - * above), so no need to test for out-of-range chars. - */ - if (ch == 0) - { - /* We can't allow this, since our TEXT type doesn't */ - FAIL_AT_CHAR_END(JSON_UNICODE_CODE_POINT_ZERO); - } - - /* - * Add the represented character to lex->strval. In the - * backend, we can let pg_unicode_to_server_noerror() - * handle any required character set conversion; in - * frontend, we can only deal with trivial conversions. - */ -#ifndef FRONTEND - { - char cbuf[MAX_UNICODE_EQUIVALENT_STRING + 1]; - - if (!pg_unicode_to_server_noerror(ch, (unsigned char *) cbuf)) - FAIL_AT_CHAR_END(JSON_UNICODE_UNTRANSLATABLE); - appendStringInfoString(lex->strval, cbuf); - } -#else - if (lex->input_encoding == PG_UTF8) - { - /* OK, we can map the code point to UTF8 easily */ - char utf8str[5]; - int utf8len; - - unicode_to_utf8(ch, (unsigned char *) utf8str); - utf8len = pg_utf_mblen((unsigned char *) utf8str); - appendBinaryStringInfo(lex->strval, utf8str, utf8len); - } - else if (ch <= 0x007f) - { - /* The ASCII range is the same in all encodings */ - appendStringInfoChar(lex->strval, (char) ch); - } - else - FAIL_AT_CHAR_END(JSON_UNICODE_HIGH_ESCAPE); -#endif /* FRONTEND */ - } - } - else if (lex->strval != NULL) - { - if (hi_surrogate != -1) - FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE); - - switch (*s) - { - case '"': - case '\\': - case '/': - appendStringInfoChar(lex->strval, *s); - break; - case 'b': - appendStringInfoChar(lex->strval, '\b'); - break; - case 'f': - appendStringInfoChar(lex->strval, '\f'); - break; - case 'n': - appendStringInfoChar(lex->strval, '\n'); - break; - case 'r': - appendStringInfoChar(lex->strval, '\r'); - break; - case 't': - appendStringInfoChar(lex->strval, '\t'); - break; - default: - - /* - * Not a valid string escape, so signal error. We - * adjust token_start so that just the escape sequence - * is reported, not the whole string. - */ - lex->token_start = s; - FAIL_AT_CHAR_END(JSON_ESCAPING_INVALID); - } - } - else if (strchr("\"\\/bfnrt", *s) == NULL) - { - /* - * Simpler processing if we're not bothered about de-escaping - * - * It's very tempting to remove the strchr() call here and - * replace it with a switch statement, but testing so far has - * shown it's not a performance win. - */ - lex->token_start = s; - FAIL_AT_CHAR_END(JSON_ESCAPING_INVALID); - } - } - else - { - char *p = s; - - if (hi_surrogate != -1) - FAIL_AT_CHAR_END(JSON_UNICODE_LOW_SURROGATE); - - /* - * Skip to the first byte that requires special handling, so we - * can batch calls to appendBinaryStringInfo. - */ - while (p < end - sizeof(Vector8) && - !pg_lfind8('\\', (uint8 *) p, sizeof(Vector8)) && - !pg_lfind8('"', (uint8 *) p, sizeof(Vector8)) && - !pg_lfind8_le(31, (uint8 *) p, sizeof(Vector8))) - p += sizeof(Vector8); - - for (; p < end; p++) - { - if (*p == '\\' || *p == '"') - break; - else if ((unsigned char) *p <= 31) - { - /* Per RFC4627, these characters MUST be escaped. */ - /* - * Since *p isn't printable, exclude it from the context - * string - */ - lex->token_terminator = p; - return JSON_ESCAPING_REQUIRED; - } - } - - if (lex->strval != NULL) - appendBinaryStringInfo(lex->strval, s, p - s); - - /* - * s will be incremented at the top of the loop, so set it to just - * behind our lookahead position - */ - s = p - 1; - } - } - - if (hi_surrogate != -1) - { - lex->token_terminator = s + 1; - return JSON_UNICODE_LOW_SURROGATE; - } - - /* Hooray, we found the end of the string! */ - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s + 1; - return JSON_SUCCESS; - -#undef FAIL_AT_CHAR_START -#undef FAIL_AT_CHAR_END -} - -/* - * The next token in the input stream is known to be a number; lex it. - * - * In JSON, a number consists of four parts: - * - * (1) An optional minus sign ('-'). - * - * (2) Either a single '0', or a string of one or more digits that does not - * begin with a '0'. - * - * (3) An optional decimal part, consisting of a period ('.') followed by - * one or more digits. (Note: While this part can be omitted - * completely, it's not OK to have only the decimal point without - * any digits afterwards.) - * - * (4) An optional exponent part, consisting of 'e' or 'E', optionally - * followed by '+' or '-', followed by one or more digits. (Note: - * As with the decimal part, if 'e' or 'E' is present, it must be - * followed by at least one digit.) - * - * The 's' argument to this function points to the ostensible beginning - * of part 2 - i.e. the character after any optional minus sign, or the - * first character of the string if there is none. - * - * If num_err is not NULL, we return an error flag to *num_err rather than - * raising an error for a badly-formed number. Also, if total_len is not NULL - * the distance from lex->input to the token end+1 is returned to *total_len. - */ -static inline JsonParseErrorType -json_lex_number(JsonLexContext *lex, char *s, - bool *num_err, int *total_len) -{ - bool error = false; - int len = s - lex->input; - - /* Part (1): leading sign indicator. */ - /* Caller already did this for us; so do nothing. */ - - /* Part (2): parse main digit string. */ - if (len < lex->input_length && *s == '0') - { - s++; - len++; - } - else if (len < lex->input_length && *s >= '1' && *s <= '9') - { - do - { - s++; - len++; - } while (len < lex->input_length && *s >= '0' && *s <= '9'); - } - else - error = true; - - /* Part (3): parse optional decimal portion. */ - if (len < lex->input_length && *s == '.') - { - s++; - len++; - if (len == lex->input_length || *s < '0' || *s > '9') - error = true; - else - { - do - { - s++; - len++; - } while (len < lex->input_length && *s >= '0' && *s <= '9'); - } - } - - /* Part (4): parse optional exponent. */ - if (len < lex->input_length && (*s == 'e' || *s == 'E')) - { - s++; - len++; - if (len < lex->input_length && (*s == '+' || *s == '-')) - { - s++; - len++; - } - if (len == lex->input_length || *s < '0' || *s > '9') - error = true; - else - { - do - { - s++; - len++; - } while (len < lex->input_length && *s >= '0' && *s <= '9'); - } - } - - /* - * Check for trailing garbage. As in json_lex(), any alphanumeric stuff - * here should be considered part of the token for error-reporting - * purposes. - */ - for (; len < lex->input_length && JSON_ALPHANUMERIC_CHAR(*s); s++, len++) - error = true; - - if (total_len != NULL) - *total_len = len; - - if (num_err != NULL) - { - /* let the caller handle any error */ - *num_err = error; - } - else - { - /* return token endpoint */ - lex->prev_token_terminator = lex->token_terminator; - lex->token_terminator = s; - /* handle error if any */ - if (error) - return JSON_INVALID_TOKEN; - } - - return JSON_SUCCESS; -} - -/* - * Report a parse error. - * - * lex->token_start and lex->token_terminator must identify the current token. - */ -static JsonParseErrorType -report_parse_error(JsonParseContext ctx, JsonLexContext *lex) -{ - /* Handle case where the input ended prematurely. */ - if (lex->token_start == NULL || lex->token_type == JSON_TOKEN_END) - return JSON_EXPECTED_MORE; - - /* Otherwise choose the error type based on the parsing context. */ - switch (ctx) - { - case JSON_PARSE_END: - return JSON_EXPECTED_END; - case JSON_PARSE_VALUE: - return JSON_EXPECTED_JSON; - case JSON_PARSE_STRING: - return JSON_EXPECTED_STRING; - case JSON_PARSE_ARRAY_START: - return JSON_EXPECTED_ARRAY_FIRST; - case JSON_PARSE_ARRAY_NEXT: - return JSON_EXPECTED_ARRAY_NEXT; - case JSON_PARSE_OBJECT_START: - return JSON_EXPECTED_OBJECT_FIRST; - case JSON_PARSE_OBJECT_LABEL: - return JSON_EXPECTED_COLON; - case JSON_PARSE_OBJECT_NEXT: - return JSON_EXPECTED_OBJECT_NEXT; - case JSON_PARSE_OBJECT_COMMA: - return JSON_EXPECTED_STRING; - } - - /* - * We don't use a default: case, so that the compiler will warn about - * unhandled enum values. - */ - Assert(false); - return JSON_SUCCESS; /* silence stupider compilers */ -} - - -#ifndef FRONTEND -/* - * Extract the current token from a lexing context, for error reporting. - */ -static char * -extract_token(JsonLexContext *lex) -{ - int toklen = lex->token_terminator - lex->token_start; - char *token = palloc(toklen + 1); - - memcpy(token, lex->token_start, toklen); - token[toklen] = '\0'; - return token; -} - -/* - * Construct an (already translated) detail message for a JSON error. - * - * Note that the error message generated by this routine may not be - * palloc'd, making it unsafe for frontend code as there is no way to - * know if this can be safely pfree'd or not. - */ -char * -json_errdetail(JsonParseErrorType error, JsonLexContext *lex) -{ - switch (error) - { - case JSON_SUCCESS: - /* fall through to the error code after switch */ - break; - case JSON_ESCAPING_INVALID: - return psprintf(_("Escape sequence \"\\%s\" is invalid."), - extract_token(lex)); - case JSON_ESCAPING_REQUIRED: - return psprintf(_("Character with value 0x%02x must be escaped."), - (unsigned char) *(lex->token_terminator)); - case JSON_EXPECTED_END: - return psprintf(_("Expected end of input, but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_ARRAY_FIRST: - return psprintf(_("Expected array element or \"]\", but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_ARRAY_NEXT: - return psprintf(_("Expected \",\" or \"]\", but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_COLON: - return psprintf(_("Expected \":\", but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_JSON: - return psprintf(_("Expected JSON value, but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_MORE: - return _("The input string ended unexpectedly."); - case JSON_EXPECTED_OBJECT_FIRST: - return psprintf(_("Expected string or \"}\", but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_OBJECT_NEXT: - return psprintf(_("Expected \",\" or \"}\", but found \"%s\"."), - extract_token(lex)); - case JSON_EXPECTED_STRING: - return psprintf(_("Expected string, but found \"%s\"."), - extract_token(lex)); - case JSON_INVALID_TOKEN: - return psprintf(_("Token \"%s\" is invalid."), - extract_token(lex)); - case JSON_UNICODE_CODE_POINT_ZERO: - return _("\\u0000 cannot be converted to text."); - case JSON_UNICODE_ESCAPE_FORMAT: - return _("\"\\u\" must be followed by four hexadecimal digits."); - case JSON_UNICODE_HIGH_ESCAPE: - /* note: this case is only reachable in frontend not backend */ - return _("Unicode escape values cannot be used for code point values above 007F when the encoding is not UTF8."); - case JSON_UNICODE_UNTRANSLATABLE: - /* note: this case is only reachable in backend not frontend */ - return psprintf(_("Unicode escape value could not be translated to the server's encoding %s."), - GetDatabaseEncodingName()); - case JSON_UNICODE_HIGH_SURROGATE: - return _("Unicode high surrogate must not follow a high surrogate."); - case JSON_UNICODE_LOW_SURROGATE: - return _("Unicode low surrogate must follow a high surrogate."); - case JSON_SEM_ACTION_FAILED: - /* fall through to the error code after switch */ - break; - } - - /* - * We don't use a default: case, so that the compiler will warn about - * unhandled enum values. But this needs to be here anyway to cover the - * possibility of an incorrect input. - */ - elog(ERROR, "unexpected json parse error type: %d", (int) error); - return NULL; -} -#endif diff --git a/contrib/libs/libpq/src/common/keywords.c b/contrib/libs/libpq/src/common/keywords.c deleted file mode 100644 index b72f0d554f..0000000000 --- a/contrib/libs/libpq/src/common/keywords.c +++ /dev/null @@ -1,48 +0,0 @@ -/*------------------------------------------------------------------------- - * - * keywords.c - * PostgreSQL's list of SQL keywords - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/keywords.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "common/keywords.h" - - -/* ScanKeywordList lookup data for SQL keywords */ - -#include "kwlist_d.h" - -/* Keyword categories for SQL keywords */ - -#define PG_KEYWORD(kwname, value, category, collabel) category, - -const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS] = { -#include "parser/kwlist.h" -}; - -#undef PG_KEYWORD - -/* Keyword can-be-bare-label flags for SQL keywords */ - -#define PG_KEYWORD(kwname, value, category, collabel) collabel, - -#define BARE_LABEL true -#define AS_LABEL false - -const bool ScanKeywordBareLabel[SCANKEYWORDS_NUM_KEYWORDS] = { -#include "parser/kwlist.h" -}; - -#undef PG_KEYWORD -#undef BARE_LABEL -#undef AS_LABEL diff --git a/contrib/libs/libpq/src/common/kwlist_d.h b/contrib/libs/libpq/src/common/kwlist_d.h deleted file mode 100644 index e8af260237..0000000000 --- a/contrib/libs/libpq/src/common/kwlist_d.h +++ /dev/null @@ -1,1119 +0,0 @@ -/*------------------------------------------------------------------------- - * - * kwlist_d.h - * List of keywords represented as a ScanKeywordList. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * NOTES - * ****************************** - * *** DO NOT EDIT THIS FILE! *** - * ****************************** - * - * It has been GENERATED by src/tools/gen_keywordlist.pl - * - *------------------------------------------------------------------------- - */ - -#ifndef KWLIST_D_H -#define KWLIST_D_H - -#include "common/kwlookup.h" - -static const char ScanKeywords_kw_string[] = - "abort\0" - "absent\0" - "absolute\0" - "access\0" - "action\0" - "add\0" - "admin\0" - "after\0" - "aggregate\0" - "all\0" - "also\0" - "alter\0" - "always\0" - "analyse\0" - "analyze\0" - "and\0" - "any\0" - "array\0" - "as\0" - "asc\0" - "asensitive\0" - "assertion\0" - "assignment\0" - "asymmetric\0" - "at\0" - "atomic\0" - "attach\0" - "attribute\0" - "authorization\0" - "backward\0" - "before\0" - "begin\0" - "between\0" - "bigint\0" - "binary\0" - "bit\0" - "boolean\0" - "both\0" - "breadth\0" - "by\0" - "cache\0" - "call\0" - "called\0" - "cascade\0" - "cascaded\0" - "case\0" - "cast\0" - "catalog\0" - "chain\0" - "char\0" - "character\0" - "characteristics\0" - "check\0" - "checkpoint\0" - "class\0" - "close\0" - "cluster\0" - "coalesce\0" - "collate\0" - "collation\0" - "column\0" - "columns\0" - "comment\0" - "comments\0" - "commit\0" - "committed\0" - "compression\0" - "concurrently\0" - "configuration\0" - "conflict\0" - "connection\0" - "constraint\0" - "constraints\0" - "content\0" - "continue\0" - "conversion\0" - "copy\0" - "cost\0" - "create\0" - "cross\0" - "csv\0" - "cube\0" - "current\0" - "current_catalog\0" - "current_date\0" - "current_role\0" - "current_schema\0" - "current_time\0" - "current_timestamp\0" - "current_user\0" - "cursor\0" - "cycle\0" - "data\0" - "database\0" - "day\0" - "deallocate\0" - "dec\0" - "decimal\0" - "declare\0" - "default\0" - "defaults\0" - "deferrable\0" - "deferred\0" - "definer\0" - "delete\0" - "delimiter\0" - "delimiters\0" - "depends\0" - "depth\0" - "desc\0" - "detach\0" - "dictionary\0" - "disable\0" - "discard\0" - "distinct\0" - "do\0" - "document\0" - "domain\0" - "double\0" - "drop\0" - "each\0" - "else\0" - "enable\0" - "encoding\0" - "encrypted\0" - "end\0" - "enum\0" - "escape\0" - "event\0" - "except\0" - "exclude\0" - "excluding\0" - "exclusive\0" - "execute\0" - "exists\0" - "explain\0" - "expression\0" - "extension\0" - "external\0" - "extract\0" - "false\0" - "family\0" - "fetch\0" - "filter\0" - "finalize\0" - "first\0" - "float\0" - "following\0" - "for\0" - "force\0" - "foreign\0" - "format\0" - "forward\0" - "freeze\0" - "from\0" - "full\0" - "function\0" - "functions\0" - "generated\0" - "global\0" - "grant\0" - "granted\0" - "greatest\0" - "group\0" - "grouping\0" - "groups\0" - "handler\0" - "having\0" - "header\0" - "hold\0" - "hour\0" - "identity\0" - "if\0" - "ilike\0" - "immediate\0" - "immutable\0" - "implicit\0" - "import\0" - "in\0" - "include\0" - "including\0" - "increment\0" - "indent\0" - "index\0" - "indexes\0" - "inherit\0" - "inherits\0" - "initially\0" - "inline\0" - "inner\0" - "inout\0" - "input\0" - "insensitive\0" - "insert\0" - "instead\0" - "int\0" - "integer\0" - "intersect\0" - "interval\0" - "into\0" - "invoker\0" - "is\0" - "isnull\0" - "isolation\0" - "join\0" - "json\0" - "json_array\0" - "json_arrayagg\0" - "json_object\0" - "json_objectagg\0" - "key\0" - "keys\0" - "label\0" - "language\0" - "large\0" - "last\0" - "lateral\0" - "leading\0" - "leakproof\0" - "least\0" - "left\0" - "level\0" - "like\0" - "limit\0" - "listen\0" - "load\0" - "local\0" - "localtime\0" - "localtimestamp\0" - "location\0" - "lock\0" - "locked\0" - "logged\0" - "mapping\0" - "match\0" - "matched\0" - "materialized\0" - "maxvalue\0" - "merge\0" - "method\0" - "minute\0" - "minvalue\0" - "mode\0" - "month\0" - "move\0" - "name\0" - "names\0" - "national\0" - "natural\0" - "nchar\0" - "new\0" - "next\0" - "nfc\0" - "nfd\0" - "nfkc\0" - "nfkd\0" - "no\0" - "none\0" - "normalize\0" - "normalized\0" - "not\0" - "nothing\0" - "notify\0" - "notnull\0" - "nowait\0" - "null\0" - "nullif\0" - "nulls\0" - "numeric\0" - "object\0" - "of\0" - "off\0" - "offset\0" - "oids\0" - "old\0" - "on\0" - "only\0" - "operator\0" - "option\0" - "options\0" - "or\0" - "order\0" - "ordinality\0" - "others\0" - "out\0" - "outer\0" - "over\0" - "overlaps\0" - "overlay\0" - "overriding\0" - "owned\0" - "owner\0" - "parallel\0" - "parameter\0" - "parser\0" - "partial\0" - "partition\0" - "passing\0" - "password\0" - "placing\0" - "plans\0" - "policy\0" - "position\0" - "preceding\0" - "precision\0" - "prepare\0" - "prepared\0" - "preserve\0" - "primary\0" - "prior\0" - "privileges\0" - "procedural\0" - "procedure\0" - "procedures\0" - "program\0" - "publication\0" - "quote\0" - "range\0" - "read\0" - "real\0" - "reassign\0" - "recheck\0" - "recursive\0" - "ref\0" - "references\0" - "referencing\0" - "refresh\0" - "reindex\0" - "relative\0" - "release\0" - "rename\0" - "repeatable\0" - "replace\0" - "replica\0" - "reset\0" - "restart\0" - "restrict\0" - "return\0" - "returning\0" - "returns\0" - "revoke\0" - "right\0" - "role\0" - "rollback\0" - "rollup\0" - "routine\0" - "routines\0" - "row\0" - "rows\0" - "rule\0" - "savepoint\0" - "scalar\0" - "schema\0" - "schemas\0" - "scroll\0" - "search\0" - "second\0" - "security\0" - "select\0" - "sequence\0" - "sequences\0" - "serializable\0" - "server\0" - "session\0" - "session_user\0" - "set\0" - "setof\0" - "sets\0" - "share\0" - "show\0" - "similar\0" - "simple\0" - "skip\0" - "smallint\0" - "snapshot\0" - "some\0" - "sql\0" - "stable\0" - "standalone\0" - "start\0" - "statement\0" - "statistics\0" - "stdin\0" - "stdout\0" - "storage\0" - "stored\0" - "strict\0" - "strip\0" - "subscription\0" - "substring\0" - "support\0" - "symmetric\0" - "sysid\0" - "system\0" - "system_user\0" - "table\0" - "tables\0" - "tablesample\0" - "tablespace\0" - "temp\0" - "template\0" - "temporary\0" - "text\0" - "then\0" - "ties\0" - "time\0" - "timestamp\0" - "to\0" - "trailing\0" - "transaction\0" - "transform\0" - "treat\0" - "trigger\0" - "trim\0" - "true\0" - "truncate\0" - "trusted\0" - "type\0" - "types\0" - "uescape\0" - "unbounded\0" - "uncommitted\0" - "unencrypted\0" - "union\0" - "unique\0" - "unknown\0" - "unlisten\0" - "unlogged\0" - "until\0" - "update\0" - "user\0" - "using\0" - "vacuum\0" - "valid\0" - "validate\0" - "validator\0" - "value\0" - "values\0" - "varchar\0" - "variadic\0" - "varying\0" - "verbose\0" - "version\0" - "view\0" - "views\0" - "volatile\0" - "when\0" - "where\0" - "whitespace\0" - "window\0" - "with\0" - "within\0" - "without\0" - "work\0" - "wrapper\0" - "write\0" - "xml\0" - "xmlattributes\0" - "xmlconcat\0" - "xmlelement\0" - "xmlexists\0" - "xmlforest\0" - "xmlnamespaces\0" - "xmlparse\0" - "xmlpi\0" - "xmlroot\0" - "xmlserialize\0" - "xmltable\0" - "year\0" - "yes\0" - "zone"; - -static const uint16 ScanKeywords_kw_offsets[] = { - 0, - 6, - 13, - 22, - 29, - 36, - 40, - 46, - 52, - 62, - 66, - 71, - 77, - 84, - 92, - 100, - 104, - 108, - 114, - 117, - 121, - 132, - 142, - 153, - 164, - 167, - 174, - 181, - 191, - 205, - 214, - 221, - 227, - 235, - 242, - 249, - 253, - 261, - 266, - 274, - 277, - 283, - 288, - 295, - 303, - 312, - 317, - 322, - 330, - 336, - 341, - 351, - 367, - 373, - 384, - 390, - 396, - 404, - 413, - 421, - 431, - 438, - 446, - 454, - 463, - 470, - 480, - 492, - 505, - 519, - 528, - 539, - 550, - 562, - 570, - 579, - 590, - 595, - 600, - 607, - 613, - 617, - 622, - 630, - 646, - 659, - 672, - 687, - 700, - 718, - 731, - 738, - 744, - 749, - 758, - 762, - 773, - 777, - 785, - 793, - 801, - 810, - 821, - 830, - 838, - 845, - 855, - 866, - 874, - 880, - 885, - 892, - 903, - 911, - 919, - 928, - 931, - 940, - 947, - 954, - 959, - 964, - 969, - 976, - 985, - 995, - 999, - 1004, - 1011, - 1017, - 1024, - 1032, - 1042, - 1052, - 1060, - 1067, - 1075, - 1086, - 1096, - 1105, - 1113, - 1119, - 1126, - 1132, - 1139, - 1148, - 1154, - 1160, - 1170, - 1174, - 1180, - 1188, - 1195, - 1203, - 1210, - 1215, - 1220, - 1229, - 1239, - 1249, - 1256, - 1262, - 1270, - 1279, - 1285, - 1294, - 1301, - 1309, - 1316, - 1323, - 1328, - 1333, - 1342, - 1345, - 1351, - 1361, - 1371, - 1380, - 1387, - 1390, - 1398, - 1408, - 1418, - 1425, - 1431, - 1439, - 1447, - 1456, - 1466, - 1473, - 1479, - 1485, - 1491, - 1503, - 1510, - 1518, - 1522, - 1530, - 1540, - 1549, - 1554, - 1562, - 1565, - 1572, - 1582, - 1587, - 1592, - 1603, - 1617, - 1629, - 1644, - 1648, - 1653, - 1659, - 1668, - 1674, - 1679, - 1687, - 1695, - 1705, - 1711, - 1716, - 1722, - 1727, - 1733, - 1740, - 1745, - 1751, - 1761, - 1776, - 1785, - 1790, - 1797, - 1804, - 1812, - 1818, - 1826, - 1839, - 1848, - 1854, - 1861, - 1868, - 1877, - 1882, - 1888, - 1893, - 1898, - 1904, - 1913, - 1921, - 1927, - 1931, - 1936, - 1940, - 1944, - 1949, - 1954, - 1957, - 1962, - 1972, - 1983, - 1987, - 1995, - 2002, - 2010, - 2017, - 2022, - 2029, - 2035, - 2043, - 2050, - 2053, - 2057, - 2064, - 2069, - 2073, - 2076, - 2081, - 2090, - 2097, - 2105, - 2108, - 2114, - 2125, - 2132, - 2136, - 2142, - 2147, - 2156, - 2164, - 2175, - 2181, - 2187, - 2196, - 2206, - 2213, - 2221, - 2231, - 2239, - 2248, - 2256, - 2262, - 2269, - 2278, - 2288, - 2298, - 2306, - 2315, - 2324, - 2332, - 2338, - 2349, - 2360, - 2370, - 2381, - 2389, - 2401, - 2407, - 2413, - 2418, - 2423, - 2432, - 2440, - 2450, - 2454, - 2465, - 2477, - 2485, - 2493, - 2502, - 2510, - 2517, - 2528, - 2536, - 2544, - 2550, - 2558, - 2567, - 2574, - 2584, - 2592, - 2599, - 2605, - 2610, - 2619, - 2626, - 2634, - 2643, - 2647, - 2652, - 2657, - 2667, - 2674, - 2681, - 2689, - 2696, - 2703, - 2710, - 2719, - 2726, - 2735, - 2745, - 2758, - 2765, - 2773, - 2786, - 2790, - 2796, - 2801, - 2807, - 2812, - 2820, - 2827, - 2832, - 2841, - 2850, - 2855, - 2859, - 2866, - 2877, - 2883, - 2893, - 2904, - 2910, - 2917, - 2925, - 2932, - 2939, - 2945, - 2958, - 2968, - 2976, - 2986, - 2992, - 2999, - 3011, - 3017, - 3024, - 3036, - 3047, - 3052, - 3061, - 3071, - 3076, - 3081, - 3086, - 3091, - 3101, - 3104, - 3113, - 3125, - 3135, - 3141, - 3149, - 3154, - 3159, - 3168, - 3176, - 3181, - 3187, - 3195, - 3205, - 3217, - 3229, - 3235, - 3242, - 3250, - 3259, - 3268, - 3274, - 3281, - 3286, - 3292, - 3299, - 3305, - 3314, - 3324, - 3330, - 3337, - 3345, - 3354, - 3362, - 3370, - 3378, - 3383, - 3389, - 3398, - 3403, - 3409, - 3420, - 3427, - 3432, - 3439, - 3447, - 3452, - 3460, - 3466, - 3470, - 3484, - 3494, - 3505, - 3515, - 3525, - 3539, - 3548, - 3554, - 3562, - 3575, - 3584, - 3589, - 3593, -}; - -#define SCANKEYWORDS_NUM_KEYWORDS 471 - -static int -ScanKeywords_hash_func(const void *key, size_t keylen) -{ - static const int16 h[943] = { - 543, -186, 201, 0, 32767, 32767, 32767, 32767, - 221, -207, 32767, 0, 135, 283, 32767, 454, - 14, 79, 32767, 32767, 77, 32767, 102, 160, - 0, 32767, 151, 32767, 30, 392, -322, 452, - 32767, 0, 32767, 0, 0, 32767, 32767, 32767, - 234, 32767, 0, 32767, 0, 631, 32767, 368, - 80, 0, 0, -115, 32767, 285, 32767, 423, - 0, 32767, 155, 229, 32767, 126, 291, 165, - -22, 400, 327, 32767, 32767, 32767, 32767, -399, - 0, 406, 32767, 210, 1102, -203, 32767, 32767, - 32767, -944, 0, -188, 32767, 32767, 0, 347, - 32767, 0, 559, 316, 133, 32767, 202, 32767, - 305, 0, 32767, -94, 32767, 0, 32767, -222, - 32767, 138, 32767, -52, 32767, 32767, 279, 69, - -136, 0, 32767, 32767, 189, 32767, 32767, 88, - 0, 32767, 32767, 274, 32767, 514, 769, 248, - 32767, 32767, 32767, 32767, 32767, 32767, 0, 81, - 8, -29, 32767, 32767, 32767, -174, 258, 0, - 465, 211, 32767, 0, -229, 32767, -191, 32767, - 1263, 48, 32767, 343, 0, 58, 0, 32767, - 32767, 855, 0, 415, 0, -217, 32767, 1195, - 32767, 32767, 166, 32767, 42, 262, -736, 0, - 32767, 32767, 418, 178, 122, 32767, 46, 32767, - 32767, 32767, 229, 443, 32767, 32767, 250, 32767, - -300, 0, 32767, 1153, 32767, 108, 32767, -462, - 266, 32767, 478, -220, 235, 32767, 32767, -127, - 32767, 32767, 32767, 427, -231, 156, 32767, 0, - 0, 148, -218, 142, 73, 420, 32767, 32767, - 523, 32767, -36, 32767, 32767, 467, 844, -415, - 32767, 32767, -148, 179, 361, 32767, 151, 0, - 0, 32767, 145, 32767, 248, 110, 29, 125, - 282, 32767, -36, 43, 32767, 1125, 32767, 530, - 251, 519, 191, 0, 32767, -34, -502, 313, - 462, 845, 32767, 32767, -255, 412, 32767, 78, - 0, 32767, 444, 161, 0, 32767, 308, 32767, - -273, 400, 32767, 296, 32767, 32767, 72, 32767, - 32767, 34, 32767, 364, 151, -63, 4, 229, - 0, -276, 32767, 32767, 32767, 32767, -406, 32767, - 203, 32767, 140, 187, 160, 32767, 286, 0, - 32767, 32767, -88, 0, 100, -361, 32767, 9, - 0, -456, 32767, -37, -404, 32767, -969, 32767, - 371, 95, 0, 703, -31, 263, 373, -745, - 507, 14, 32767, -159, 0, 32767, 47, 299, - -126, 0, 32767, 83, 32767, 32767, 420, 236, - 32767, 32767, 0, 310, 89, 233, 32767, 93, - 32767, 0, 816, 60, 301, 211, 193, 0, - 452, -107, -403, -242, 353, 18, 32767, 32767, - 32767, 243, 104, 32767, 32767, 32767, -305, 32767, - -1048, 54, 0, 383, 32767, 32767, 32767, 226, - 319, 0, 32767, 32767, 32767, -130, 537, 32767, - 0, -206, 240, 696, 121, 32767, 180, 164, - 32767, 390, 185, 32767, 220, 545, 29, 32767, - 0, 32767, 32767, 1120, -163, 32767, 32767, 32767, - -368, 136, 445, 171, 233, 32767, 73, 32767, - 92, 32767, 0, 32767, 0, 208, 354, 32767, - 54, 32767, 32767, -246, -93, 389, 32767, 32767, - 32767, 32767, 50, 32767, 32767, 308, 32767, -278, - 0, 32767, 32767, -1172, 32767, 8, 32767, 0, - 32767, 341, 304, 242, -174, -92, 76, 419, - 32767, 87, 32767, -262, 32767, 32767, 32767, 109, - 200, 0, 32767, 0, 85, 530, 32767, -316, - 32767, 0, -286, 32767, 193, 268, 32767, 32767, - 278, 32767, 32767, 155, 445, 95, -310, 32767, - 207, -56, 32767, 32767, 0, -127, 232, -283, - 103, 32767, 1, 0, 32767, 32767, -485, 350, - 79, -56, -354, 32767, 121, 24, 81, 20, - 325, 40, 248, 32767, 32767, 32767, 358, 32767, - -56, 32767, 0, 174, -28, -301, -92, 32767, - 114, 295, 32767, 363, -355, 32767, 290, 0, - 32767, 32767, 32767, 122, 55, -142, 32767, 50, - 32767, 32767, 152, 571, 1397, 0, 472, -448, - 185, 140, 228, 435, 0, 32767, 32767, 414, - 32767, 379, 92, 185, 23, 299, 32767, 32767, - 0, 32767, 32767, 32767, 306, 439, -198, 219, - 340, 32767, 416, 0, -123, 377, 32767, 32767, - 0, 32767, 670, -670, 339, 32767, 32767, 32767, - 0, -256, 70, 514, 331, 0, 302, 469, - 0, 370, 32767, 32767, 42, 255, 212, 0, - 322, 277, 32767, -163, 32767, 216, 32767, 32767, - 0, 32767, 190, 32767, 32767, 0, 32767, 0, - -409, 1366, 32767, 32767, 32767, 193, 32767, 325, - 32767, 0, 142, 466, 32767, 32767, 32767, 113, - 32767, 32767, 62, 0, -62, 113, -90, 34, - -256, 32767, 32767, -936, 32767, 32767, 32767, 0, - -64, 0, -34, 451, 290, 108, 32767, 276, - 842, 0, 556, -153, 32767, 412, -168, 32767, - 32767, 1331, 407, 234, -60, 115, 457, -73, - 502, 772, 32767, 33, 404, -925, 32767, 32767, - 421, -123, 32767, 32767, 32767, 0, 0, 32767, - 32767, 32767, 429, 0, 3, 769, -81, 306, - 64, 32767, 192, 96, 0, 63, 44, 32767, - 32767, 32767, 32767, 0, 284, 32767, 575, 32767, - 32767, 12, 32767, 516, 116, 32767, 32767, 150, - 442, 134, 32767, 198, -45, 249, 40, 373, - 32767, 0, 32767, 32767, 0, 0, 352, 32767, - 117, 32767, 426, 0, 0, 32767, 32767, 32767, - 32767, -92, 32767, -442, 32767, 269, 32767, 32767, - 32767, 429, 32767, 0, 32767, 0, 143, 32767, - 508, -66, 32767, 280, 32767, 39, 162, 32767, - 32767, 0, 32767, 31, 32767, 32767, 32767, 0, - 32767, 257, -90, -249, 224, 272, 32767, 32767, - 313, -467, 214, 0, -85, 32767, 48, 0, - 32767, -336, 202, 0, 447, 90, 264, 32767, - 32767, 0, 101, 32767, 32767, 32767, 0, 32767, - 32767, 227, -1093, 32767, 0, 32767, 27, 174, - 32767, 7, 32767, -621, 146, 32767, 32767, 32767, - 854, 0, 32767, 161, 0, 137, 32767, 32767, - 32767, 32767, 0, 391, 219, 276, 32767, 168, - 32767, 32767, 0, 32767, 32767, 32767, 1, -4, - 32767, 0, 293, 0, 374, 256, 0, 0, - 32767, 355, 212, 404, 0, 186, 32767, 0, - 359, 32767, 32767, 172, 32767, 32767, -131, 0, - 402, 0, 56, 32767, 462, 389, 82, 0, - 32767, 0, 32767, 0, 32767, 32767, 32767, 32767, - 106, 425, -160, 31, 32767, 55, 0, 0, - 32767, 32767, 430, 1224, 179, -179, 0, 397, - 32767, 0, 0, 0, -60, 47, 32767, 396, - 32767, 326, 383, 369, 32767, 368, 32767 - }; - - const unsigned char *k = (const unsigned char *) key; - uint32 a = 0; - uint32 b = 0; - - while (keylen--) - { - unsigned char c = *k++ | 0x20; - - a = a * 257 + c; - b = b * 31 + c; - } - return h[a % 943] + h[b % 943]; -} - -const ScanKeywordList ScanKeywords = { - ScanKeywords_kw_string, - ScanKeywords_kw_offsets, - ScanKeywords_hash_func, - SCANKEYWORDS_NUM_KEYWORDS, - 17 -}; - -#endif /* KWLIST_D_H */ diff --git a/contrib/libs/libpq/src/common/kwlookup.c b/contrib/libs/libpq/src/common/kwlookup.c deleted file mode 100644 index 7e49825c7b..0000000000 --- a/contrib/libs/libpq/src/common/kwlookup.c +++ /dev/null @@ -1,85 +0,0 @@ -/*------------------------------------------------------------------------- - * - * kwlookup.c - * Key word lookup for PostgreSQL - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/kwlookup.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "common/kwlookup.h" - - -/* - * ScanKeywordLookup - see if a given word is a keyword - * - * The list of keywords to be matched against is passed as a ScanKeywordList. - * - * Returns the keyword number (0..N-1) of the keyword, or -1 if no match. - * Callers typically use the keyword number to index into information - * arrays, but that is no concern of this code. - * - * The match is done case-insensitively. Note that we deliberately use a - * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', - * even if we are in a locale where tolower() would produce more or different - * translations. This is to conform to the SQL99 spec, which says that - * keywords are to be matched in this way even though non-keyword identifiers - * receive a different case-normalization mapping. - */ -int -ScanKeywordLookup(const char *str, - const ScanKeywordList *keywords) -{ - size_t len; - int h; - const char *kw; - - /* - * Reject immediately if too long to be any keyword. This saves useless - * hashing and downcasing work on long strings. - */ - len = strlen(str); - if (len > keywords->max_kw_len) - return -1; - - /* - * Compute the hash function. We assume it was generated to produce - * case-insensitive results. Since it's a perfect hash, we need only - * match to the specific keyword it identifies. - */ - h = keywords->hash(str, len); - - /* An out-of-range result implies no match */ - if (h < 0 || h >= keywords->num_keywords) - return -1; - - /* - * Compare character-by-character to see if we have a match, applying an - * ASCII-only downcasing to the input characters. We must not use - * tolower() since it may produce the wrong translation in some locales - * (eg, Turkish). - */ - kw = GetScanKeyword(h, keywords); - while (*str != '\0') - { - char ch = *str++; - - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - if (ch != *kw++) - return -1; - } - if (*kw != '\0') - return -1; - - /* Success! */ - return h; -} diff --git a/contrib/libs/libpq/src/common/link-canary.c b/contrib/libs/libpq/src/common/link-canary.c deleted file mode 100644 index f84331a9a4..0000000000 --- a/contrib/libs/libpq/src/common/link-canary.c +++ /dev/null @@ -1,36 +0,0 @@ -/*------------------------------------------------------------------------- - * link-canary.c - * Detect whether src/common functions came from frontend or backend. - * - * Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/link-canary.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "common/link-canary.h" - -/* - * This function just reports whether this file was compiled for frontend - * or backend environment. We need this because in some systems, mainly - * ELF-based platforms, it is possible for a shlib (such as libpq) loaded - * into the backend to call a backend function named XYZ in preference to - * the shlib's own function XYZ. That's bad if the two functions don't - * act identically. This exact situation comes up for many functions in - * src/common and src/port, where the same function names exist in both - * libpq and the backend but they don't act quite identically. To verify - * that appropriate measures have been taken to prevent incorrect symbol - * resolution, libpq should test that this function returns true. - */ -bool -pg_link_canary_is_frontend(void) -{ -#ifdef FRONTEND - return true; -#else - return false; -#endif -} diff --git a/contrib/libs/libpq/src/common/logging.c b/contrib/libs/libpq/src/common/logging.c deleted file mode 100644 index dab718b482..0000000000 --- a/contrib/libs/libpq/src/common/logging.c +++ /dev/null @@ -1,334 +0,0 @@ -/*------------------------------------------------------------------------- - * Logging framework for frontend programs - * - * Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * src/common/logging.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#error "This file is not expected to be compiled for backend code" -#endif - -#include "postgres_fe.h" - -#include <unistd.h> - -#include "common/logging.h" - -enum pg_log_level __pg_log_level; - -static const char *progname; -static int log_flags; - -static void (*log_pre_callback) (void); -static void (*log_locus_callback) (const char **, uint64 *); - -static const char *sgr_error = NULL; -static const char *sgr_warning = NULL; -static const char *sgr_note = NULL; -static const char *sgr_locus = NULL; - -#define SGR_ERROR_DEFAULT "01;31" -#define SGR_WARNING_DEFAULT "01;35" -#define SGR_NOTE_DEFAULT "01;36" -#define SGR_LOCUS_DEFAULT "01" - -#define ANSI_ESCAPE_FMT "\x1b[%sm" -#define ANSI_ESCAPE_RESET "\x1b[0m" - -#ifdef WIN32 - -#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING -#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 -#endif - -/* - * Attempt to enable VT100 sequence processing for colorization on Windows. - * If current environment is not VT100-compatible or if this mode could not - * be enabled, return false. - */ -static bool -enable_vt_processing(void) -{ - /* Check stderr */ - HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE); - DWORD dwMode = 0; - - if (hOut == INVALID_HANDLE_VALUE) - return false; - - /* - * Look for the current console settings and check if VT100 is already - * enabled. - */ - if (!GetConsoleMode(hOut, &dwMode)) - return false; - if ((dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0) - return true; - - dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - if (!SetConsoleMode(hOut, dwMode)) - return false; - return true; -} -#endif /* WIN32 */ - -/* - * This should be called before any output happens. - */ -void -pg_logging_init(const char *argv0) -{ - const char *pg_color_env = getenv("PG_COLOR"); - bool log_color = false; - bool color_terminal = isatty(fileno(stderr)); - -#ifdef WIN32 - - /* - * On Windows, check if environment is VT100-compatible if using a - * terminal. - */ - if (color_terminal) - color_terminal = enable_vt_processing(); -#endif - - /* usually the default, but not on Windows */ - setvbuf(stderr, NULL, _IONBF, 0); - - progname = get_progname(argv0); - __pg_log_level = PG_LOG_INFO; - - if (pg_color_env) - { - if (strcmp(pg_color_env, "always") == 0 || - (strcmp(pg_color_env, "auto") == 0 && color_terminal)) - log_color = true; - } - - if (log_color) - { - const char *pg_colors_env = getenv("PG_COLORS"); - - if (pg_colors_env) - { - char *colors = strdup(pg_colors_env); - - if (colors) - { - for (char *token = strtok(colors, ":"); token; token = strtok(NULL, ":")) - { - char *e = strchr(token, '='); - - if (e) - { - char *name; - char *value; - - *e = '\0'; - name = token; - value = e + 1; - - if (strcmp(name, "error") == 0) - sgr_error = strdup(value); - if (strcmp(name, "warning") == 0) - sgr_warning = strdup(value); - if (strcmp(name, "note") == 0) - sgr_note = strdup(value); - if (strcmp(name, "locus") == 0) - sgr_locus = strdup(value); - } - } - - free(colors); - } - } - else - { - sgr_error = SGR_ERROR_DEFAULT; - sgr_warning = SGR_WARNING_DEFAULT; - sgr_note = SGR_NOTE_DEFAULT; - sgr_locus = SGR_LOCUS_DEFAULT; - } - } -} - -/* - * Change the logging flags. - */ -void -pg_logging_config(int new_flags) -{ - log_flags = new_flags; -} - -/* - * pg_logging_init sets the default log level to INFO. Programs that prefer - * a different default should use this to set it, immediately afterward. - */ -void -pg_logging_set_level(enum pg_log_level new_level) -{ - __pg_log_level = new_level; -} - -/* - * Command line switches such as --verbose should invoke this. - */ -void -pg_logging_increase_verbosity(void) -{ - /* - * The enum values are chosen such that we have to decrease __pg_log_level - * in order to become more verbose. - */ - if (__pg_log_level > PG_LOG_NOTSET + 1) - __pg_log_level--; -} - -void -pg_logging_set_pre_callback(void (*cb) (void)) -{ - log_pre_callback = cb; -} - -void -pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)) -{ - log_locus_callback = cb; -} - -void -pg_log_generic(enum pg_log_level level, enum pg_log_part part, - const char *pg_restrict fmt,...) -{ - va_list ap; - - va_start(ap, fmt); - pg_log_generic_v(level, part, fmt, ap); - va_end(ap); -} - -void -pg_log_generic_v(enum pg_log_level level, enum pg_log_part part, - const char *pg_restrict fmt, va_list ap) -{ - int save_errno = errno; - const char *filename = NULL; - uint64 lineno = 0; - va_list ap2; - size_t required_len; - char *buf; - - Assert(progname); - Assert(level); - Assert(fmt); - Assert(fmt[strlen(fmt) - 1] != '\n'); - - /* Do nothing if log level is too low. */ - if (level < __pg_log_level) - return; - - /* - * Flush stdout before output to stderr, to ensure sync even when stdout - * is buffered. - */ - fflush(stdout); - - if (log_pre_callback) - log_pre_callback(); - - if (log_locus_callback) - log_locus_callback(&filename, &lineno); - - fmt = _(fmt); - - if (!(log_flags & PG_LOG_FLAG_TERSE) || filename) - { - if (sgr_locus) - fprintf(stderr, ANSI_ESCAPE_FMT, sgr_locus); - if (!(log_flags & PG_LOG_FLAG_TERSE)) - fprintf(stderr, "%s:", progname); - if (filename) - { - fprintf(stderr, "%s:", filename); - if (lineno > 0) - fprintf(stderr, UINT64_FORMAT ":", lineno); - } - fprintf(stderr, " "); - if (sgr_locus) - fprintf(stderr, ANSI_ESCAPE_RESET); - } - - if (!(log_flags & PG_LOG_FLAG_TERSE)) - { - switch (part) - { - case PG_LOG_PRIMARY: - switch (level) - { - case PG_LOG_ERROR: - if (sgr_error) - fprintf(stderr, ANSI_ESCAPE_FMT, sgr_error); - fprintf(stderr, _("error: ")); - if (sgr_error) - fprintf(stderr, ANSI_ESCAPE_RESET); - break; - case PG_LOG_WARNING: - if (sgr_warning) - fprintf(stderr, ANSI_ESCAPE_FMT, sgr_warning); - fprintf(stderr, _("warning: ")); - if (sgr_warning) - fprintf(stderr, ANSI_ESCAPE_RESET); - break; - default: - break; - } - break; - case PG_LOG_DETAIL: - if (sgr_note) - fprintf(stderr, ANSI_ESCAPE_FMT, sgr_note); - fprintf(stderr, _("detail: ")); - if (sgr_note) - fprintf(stderr, ANSI_ESCAPE_RESET); - break; - case PG_LOG_HINT: - if (sgr_note) - fprintf(stderr, ANSI_ESCAPE_FMT, sgr_note); - fprintf(stderr, _("hint: ")); - if (sgr_note) - fprintf(stderr, ANSI_ESCAPE_RESET); - break; - } - } - - errno = save_errno; - - va_copy(ap2, ap); - required_len = vsnprintf(NULL, 0, fmt, ap2) + 1; - va_end(ap2); - - buf = pg_malloc_extended(required_len, MCXT_ALLOC_NO_OOM); - - errno = save_errno; /* malloc might change errno */ - - if (!buf) - { - /* memory trouble, just print what we can and get out of here */ - vfprintf(stderr, fmt, ap); - return; - } - - vsnprintf(buf, required_len, fmt, ap); - - /* strip one newline, for PQerrorMessage() */ - if (required_len >= 2 && buf[required_len - 2] == '\n') - buf[required_len - 2] = '\0'; - - fprintf(stderr, "%s\n", buf); - - free(buf); -} diff --git a/contrib/libs/libpq/src/common/md5_common.c b/contrib/libs/libpq/src/common/md5_common.c deleted file mode 100644 index 82ce75dcf2..0000000000 --- a/contrib/libs/libpq/src/common/md5_common.c +++ /dev/null @@ -1,172 +0,0 @@ -/*------------------------------------------------------------------------- - * - * md5_common.c - * Routines shared between all MD5 implementations used for encrypted - * passwords. - * - * Sverre H. Huseby <sverrehu@online.no> - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/md5_common.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/cryptohash.h" -#include "common/md5.h" - -static void -bytesToHex(uint8 b[16], char *s) -{ - static const char *hex = "0123456789abcdef"; - int q, - w; - - for (q = 0, w = 0; q < 16; q++) - { - s[w++] = hex[(b[q] >> 4) & 0x0F]; - s[w++] = hex[b[q] & 0x0F]; - } - s[w] = '\0'; -} - -/* - * pg_md5_hash - * - * Calculates the MD5 sum of the bytes in a buffer. - * - * SYNOPSIS #include "md5.h" - * int pg_md5_hash(const void *buff, size_t len, char *hexsum) - * - * INPUT buff the buffer containing the bytes that you want - * the MD5 sum of. - * len number of bytes in the buffer. - * - * OUTPUT hexsum the MD5 sum as a '\0'-terminated string of - * hexadecimal digits. an MD5 sum is 16 bytes long. - * each byte is represented by two hexadecimal - * characters. you thus need to provide an array - * of 33 characters, including the trailing '\0'. - * - * errstr filled with a constant-string error message - * on failure return; NULL on success. - * - * RETURNS false on failure (out of memory for internal buffers - * or MD5 computation failure) or true on success. - * - * STANDARDS MD5 is described in RFC 1321. - * - * AUTHOR Sverre H. Huseby <sverrehu@online.no> - * - */ - -bool -pg_md5_hash(const void *buff, size_t len, char *hexsum, const char **errstr) -{ - uint8 sum[MD5_DIGEST_LENGTH]; - pg_cryptohash_ctx *ctx; - - *errstr = NULL; - ctx = pg_cryptohash_create(PG_MD5); - if (ctx == NULL) - { - *errstr = pg_cryptohash_error(NULL); /* returns OOM */ - return false; - } - - if (pg_cryptohash_init(ctx) < 0 || - pg_cryptohash_update(ctx, buff, len) < 0 || - pg_cryptohash_final(ctx, sum, sizeof(sum)) < 0) - { - *errstr = pg_cryptohash_error(ctx); - pg_cryptohash_free(ctx); - return false; - } - - bytesToHex(sum, hexsum); - pg_cryptohash_free(ctx); - return true; -} - -/* - * pg_md5_binary - * - * As above, except that the MD5 digest is returned as a binary string - * (of size MD5_DIGEST_LENGTH) rather than being converted to ASCII hex. - */ -bool -pg_md5_binary(const void *buff, size_t len, void *outbuf, const char **errstr) -{ - pg_cryptohash_ctx *ctx; - - *errstr = NULL; - ctx = pg_cryptohash_create(PG_MD5); - if (ctx == NULL) - { - *errstr = pg_cryptohash_error(NULL); /* returns OOM */ - return false; - } - - if (pg_cryptohash_init(ctx) < 0 || - pg_cryptohash_update(ctx, buff, len) < 0 || - pg_cryptohash_final(ctx, outbuf, MD5_DIGEST_LENGTH) < 0) - { - *errstr = pg_cryptohash_error(ctx); - pg_cryptohash_free(ctx); - return false; - } - - pg_cryptohash_free(ctx); - return true; -} - - -/* - * Computes MD5 checksum of "passwd" (a null-terminated string) followed - * by "salt" (which need not be null-terminated). - * - * Output format is "md5" followed by a 32-hex-digit MD5 checksum. - * Hence, the output buffer "buf" must be at least 36 bytes long. - * - * Returns true if okay, false on error with *errstr providing some - * error context. - */ -bool -pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, - char *buf, const char **errstr) -{ - size_t passwd_len = strlen(passwd); - - /* +1 here is just to avoid risk of unportable malloc(0) */ - char *crypt_buf = malloc(passwd_len + salt_len + 1); - bool ret; - - if (!crypt_buf) - { - *errstr = _("out of memory"); - return false; - } - - /* - * Place salt at the end because it may be known by users trying to crack - * the MD5 output. - */ - memcpy(crypt_buf, passwd, passwd_len); - memcpy(crypt_buf + passwd_len, salt, salt_len); - - strcpy(buf, "md5"); - ret = pg_md5_hash(crypt_buf, passwd_len + salt_len, buf + 3, errstr); - - free(crypt_buf); - - return ret; -} diff --git a/contrib/libs/libpq/src/common/percentrepl.c b/contrib/libs/libpq/src/common/percentrepl.c deleted file mode 100644 index 7aa85fdc94..0000000000 --- a/contrib/libs/libpq/src/common/percentrepl.c +++ /dev/null @@ -1,137 +0,0 @@ -/*------------------------------------------------------------------------- - * - * percentrepl.c - * Common routines to replace percent placeholders in strings - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/percentrepl.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#include "common/logging.h" -#endif - -#include "common/percentrepl.h" -#include "lib/stringinfo.h" - -/* - * replace_percent_placeholders - * - * Replace percent-letter placeholders in input string with the supplied - * values. For example, to replace %f with foo and %b with bar, call - * - * replace_percent_placeholders(instr, "param_name", "bf", bar, foo); - * - * The return value is palloc'd. - * - * "%%" is replaced by a single "%". - * - * This throws an error for an unsupported placeholder or a "%" at the end of - * the input string. - * - * A value may be NULL. If the corresponding placeholder is found in the - * input string, it will be treated as if an unsupported placeholder was used. - * This allows callers to share a "letters" specification but vary the - * actually supported placeholders at run time. - * - * This functions is meant for cases where all the values are readily - * available or cheap to compute and most invocations will use most values - * (for example for archive_command). Also, it requires that all values are - * strings. It won't be a good match for things like log prefixes or prompts - * that use a mix of data types and any invocation will only use a few of the - * possible values. - * - * param_name is the name of the underlying GUC parameter, for error - * reporting. At the moment, this function is only used for GUC parameters. - * If other kinds of uses were added, the error reporting would need to be - * revised. - */ -char * -replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...) -{ - StringInfoData result; - - initStringInfo(&result); - - for (const char *sp = instr; *sp; sp++) - { - if (*sp == '%') - { - if (sp[1] == '%') - { - /* Convert %% to a single % */ - sp++; - appendStringInfoChar(&result, *sp); - } - else if (sp[1] == '\0') - { - /* Incomplete escape sequence, expected a character afterward */ -#ifdef FRONTEND - pg_log_error("invalid value for parameter \"%s\": \"%s\"", param_name, instr); - pg_log_error_detail("String ends unexpectedly after escape character \"%%\"."); - exit(1); -#else - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for parameter \"%s\": \"%s\"", param_name, instr), - errdetail("String ends unexpectedly after escape character \"%%\".")); -#endif - } - else - { - /* Look up placeholder character */ - bool found = false; - va_list ap; - - sp++; - - va_start(ap, letters); - for (const char *lp = letters; *lp; lp++) - { - char *val = va_arg(ap, char *); - - if (*sp == *lp) - { - if (val) - { - appendStringInfoString(&result, val); - found = true; - } - /* If val is NULL, we will report an error. */ - break; - } - } - va_end(ap); - if (!found) - { - /* Unknown placeholder */ -#ifdef FRONTEND - pg_log_error("invalid value for parameter \"%s\": \"%s\"", param_name, instr); - pg_log_error_detail("String contains unexpected placeholder \"%%%c\".", *sp); - exit(1); -#else - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid value for parameter \"%s\": \"%s\"", param_name, instr), - errdetail("String contains unexpected placeholder \"%%%c\".", *sp)); -#endif - } - } - } - else - { - appendStringInfoChar(&result, *sp); - } - } - - return result.data; -} diff --git a/contrib/libs/libpq/src/common/pg_get_line.c b/contrib/libs/libpq/src/common/pg_get_line.c deleted file mode 100644 index 3cdf0908d2..0000000000 --- a/contrib/libs/libpq/src/common/pg_get_line.c +++ /dev/null @@ -1,180 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_get_line.c - * fgets() with an expansible result buffer - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/pg_get_line.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <setjmp.h> - -#include "common/string.h" -#include "lib/stringinfo.h" - - -/* - * pg_get_line() - * - * This is meant to be equivalent to fgets(), except that instead of - * reading into a caller-supplied, fixed-size buffer, it reads into - * a palloc'd (in frontend, really malloc'd) string, which is resized - * as needed to handle indefinitely long input lines. The caller is - * responsible for pfree'ing the result string when appropriate. - * - * As with fgets(), returns NULL if there is a read error or if no - * characters are available before EOF. The caller can distinguish - * these cases by checking ferror(stream). - * - * Since this is meant to be equivalent to fgets(), the trailing newline - * (if any) is not stripped. Callers may wish to apply pg_strip_crlf(). - * - * Note that while I/O errors are reflected back to the caller to be - * dealt with, an OOM condition for the palloc'd buffer will not be; - * there'll be an ereport(ERROR) or exit(1) inside stringinfo.c. - * - * Also note that the palloc'd buffer is usually a lot longer than - * strictly necessary, so it may be inadvisable to use this function - * to collect lots of long-lived data. A less memory-hungry option - * is to use pg_get_line_buf() or pg_get_line_append() in a loop, - * then pstrdup() each line. - * - * prompt_ctx can optionally be provided to allow this function to be - * canceled via an existing SIGINT signal handler that will longjmp to the - * specified place only when *(prompt_ctx->enabled) is true. If canceled, - * this function returns NULL, and prompt_ctx->canceled is set to true. - */ -char * -pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx) -{ - StringInfoData buf; - - initStringInfo(&buf); - - if (!pg_get_line_append(stream, &buf, prompt_ctx)) - { - /* ensure that free() doesn't mess up errno */ - int save_errno = errno; - - pfree(buf.data); - errno = save_errno; - return NULL; - } - - return buf.data; -} - -/* - * pg_get_line_buf() - * - * This has similar behavior to pg_get_line(), and thence to fgets(), - * except that the collected data is returned in a caller-supplied - * StringInfo buffer. This is a convenient API for code that just - * wants to read and process one line at a time, without any artificial - * limit on line length. - * - * Returns true if a line was successfully collected (including the - * case of a non-newline-terminated line at EOF). Returns false if - * there was an I/O error or no data was available before EOF. - * (Check ferror(stream) to distinguish these cases.) - * - * In the false-result case, buf is reset to empty. - */ -bool -pg_get_line_buf(FILE *stream, StringInfo buf) -{ - /* We just need to drop any data from the previous call */ - resetStringInfo(buf); - return pg_get_line_append(stream, buf, NULL); -} - -/* - * pg_get_line_append() - * - * This has similar behavior to pg_get_line(), and thence to fgets(), - * except that the collected data is appended to whatever is in *buf. - * This is useful in preference to pg_get_line_buf() if the caller wants - * to merge some lines together, e.g. to implement backslash continuation. - * - * Returns true if a line was successfully collected (including the - * case of a non-newline-terminated line at EOF). Returns false if - * there was an I/O error or no data was available before EOF. - * (Check ferror(stream) to distinguish these cases.) - * - * In the false-result case, the contents of *buf are logically unmodified, - * though it's possible that the buffer has been resized. - * - * prompt_ctx can optionally be provided to allow this function to be - * canceled via an existing SIGINT signal handler that will longjmp to the - * specified place only when *(prompt_ctx->enabled) is true. If canceled, - * this function returns false, and prompt_ctx->canceled is set to true. - */ -bool -pg_get_line_append(FILE *stream, StringInfo buf, - PromptInterruptContext *prompt_ctx) -{ - int orig_len = buf->len; - - if (prompt_ctx && sigsetjmp(*((sigjmp_buf *) prompt_ctx->jmpbuf), 1) != 0) - { - /* Got here with longjmp */ - prompt_ctx->canceled = true; - /* Discard any data we collected before detecting error */ - buf->len = orig_len; - buf->data[orig_len] = '\0'; - return false; - } - - /* Loop until newline or EOF/error */ - for (;;) - { - char *res; - - /* Enable longjmp while waiting for input */ - if (prompt_ctx) - *(prompt_ctx->enabled) = true; - - /* Read some data, appending it to whatever we already have */ - res = fgets(buf->data + buf->len, buf->maxlen - buf->len, stream); - - /* Disable longjmp again, then break if fgets failed */ - if (prompt_ctx) - *(prompt_ctx->enabled) = false; - - if (res == NULL) - break; - - /* Got data, so update buf->len */ - buf->len += strlen(buf->data + buf->len); - - /* Done if we have collected a newline */ - if (buf->len > orig_len && buf->data[buf->len - 1] == '\n') - return true; - - /* Make some more room in the buffer, and loop to read more data */ - enlargeStringInfo(buf, 128); - } - - /* Check for I/O errors and EOF */ - if (ferror(stream) || buf->len == orig_len) - { - /* Discard any data we collected before detecting error */ - buf->len = orig_len; - buf->data[orig_len] = '\0'; - return false; - } - - /* No newline at EOF, but we did collect some data */ - return true; -} diff --git a/contrib/libs/libpq/src/common/pg_lzcompress.c b/contrib/libs/libpq/src/common/pg_lzcompress.c deleted file mode 100644 index 95ad3388ef..0000000000 --- a/contrib/libs/libpq/src/common/pg_lzcompress.c +++ /dev/null @@ -1,876 +0,0 @@ -/* ---------- - * pg_lzcompress.c - - * - * This is an implementation of LZ compression for PostgreSQL. - * It uses a simple history table and generates 2-3 byte tags - * capable of backward copy information for 3-273 bytes with - * a max offset of 4095. - * - * Entry routines: - * - * int32 - * pglz_compress(const char *source, int32 slen, char *dest, - * const PGLZ_Strategy *strategy); - * - * source is the input data to be compressed. - * - * slen is the length of the input data. - * - * dest is the output area for the compressed result. - * It must be at least as big as PGLZ_MAX_OUTPUT(slen). - * - * strategy is a pointer to some information controlling - * the compression algorithm. If NULL, the compiled - * in default strategy is used. - * - * The return value is the number of bytes written in the - * buffer dest, or -1 if compression fails; in the latter - * case the contents of dest are undefined. - * - * int32 - * pglz_decompress(const char *source, int32 slen, char *dest, - * int32 rawsize, bool check_complete) - * - * source is the compressed input. - * - * slen is the length of the compressed input. - * - * dest is the area where the uncompressed data will be - * written to. It is the callers responsibility to - * provide enough space. - * - * The data is written to buff exactly as it was handed - * to pglz_compress(). No terminating zero byte is added. - * - * rawsize is the length of the uncompressed data. - * - * check_complete is a flag to let us know if -1 should be - * returned in cases where we don't reach the end of the - * source or dest buffers, or not. This should be false - * if the caller is asking for only a partial result and - * true otherwise. - * - * The return value is the number of bytes written in the - * buffer dest, or -1 if decompression fails. - * - * The decompression algorithm and internal data format: - * - * It is made with the compressed data itself. - * - * The data representation is easiest explained by describing - * the process of decompression. - * - * If compressed_size == rawsize, then the data - * is stored uncompressed as plain bytes. Thus, the decompressor - * simply copies rawsize bytes to the destination. - * - * Otherwise the first byte tells what to do the next 8 times. - * We call this the control byte. - * - * An unset bit in the control byte means, that one uncompressed - * byte follows, which is copied from input to output. - * - * A set bit in the control byte means, that a tag of 2-3 bytes - * follows. A tag contains information to copy some bytes, that - * are already in the output buffer, to the current location in - * the output. Let's call the three tag bytes T1, T2 and T3. The - * position of the data to copy is coded as an offset from the - * actual output position. - * - * The offset is in the upper nibble of T1 and in T2. - * The length is in the lower nibble of T1. - * - * So the 16 bits of a 2 byte tag are coded as - * - * 7---T1--0 7---T2--0 - * OOOO LLLL OOOO OOOO - * - * This limits the offset to 1-4095 (12 bits) and the length - * to 3-18 (4 bits) because 3 is always added to it. To emit - * a tag of 2 bytes with a length of 2 only saves one control - * bit. But we lose one byte in the possible length of a tag. - * - * In the actual implementation, the 2 byte tag's length is - * limited to 3-17, because the value 0xF in the length nibble - * has special meaning. It means, that the next following - * byte (T3) has to be added to the length value of 18. That - * makes total limits of 1-4095 for offset and 3-273 for length. - * - * Now that we have successfully decoded a tag. We simply copy - * the output that occurred <offset> bytes back to the current - * output location in the specified <length>. Thus, a - * sequence of 200 spaces (think about bpchar fields) could be - * coded in 4 bytes. One literal space and a three byte tag to - * copy 199 bytes with a -1 offset. Whow - that's a compression - * rate of 98%! Well, the implementation needs to save the - * original data size too, so we need another 4 bytes for it - * and end up with a total compression rate of 96%, what's still - * worth a Whow. - * - * The compression algorithm - * - * The following uses numbers used in the default strategy. - * - * The compressor works best for attributes of a size between - * 1K and 1M. For smaller items there's not that much chance of - * redundancy in the character sequence (except for large areas - * of identical bytes like trailing spaces) and for bigger ones - * our 4K maximum look-back distance is too small. - * - * The compressor creates a table for lists of positions. - * For each input position (except the last 3), a hash key is - * built from the 4 next input bytes and the position remembered - * in the appropriate list. Thus, the table points to linked - * lists of likely to be at least in the first 4 characters - * matching strings. This is done on the fly while the input - * is compressed into the output area. Table entries are only - * kept for the last 4096 input positions, since we cannot use - * back-pointers larger than that anyway. The size of the hash - * table is chosen based on the size of the input - a larger table - * has a larger startup cost, as it needs to be initialized to - * zero, but reduces the number of hash collisions on long inputs. - * - * For each byte in the input, its hash key (built from this - * byte and the next 3) is used to find the appropriate list - * in the table. The lists remember the positions of all bytes - * that had the same hash key in the past in increasing backward - * offset order. Now for all entries in the used lists, the - * match length is computed by comparing the characters from the - * entries position with the characters from the actual input - * position. - * - * The compressor starts with a so called "good_match" of 128. - * It is a "prefer speed against compression ratio" optimizer. - * So if the first entry looked at already has 128 or more - * matching characters, the lookup stops and that position is - * used for the next tag in the output. - * - * For each subsequent entry in the history list, the "good_match" - * is lowered by 10%. So the compressor will be more happy with - * short matches the further it has to go back in the history. - * Another "speed against ratio" preference characteristic of - * the algorithm. - * - * Thus there are 3 stop conditions for the lookup of matches: - * - * - a match >= good_match is found - * - there are no more history entries to look at - * - the next history entry is already too far back - * to be coded into a tag. - * - * Finally the match algorithm checks that at least a match - * of 3 or more bytes has been found, because that is the smallest - * amount of copy information to code into a tag. If so, a tag - * is omitted and all the input bytes covered by that are just - * scanned for the history add's, otherwise a literal character - * is omitted and only his history entry added. - * - * Acknowledgments: - * - * Many thanks to Adisak Pochanayon, who's article about SLZ - * inspired me to write the PostgreSQL compression this way. - * - * Jan Wieck - * - * Copyright (c) 1999-2023, PostgreSQL Global Development Group - * - * src/common/pg_lzcompress.c - * ---------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <limits.h> - -#include "common/pg_lzcompress.h" - - -/* ---------- - * Local definitions - * ---------- - */ -#define PGLZ_MAX_HISTORY_LISTS 8192 /* must be power of 2 */ -#define PGLZ_HISTORY_SIZE 4096 -#define PGLZ_MAX_MATCH 273 - - -/* ---------- - * PGLZ_HistEntry - - * - * Linked list for the backward history lookup - * - * All the entries sharing a hash key are linked in a doubly linked list. - * This makes it easy to remove an entry when it's time to recycle it - * (because it's more than 4K positions old). - * ---------- - */ -typedef struct PGLZ_HistEntry -{ - struct PGLZ_HistEntry *next; /* links for my hash key's list */ - struct PGLZ_HistEntry *prev; - int hindex; /* my current hash key */ - const char *pos; /* my input position */ -} PGLZ_HistEntry; - - -/* ---------- - * The provided standard strategies - * ---------- - */ -static const PGLZ_Strategy strategy_default_data = { - 32, /* Data chunks less than 32 bytes are not - * compressed */ - INT_MAX, /* No upper limit on what we'll try to - * compress */ - 25, /* Require 25% compression rate, or not worth - * it */ - 1024, /* Give up if no compression in the first 1KB */ - 128, /* Stop history lookup if a match of 128 bytes - * is found */ - 10 /* Lower good match size by 10% at every loop - * iteration */ -}; -const PGLZ_Strategy *const PGLZ_strategy_default = &strategy_default_data; - - -static const PGLZ_Strategy strategy_always_data = { - 0, /* Chunks of any size are compressed */ - INT_MAX, - 0, /* It's enough to save one single byte */ - INT_MAX, /* Never give up early */ - 128, /* Stop history lookup if a match of 128 bytes - * is found */ - 6 /* Look harder for a good match */ -}; -const PGLZ_Strategy *const PGLZ_strategy_always = &strategy_always_data; - - -/* ---------- - * Statically allocated work arrays for history - * ---------- - */ -static int16 hist_start[PGLZ_MAX_HISTORY_LISTS]; -static PGLZ_HistEntry hist_entries[PGLZ_HISTORY_SIZE + 1]; - -/* - * Element 0 in hist_entries is unused, and means 'invalid'. Likewise, - * INVALID_ENTRY_PTR in next/prev pointers mean 'invalid'. - */ -#define INVALID_ENTRY 0 -#define INVALID_ENTRY_PTR (&hist_entries[INVALID_ENTRY]) - -/* ---------- - * pglz_hist_idx - - * - * Computes the history table slot for the lookup by the next 4 - * characters in the input. - * - * NB: because we use the next 4 characters, we are not guaranteed to - * find 3-character matches; they very possibly will be in the wrong - * hash list. This seems an acceptable tradeoff for spreading out the - * hash keys more. - * ---------- - */ -#define pglz_hist_idx(_s,_e, _mask) ( \ - ((((_e) - (_s)) < 4) ? (int) (_s)[0] : \ - (((_s)[0] << 6) ^ ((_s)[1] << 4) ^ \ - ((_s)[2] << 2) ^ (_s)[3])) & (_mask) \ - ) - - -/* ---------- - * pglz_hist_add - - * - * Adds a new entry to the history table. - * - * If _recycle is true, then we are recycling a previously used entry, - * and must first delink it from its old hashcode's linked list. - * - * NOTE: beware of multiple evaluations of macro's arguments, and note that - * _hn and _recycle are modified in the macro. - * ---------- - */ -#define pglz_hist_add(_hs,_he,_hn,_recycle,_s,_e, _mask) \ -do { \ - int __hindex = pglz_hist_idx((_s),(_e), (_mask)); \ - int16 *__myhsp = &(_hs)[__hindex]; \ - PGLZ_HistEntry *__myhe = &(_he)[_hn]; \ - if (_recycle) { \ - if (__myhe->prev == NULL) \ - (_hs)[__myhe->hindex] = __myhe->next - (_he); \ - else \ - __myhe->prev->next = __myhe->next; \ - if (__myhe->next != NULL) \ - __myhe->next->prev = __myhe->prev; \ - } \ - __myhe->next = &(_he)[*__myhsp]; \ - __myhe->prev = NULL; \ - __myhe->hindex = __hindex; \ - __myhe->pos = (_s); \ - /* If there was an existing entry in this hash slot, link */ \ - /* this new entry to it. However, the 0th entry in the */ \ - /* entries table is unused, so we can freely scribble on it. */ \ - /* So don't bother checking if the slot was used - we'll */ \ - /* scribble on the unused entry if it was not, but that's */ \ - /* harmless. Avoiding the branch in this critical path */ \ - /* speeds this up a little bit. */ \ - /* if (*__myhsp != INVALID_ENTRY) */ \ - (_he)[(*__myhsp)].prev = __myhe; \ - *__myhsp = _hn; \ - if (++(_hn) >= PGLZ_HISTORY_SIZE + 1) { \ - (_hn) = 1; \ - (_recycle) = true; \ - } \ -} while (0) - - -/* ---------- - * pglz_out_ctrl - - * - * Outputs the last and allocates a new control byte if needed. - * ---------- - */ -#define pglz_out_ctrl(__ctrlp,__ctrlb,__ctrl,__buf) \ -do { \ - if ((__ctrl & 0xff) == 0) \ - { \ - *(__ctrlp) = __ctrlb; \ - __ctrlp = (__buf)++; \ - __ctrlb = 0; \ - __ctrl = 1; \ - } \ -} while (0) - - -/* ---------- - * pglz_out_literal - - * - * Outputs a literal byte to the destination buffer including the - * appropriate control bit. - * ---------- - */ -#define pglz_out_literal(_ctrlp,_ctrlb,_ctrl,_buf,_byte) \ -do { \ - pglz_out_ctrl(_ctrlp,_ctrlb,_ctrl,_buf); \ - *(_buf)++ = (unsigned char)(_byte); \ - _ctrl <<= 1; \ -} while (0) - - -/* ---------- - * pglz_out_tag - - * - * Outputs a backward reference tag of 2-4 bytes (depending on - * offset and length) to the destination buffer including the - * appropriate control bit. - * ---------- - */ -#define pglz_out_tag(_ctrlp,_ctrlb,_ctrl,_buf,_len,_off) \ -do { \ - pglz_out_ctrl(_ctrlp,_ctrlb,_ctrl,_buf); \ - _ctrlb |= _ctrl; \ - _ctrl <<= 1; \ - if (_len > 17) \ - { \ - (_buf)[0] = (unsigned char)((((_off) & 0xf00) >> 4) | 0x0f); \ - (_buf)[1] = (unsigned char)(((_off) & 0xff)); \ - (_buf)[2] = (unsigned char)((_len) - 18); \ - (_buf) += 3; \ - } else { \ - (_buf)[0] = (unsigned char)((((_off) & 0xf00) >> 4) | ((_len) - 3)); \ - (_buf)[1] = (unsigned char)((_off) & 0xff); \ - (_buf) += 2; \ - } \ -} while (0) - - -/* ---------- - * pglz_find_match - - * - * Lookup the history table if the actual input stream matches - * another sequence of characters, starting somewhere earlier - * in the input buffer. - * ---------- - */ -static inline int -pglz_find_match(int16 *hstart, const char *input, const char *end, - int *lenp, int *offp, int good_match, int good_drop, int mask) -{ - PGLZ_HistEntry *hent; - int16 hentno; - int32 len = 0; - int32 off = 0; - - /* - * Traverse the linked history list until a good enough match is found. - */ - hentno = hstart[pglz_hist_idx(input, end, mask)]; - hent = &hist_entries[hentno]; - while (hent != INVALID_ENTRY_PTR) - { - const char *ip = input; - const char *hp = hent->pos; - int32 thisoff; - int32 thislen; - - /* - * Stop if the offset does not fit into our tag anymore. - */ - thisoff = ip - hp; - if (thisoff >= 0x0fff) - break; - - /* - * Determine length of match. A better match must be larger than the - * best so far. And if we already have a match of 16 or more bytes, - * it's worth the call overhead to use memcmp() to check if this match - * is equal for the same size. After that we must fallback to - * character by character comparison to know the exact position where - * the diff occurred. - */ - thislen = 0; - if (len >= 16) - { - if (memcmp(ip, hp, len) == 0) - { - thislen = len; - ip += len; - hp += len; - while (ip < end && *ip == *hp && thislen < PGLZ_MAX_MATCH) - { - thislen++; - ip++; - hp++; - } - } - } - else - { - while (ip < end && *ip == *hp && thislen < PGLZ_MAX_MATCH) - { - thislen++; - ip++; - hp++; - } - } - - /* - * Remember this match as the best (if it is) - */ - if (thislen > len) - { - len = thislen; - off = thisoff; - } - - /* - * Advance to the next history entry - */ - hent = hent->next; - - /* - * Be happy with lesser good matches the more entries we visited. But - * no point in doing calculation if we're at end of list. - */ - if (hent != INVALID_ENTRY_PTR) - { - if (len >= good_match) - break; - good_match -= (good_match * good_drop) / 100; - } - } - - /* - * Return match information only if it results at least in one byte - * reduction. - */ - if (len > 2) - { - *lenp = len; - *offp = off; - return 1; - } - - return 0; -} - - -/* ---------- - * pglz_compress - - * - * Compresses source into dest using strategy. Returns the number of - * bytes written in buffer dest, or -1 if compression fails. - * ---------- - */ -int32 -pglz_compress(const char *source, int32 slen, char *dest, - const PGLZ_Strategy *strategy) -{ - unsigned char *bp = (unsigned char *) dest; - unsigned char *bstart = bp; - int hist_next = 1; - bool hist_recycle = false; - const char *dp = source; - const char *dend = source + slen; - unsigned char ctrl_dummy = 0; - unsigned char *ctrlp = &ctrl_dummy; - unsigned char ctrlb = 0; - unsigned char ctrl = 0; - bool found_match = false; - int32 match_len; - int32 match_off; - int32 good_match; - int32 good_drop; - int32 result_size; - int32 result_max; - int32 need_rate; - int hashsz; - int mask; - - /* - * Our fallback strategy is the default. - */ - if (strategy == NULL) - strategy = PGLZ_strategy_default; - - /* - * If the strategy forbids compression (at all or if source chunk size out - * of range), fail. - */ - if (strategy->match_size_good <= 0 || - slen < strategy->min_input_size || - slen > strategy->max_input_size) - return -1; - - /* - * Limit the match parameters to the supported range. - */ - good_match = strategy->match_size_good; - if (good_match > PGLZ_MAX_MATCH) - good_match = PGLZ_MAX_MATCH; - else if (good_match < 17) - good_match = 17; - - good_drop = strategy->match_size_drop; - if (good_drop < 0) - good_drop = 0; - else if (good_drop > 100) - good_drop = 100; - - need_rate = strategy->min_comp_rate; - if (need_rate < 0) - need_rate = 0; - else if (need_rate > 99) - need_rate = 99; - - /* - * Compute the maximum result size allowed by the strategy, namely the - * input size minus the minimum wanted compression rate. This had better - * be <= slen, else we might overrun the provided output buffer. - */ - if (slen > (INT_MAX / 100)) - { - /* Approximate to avoid overflow */ - result_max = (slen / 100) * (100 - need_rate); - } - else - result_max = (slen * (100 - need_rate)) / 100; - - /* - * Experiments suggest that these hash sizes work pretty well. A large - * hash table minimizes collision, but has a higher startup cost. For a - * small input, the startup cost dominates. The table size must be a power - * of two. - */ - if (slen < 128) - hashsz = 512; - else if (slen < 256) - hashsz = 1024; - else if (slen < 512) - hashsz = 2048; - else if (slen < 1024) - hashsz = 4096; - else - hashsz = 8192; - mask = hashsz - 1; - - /* - * Initialize the history lists to empty. We do not need to zero the - * hist_entries[] array; its entries are initialized as they are used. - */ - memset(hist_start, 0, hashsz * sizeof(int16)); - - /* - * Compress the source directly into the output buffer. - */ - while (dp < dend) - { - /* - * If we already exceeded the maximum result size, fail. - * - * We check once per loop; since the loop body could emit as many as 4 - * bytes (a control byte and 3-byte tag), PGLZ_MAX_OUTPUT() had better - * allow 4 slop bytes. - */ - if (bp - bstart >= result_max) - return -1; - - /* - * If we've emitted more than first_success_by bytes without finding - * anything compressible at all, fail. This lets us fall out - * reasonably quickly when looking at incompressible input (such as - * pre-compressed data). - */ - if (!found_match && bp - bstart >= strategy->first_success_by) - return -1; - - /* - * Try to find a match in the history - */ - if (pglz_find_match(hist_start, dp, dend, &match_len, - &match_off, good_match, good_drop, mask)) - { - /* - * Create the tag and add history entries for all matched - * characters. - */ - pglz_out_tag(ctrlp, ctrlb, ctrl, bp, match_len, match_off); - while (match_len--) - { - pglz_hist_add(hist_start, hist_entries, - hist_next, hist_recycle, - dp, dend, mask); - dp++; /* Do not do this ++ in the line above! */ - /* The macro would do it four times - Jan. */ - } - found_match = true; - } - else - { - /* - * No match found. Copy one literal byte. - */ - pglz_out_literal(ctrlp, ctrlb, ctrl, bp, *dp); - pglz_hist_add(hist_start, hist_entries, - hist_next, hist_recycle, - dp, dend, mask); - dp++; /* Do not do this ++ in the line above! */ - /* The macro would do it four times - Jan. */ - } - } - - /* - * Write out the last control byte and check that we haven't overrun the - * output size allowed by the strategy. - */ - *ctrlp = ctrlb; - result_size = bp - bstart; - if (result_size >= result_max) - return -1; - - /* success */ - return result_size; -} - - -/* ---------- - * pglz_decompress - - * - * Decompresses source into dest. Returns the number of bytes - * decompressed into the destination buffer, or -1 if the - * compressed data is corrupted. - * - * If check_complete is true, the data is considered corrupted - * if we don't exactly fill the destination buffer. Callers that - * are extracting a slice typically can't apply this check. - * ---------- - */ -int32 -pglz_decompress(const char *source, int32 slen, char *dest, - int32 rawsize, bool check_complete) -{ - const unsigned char *sp; - const unsigned char *srcend; - unsigned char *dp; - unsigned char *destend; - - sp = (const unsigned char *) source; - srcend = ((const unsigned char *) source) + slen; - dp = (unsigned char *) dest; - destend = dp + rawsize; - - while (sp < srcend && dp < destend) - { - /* - * Read one control byte and process the next 8 items (or as many as - * remain in the compressed input). - */ - unsigned char ctrl = *sp++; - int ctrlc; - - for (ctrlc = 0; ctrlc < 8 && sp < srcend && dp < destend; ctrlc++) - { - if (ctrl & 1) - { - /* - * Set control bit means we must read a match tag. The match - * is coded with two bytes. First byte uses lower nibble to - * code length - 3. Higher nibble contains upper 4 bits of the - * offset. The next following byte contains the lower 8 bits - * of the offset. If the length is coded as 18, another - * extension tag byte tells how much longer the match really - * was (0-255). - */ - int32 len; - int32 off; - - len = (sp[0] & 0x0f) + 3; - off = ((sp[0] & 0xf0) << 4) | sp[1]; - sp += 2; - if (len == 18) - len += *sp++; - - /* - * Check for corrupt data: if we fell off the end of the - * source, or if we obtained off = 0, or if off is more than - * the distance back to the buffer start, we have problems. - * (We must check for off = 0, else we risk an infinite loop - * below in the face of corrupt data. Likewise, the upper - * limit on off prevents accessing outside the buffer - * boundaries.) - */ - if (unlikely(sp > srcend || off == 0 || - off > (dp - (unsigned char *) dest))) - return -1; - - /* - * Don't emit more data than requested. - */ - len = Min(len, destend - dp); - - /* - * Now we copy the bytes specified by the tag from OUTPUT to - * OUTPUT (copy len bytes from dp - off to dp). The copied - * areas could overlap, so to avoid undefined behavior in - * memcpy(), be careful to copy only non-overlapping regions. - * - * Note that we cannot use memmove() instead, since while its - * behavior is well-defined, it's also not what we want. - */ - while (off < len) - { - /* - * We can safely copy "off" bytes since that clearly - * results in non-overlapping source and destination. - */ - memcpy(dp, dp - off, off); - len -= off; - dp += off; - - /*---------- - * This bit is less obvious: we can double "off" after - * each such step. Consider this raw input: - * 112341234123412341234 - * This will be encoded as 5 literal bytes "11234" and - * then a match tag with length 16 and offset 4. After - * memcpy'ing the first 4 bytes, we will have emitted - * 112341234 - * so we can double "off" to 8, then after the next step - * we have emitted - * 11234123412341234 - * Then we can double "off" again, after which it is more - * than the remaining "len" so we fall out of this loop - * and finish with a non-overlapping copy of the - * remainder. In general, a match tag with off < len - * implies that the decoded data has a repeat length of - * "off". We can handle 1, 2, 4, etc repetitions of the - * repeated string per memcpy until we get to a situation - * where the final copy step is non-overlapping. - * - * (Another way to understand this is that we are keeping - * the copy source point dp - off the same throughout.) - *---------- - */ - off += off; - } - memcpy(dp, dp - off, len); - dp += len; - } - else - { - /* - * An unset control bit means LITERAL BYTE. So we just copy - * one from INPUT to OUTPUT. - */ - *dp++ = *sp++; - } - - /* - * Advance the control bit - */ - ctrl >>= 1; - } - } - - /* - * If requested, check we decompressed the right amount. - */ - if (check_complete && (dp != destend || sp != srcend)) - return -1; - - /* - * That's it. - */ - return (char *) dp - dest; -} - - -/* ---------- - * pglz_maximum_compressed_size - - * - * Calculate the maximum compressed size for a given amount of raw data. - * Return the maximum size, or total compressed size if maximum size is - * larger than total compressed size. - * - * We can't use PGLZ_MAX_OUTPUT for this purpose, because that's used to size - * the compression buffer (and abort the compression). It does not really say - * what's the maximum compressed size for an input of a given length, and it - * may happen that while the whole value is compressible (and thus fits into - * PGLZ_MAX_OUTPUT nicely), the prefix is not compressible at all. - * ---------- - */ -int32 -pglz_maximum_compressed_size(int32 rawsize, int32 total_compressed_size) -{ - int64 compressed_size; - - /* - * pglz uses one control bit per byte, so if the entire desired prefix is - * represented as literal bytes, we'll need (rawsize * 9) bits. We care - * about bytes though, so be sure to round up not down. - * - * Use int64 here to prevent overflow during calculation. - */ - compressed_size = ((int64) rawsize * 9 + 7) / 8; - - /* - * The above fails to account for a corner case: we could have compressed - * data that starts with N-1 or N-2 literal bytes and then has a match tag - * of 2 or 3 bytes. It's therefore possible that we need to fetch 1 or 2 - * more bytes in order to have the whole match tag. (Match tags earlier - * in the compressed data don't cause a problem, since they should - * represent more decompressed bytes than they occupy themselves.) - */ - compressed_size += 2; - - /* - * Maximum compressed size can't be larger than total compressed size. - * (This also ensures that our result fits in int32.) - */ - compressed_size = Min(compressed_size, total_compressed_size); - - return (int32) compressed_size; -} diff --git a/contrib/libs/libpq/src/common/pg_prng.c b/contrib/libs/libpq/src/common/pg_prng.c deleted file mode 100644 index c7bb92ede3..0000000000 --- a/contrib/libs/libpq/src/common/pg_prng.c +++ /dev/null @@ -1,282 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Pseudo-Random Number Generator - * - * We use Blackman and Vigna's xoroshiro128** 1.0 algorithm - * to have a small, fast PRNG suitable for generating reasonably - * good-quality 64-bit data. This should not be considered - * cryptographically strong, however. - * - * About these generators: https://prng.di.unimi.it/ - * See also https://en.wikipedia.org/wiki/List_of_random_number_generators - * - * Copyright (c) 2021-2023, PostgreSQL Global Development Group - * - * src/common/pg_prng.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <math.h> - -#include "common/pg_prng.h" -#include "port/pg_bitutils.h" - -/* X/Open (XSI) requires <math.h> to provide M_PI, but core POSIX does not */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - - -/* process-wide state vector */ -pg_prng_state pg_global_prng_state; - - -/* - * 64-bit rotate left - */ -static inline uint64 -rotl(uint64 x, int bits) -{ - return (x << bits) | (x >> (64 - bits)); -} - -/* - * The basic xoroshiro128** algorithm. - * Generates and returns a 64-bit uniformly distributed number, - * updating the state vector for next time. - * - * Note: the state vector must not be all-zeroes, as that is a fixed point. - */ -static uint64 -xoroshiro128ss(pg_prng_state *state) -{ - uint64 s0 = state->s0, - sx = state->s1 ^ s0, - val = rotl(s0 * 5, 7) * 9; - - /* update state */ - state->s0 = rotl(s0, 24) ^ sx ^ (sx << 16); - state->s1 = rotl(sx, 37); - - return val; -} - -/* - * We use this generator just to fill the xoroshiro128** state vector - * from a 64-bit seed. - */ -static uint64 -splitmix64(uint64 *state) -{ - /* state update */ - uint64 val = (*state += UINT64CONST(0x9E3779B97f4A7C15)); - - /* value extraction */ - val = (val ^ (val >> 30)) * UINT64CONST(0xBF58476D1CE4E5B9); - val = (val ^ (val >> 27)) * UINT64CONST(0x94D049BB133111EB); - - return val ^ (val >> 31); -} - -/* - * Initialize the PRNG state from a 64-bit integer, - * taking care that we don't produce all-zeroes. - */ -void -pg_prng_seed(pg_prng_state *state, uint64 seed) -{ - state->s0 = splitmix64(&seed); - state->s1 = splitmix64(&seed); - /* Let's just make sure we didn't get all-zeroes */ - (void) pg_prng_seed_check(state); -} - -/* - * Initialize the PRNG state from a double in the range [-1.0, 1.0], - * taking care that we don't produce all-zeroes. - */ -void -pg_prng_fseed(pg_prng_state *state, double fseed) -{ - /* Assume there's about 52 mantissa bits; the sign contributes too. */ - int64 seed = ((double) ((UINT64CONST(1) << 52) - 1)) * fseed; - - pg_prng_seed(state, (uint64) seed); -} - -/* - * Validate a PRNG seed value. - */ -bool -pg_prng_seed_check(pg_prng_state *state) -{ - /* - * If the seeding mechanism chanced to produce all-zeroes, insert - * something nonzero. Anything would do; use Knuth's LCG parameters. - */ - if (unlikely(state->s0 == 0 && state->s1 == 0)) - { - state->s0 = UINT64CONST(0x5851F42D4C957F2D); - state->s1 = UINT64CONST(0x14057B7EF767814F); - } - - /* As a convenience for the pg_prng_strong_seed macro, return true */ - return true; -} - -/* - * Select a random uint64 uniformly from the range [0, PG_UINT64_MAX]. - */ -uint64 -pg_prng_uint64(pg_prng_state *state) -{ - return xoroshiro128ss(state); -} - -/* - * Select a random uint64 uniformly from the range [rmin, rmax]. - * If the range is empty, rmin is always produced. - */ -uint64 -pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax) -{ - uint64 val; - - if (likely(rmax > rmin)) - { - /* - * Use bitmask rejection method to generate an offset in 0..range. - * Each generated val is less than twice "range", so on average we - * should not have to iterate more than twice. - */ - uint64 range = rmax - rmin; - uint32 rshift = 63 - pg_leftmost_one_pos64(range); - - do - { - val = xoroshiro128ss(state) >> rshift; - } while (val > range); - } - else - val = 0; - - return rmin + val; -} - -/* - * Select a random int64 uniformly from the range [PG_INT64_MIN, PG_INT64_MAX]. - */ -int64 -pg_prng_int64(pg_prng_state *state) -{ - return (int64) xoroshiro128ss(state); -} - -/* - * Select a random int64 uniformly from the range [0, PG_INT64_MAX]. - */ -int64 -pg_prng_int64p(pg_prng_state *state) -{ - return (int64) (xoroshiro128ss(state) & UINT64CONST(0x7FFFFFFFFFFFFFFF)); -} - -/* - * Select a random uint32 uniformly from the range [0, PG_UINT32_MAX]. - */ -uint32 -pg_prng_uint32(pg_prng_state *state) -{ - /* - * Although xoroshiro128** is not known to have any weaknesses in - * randomness of low-order bits, we prefer to use the upper bits of its - * result here and below. - */ - uint64 v = xoroshiro128ss(state); - - return (uint32) (v >> 32); -} - -/* - * Select a random int32 uniformly from the range [PG_INT32_MIN, PG_INT32_MAX]. - */ -int32 -pg_prng_int32(pg_prng_state *state) -{ - uint64 v = xoroshiro128ss(state); - - return (int32) (v >> 32); -} - -/* - * Select a random int32 uniformly from the range [0, PG_INT32_MAX]. - */ -int32 -pg_prng_int32p(pg_prng_state *state) -{ - uint64 v = xoroshiro128ss(state); - - return (int32) (v >> 33); -} - -/* - * Select a random double uniformly from the range [0.0, 1.0). - * - * Note: if you want a result in the range (0.0, 1.0], the standard way - * to get that is "1.0 - pg_prng_double(state)". - */ -double -pg_prng_double(pg_prng_state *state) -{ - uint64 v = xoroshiro128ss(state); - - /* - * As above, assume there's 52 mantissa bits in a double. This result - * could round to 1.0 if double's precision is less than that; but we - * assume IEEE float arithmetic elsewhere in Postgres, so this seems OK. - */ - return ldexp((double) (v >> (64 - 52)), -52); -} - -/* - * Select a random double from the normal distribution with - * mean = 0.0 and stddev = 1.0. - * - * To get a result from a different normal distribution use - * STDDEV * pg_prng_double_normal() + MEAN - * - * Uses https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform - */ -double -pg_prng_double_normal(pg_prng_state *state) -{ - double u1, - u2, - z0; - - /* - * pg_prng_double generates [0, 1), but for the basic version of the - * Box-Muller transform the two uniformly distributed random numbers are - * expected to be in (0, 1]; in particular we'd better not compute log(0). - */ - u1 = 1.0 - pg_prng_double(state); - u2 = 1.0 - pg_prng_double(state); - - /* Apply Box-Muller transform to get one normal-valued output */ - z0 = sqrt(-2.0 * log(u1)) * sin(2.0 * M_PI * u2); - return z0; -} - -/* - * Select a random boolean value. - */ -bool -pg_prng_bool(pg_prng_state *state) -{ - uint64 v = xoroshiro128ss(state); - - return (bool) (v >> 63); -} diff --git a/contrib/libs/libpq/src/common/pgfnames.c b/contrib/libs/libpq/src/common/pgfnames.c deleted file mode 100644 index 9d2fe9d659..0000000000 --- a/contrib/libs/libpq/src/common/pgfnames.c +++ /dev/null @@ -1,94 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgfnames.c - * directory handling functions - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/pgfnames.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <dirent.h> - -#ifndef FRONTEND -#define pg_log_warning(...) elog(WARNING, __VA_ARGS__) -#else -#include "common/logging.h" -#endif - -/* - * pgfnames - * - * return a list of the names of objects in the argument directory. Caller - * must call pgfnames_cleanup later to free the memory allocated by this - * function. - */ -char ** -pgfnames(const char *path) -{ - DIR *dir; - struct dirent *file; - char **filenames; - int numnames = 0; - int fnsize = 200; /* enough for many small dbs */ - - dir = opendir(path); - if (dir == NULL) - { - pg_log_warning("could not open directory \"%s\": %m", path); - return NULL; - } - - filenames = (char **) palloc(fnsize * sizeof(char *)); - - while (errno = 0, (file = readdir(dir)) != NULL) - { - if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) - { - if (numnames + 1 >= fnsize) - { - fnsize *= 2; - filenames = (char **) repalloc(filenames, - fnsize * sizeof(char *)); - } - filenames[numnames++] = pstrdup(file->d_name); - } - } - - if (errno) - pg_log_warning("could not read directory \"%s\": %m", path); - - filenames[numnames] = NULL; - - if (closedir(dir)) - pg_log_warning("could not close directory \"%s\": %m", path); - - return filenames; -} - - -/* - * pgfnames_cleanup - * - * deallocate memory used for filenames - */ -void -pgfnames_cleanup(char **filenames) -{ - char **fn; - - for (fn = filenames; *fn; fn++) - pfree(*fn); - - pfree(filenames); -} diff --git a/contrib/libs/libpq/src/common/protocol_openssl.c b/contrib/libs/libpq/src/common/protocol_openssl.c deleted file mode 100644 index 089cbd33cc..0000000000 --- a/contrib/libs/libpq/src/common/protocol_openssl.c +++ /dev/null @@ -1,117 +0,0 @@ -/*------------------------------------------------------------------------- - * - * protocol_openssl.c - * OpenSSL functionality shared between frontend and backend - * - * This should only be used if code is compiled with OpenSSL support. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/protocol_openssl.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/openssl.h" - -/* - * Replacements for APIs introduced in OpenSSL 1.1.0. - */ -#ifndef SSL_CTX_set_min_proto_version - -/* - * OpenSSL versions that support TLS 1.3 shouldn't get here because they - * already have these functions. So we don't have to keep updating the below - * code for every new TLS version, and eventually it can go away. But let's - * just check this to make sure ... - */ -#ifdef TLS1_3_VERSION -#error OpenSSL version mismatch -#endif - -int -SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) -{ - int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; - - if (version > TLS1_VERSION) - ssl_options |= SSL_OP_NO_TLSv1; - - /* - * Some OpenSSL versions define TLS*_VERSION macros but not the - * corresponding SSL_OP_NO_* macro, so in those cases we have to return - * unsuccessfully here. - */ -#ifdef TLS1_1_VERSION - if (version > TLS1_1_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_1 - ssl_options |= SSL_OP_NO_TLSv1_1; -#else - return 0; -#endif - } -#endif -#ifdef TLS1_2_VERSION - if (version > TLS1_2_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_2 - ssl_options |= SSL_OP_NO_TLSv1_2; -#else - return 0; -#endif - } -#endif - - SSL_CTX_set_options(ctx, ssl_options); - - return 1; /* success */ -} - -int -SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) -{ - int ssl_options = 0; - - Assert(version != 0); - - /* - * Some OpenSSL versions define TLS*_VERSION macros but not the - * corresponding SSL_OP_NO_* macro, so in those cases we have to return - * unsuccessfully here. - */ -#ifdef TLS1_1_VERSION - if (version < TLS1_1_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_1 - ssl_options |= SSL_OP_NO_TLSv1_1; -#else - return 0; -#endif - } -#endif -#ifdef TLS1_2_VERSION - if (version < TLS1_2_VERSION) - { -#ifdef SSL_OP_NO_TLSv1_2 - ssl_options |= SSL_OP_NO_TLSv1_2; -#else - return 0; -#endif - } -#endif - - SSL_CTX_set_options(ctx, ssl_options); - - return 1; /* success */ -} - -#endif /* !SSL_CTX_set_min_proto_version */ diff --git a/contrib/libs/libpq/src/common/psprintf.c b/contrib/libs/libpq/src/common/psprintf.c deleted file mode 100644 index c8280c0880..0000000000 --- a/contrib/libs/libpq/src/common/psprintf.c +++ /dev/null @@ -1,151 +0,0 @@ -/*------------------------------------------------------------------------- - * - * psprintf.c - * sprintf into an allocated-on-demand buffer - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/psprintf.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND - -#include "postgres.h" - -#error #include "utils/memutils.h" - -#else - -#include "postgres_fe.h" - -/* It's possible we could use a different value for this in frontend code */ -#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ - -#endif - - -/* - * psprintf - * - * Format text data under the control of fmt (an sprintf-style format string) - * and return it in an allocated-on-demand buffer. The buffer is allocated - * with palloc in the backend, or malloc in frontend builds. Caller is - * responsible to free the buffer when no longer needed, if appropriate. - * - * Errors are not returned to the caller, but are reported via elog(ERROR) - * in the backend, or printf-to-stderr-and-exit() in frontend builds. - * One should therefore think twice about using this in libpq. - */ -char * -psprintf(const char *fmt,...) -{ - int save_errno = errno; - size_t len = 128; /* initial assumption about buffer size */ - - for (;;) - { - char *result; - va_list args; - size_t newlen; - - /* - * Allocate result buffer. Note that in frontend this maps to malloc - * with exit-on-error. - */ - result = (char *) palloc(len); - - /* Try to format the data. */ - errno = save_errno; - va_start(args, fmt); - newlen = pvsnprintf(result, len, fmt, args); - va_end(args); - - if (newlen < len) - return result; /* success */ - - /* Release buffer and loop around to try again with larger len. */ - pfree(result); - len = newlen; - } -} - -/* - * pvsnprintf - * - * Attempt to format text data under the control of fmt (an sprintf-style - * format string) and insert it into buf (which has length len). - * - * If successful, return the number of bytes emitted, not counting the - * trailing zero byte. This will always be strictly less than len. - * - * If there's not enough space in buf, return an estimate of the buffer size - * needed to succeed (this *must* be more than the given len, else callers - * might loop infinitely). - * - * Other error cases do not return, but exit via elog(ERROR) or exit(). - * Hence, this shouldn't be used inside libpq. - * - * Caution: callers must be sure to preserve their entry-time errno - * when looping, in case the fmt contains "%m". - * - * Note that the semantics of the return value are not exactly C99's. - * First, we don't promise that the estimated buffer size is exactly right; - * callers must be prepared to loop multiple times to get the right size. - * (Given a C99-compliant vsnprintf, that won't happen, but it is rumored - * that some implementations don't always return the same value ...) - * Second, we return the recommended buffer size, not one less than that; - * this lets overflow concerns be handled here rather than in the callers. - */ -size_t -pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) -{ - int nprinted; - - nprinted = vsnprintf(buf, len, fmt, args); - - /* We assume failure means the fmt is bogus, hence hard failure is OK */ - if (unlikely(nprinted < 0)) - { -#ifndef FRONTEND - elog(ERROR, "vsnprintf failed: %m with format string \"%s\"", fmt); -#else - fprintf(stderr, "vsnprintf failed: %s with format string \"%s\"\n", - strerror(errno), fmt); - exit(EXIT_FAILURE); -#endif - } - - if ((size_t) nprinted < len) - { - /* Success. Note nprinted does not include trailing null. */ - return (size_t) nprinted; - } - - /* - * We assume a C99-compliant vsnprintf, so believe its estimate of the - * required space, and add one for the trailing null. (If it's wrong, the - * logic will still work, but we may loop multiple times.) - * - * Choke if the required space would exceed MaxAllocSize. Note we use - * this palloc-oriented overflow limit even when in frontend. - */ - if (unlikely((size_t) nprinted > MaxAllocSize - 1)) - { -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("out of memory"))); -#else - fprintf(stderr, _("out of memory\n")); - exit(EXIT_FAILURE); -#endif - } - - return nprinted + 1; -} diff --git a/contrib/libs/libpq/src/common/relpath.c b/contrib/libs/libpq/src/common/relpath.c deleted file mode 100644 index 87de5f6c96..0000000000 --- a/contrib/libs/libpq/src/common/relpath.c +++ /dev/null @@ -1,210 +0,0 @@ -/*------------------------------------------------------------------------- - * relpath.c - * Shared frontend/backend code to compute pathnames of relation files - * - * This module also contains some logic associated with fork names. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/relpath.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "catalog/pg_tablespace_d.h" -#include "common/relpath.h" -#include "storage/backendid.h" - - -/* - * Lookup table of fork name by fork number. - * - * If you add a new entry, remember to update the errhint in - * forkname_to_number() below, and update the SGML documentation for - * pg_relation_size(). - */ -const char *const forkNames[] = { - "main", /* MAIN_FORKNUM */ - "fsm", /* FSM_FORKNUM */ - "vm", /* VISIBILITYMAP_FORKNUM */ - "init" /* INIT_FORKNUM */ -}; - -StaticAssertDecl(lengthof(forkNames) == (MAX_FORKNUM + 1), - "array length mismatch"); - -/* - * forkname_to_number - look up fork number by name - * - * In backend, we throw an error for no match; in frontend, we just - * return InvalidForkNumber. - */ -ForkNumber -forkname_to_number(const char *forkName) -{ - ForkNumber forkNum; - - for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) - if (strcmp(forkNames[forkNum], forkName) == 0) - return forkNum; - -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid fork name"), - errhint("Valid fork names are \"main\", \"fsm\", " - "\"vm\", and \"init\"."))); -#endif - - return InvalidForkNumber; -} - -/* - * forkname_chars - * We use this to figure out whether a filename could be a relation - * fork (as opposed to an oddly named stray file that somehow ended - * up in the database directory). If the passed string begins with - * a fork name (other than the main fork name), we return its length, - * and set *fork (if not NULL) to the fork number. If not, we return 0. - * - * Note that the present coding assumes that there are no fork names which - * are prefixes of other fork names. - */ -int -forkname_chars(const char *str, ForkNumber *fork) -{ - ForkNumber forkNum; - - for (forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++) - { - int len = strlen(forkNames[forkNum]); - - if (strncmp(forkNames[forkNum], str, len) == 0) - { - if (fork) - *fork = forkNum; - return len; - } - } - if (fork) - *fork = InvalidForkNumber; - return 0; -} - - -/* - * GetDatabasePath - construct path to a database directory - * - * Result is a palloc'd string. - * - * XXX this must agree with GetRelationPath()! - */ -char * -GetDatabasePath(Oid dbOid, Oid spcOid) -{ - if (spcOid == GLOBALTABLESPACE_OID) - { - /* Shared system relations live in {datadir}/global */ - Assert(dbOid == 0); - return pstrdup("global"); - } - else if (spcOid == DEFAULTTABLESPACE_OID) - { - /* The default tablespace is {datadir}/base */ - return psprintf("base/%u", dbOid); - } - else - { - /* All other tablespaces are accessed via symlinks */ - return psprintf("pg_tblspc/%u/%s/%u", - spcOid, TABLESPACE_VERSION_DIRECTORY, dbOid); - } -} - -/* - * GetRelationPath - construct path to a relation's file - * - * Result is a palloc'd string. - * - * Note: ideally, backendId would be declared as type BackendId, but relpath.h - * would have to include a backend-only header to do that; doesn't seem worth - * the trouble considering BackendId is just int anyway. - */ -char * -GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber, - int backendId, ForkNumber forkNumber) -{ - char *path; - - if (spcOid == GLOBALTABLESPACE_OID) - { - /* Shared system relations live in {datadir}/global */ - Assert(dbOid == 0); - Assert(backendId == InvalidBackendId); - if (forkNumber != MAIN_FORKNUM) - path = psprintf("global/%u_%s", - relNumber, forkNames[forkNumber]); - else - path = psprintf("global/%u", relNumber); - } - else if (spcOid == DEFAULTTABLESPACE_OID) - { - /* The default tablespace is {datadir}/base */ - if (backendId == InvalidBackendId) - { - if (forkNumber != MAIN_FORKNUM) - path = psprintf("base/%u/%u_%s", - dbOid, relNumber, - forkNames[forkNumber]); - else - path = psprintf("base/%u/%u", - dbOid, relNumber); - } - else - { - if (forkNumber != MAIN_FORKNUM) - path = psprintf("base/%u/t%d_%u_%s", - dbOid, backendId, relNumber, - forkNames[forkNumber]); - else - path = psprintf("base/%u/t%d_%u", - dbOid, backendId, relNumber); - } - } - else - { - /* All other tablespaces are accessed via symlinks */ - if (backendId == InvalidBackendId) - { - if (forkNumber != MAIN_FORKNUM) - path = psprintf("pg_tblspc/%u/%s/%u/%u_%s", - spcOid, TABLESPACE_VERSION_DIRECTORY, - dbOid, relNumber, - forkNames[forkNumber]); - else - path = psprintf("pg_tblspc/%u/%s/%u/%u", - spcOid, TABLESPACE_VERSION_DIRECTORY, - dbOid, relNumber); - } - else - { - if (forkNumber != MAIN_FORKNUM) - path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u_%s", - spcOid, TABLESPACE_VERSION_DIRECTORY, - dbOid, backendId, relNumber, - forkNames[forkNumber]); - else - path = psprintf("pg_tblspc/%u/%s/%u/t%d_%u", - spcOid, TABLESPACE_VERSION_DIRECTORY, - dbOid, backendId, relNumber); - } - } - return path; -} diff --git a/contrib/libs/libpq/src/common/restricted_token.c b/contrib/libs/libpq/src/common/restricted_token.c deleted file mode 100644 index 4ae1ed1e8a..0000000000 --- a/contrib/libs/libpq/src/common/restricted_token.c +++ /dev/null @@ -1,174 +0,0 @@ -/*------------------------------------------------------------------------- - * - * restricted_token.c - * helper routine to ensure restricted token on Windows - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/restricted_token.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#error "This file is not expected to be compiled for backend code" -#endif - -#include "postgres_fe.h" - -#include "common/logging.h" -#include "common/restricted_token.h" - -#ifdef WIN32 - -/* internal vars */ -char *restrict_env; - -/* Windows API define missing from some versions of MingW headers */ -#ifndef DISABLE_MAX_PRIVILEGE -#define DISABLE_MAX_PRIVILEGE 0x1 -#endif - -/* - * Create a restricted token and execute the specified process with it. - * - * Returns restricted token on success and 0 on failure. - * - * On any system not containing the required functions, do nothing - * but still report an error. - */ -HANDLE -CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo) -{ - BOOL b; - STARTUPINFO si; - HANDLE origToken; - HANDLE restrictedToken; - SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; - SID_AND_ATTRIBUTES dropSids[2]; - - ZeroMemory(&si, sizeof(si)); - si.cb = sizeof(si); - - /* Open the current token to use as a base for the restricted one */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &origToken)) - { - pg_log_error("could not open process token: error code %lu", - GetLastError()); - return 0; - } - - /* Allocate list of SIDs to remove */ - ZeroMemory(&dropSids, sizeof(dropSids)); - if (!AllocateAndInitializeSid(&NtAuthority, 2, - SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, - 0, &dropSids[0].Sid) || - !AllocateAndInitializeSid(&NtAuthority, 2, - SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0, - 0, &dropSids[1].Sid)) - { - pg_log_error("could not allocate SIDs: error code %lu", - GetLastError()); - CloseHandle(origToken); - return 0; - } - - b = CreateRestrictedToken(origToken, - DISABLE_MAX_PRIVILEGE, - sizeof(dropSids) / sizeof(dropSids[0]), - dropSids, - 0, NULL, - 0, NULL, - &restrictedToken); - - FreeSid(dropSids[1].Sid); - FreeSid(dropSids[0].Sid); - CloseHandle(origToken); - - if (!b) - { - pg_log_error("could not create restricted token: error code %lu", GetLastError()); - return 0; - } - -#ifndef __CYGWIN__ - AddUserToTokenDacl(restrictedToken); -#endif - - if (!CreateProcessAsUser(restrictedToken, - NULL, - cmd, - NULL, - NULL, - TRUE, - CREATE_SUSPENDED, - NULL, - NULL, - &si, - processInfo)) - - { - pg_log_error("could not start process for command \"%s\": error code %lu", cmd, GetLastError()); - return 0; - } - - ResumeThread(processInfo->hThread); - return restrictedToken; -} -#endif - -/* - * On Windows make sure that we are running with a restricted token, - * On other platforms do nothing. - */ -void -get_restricted_token(void) -{ -#ifdef WIN32 - HANDLE restrictedToken; - - /* - * Before we execute another program, make sure that we are running with a - * restricted token. If not, re-execute ourselves with one. - */ - - if ((restrict_env = getenv("PG_RESTRICT_EXEC")) == NULL - || strcmp(restrict_env, "1") != 0) - { - PROCESS_INFORMATION pi; - char *cmdline; - - ZeroMemory(&pi, sizeof(pi)); - - cmdline = pg_strdup(GetCommandLine()); - - setenv("PG_RESTRICT_EXEC", "1", 1); - - if ((restrictedToken = CreateRestrictedProcess(cmdline, &pi)) == 0) - { - pg_log_error("could not re-execute with restricted token: error code %lu", GetLastError()); - } - else - { - /* - * Successfully re-executed. Now wait for child process to capture - * the exit code. - */ - DWORD x; - - CloseHandle(restrictedToken); - CloseHandle(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); - - if (!GetExitCodeProcess(pi.hProcess, &x)) - pg_fatal("could not get exit code from subprocess: error code %lu", GetLastError()); - exit(x); - } - pg_free(cmdline); - } -#endif -} diff --git a/contrib/libs/libpq/src/common/rmtree.c b/contrib/libs/libpq/src/common/rmtree.c deleted file mode 100644 index 9d0c32955a..0000000000 --- a/contrib/libs/libpq/src/common/rmtree.c +++ /dev/null @@ -1,130 +0,0 @@ -/*------------------------------------------------------------------------- - * - * rmtree.c - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/rmtree.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <unistd.h> -#include <sys/stat.h> - -#include "common/file_utils.h" - -#ifndef FRONTEND -#error #include "storage/fd.h" -#define pg_log_warning(...) elog(WARNING, __VA_ARGS__) -#define LOG_LEVEL WARNING -#define OPENDIR(x) AllocateDir(x) -#define CLOSEDIR(x) FreeDir(x) -#else -#include "common/logging.h" -#define LOG_LEVEL PG_LOG_WARNING -#define OPENDIR(x) opendir(x) -#define CLOSEDIR(x) closedir(x) -#endif - -/* - * rmtree - * - * Delete a directory tree recursively. - * Assumes path points to a valid directory. - * Deletes everything under path. - * If rmtopdir is true deletes the directory too. - * Returns true if successful, false if there was any problem. - * (The details of the problem are reported already, so caller - * doesn't really have to say anything more, but most do.) - */ -bool -rmtree(const char *path, bool rmtopdir) -{ - char pathbuf[MAXPGPATH]; - DIR *dir; - struct dirent *de; - bool result = true; - size_t dirnames_size = 0; - size_t dirnames_capacity = 8; - char **dirnames = palloc(sizeof(char *) * dirnames_capacity); - - dir = OPENDIR(path); - if (dir == NULL) - { - pg_log_warning("could not open directory \"%s\": %m", path); - return false; - } - - while (errno = 0, (de = readdir(dir))) - { - if (strcmp(de->d_name, ".") == 0 || - strcmp(de->d_name, "..") == 0) - continue; - snprintf(pathbuf, sizeof(pathbuf), "%s/%s", path, de->d_name); - switch (get_dirent_type(pathbuf, de, false, LOG_LEVEL)) - { - case PGFILETYPE_ERROR: - /* already logged, press on */ - break; - case PGFILETYPE_DIR: - - /* - * Defer recursion until after we've closed this directory, to - * avoid using more than one file descriptor at a time. - */ - if (dirnames_size == dirnames_capacity) - { - dirnames = repalloc(dirnames, - sizeof(char *) * dirnames_capacity * 2); - dirnames_capacity *= 2; - } - dirnames[dirnames_size++] = pstrdup(pathbuf); - break; - default: - if (unlink(pathbuf) != 0 && errno != ENOENT) - { - pg_log_warning("could not remove file \"%s\": %m", pathbuf); - result = false; - } - break; - } - } - - if (errno != 0) - { - pg_log_warning("could not read directory \"%s\": %m", path); - result = false; - } - - CLOSEDIR(dir); - - /* Now recurse into the subdirectories we found. */ - for (size_t i = 0; i < dirnames_size; ++i) - { - if (!rmtree(dirnames[i], true)) - result = false; - pfree(dirnames[i]); - } - - if (rmtopdir) - { - if (rmdir(path) != 0) - { - pg_log_warning("could not remove directory \"%s\": %m", path); - result = false; - } - } - - pfree(dirnames); - - return result; -} diff --git a/contrib/libs/libpq/src/common/ryu_common.h b/contrib/libs/libpq/src/common/ryu_common.h deleted file mode 100644 index ad850acf62..0000000000 --- a/contrib/libs/libpq/src/common/ryu_common.h +++ /dev/null @@ -1,133 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Common routines for Ryu floating-point output. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/ryu_common.h - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ -#ifndef RYU_COMMON_H -#define RYU_COMMON_H - -/* - * Upstream Ryu's output is always the shortest possible. But we adjust that - * slightly to improve portability: we avoid outputting the exact midpoint - * value between two representable floats, since that relies on the reader - * getting the round-to-even rule correct, which seems to be the common - * failure mode. - * - * Defining this to 1 would restore the upstream behavior. - */ -#define STRICTLY_SHORTEST 0 - -#if SIZEOF_SIZE_T < 8 -#define RYU_32_BIT_PLATFORM -#endif - -/* Returns e == 0 ? 1 : ceil(log_2(5^e)). */ -static inline uint32 -pow5bits(const int32 e) -{ - /* - * This approximation works up to the point that the multiplication - * overflows at e = 3529. - * - * If the multiplication were done in 64 bits, it would fail at 5^4004 - * which is just greater than 2^9297. - */ - Assert(e >= 0); - Assert(e <= 3528); - return ((((uint32) e) * 1217359) >> 19) + 1; -} - -/* Returns floor(log_10(2^e)). */ -static inline int32 -log10Pow2(const int32 e) -{ - /* - * The first value this approximation fails for is 2^1651 which is just - * greater than 10^297. - */ - Assert(e >= 0); - Assert(e <= 1650); - return (int32) ((((uint32) e) * 78913) >> 18); -} - -/* Returns floor(log_10(5^e)). */ -static inline int32 -log10Pow5(const int32 e) -{ - /* - * The first value this approximation fails for is 5^2621 which is just - * greater than 10^1832. - */ - Assert(e >= 0); - Assert(e <= 2620); - return (int32) ((((uint32) e) * 732923) >> 20); -} - -static inline int -copy_special_str(char *const result, const bool sign, const bool exponent, const bool mantissa) -{ - if (mantissa) - { - memcpy(result, "NaN", 3); - return 3; - } - if (sign) - { - result[0] = '-'; - } - if (exponent) - { - memcpy(result + sign, "Infinity", 8); - return sign + 8; - } - result[sign] = '0'; - return sign + 1; -} - -static inline uint32 -float_to_bits(const float f) -{ - uint32 bits = 0; - - memcpy(&bits, &f, sizeof(float)); - return bits; -} - -static inline uint64 -double_to_bits(const double d) -{ - uint64 bits = 0; - - memcpy(&bits, &d, sizeof(double)); - return bits; -} - -#endif /* RYU_COMMON_H */ diff --git a/contrib/libs/libpq/src/common/saslprep.c b/contrib/libs/libpq/src/common/saslprep.c deleted file mode 100644 index 3cf498866a..0000000000 --- a/contrib/libs/libpq/src/common/saslprep.c +++ /dev/null @@ -1,1245 +0,0 @@ -/*------------------------------------------------------------------------- - * saslprep.c - * SASLprep normalization, for SCRAM authentication - * - * The SASLprep algorithm is used to process a user-supplied password into - * canonical form. For more details, see: - * - * [RFC3454] Preparation of Internationalized Strings ("stringprep"), - * http://www.ietf.org/rfc/rfc3454.txt - * - * [RFC4013] SASLprep: Stringprep Profile for User Names and Passwords - * http://www.ietf.org/rfc/rfc4013.txt - * - * - * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/saslprep.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/saslprep.h" -#include "common/string.h" -#include "common/unicode_norm.h" -#include "mb/pg_wchar.h" - -/* - * In backend, we will use palloc/pfree. In frontend, use malloc, and - * return SASLPREP_OOM on out-of-memory. - */ -#ifndef FRONTEND -#define STRDUP(s) pstrdup(s) -#define ALLOC(size) palloc(size) -#define FREE(size) pfree(size) -#else -#define STRDUP(s) strdup(s) -#define ALLOC(size) malloc(size) -#define FREE(size) free(size) -#endif - -/* Prototypes for local functions */ -static int codepoint_range_cmp(const void *a, const void *b); -static bool is_code_in_table(pg_wchar code, const pg_wchar *map, int mapsize); -static int pg_utf8_string_len(const char *source); - -/* - * Stringprep Mapping Tables. - * - * The stringprep specification includes a number of tables of Unicode - * codepoints, used in different parts of the algorithm. They are below, - * as arrays of codepoint ranges. Each range is a pair of codepoints, - * for the first and last codepoint included the range (inclusive!). - */ - -/* - * C.1.2 Non-ASCII space characters - * - * These are all mapped to the ASCII space character (U+00A0). - */ -static const pg_wchar non_ascii_space_ranges[] = -{ - 0x00A0, 0x00A0, - 0x1680, 0x1680, - 0x2000, 0x200B, - 0x202F, 0x202F, - 0x205F, 0x205F, - 0x3000, 0x3000 -}; - -/* - * B.1 Commonly mapped to nothing - * - * If any of these appear in the input, they are removed. - */ -static const pg_wchar commonly_mapped_to_nothing_ranges[] = -{ - 0x00AD, 0x00AD, - 0x034F, 0x034F, - 0x1806, 0x1806, - 0x180B, 0x180D, - 0x200B, 0x200D, - 0x2060, 0x2060, - 0xFE00, 0xFE0F, - 0xFEFF, 0xFEFF -}; - -/* - * prohibited_output_ranges is a union of all the characters from - * the following tables: - * - * C.1.2 Non-ASCII space characters - * C.2.1 ASCII control characters - * C.2.2 Non-ASCII control characters - * C.3 Private Use characters - * C.4 Non-character code points - * C.5 Surrogate code points - * C.6 Inappropriate for plain text characters - * C.7 Inappropriate for canonical representation characters - * C.7 Change display properties or deprecated characters - * C.8 Tagging characters - * - * These are the tables that are listed as "prohibited output" - * characters in the SASLprep profile. - * - * The comment after each code range indicates which source table - * the code came from. Note that there is some overlap in the source - * tables, so one code might originate from multiple source tables. - * Adjacent ranges have also been merged together, to save space. - */ -static const pg_wchar prohibited_output_ranges[] = -{ - 0x0000, 0x001F, /* C.2.1 */ - 0x007F, 0x00A0, /* C.1.2, C.2.1, C.2.2 */ - 0x0340, 0x0341, /* C.8 */ - 0x06DD, 0x06DD, /* C.2.2 */ - 0x070F, 0x070F, /* C.2.2 */ - 0x1680, 0x1680, /* C.1.2 */ - 0x180E, 0x180E, /* C.2.2 */ - 0x2000, 0x200F, /* C.1.2, C.2.2, C.8 */ - 0x2028, 0x202F, /* C.1.2, C.2.2, C.8 */ - 0x205F, 0x2063, /* C.1.2, C.2.2 */ - 0x206A, 0x206F, /* C.2.2, C.8 */ - 0x2FF0, 0x2FFB, /* C.7 */ - 0x3000, 0x3000, /* C.1.2 */ - 0xD800, 0xF8FF, /* C.3, C.5 */ - 0xFDD0, 0xFDEF, /* C.4 */ - 0xFEFF, 0xFEFF, /* C.2.2 */ - 0xFFF9, 0xFFFF, /* C.2.2, C.4, C.6 */ - 0x1D173, 0x1D17A, /* C.2.2 */ - 0x1FFFE, 0x1FFFF, /* C.4 */ - 0x2FFFE, 0x2FFFF, /* C.4 */ - 0x3FFFE, 0x3FFFF, /* C.4 */ - 0x4FFFE, 0x4FFFF, /* C.4 */ - 0x5FFFE, 0x5FFFF, /* C.4 */ - 0x6FFFE, 0x6FFFF, /* C.4 */ - 0x7FFFE, 0x7FFFF, /* C.4 */ - 0x8FFFE, 0x8FFFF, /* C.4 */ - 0x9FFFE, 0x9FFFF, /* C.4 */ - 0xAFFFE, 0xAFFFF, /* C.4 */ - 0xBFFFE, 0xBFFFF, /* C.4 */ - 0xCFFFE, 0xCFFFF, /* C.4 */ - 0xDFFFE, 0xDFFFF, /* C.4 */ - 0xE0001, 0xE0001, /* C.9 */ - 0xE0020, 0xE007F, /* C.9 */ - 0xEFFFE, 0xEFFFF, /* C.4 */ - 0xF0000, 0xFFFFF, /* C.3, C.4 */ - 0x100000, 0x10FFFF /* C.3, C.4 */ -}; - -/* A.1 Unassigned code points in Unicode 3.2 */ -static const pg_wchar unassigned_codepoint_ranges[] = -{ - 0x0221, 0x0221, - 0x0234, 0x024F, - 0x02AE, 0x02AF, - 0x02EF, 0x02FF, - 0x0350, 0x035F, - 0x0370, 0x0373, - 0x0376, 0x0379, - 0x037B, 0x037D, - 0x037F, 0x0383, - 0x038B, 0x038B, - 0x038D, 0x038D, - 0x03A2, 0x03A2, - 0x03CF, 0x03CF, - 0x03F7, 0x03FF, - 0x0487, 0x0487, - 0x04CF, 0x04CF, - 0x04F6, 0x04F7, - 0x04FA, 0x04FF, - 0x0510, 0x0530, - 0x0557, 0x0558, - 0x0560, 0x0560, - 0x0588, 0x0588, - 0x058B, 0x0590, - 0x05A2, 0x05A2, - 0x05BA, 0x05BA, - 0x05C5, 0x05CF, - 0x05EB, 0x05EF, - 0x05F5, 0x060B, - 0x060D, 0x061A, - 0x061C, 0x061E, - 0x0620, 0x0620, - 0x063B, 0x063F, - 0x0656, 0x065F, - 0x06EE, 0x06EF, - 0x06FF, 0x06FF, - 0x070E, 0x070E, - 0x072D, 0x072F, - 0x074B, 0x077F, - 0x07B2, 0x0900, - 0x0904, 0x0904, - 0x093A, 0x093B, - 0x094E, 0x094F, - 0x0955, 0x0957, - 0x0971, 0x0980, - 0x0984, 0x0984, - 0x098D, 0x098E, - 0x0991, 0x0992, - 0x09A9, 0x09A9, - 0x09B1, 0x09B1, - 0x09B3, 0x09B5, - 0x09BA, 0x09BB, - 0x09BD, 0x09BD, - 0x09C5, 0x09C6, - 0x09C9, 0x09CA, - 0x09CE, 0x09D6, - 0x09D8, 0x09DB, - 0x09DE, 0x09DE, - 0x09E4, 0x09E5, - 0x09FB, 0x0A01, - 0x0A03, 0x0A04, - 0x0A0B, 0x0A0E, - 0x0A11, 0x0A12, - 0x0A29, 0x0A29, - 0x0A31, 0x0A31, - 0x0A34, 0x0A34, - 0x0A37, 0x0A37, - 0x0A3A, 0x0A3B, - 0x0A3D, 0x0A3D, - 0x0A43, 0x0A46, - 0x0A49, 0x0A4A, - 0x0A4E, 0x0A58, - 0x0A5D, 0x0A5D, - 0x0A5F, 0x0A65, - 0x0A75, 0x0A80, - 0x0A84, 0x0A84, - 0x0A8C, 0x0A8C, - 0x0A8E, 0x0A8E, - 0x0A92, 0x0A92, - 0x0AA9, 0x0AA9, - 0x0AB1, 0x0AB1, - 0x0AB4, 0x0AB4, - 0x0ABA, 0x0ABB, - 0x0AC6, 0x0AC6, - 0x0ACA, 0x0ACA, - 0x0ACE, 0x0ACF, - 0x0AD1, 0x0ADF, - 0x0AE1, 0x0AE5, - 0x0AF0, 0x0B00, - 0x0B04, 0x0B04, - 0x0B0D, 0x0B0E, - 0x0B11, 0x0B12, - 0x0B29, 0x0B29, - 0x0B31, 0x0B31, - 0x0B34, 0x0B35, - 0x0B3A, 0x0B3B, - 0x0B44, 0x0B46, - 0x0B49, 0x0B4A, - 0x0B4E, 0x0B55, - 0x0B58, 0x0B5B, - 0x0B5E, 0x0B5E, - 0x0B62, 0x0B65, - 0x0B71, 0x0B81, - 0x0B84, 0x0B84, - 0x0B8B, 0x0B8D, - 0x0B91, 0x0B91, - 0x0B96, 0x0B98, - 0x0B9B, 0x0B9B, - 0x0B9D, 0x0B9D, - 0x0BA0, 0x0BA2, - 0x0BA5, 0x0BA7, - 0x0BAB, 0x0BAD, - 0x0BB6, 0x0BB6, - 0x0BBA, 0x0BBD, - 0x0BC3, 0x0BC5, - 0x0BC9, 0x0BC9, - 0x0BCE, 0x0BD6, - 0x0BD8, 0x0BE6, - 0x0BF3, 0x0C00, - 0x0C04, 0x0C04, - 0x0C0D, 0x0C0D, - 0x0C11, 0x0C11, - 0x0C29, 0x0C29, - 0x0C34, 0x0C34, - 0x0C3A, 0x0C3D, - 0x0C45, 0x0C45, - 0x0C49, 0x0C49, - 0x0C4E, 0x0C54, - 0x0C57, 0x0C5F, - 0x0C62, 0x0C65, - 0x0C70, 0x0C81, - 0x0C84, 0x0C84, - 0x0C8D, 0x0C8D, - 0x0C91, 0x0C91, - 0x0CA9, 0x0CA9, - 0x0CB4, 0x0CB4, - 0x0CBA, 0x0CBD, - 0x0CC5, 0x0CC5, - 0x0CC9, 0x0CC9, - 0x0CCE, 0x0CD4, - 0x0CD7, 0x0CDD, - 0x0CDF, 0x0CDF, - 0x0CE2, 0x0CE5, - 0x0CF0, 0x0D01, - 0x0D04, 0x0D04, - 0x0D0D, 0x0D0D, - 0x0D11, 0x0D11, - 0x0D29, 0x0D29, - 0x0D3A, 0x0D3D, - 0x0D44, 0x0D45, - 0x0D49, 0x0D49, - 0x0D4E, 0x0D56, - 0x0D58, 0x0D5F, - 0x0D62, 0x0D65, - 0x0D70, 0x0D81, - 0x0D84, 0x0D84, - 0x0D97, 0x0D99, - 0x0DB2, 0x0DB2, - 0x0DBC, 0x0DBC, - 0x0DBE, 0x0DBF, - 0x0DC7, 0x0DC9, - 0x0DCB, 0x0DCE, - 0x0DD5, 0x0DD5, - 0x0DD7, 0x0DD7, - 0x0DE0, 0x0DF1, - 0x0DF5, 0x0E00, - 0x0E3B, 0x0E3E, - 0x0E5C, 0x0E80, - 0x0E83, 0x0E83, - 0x0E85, 0x0E86, - 0x0E89, 0x0E89, - 0x0E8B, 0x0E8C, - 0x0E8E, 0x0E93, - 0x0E98, 0x0E98, - 0x0EA0, 0x0EA0, - 0x0EA4, 0x0EA4, - 0x0EA6, 0x0EA6, - 0x0EA8, 0x0EA9, - 0x0EAC, 0x0EAC, - 0x0EBA, 0x0EBA, - 0x0EBE, 0x0EBF, - 0x0EC5, 0x0EC5, - 0x0EC7, 0x0EC7, - 0x0ECE, 0x0ECF, - 0x0EDA, 0x0EDB, - 0x0EDE, 0x0EFF, - 0x0F48, 0x0F48, - 0x0F6B, 0x0F70, - 0x0F8C, 0x0F8F, - 0x0F98, 0x0F98, - 0x0FBD, 0x0FBD, - 0x0FCD, 0x0FCE, - 0x0FD0, 0x0FFF, - 0x1022, 0x1022, - 0x1028, 0x1028, - 0x102B, 0x102B, - 0x1033, 0x1035, - 0x103A, 0x103F, - 0x105A, 0x109F, - 0x10C6, 0x10CF, - 0x10F9, 0x10FA, - 0x10FC, 0x10FF, - 0x115A, 0x115E, - 0x11A3, 0x11A7, - 0x11FA, 0x11FF, - 0x1207, 0x1207, - 0x1247, 0x1247, - 0x1249, 0x1249, - 0x124E, 0x124F, - 0x1257, 0x1257, - 0x1259, 0x1259, - 0x125E, 0x125F, - 0x1287, 0x1287, - 0x1289, 0x1289, - 0x128E, 0x128F, - 0x12AF, 0x12AF, - 0x12B1, 0x12B1, - 0x12B6, 0x12B7, - 0x12BF, 0x12BF, - 0x12C1, 0x12C1, - 0x12C6, 0x12C7, - 0x12CF, 0x12CF, - 0x12D7, 0x12D7, - 0x12EF, 0x12EF, - 0x130F, 0x130F, - 0x1311, 0x1311, - 0x1316, 0x1317, - 0x131F, 0x131F, - 0x1347, 0x1347, - 0x135B, 0x1360, - 0x137D, 0x139F, - 0x13F5, 0x1400, - 0x1677, 0x167F, - 0x169D, 0x169F, - 0x16F1, 0x16FF, - 0x170D, 0x170D, - 0x1715, 0x171F, - 0x1737, 0x173F, - 0x1754, 0x175F, - 0x176D, 0x176D, - 0x1771, 0x1771, - 0x1774, 0x177F, - 0x17DD, 0x17DF, - 0x17EA, 0x17FF, - 0x180F, 0x180F, - 0x181A, 0x181F, - 0x1878, 0x187F, - 0x18AA, 0x1DFF, - 0x1E9C, 0x1E9F, - 0x1EFA, 0x1EFF, - 0x1F16, 0x1F17, - 0x1F1E, 0x1F1F, - 0x1F46, 0x1F47, - 0x1F4E, 0x1F4F, - 0x1F58, 0x1F58, - 0x1F5A, 0x1F5A, - 0x1F5C, 0x1F5C, - 0x1F5E, 0x1F5E, - 0x1F7E, 0x1F7F, - 0x1FB5, 0x1FB5, - 0x1FC5, 0x1FC5, - 0x1FD4, 0x1FD5, - 0x1FDC, 0x1FDC, - 0x1FF0, 0x1FF1, - 0x1FF5, 0x1FF5, - 0x1FFF, 0x1FFF, - 0x2053, 0x2056, - 0x2058, 0x205E, - 0x2064, 0x2069, - 0x2072, 0x2073, - 0x208F, 0x209F, - 0x20B2, 0x20CF, - 0x20EB, 0x20FF, - 0x213B, 0x213C, - 0x214C, 0x2152, - 0x2184, 0x218F, - 0x23CF, 0x23FF, - 0x2427, 0x243F, - 0x244B, 0x245F, - 0x24FF, 0x24FF, - 0x2614, 0x2615, - 0x2618, 0x2618, - 0x267E, 0x267F, - 0x268A, 0x2700, - 0x2705, 0x2705, - 0x270A, 0x270B, - 0x2728, 0x2728, - 0x274C, 0x274C, - 0x274E, 0x274E, - 0x2753, 0x2755, - 0x2757, 0x2757, - 0x275F, 0x2760, - 0x2795, 0x2797, - 0x27B0, 0x27B0, - 0x27BF, 0x27CF, - 0x27EC, 0x27EF, - 0x2B00, 0x2E7F, - 0x2E9A, 0x2E9A, - 0x2EF4, 0x2EFF, - 0x2FD6, 0x2FEF, - 0x2FFC, 0x2FFF, - 0x3040, 0x3040, - 0x3097, 0x3098, - 0x3100, 0x3104, - 0x312D, 0x3130, - 0x318F, 0x318F, - 0x31B8, 0x31EF, - 0x321D, 0x321F, - 0x3244, 0x3250, - 0x327C, 0x327E, - 0x32CC, 0x32CF, - 0x32FF, 0x32FF, - 0x3377, 0x337A, - 0x33DE, 0x33DF, - 0x33FF, 0x33FF, - 0x4DB6, 0x4DFF, - 0x9FA6, 0x9FFF, - 0xA48D, 0xA48F, - 0xA4C7, 0xABFF, - 0xD7A4, 0xD7FF, - 0xFA2E, 0xFA2F, - 0xFA6B, 0xFAFF, - 0xFB07, 0xFB12, - 0xFB18, 0xFB1C, - 0xFB37, 0xFB37, - 0xFB3D, 0xFB3D, - 0xFB3F, 0xFB3F, - 0xFB42, 0xFB42, - 0xFB45, 0xFB45, - 0xFBB2, 0xFBD2, - 0xFD40, 0xFD4F, - 0xFD90, 0xFD91, - 0xFDC8, 0xFDCF, - 0xFDFD, 0xFDFF, - 0xFE10, 0xFE1F, - 0xFE24, 0xFE2F, - 0xFE47, 0xFE48, - 0xFE53, 0xFE53, - 0xFE67, 0xFE67, - 0xFE6C, 0xFE6F, - 0xFE75, 0xFE75, - 0xFEFD, 0xFEFE, - 0xFF00, 0xFF00, - 0xFFBF, 0xFFC1, - 0xFFC8, 0xFFC9, - 0xFFD0, 0xFFD1, - 0xFFD8, 0xFFD9, - 0xFFDD, 0xFFDF, - 0xFFE7, 0xFFE7, - 0xFFEF, 0xFFF8, - 0x10000, 0x102FF, - 0x1031F, 0x1031F, - 0x10324, 0x1032F, - 0x1034B, 0x103FF, - 0x10426, 0x10427, - 0x1044E, 0x1CFFF, - 0x1D0F6, 0x1D0FF, - 0x1D127, 0x1D129, - 0x1D1DE, 0x1D3FF, - 0x1D455, 0x1D455, - 0x1D49D, 0x1D49D, - 0x1D4A0, 0x1D4A1, - 0x1D4A3, 0x1D4A4, - 0x1D4A7, 0x1D4A8, - 0x1D4AD, 0x1D4AD, - 0x1D4BA, 0x1D4BA, - 0x1D4BC, 0x1D4BC, - 0x1D4C1, 0x1D4C1, - 0x1D4C4, 0x1D4C4, - 0x1D506, 0x1D506, - 0x1D50B, 0x1D50C, - 0x1D515, 0x1D515, - 0x1D51D, 0x1D51D, - 0x1D53A, 0x1D53A, - 0x1D53F, 0x1D53F, - 0x1D545, 0x1D545, - 0x1D547, 0x1D549, - 0x1D551, 0x1D551, - 0x1D6A4, 0x1D6A7, - 0x1D7CA, 0x1D7CD, - 0x1D800, 0x1FFFD, - 0x2A6D7, 0x2F7FF, - 0x2FA1E, 0x2FFFD, - 0x30000, 0x3FFFD, - 0x40000, 0x4FFFD, - 0x50000, 0x5FFFD, - 0x60000, 0x6FFFD, - 0x70000, 0x7FFFD, - 0x80000, 0x8FFFD, - 0x90000, 0x9FFFD, - 0xA0000, 0xAFFFD, - 0xB0000, 0xBFFFD, - 0xC0000, 0xCFFFD, - 0xD0000, 0xDFFFD, - 0xE0000, 0xE0000, - 0xE0002, 0xE001F, - 0xE0080, 0xEFFFD -}; - -/* D.1 Characters with bidirectional property "R" or "AL" */ -static const pg_wchar RandALCat_codepoint_ranges[] = -{ - 0x05BE, 0x05BE, - 0x05C0, 0x05C0, - 0x05C3, 0x05C3, - 0x05D0, 0x05EA, - 0x05F0, 0x05F4, - 0x061B, 0x061B, - 0x061F, 0x061F, - 0x0621, 0x063A, - 0x0640, 0x064A, - 0x066D, 0x066F, - 0x0671, 0x06D5, - 0x06DD, 0x06DD, - 0x06E5, 0x06E6, - 0x06FA, 0x06FE, - 0x0700, 0x070D, - 0x0710, 0x0710, - 0x0712, 0x072C, - 0x0780, 0x07A5, - 0x07B1, 0x07B1, - 0x200F, 0x200F, - 0xFB1D, 0xFB1D, - 0xFB1F, 0xFB28, - 0xFB2A, 0xFB36, - 0xFB38, 0xFB3C, - 0xFB3E, 0xFB3E, - 0xFB40, 0xFB41, - 0xFB43, 0xFB44, - 0xFB46, 0xFBB1, - 0xFBD3, 0xFD3D, - 0xFD50, 0xFD8F, - 0xFD92, 0xFDC7, - 0xFDF0, 0xFDFC, - 0xFE70, 0xFE74, - 0xFE76, 0xFEFC -}; - -/* D.2 Characters with bidirectional property "L" */ -static const pg_wchar LCat_codepoint_ranges[] = -{ - 0x0041, 0x005A, - 0x0061, 0x007A, - 0x00AA, 0x00AA, - 0x00B5, 0x00B5, - 0x00BA, 0x00BA, - 0x00C0, 0x00D6, - 0x00D8, 0x00F6, - 0x00F8, 0x0220, - 0x0222, 0x0233, - 0x0250, 0x02AD, - 0x02B0, 0x02B8, - 0x02BB, 0x02C1, - 0x02D0, 0x02D1, - 0x02E0, 0x02E4, - 0x02EE, 0x02EE, - 0x037A, 0x037A, - 0x0386, 0x0386, - 0x0388, 0x038A, - 0x038C, 0x038C, - 0x038E, 0x03A1, - 0x03A3, 0x03CE, - 0x03D0, 0x03F5, - 0x0400, 0x0482, - 0x048A, 0x04CE, - 0x04D0, 0x04F5, - 0x04F8, 0x04F9, - 0x0500, 0x050F, - 0x0531, 0x0556, - 0x0559, 0x055F, - 0x0561, 0x0587, - 0x0589, 0x0589, - 0x0903, 0x0903, - 0x0905, 0x0939, - 0x093D, 0x0940, - 0x0949, 0x094C, - 0x0950, 0x0950, - 0x0958, 0x0961, - 0x0964, 0x0970, - 0x0982, 0x0983, - 0x0985, 0x098C, - 0x098F, 0x0990, - 0x0993, 0x09A8, - 0x09AA, 0x09B0, - 0x09B2, 0x09B2, - 0x09B6, 0x09B9, - 0x09BE, 0x09C0, - 0x09C7, 0x09C8, - 0x09CB, 0x09CC, - 0x09D7, 0x09D7, - 0x09DC, 0x09DD, - 0x09DF, 0x09E1, - 0x09E6, 0x09F1, - 0x09F4, 0x09FA, - 0x0A05, 0x0A0A, - 0x0A0F, 0x0A10, - 0x0A13, 0x0A28, - 0x0A2A, 0x0A30, - 0x0A32, 0x0A33, - 0x0A35, 0x0A36, - 0x0A38, 0x0A39, - 0x0A3E, 0x0A40, - 0x0A59, 0x0A5C, - 0x0A5E, 0x0A5E, - 0x0A66, 0x0A6F, - 0x0A72, 0x0A74, - 0x0A83, 0x0A83, - 0x0A85, 0x0A8B, - 0x0A8D, 0x0A8D, - 0x0A8F, 0x0A91, - 0x0A93, 0x0AA8, - 0x0AAA, 0x0AB0, - 0x0AB2, 0x0AB3, - 0x0AB5, 0x0AB9, - 0x0ABD, 0x0AC0, - 0x0AC9, 0x0AC9, - 0x0ACB, 0x0ACC, - 0x0AD0, 0x0AD0, - 0x0AE0, 0x0AE0, - 0x0AE6, 0x0AEF, - 0x0B02, 0x0B03, - 0x0B05, 0x0B0C, - 0x0B0F, 0x0B10, - 0x0B13, 0x0B28, - 0x0B2A, 0x0B30, - 0x0B32, 0x0B33, - 0x0B36, 0x0B39, - 0x0B3D, 0x0B3E, - 0x0B40, 0x0B40, - 0x0B47, 0x0B48, - 0x0B4B, 0x0B4C, - 0x0B57, 0x0B57, - 0x0B5C, 0x0B5D, - 0x0B5F, 0x0B61, - 0x0B66, 0x0B70, - 0x0B83, 0x0B83, - 0x0B85, 0x0B8A, - 0x0B8E, 0x0B90, - 0x0B92, 0x0B95, - 0x0B99, 0x0B9A, - 0x0B9C, 0x0B9C, - 0x0B9E, 0x0B9F, - 0x0BA3, 0x0BA4, - 0x0BA8, 0x0BAA, - 0x0BAE, 0x0BB5, - 0x0BB7, 0x0BB9, - 0x0BBE, 0x0BBF, - 0x0BC1, 0x0BC2, - 0x0BC6, 0x0BC8, - 0x0BCA, 0x0BCC, - 0x0BD7, 0x0BD7, - 0x0BE7, 0x0BF2, - 0x0C01, 0x0C03, - 0x0C05, 0x0C0C, - 0x0C0E, 0x0C10, - 0x0C12, 0x0C28, - 0x0C2A, 0x0C33, - 0x0C35, 0x0C39, - 0x0C41, 0x0C44, - 0x0C60, 0x0C61, - 0x0C66, 0x0C6F, - 0x0C82, 0x0C83, - 0x0C85, 0x0C8C, - 0x0C8E, 0x0C90, - 0x0C92, 0x0CA8, - 0x0CAA, 0x0CB3, - 0x0CB5, 0x0CB9, - 0x0CBE, 0x0CBE, - 0x0CC0, 0x0CC4, - 0x0CC7, 0x0CC8, - 0x0CCA, 0x0CCB, - 0x0CD5, 0x0CD6, - 0x0CDE, 0x0CDE, - 0x0CE0, 0x0CE1, - 0x0CE6, 0x0CEF, - 0x0D02, 0x0D03, - 0x0D05, 0x0D0C, - 0x0D0E, 0x0D10, - 0x0D12, 0x0D28, - 0x0D2A, 0x0D39, - 0x0D3E, 0x0D40, - 0x0D46, 0x0D48, - 0x0D4A, 0x0D4C, - 0x0D57, 0x0D57, - 0x0D60, 0x0D61, - 0x0D66, 0x0D6F, - 0x0D82, 0x0D83, - 0x0D85, 0x0D96, - 0x0D9A, 0x0DB1, - 0x0DB3, 0x0DBB, - 0x0DBD, 0x0DBD, - 0x0DC0, 0x0DC6, - 0x0DCF, 0x0DD1, - 0x0DD8, 0x0DDF, - 0x0DF2, 0x0DF4, - 0x0E01, 0x0E30, - 0x0E32, 0x0E33, - 0x0E40, 0x0E46, - 0x0E4F, 0x0E5B, - 0x0E81, 0x0E82, - 0x0E84, 0x0E84, - 0x0E87, 0x0E88, - 0x0E8A, 0x0E8A, - 0x0E8D, 0x0E8D, - 0x0E94, 0x0E97, - 0x0E99, 0x0E9F, - 0x0EA1, 0x0EA3, - 0x0EA5, 0x0EA5, - 0x0EA7, 0x0EA7, - 0x0EAA, 0x0EAB, - 0x0EAD, 0x0EB0, - 0x0EB2, 0x0EB3, - 0x0EBD, 0x0EBD, - 0x0EC0, 0x0EC4, - 0x0EC6, 0x0EC6, - 0x0ED0, 0x0ED9, - 0x0EDC, 0x0EDD, - 0x0F00, 0x0F17, - 0x0F1A, 0x0F34, - 0x0F36, 0x0F36, - 0x0F38, 0x0F38, - 0x0F3E, 0x0F47, - 0x0F49, 0x0F6A, - 0x0F7F, 0x0F7F, - 0x0F85, 0x0F85, - 0x0F88, 0x0F8B, - 0x0FBE, 0x0FC5, - 0x0FC7, 0x0FCC, - 0x0FCF, 0x0FCF, - 0x1000, 0x1021, - 0x1023, 0x1027, - 0x1029, 0x102A, - 0x102C, 0x102C, - 0x1031, 0x1031, - 0x1038, 0x1038, - 0x1040, 0x1057, - 0x10A0, 0x10C5, - 0x10D0, 0x10F8, - 0x10FB, 0x10FB, - 0x1100, 0x1159, - 0x115F, 0x11A2, - 0x11A8, 0x11F9, - 0x1200, 0x1206, - 0x1208, 0x1246, - 0x1248, 0x1248, - 0x124A, 0x124D, - 0x1250, 0x1256, - 0x1258, 0x1258, - 0x125A, 0x125D, - 0x1260, 0x1286, - 0x1288, 0x1288, - 0x128A, 0x128D, - 0x1290, 0x12AE, - 0x12B0, 0x12B0, - 0x12B2, 0x12B5, - 0x12B8, 0x12BE, - 0x12C0, 0x12C0, - 0x12C2, 0x12C5, - 0x12C8, 0x12CE, - 0x12D0, 0x12D6, - 0x12D8, 0x12EE, - 0x12F0, 0x130E, - 0x1310, 0x1310, - 0x1312, 0x1315, - 0x1318, 0x131E, - 0x1320, 0x1346, - 0x1348, 0x135A, - 0x1361, 0x137C, - 0x13A0, 0x13F4, - 0x1401, 0x1676, - 0x1681, 0x169A, - 0x16A0, 0x16F0, - 0x1700, 0x170C, - 0x170E, 0x1711, - 0x1720, 0x1731, - 0x1735, 0x1736, - 0x1740, 0x1751, - 0x1760, 0x176C, - 0x176E, 0x1770, - 0x1780, 0x17B6, - 0x17BE, 0x17C5, - 0x17C7, 0x17C8, - 0x17D4, 0x17DA, - 0x17DC, 0x17DC, - 0x17E0, 0x17E9, - 0x1810, 0x1819, - 0x1820, 0x1877, - 0x1880, 0x18A8, - 0x1E00, 0x1E9B, - 0x1EA0, 0x1EF9, - 0x1F00, 0x1F15, - 0x1F18, 0x1F1D, - 0x1F20, 0x1F45, - 0x1F48, 0x1F4D, - 0x1F50, 0x1F57, - 0x1F59, 0x1F59, - 0x1F5B, 0x1F5B, - 0x1F5D, 0x1F5D, - 0x1F5F, 0x1F7D, - 0x1F80, 0x1FB4, - 0x1FB6, 0x1FBC, - 0x1FBE, 0x1FBE, - 0x1FC2, 0x1FC4, - 0x1FC6, 0x1FCC, - 0x1FD0, 0x1FD3, - 0x1FD6, 0x1FDB, - 0x1FE0, 0x1FEC, - 0x1FF2, 0x1FF4, - 0x1FF6, 0x1FFC, - 0x200E, 0x200E, - 0x2071, 0x2071, - 0x207F, 0x207F, - 0x2102, 0x2102, - 0x2107, 0x2107, - 0x210A, 0x2113, - 0x2115, 0x2115, - 0x2119, 0x211D, - 0x2124, 0x2124, - 0x2126, 0x2126, - 0x2128, 0x2128, - 0x212A, 0x212D, - 0x212F, 0x2131, - 0x2133, 0x2139, - 0x213D, 0x213F, - 0x2145, 0x2149, - 0x2160, 0x2183, - 0x2336, 0x237A, - 0x2395, 0x2395, - 0x249C, 0x24E9, - 0x3005, 0x3007, - 0x3021, 0x3029, - 0x3031, 0x3035, - 0x3038, 0x303C, - 0x3041, 0x3096, - 0x309D, 0x309F, - 0x30A1, 0x30FA, - 0x30FC, 0x30FF, - 0x3105, 0x312C, - 0x3131, 0x318E, - 0x3190, 0x31B7, - 0x31F0, 0x321C, - 0x3220, 0x3243, - 0x3260, 0x327B, - 0x327F, 0x32B0, - 0x32C0, 0x32CB, - 0x32D0, 0x32FE, - 0x3300, 0x3376, - 0x337B, 0x33DD, - 0x33E0, 0x33FE, - 0x3400, 0x4DB5, - 0x4E00, 0x9FA5, - 0xA000, 0xA48C, - 0xAC00, 0xD7A3, - 0xD800, 0xFA2D, - 0xFA30, 0xFA6A, - 0xFB00, 0xFB06, - 0xFB13, 0xFB17, - 0xFF21, 0xFF3A, - 0xFF41, 0xFF5A, - 0xFF66, 0xFFBE, - 0xFFC2, 0xFFC7, - 0xFFCA, 0xFFCF, - 0xFFD2, 0xFFD7, - 0xFFDA, 0xFFDC, - 0x10300, 0x1031E, - 0x10320, 0x10323, - 0x10330, 0x1034A, - 0x10400, 0x10425, - 0x10428, 0x1044D, - 0x1D000, 0x1D0F5, - 0x1D100, 0x1D126, - 0x1D12A, 0x1D166, - 0x1D16A, 0x1D172, - 0x1D183, 0x1D184, - 0x1D18C, 0x1D1A9, - 0x1D1AE, 0x1D1DD, - 0x1D400, 0x1D454, - 0x1D456, 0x1D49C, - 0x1D49E, 0x1D49F, - 0x1D4A2, 0x1D4A2, - 0x1D4A5, 0x1D4A6, - 0x1D4A9, 0x1D4AC, - 0x1D4AE, 0x1D4B9, - 0x1D4BB, 0x1D4BB, - 0x1D4BD, 0x1D4C0, - 0x1D4C2, 0x1D4C3, - 0x1D4C5, 0x1D505, - 0x1D507, 0x1D50A, - 0x1D50D, 0x1D514, - 0x1D516, 0x1D51C, - 0x1D51E, 0x1D539, - 0x1D53B, 0x1D53E, - 0x1D540, 0x1D544, - 0x1D546, 0x1D546, - 0x1D54A, 0x1D550, - 0x1D552, 0x1D6A3, - 0x1D6A8, 0x1D7C9, - 0x20000, 0x2A6D6, - 0x2F800, 0x2FA1D, - 0xF0000, 0xFFFFD, - 0x100000, 0x10FFFD -}; - -/* End of stringprep tables */ - - -/* Is the given Unicode codepoint in the given table of ranges? */ -#define IS_CODE_IN_TABLE(code, map) is_code_in_table(code, map, lengthof(map)) - -static int -codepoint_range_cmp(const void *a, const void *b) -{ - const pg_wchar *key = (const pg_wchar *) a; - const pg_wchar *range = (const pg_wchar *) b; - - if (*key < range[0]) - return -1; /* less than lower bound */ - if (*key > range[1]) - return 1; /* greater than upper bound */ - - return 0; /* within range */ -} - -static bool -is_code_in_table(pg_wchar code, const pg_wchar *map, int mapsize) -{ - Assert(mapsize % 2 == 0); - - if (code < map[0] || code > map[mapsize - 1]) - return false; - - if (bsearch(&code, map, mapsize / 2, sizeof(pg_wchar) * 2, - codepoint_range_cmp)) - return true; - else - return false; -} - -/* - * Calculate the length in characters of a null-terminated UTF-8 string. - * - * Returns -1 if the input is not valid UTF-8. - */ -static int -pg_utf8_string_len(const char *source) -{ - const unsigned char *p = (const unsigned char *) source; - int l; - int num_chars = 0; - - while (*p) - { - l = pg_utf_mblen(p); - - if (!pg_utf8_islegal(p, l)) - return -1; - - p += l; - num_chars++; - } - - return num_chars; -} - - -/* - * pg_saslprep - Normalize a password with SASLprep. - * - * SASLprep requires the input to be in UTF-8 encoding, but PostgreSQL - * supports many encodings, so we don't blindly assume that. pg_saslprep - * will check if the input looks like valid UTF-8, and returns - * SASLPREP_INVALID_UTF8 if not. - * - * If the string contains prohibited characters (or more precisely, if the - * output string would contain prohibited characters after normalization), - * returns SASLPREP_PROHIBITED. - * - * On success, returns SASLPREP_SUCCESS, and the normalized string in - * *output. - * - * In frontend, the normalized string is malloc'd, and the caller is - * responsible for freeing it. If an allocation fails, returns - * SASLPREP_OOM. In backend, the normalized string is palloc'd instead, - * and a failed allocation leads to ereport(ERROR). - */ -pg_saslprep_rc -pg_saslprep(const char *input, char **output) -{ - pg_wchar *input_chars = NULL; - pg_wchar *output_chars = NULL; - int input_size; - char *result; - int result_size; - int count; - int i; - bool contains_RandALCat; - unsigned char *p; - pg_wchar *wp; - - /* Ensure we return *output as NULL on failure */ - *output = NULL; - - /* - * Quick check if the input is pure ASCII. An ASCII string requires no - * further processing. - */ - if (pg_is_ascii(input)) - { - *output = STRDUP(input); - if (!(*output)) - goto oom; - return SASLPREP_SUCCESS; - } - - /* - * Convert the input from UTF-8 to an array of Unicode codepoints. - * - * This also checks that the input is a legal UTF-8 string. - */ - input_size = pg_utf8_string_len(input); - if (input_size < 0) - return SASLPREP_INVALID_UTF8; - - input_chars = ALLOC((input_size + 1) * sizeof(pg_wchar)); - if (!input_chars) - goto oom; - - p = (unsigned char *) input; - for (i = 0; i < input_size; i++) - { - input_chars[i] = utf8_to_unicode(p); - p += pg_utf_mblen(p); - } - input_chars[i] = (pg_wchar) '\0'; - - /* - * The steps below correspond to the steps listed in [RFC3454], Section - * "2. Preparation Overview" - */ - - /* - * 1) Map -- For each character in the input, check if it has a mapping - * and, if so, replace it with its mapping. - */ - count = 0; - for (i = 0; i < input_size; i++) - { - pg_wchar code = input_chars[i]; - - if (IS_CODE_IN_TABLE(code, non_ascii_space_ranges)) - input_chars[count++] = 0x0020; - else if (IS_CODE_IN_TABLE(code, commonly_mapped_to_nothing_ranges)) - { - /* map to nothing */ - } - else - input_chars[count++] = code; - } - input_chars[count] = (pg_wchar) '\0'; - input_size = count; - - if (input_size == 0) - goto prohibited; /* don't allow empty password */ - - /* - * 2) Normalize -- Normalize the result of step 1 using Unicode - * normalization. - */ - output_chars = unicode_normalize(UNICODE_NFKC, input_chars); - if (!output_chars) - goto oom; - - /* - * 3) Prohibit -- Check for any characters that are not allowed in the - * output. If any are found, return an error. - */ - for (i = 0; i < input_size; i++) - { - pg_wchar code = input_chars[i]; - - if (IS_CODE_IN_TABLE(code, prohibited_output_ranges)) - goto prohibited; - if (IS_CODE_IN_TABLE(code, unassigned_codepoint_ranges)) - goto prohibited; - } - - /* - * 4) Check bidi -- Possibly check for right-to-left characters, and if - * any are found, make sure that the whole string satisfies the - * requirements for bidirectional strings. If the string does not satisfy - * the requirements for bidirectional strings, return an error. - * - * [RFC3454], Section "6. Bidirectional Characters" explains in more - * detail what that means: - * - * "In any profile that specifies bidirectional character handling, all - * three of the following requirements MUST be met: - * - * 1) The characters in section 5.8 MUST be prohibited. - * - * 2) If a string contains any RandALCat character, the string MUST NOT - * contain any LCat character. - * - * 3) If a string contains any RandALCat character, a RandALCat character - * MUST be the first character of the string, and a RandALCat character - * MUST be the last character of the string." - */ - contains_RandALCat = false; - for (i = 0; i < input_size; i++) - { - pg_wchar code = input_chars[i]; - - if (IS_CODE_IN_TABLE(code, RandALCat_codepoint_ranges)) - { - contains_RandALCat = true; - break; - } - } - - if (contains_RandALCat) - { - pg_wchar first = input_chars[0]; - pg_wchar last = input_chars[input_size - 1]; - - for (i = 0; i < input_size; i++) - { - pg_wchar code = input_chars[i]; - - if (IS_CODE_IN_TABLE(code, LCat_codepoint_ranges)) - goto prohibited; - } - - if (!IS_CODE_IN_TABLE(first, RandALCat_codepoint_ranges) || - !IS_CODE_IN_TABLE(last, RandALCat_codepoint_ranges)) - goto prohibited; - } - - /* - * Finally, convert the result back to UTF-8. - */ - result_size = 0; - for (wp = output_chars; *wp; wp++) - { - unsigned char buf[4]; - - unicode_to_utf8(*wp, buf); - result_size += pg_utf_mblen(buf); - } - - result = ALLOC(result_size + 1); - if (!result) - goto oom; - - /* - * There are no error exits below here, so the error exit paths don't need - * to worry about possibly freeing "result". - */ - p = (unsigned char *) result; - for (wp = output_chars; *wp; wp++) - { - unicode_to_utf8(*wp, p); - p += pg_utf_mblen(p); - } - Assert((char *) p == result + result_size); - *p = '\0'; - - FREE(input_chars); - FREE(output_chars); - - *output = result; - return SASLPREP_SUCCESS; - -prohibited: - if (input_chars) - FREE(input_chars); - if (output_chars) - FREE(output_chars); - - return SASLPREP_PROHIBITED; - -oom: - if (input_chars) - FREE(input_chars); - if (output_chars) - FREE(output_chars); - - return SASLPREP_OOM; -} diff --git a/contrib/libs/libpq/src/common/scram-common.c b/contrib/libs/libpq/src/common/scram-common.c deleted file mode 100644 index 22ad929218..0000000000 --- a/contrib/libs/libpq/src/common/scram-common.c +++ /dev/null @@ -1,330 +0,0 @@ -/*------------------------------------------------------------------------- - * scram-common.c - * Shared frontend/backend code for SCRAM authentication - * - * This contains the common low-level functions needed in both frontend and - * backend, for implement the Salted Challenge Response Authentication - * Mechanism (SCRAM), per IETF's RFC 5802. - * - * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/scram-common.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/base64.h" -#include "common/hmac.h" -#include "common/scram-common.h" -#ifndef FRONTEND -#error #include "miscadmin.h" -#endif -#include "port/pg_bswap.h" - -/* - * Calculate SaltedPassword. - * - * The password should already be normalized by SASLprep. Returns 0 on - * success, -1 on failure with *errstr pointing to a message about the - * error details. - */ -int -scram_SaltedPassword(const char *password, - pg_cryptohash_type hash_type, int key_length, - const char *salt, int saltlen, int iterations, - uint8 *result, const char **errstr) -{ - int password_len = strlen(password); - uint32 one = pg_hton32(1); - int i, - j; - uint8 Ui[SCRAM_MAX_KEY_LEN]; - uint8 Ui_prev[SCRAM_MAX_KEY_LEN]; - pg_hmac_ctx *hmac_ctx = pg_hmac_create(hash_type); - - if (hmac_ctx == NULL) - { - *errstr = pg_hmac_error(NULL); /* returns OOM */ - return -1; - } - - /* - * Iterate hash calculation of HMAC entry using given salt. This is - * essentially PBKDF2 (see RFC2898) with HMAC() as the pseudorandom - * function. - */ - - /* First iteration */ - if (pg_hmac_init(hmac_ctx, (uint8 *) password, password_len) < 0 || - pg_hmac_update(hmac_ctx, (uint8 *) salt, saltlen) < 0 || - pg_hmac_update(hmac_ctx, (uint8 *) &one, sizeof(uint32)) < 0 || - pg_hmac_final(hmac_ctx, Ui_prev, key_length) < 0) - { - *errstr = pg_hmac_error(hmac_ctx); - pg_hmac_free(hmac_ctx); - return -1; - } - - memcpy(result, Ui_prev, key_length); - - /* Subsequent iterations */ - for (i = 2; i <= iterations; i++) - { -#ifndef FRONTEND - /* - * Make sure that this is interruptible as scram_iterations could be - * set to a large value. - */ - CHECK_FOR_INTERRUPTS(); -#endif - - if (pg_hmac_init(hmac_ctx, (uint8 *) password, password_len) < 0 || - pg_hmac_update(hmac_ctx, (uint8 *) Ui_prev, key_length) < 0 || - pg_hmac_final(hmac_ctx, Ui, key_length) < 0) - { - *errstr = pg_hmac_error(hmac_ctx); - pg_hmac_free(hmac_ctx); - return -1; - } - - for (j = 0; j < key_length; j++) - result[j] ^= Ui[j]; - memcpy(Ui_prev, Ui, key_length); - } - - pg_hmac_free(hmac_ctx); - return 0; -} - - -/* - * Calculate hash for a NULL-terminated string. (The NULL terminator is - * not included in the hash). Returns 0 on success, -1 on failure with *errstr - * pointing to a message about the error details. - */ -int -scram_H(const uint8 *input, pg_cryptohash_type hash_type, int key_length, - uint8 *result, const char **errstr) -{ - pg_cryptohash_ctx *ctx; - - ctx = pg_cryptohash_create(hash_type); - if (ctx == NULL) - { - *errstr = pg_cryptohash_error(NULL); /* returns OOM */ - return -1; - } - - if (pg_cryptohash_init(ctx) < 0 || - pg_cryptohash_update(ctx, input, key_length) < 0 || - pg_cryptohash_final(ctx, result, key_length) < 0) - { - *errstr = pg_cryptohash_error(ctx); - pg_cryptohash_free(ctx); - return -1; - } - - pg_cryptohash_free(ctx); - return 0; -} - -/* - * Calculate ClientKey. Returns 0 on success, -1 on failure with *errstr - * pointing to a message about the error details. - */ -int -scram_ClientKey(const uint8 *salted_password, - pg_cryptohash_type hash_type, int key_length, - uint8 *result, const char **errstr) -{ - pg_hmac_ctx *ctx = pg_hmac_create(hash_type); - - if (ctx == NULL) - { - *errstr = pg_hmac_error(NULL); /* returns OOM */ - return -1; - } - - if (pg_hmac_init(ctx, salted_password, key_length) < 0 || - pg_hmac_update(ctx, (uint8 *) "Client Key", strlen("Client Key")) < 0 || - pg_hmac_final(ctx, result, key_length) < 0) - { - *errstr = pg_hmac_error(ctx); - pg_hmac_free(ctx); - return -1; - } - - pg_hmac_free(ctx); - return 0; -} - -/* - * Calculate ServerKey. Returns 0 on success, -1 on failure with *errstr - * pointing to a message about the error details. - */ -int -scram_ServerKey(const uint8 *salted_password, - pg_cryptohash_type hash_type, int key_length, - uint8 *result, const char **errstr) -{ - pg_hmac_ctx *ctx = pg_hmac_create(hash_type); - - if (ctx == NULL) - { - *errstr = pg_hmac_error(NULL); /* returns OOM */ - return -1; - } - - if (pg_hmac_init(ctx, salted_password, key_length) < 0 || - pg_hmac_update(ctx, (uint8 *) "Server Key", strlen("Server Key")) < 0 || - pg_hmac_final(ctx, result, key_length) < 0) - { - *errstr = pg_hmac_error(ctx); - pg_hmac_free(ctx); - return -1; - } - - pg_hmac_free(ctx); - return 0; -} - - -/* - * Construct a SCRAM secret, for storing in pg_authid.rolpassword. - * - * The password should already have been processed with SASLprep, if necessary! - * - * If iterations is 0, default number of iterations is used. The result is - * palloc'd or malloc'd, so caller is responsible for freeing it. - * - * On error, returns NULL and sets *errstr to point to a message about the - * error details. - */ -char * -scram_build_secret(pg_cryptohash_type hash_type, int key_length, - const char *salt, int saltlen, int iterations, - const char *password, const char **errstr) -{ - uint8 salted_password[SCRAM_MAX_KEY_LEN]; - uint8 stored_key[SCRAM_MAX_KEY_LEN]; - uint8 server_key[SCRAM_MAX_KEY_LEN]; - char *result; - char *p; - int maxlen; - int encoded_salt_len; - int encoded_stored_len; - int encoded_server_len; - int encoded_result; - - /* Only this hash method is supported currently */ - Assert(hash_type == PG_SHA256); - - Assert(iterations > 0); - - /* Calculate StoredKey and ServerKey */ - if (scram_SaltedPassword(password, hash_type, key_length, - salt, saltlen, iterations, - salted_password, errstr) < 0 || - scram_ClientKey(salted_password, hash_type, key_length, - stored_key, errstr) < 0 || - scram_H(stored_key, hash_type, key_length, - stored_key, errstr) < 0 || - scram_ServerKey(salted_password, hash_type, key_length, - server_key, errstr) < 0) - { - /* errstr is filled already here */ -#ifdef FRONTEND - return NULL; -#else - elog(ERROR, "could not calculate stored key and server key: %s", - *errstr); -#endif - } - - /*---------- - * The format is: - * SCRAM-SHA-256$<iteration count>:<salt>$<StoredKey>:<ServerKey> - *---------- - */ - encoded_salt_len = pg_b64_enc_len(saltlen); - encoded_stored_len = pg_b64_enc_len(key_length); - encoded_server_len = pg_b64_enc_len(key_length); - - maxlen = strlen("SCRAM-SHA-256") + 1 - + 10 + 1 /* iteration count */ - + encoded_salt_len + 1 /* Base64-encoded salt */ - + encoded_stored_len + 1 /* Base64-encoded StoredKey */ - + encoded_server_len + 1; /* Base64-encoded ServerKey */ - -#ifdef FRONTEND - result = malloc(maxlen); - if (!result) - { - *errstr = _("out of memory"); - return NULL; - } -#else - result = palloc(maxlen); -#endif - - p = result + sprintf(result, "SCRAM-SHA-256$%d:", iterations); - - /* salt */ - encoded_result = pg_b64_encode(salt, saltlen, p, encoded_salt_len); - if (encoded_result < 0) - { - *errstr = _("could not encode salt"); -#ifdef FRONTEND - free(result); - return NULL; -#else - elog(ERROR, "%s", *errstr); -#endif - } - p += encoded_result; - *(p++) = '$'; - - /* stored key */ - encoded_result = pg_b64_encode((char *) stored_key, key_length, p, - encoded_stored_len); - if (encoded_result < 0) - { - *errstr = _("could not encode stored key"); -#ifdef FRONTEND - free(result); - return NULL; -#else - elog(ERROR, "%s", *errstr); -#endif - } - - p += encoded_result; - *(p++) = ':'; - - /* server key */ - encoded_result = pg_b64_encode((char *) server_key, key_length, p, - encoded_server_len); - if (encoded_result < 0) - { - *errstr = _("could not encode server key"); -#ifdef FRONTEND - free(result); - return NULL; -#else - elog(ERROR, "%s", *errstr); -#endif - } - - p += encoded_result; - *(p++) = '\0'; - - Assert(p - result <= maxlen); - - return result; -} diff --git a/contrib/libs/libpq/src/common/sprompt.c b/contrib/libs/libpq/src/common/sprompt.c deleted file mode 100644 index 201c831746..0000000000 --- a/contrib/libs/libpq/src/common/sprompt.c +++ /dev/null @@ -1,181 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sprompt.c - * simple_prompt() routine - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/sprompt.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "common/fe_memutils.h" -#include "common/string.h" - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#endif - - -/* - * simple_prompt - * - * Generalized function especially intended for reading in usernames and - * passwords interactively. Reads from /dev/tty or stdin/stderr. - * - * prompt: The prompt to print, or NULL if none (automatically localized) - * echo: Set to false if you want to hide what is entered (for passwords) - * - * The input (without trailing newline) is returned as a malloc'd string. - * Caller is responsible for freeing it when done. - */ -char * -simple_prompt(const char *prompt, bool echo) -{ - return simple_prompt_extended(prompt, echo, NULL); -} - -/* - * simple_prompt_extended - * - * This is the same as simple_prompt(), except that prompt_ctx can - * optionally be provided to allow this function to be canceled via an - * existing SIGINT signal handler that will longjmp to the specified place - * only when *(prompt_ctx->enabled) is true. If canceled, this function - * returns an empty string, and prompt_ctx->canceled is set to true. - */ -char * -simple_prompt_extended(const char *prompt, bool echo, - PromptInterruptContext *prompt_ctx) -{ - char *result; - FILE *termin, - *termout; -#if defined(HAVE_TERMIOS_H) - struct termios t_orig, - t; -#elif defined(WIN32) - HANDLE t = NULL; - DWORD t_orig = 0; -#endif - -#ifdef WIN32 - - /* - * A Windows console has an "input code page" and an "output code page"; - * these usually match each other, but they rarely match the "Windows ANSI - * code page" defined at system boot and expected of "char *" arguments to - * Windows API functions. The Microsoft CRT write() implementation - * automatically converts text between these code pages when writing to a - * console. To identify such file descriptors, it calls GetConsoleMode() - * on the underlying HANDLE, which in turn requires GENERIC_READ access on - * the HANDLE. Opening termout in mode "w+" allows that detection to - * succeed. Otherwise, write() would not recognize the descriptor as a - * console, and non-ASCII characters would display incorrectly. - * - * XXX fgets() still receives text in the console's input code page. This - * makes non-ASCII credentials unportable. - * - * Unintuitively, we also open termin in mode "w+", even though we only - * read it; that's needed for SetConsoleMode() to succeed. - */ - termin = fopen("CONIN$", "w+"); - termout = fopen("CONOUT$", "w+"); -#else - - /* - * Do not try to collapse these into one "w+" mode file. Doesn't work on - * some platforms (eg, HPUX 10.20). - */ - termin = fopen("/dev/tty", "r"); - termout = fopen("/dev/tty", "w"); -#endif - if (!termin || !termout -#ifdef WIN32 - - /* - * Direct console I/O does not work from the MSYS 1.0.10 console. Writes - * reach nowhere user-visible; reads block indefinitely. XXX This affects - * most Windows terminal environments, including rxvt, mintty, Cygwin - * xterm, Cygwin sshd, and PowerShell ISE. Switch to a more-generic test. - */ - || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0) -#endif - ) - { - if (termin) - fclose(termin); - if (termout) - fclose(termout); - termin = stdin; - termout = stderr; - } - - if (!echo) - { -#if defined(HAVE_TERMIOS_H) - /* disable echo via tcgetattr/tcsetattr */ - tcgetattr(fileno(termin), &t); - t_orig = t; - t.c_lflag &= ~ECHO; - tcsetattr(fileno(termin), TCSAFLUSH, &t); -#elif defined(WIN32) - /* need the file's HANDLE to turn echo off */ - t = (HANDLE) _get_osfhandle(_fileno(termin)); - - /* save the old configuration first */ - GetConsoleMode(t, &t_orig); - - /* set to the new mode */ - SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); -#endif - } - - if (prompt) - { - fputs(_(prompt), termout); - fflush(termout); - } - - result = pg_get_line(termin, prompt_ctx); - - /* If we failed to read anything, just return an empty string */ - if (result == NULL) - result = pg_strdup(""); - - /* strip trailing newline, including \r in case we're on Windows */ - (void) pg_strip_crlf(result); - - if (!echo) - { - /* restore previous echo behavior, then echo \n */ -#if defined(HAVE_TERMIOS_H) - tcsetattr(fileno(termin), TCSAFLUSH, &t_orig); - fputs("\n", termout); - fflush(termout); -#elif defined(WIN32) - SetConsoleMode(t, t_orig); - fputs("\n", termout); - fflush(termout); -#endif - } - else if (prompt_ctx && prompt_ctx->canceled) - { - /* also echo \n if prompt was canceled */ - fputs("\n", termout); - fflush(termout); - } - - if (termin != stdin) - { - fclose(termin); - fclose(termout); - } - - return result; -} diff --git a/contrib/libs/libpq/src/common/string.c b/contrib/libs/libpq/src/common/string.c deleted file mode 100644 index de97413635..0000000000 --- a/contrib/libs/libpq/src/common/string.c +++ /dev/null @@ -1,164 +0,0 @@ -/*------------------------------------------------------------------------- - * - * string.c - * string handling helpers - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/string.c - * - *------------------------------------------------------------------------- - */ - - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/string.h" -#include "lib/stringinfo.h" - - -/* - * Returns whether the string `str' has the postfix `end'. - */ -bool -pg_str_endswith(const char *str, const char *end) -{ - size_t slen = strlen(str); - size_t elen = strlen(end); - - /* can't be a postfix if longer */ - if (elen > slen) - return false; - - /* compare the end of the strings */ - str += slen - elen; - return strcmp(str, end) == 0; -} - - -/* - * strtoint --- just like strtol, but returns int not long - */ -int -strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base) -{ - long val; - - val = strtol(str, endptr, base); - if (val != (int) val) - errno = ERANGE; - return (int) val; -} - - -/* - * pg_clean_ascii -- Replace any non-ASCII chars with a "\xXX" string - * - * Makes a newly allocated copy of the string passed in, which must be - * '\0'-terminated. In the backend, additional alloc_flags may be provided and - * will be passed as-is to palloc_extended(); in the frontend, alloc_flags is - * ignored and the copy is malloc'd. - * - * This function exists specifically to deal with filtering out - * non-ASCII characters in a few places where the client can provide an almost - * arbitrary string (and it isn't checked to ensure it's a valid username or - * database name or similar) and we don't want to have control characters or other - * things ending up in the log file where server admins might end up with a - * messed up terminal when looking at them. - * - * In general, this function should NOT be used- instead, consider how to handle - * the string without needing to filter out the non-ASCII characters. - * - * Ultimately, we'd like to improve the situation to not require replacing all - * non-ASCII but perform more intelligent filtering which would allow UTF or - * similar, but it's unclear exactly what we should allow, so stick to ASCII only - * for now. - */ -char * -pg_clean_ascii(const char *str, int alloc_flags) -{ - size_t dstlen; - char *dst; - const char *p; - size_t i = 0; - - /* Worst case, each byte can become four bytes, plus a null terminator. */ - dstlen = strlen(str) * 4 + 1; - -#ifdef FRONTEND - dst = malloc(dstlen); -#else - dst = palloc_extended(dstlen, alloc_flags); -#endif - - if (!dst) - return NULL; - - for (p = str; *p != '\0'; p++) - { - - /* Only allow clean ASCII chars in the string */ - if (*p < 32 || *p > 126) - { - Assert(i < (dstlen - 3)); - snprintf(&dst[i], dstlen - i, "\\x%02x", (unsigned char) *p); - i += 4; - } - else - { - Assert(i < dstlen); - dst[i] = *p; - i++; - } - } - - Assert(i < dstlen); - dst[i] = '\0'; - return dst; -} - - -/* - * pg_is_ascii -- Check if string is made only of ASCII characters - */ -bool -pg_is_ascii(const char *str) -{ - while (*str) - { - if (IS_HIGHBIT_SET(*str)) - return false; - str++; - } - return true; -} - - -/* - * pg_strip_crlf -- Remove any trailing newline and carriage return - * - * Removes any trailing newline and carriage return characters (\r on - * Windows) in the input string, zero-terminating it. - * - * The passed in string must be zero-terminated. This function returns - * the new length of the string. - */ -int -pg_strip_crlf(char *str) -{ - int len = strlen(str); - - while (len > 0 && (str[len - 1] == '\n' || - str[len - 1] == '\r')) - str[--len] = '\0'; - - return len; -} diff --git a/contrib/libs/libpq/src/common/stringinfo.c b/contrib/libs/libpq/src/common/stringinfo.c deleted file mode 100644 index 230dafd6c8..0000000000 --- a/contrib/libs/libpq/src/common/stringinfo.c +++ /dev/null @@ -1,343 +0,0 @@ -/*------------------------------------------------------------------------- - * - * stringinfo.c - * - * StringInfo provides an extensible string data type (currently limited to a - * length of 1GB). It can be used to buffer either ordinary C strings - * (null-terminated text) or arbitrary binary data. All storage is allocated - * with palloc() (falling back to malloc in frontend code). - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/common/stringinfo.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND - -#include "postgres.h" -#error #include "utils/memutils.h" - -#else - -#include "postgres_fe.h" - -/* It's possible we could use a different value for this in frontend code */ -#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ - -#endif - -#include "lib/stringinfo.h" - - -/* - * makeStringInfo - * - * Create an empty 'StringInfoData' & return a pointer to it. - */ -StringInfo -makeStringInfo(void) -{ - StringInfo res; - - res = (StringInfo) palloc(sizeof(StringInfoData)); - - initStringInfo(res); - - return res; -} - -/* - * initStringInfo - * - * Initialize a StringInfoData struct (with previously undefined contents) - * to describe an empty string. - */ -void -initStringInfo(StringInfo str) -{ - int size = 1024; /* initial default buffer size */ - - str->data = (char *) palloc(size); - str->maxlen = size; - resetStringInfo(str); -} - -/* - * resetStringInfo - * - * Reset the StringInfo: the data buffer remains valid, but its - * previous content, if any, is cleared. - */ -void -resetStringInfo(StringInfo str) -{ - str->data[0] = '\0'; - str->len = 0; - str->cursor = 0; -} - -/* - * appendStringInfo - * - * Format text data under the control of fmt (an sprintf-style format string) - * and append it to whatever is already in str. More space is allocated - * to str if necessary. This is sort of like a combination of sprintf and - * strcat. - */ -void -appendStringInfo(StringInfo str, const char *fmt,...) -{ - int save_errno = errno; - - for (;;) - { - va_list args; - int needed; - - /* Try to format the data. */ - errno = save_errno; - va_start(args, fmt); - needed = appendStringInfoVA(str, fmt, args); - va_end(args); - - if (needed == 0) - break; /* success */ - - /* Increase the buffer size and try again. */ - enlargeStringInfo(str, needed); - } -} - -/* - * appendStringInfoVA - * - * Attempt to format text data under the control of fmt (an sprintf-style - * format string) and append it to whatever is already in str. If successful - * return zero; if not (because there's not enough space), return an estimate - * of the space needed, without modifying str. Typically the caller should - * pass the return value to enlargeStringInfo() before trying again; see - * appendStringInfo for standard usage pattern. - * - * Caution: callers must be sure to preserve their entry-time errno - * when looping, in case the fmt contains "%m". - * - * XXX This API is ugly, but there seems no alternative given the C spec's - * restrictions on what can portably be done with va_list arguments: you have - * to redo va_start before you can rescan the argument list, and we can't do - * that from here. - */ -int -appendStringInfoVA(StringInfo str, const char *fmt, va_list args) -{ - int avail; - size_t nprinted; - - Assert(str != NULL); - - /* - * If there's hardly any space, don't bother trying, just fail to make the - * caller enlarge the buffer first. We have to guess at how much to - * enlarge, since we're skipping the formatting work. - */ - avail = str->maxlen - str->len; - if (avail < 16) - return 32; - - nprinted = pvsnprintf(str->data + str->len, (size_t) avail, fmt, args); - - if (nprinted < (size_t) avail) - { - /* Success. Note nprinted does not include trailing null. */ - str->len += (int) nprinted; - return 0; - } - - /* Restore the trailing null so that str is unmodified. */ - str->data[str->len] = '\0'; - - /* - * Return pvsnprintf's estimate of the space needed. (Although this is - * given as a size_t, we know it will fit in int because it's not more - * than MaxAllocSize.) - */ - return (int) nprinted; -} - -/* - * appendStringInfoString - * - * Append a null-terminated string to str. - * Like appendStringInfo(str, "%s", s) but faster. - */ -void -appendStringInfoString(StringInfo str, const char *s) -{ - appendBinaryStringInfo(str, s, strlen(s)); -} - -/* - * appendStringInfoChar - * - * Append a single byte to str. - * Like appendStringInfo(str, "%c", ch) but much faster. - */ -void -appendStringInfoChar(StringInfo str, char ch) -{ - /* Make more room if needed */ - if (str->len + 1 >= str->maxlen) - enlargeStringInfo(str, 1); - - /* OK, append the character */ - str->data[str->len] = ch; - str->len++; - str->data[str->len] = '\0'; -} - -/* - * appendStringInfoSpaces - * - * Append the specified number of spaces to a buffer. - */ -void -appendStringInfoSpaces(StringInfo str, int count) -{ - if (count > 0) - { - /* Make more room if needed */ - enlargeStringInfo(str, count); - - /* OK, append the spaces */ - memset(&str->data[str->len], ' ', count); - str->len += count; - str->data[str->len] = '\0'; - } -} - -/* - * appendBinaryStringInfo - * - * Append arbitrary binary data to a StringInfo, allocating more space - * if necessary. Ensures that a trailing null byte is present. - */ -void -appendBinaryStringInfo(StringInfo str, const void *data, int datalen) -{ - Assert(str != NULL); - - /* Make more room if needed */ - enlargeStringInfo(str, datalen); - - /* OK, append the data */ - memcpy(str->data + str->len, data, datalen); - str->len += datalen; - - /* - * Keep a trailing null in place, even though it's probably useless for - * binary data. (Some callers are dealing with text but call this because - * their input isn't null-terminated.) - */ - str->data[str->len] = '\0'; -} - -/* - * appendBinaryStringInfoNT - * - * Append arbitrary binary data to a StringInfo, allocating more space - * if necessary. Does not ensure a trailing null-byte exists. - */ -void -appendBinaryStringInfoNT(StringInfo str, const void *data, int datalen) -{ - Assert(str != NULL); - - /* Make more room if needed */ - enlargeStringInfo(str, datalen); - - /* OK, append the data */ - memcpy(str->data + str->len, data, datalen); - str->len += datalen; -} - -/* - * enlargeStringInfo - * - * Make sure there is enough space for 'needed' more bytes - * ('needed' does not include the terminating null). - * - * External callers usually need not concern themselves with this, since - * all stringinfo.c routines do it automatically. However, if a caller - * knows that a StringInfo will eventually become X bytes large, it - * can save some palloc overhead by enlarging the buffer before starting - * to store data in it. - * - * NB: In the backend, because we use repalloc() to enlarge the buffer, the - * string buffer will remain allocated in the same memory context that was - * current when initStringInfo was called, even if another context is now - * current. This is the desired and indeed critical behavior! - */ -void -enlargeStringInfo(StringInfo str, int needed) -{ - int newlen; - - /* - * Guard against out-of-range "needed" values. Without this, we can get - * an overflow or infinite loop in the following. - */ - if (needed < 0) /* should not happen */ - { -#ifndef FRONTEND - elog(ERROR, "invalid string enlargement request size: %d", needed); -#else - fprintf(stderr, "invalid string enlargement request size: %d\n", needed); - exit(EXIT_FAILURE); -#endif - } - if (((Size) needed) >= (MaxAllocSize - (Size) str->len)) - { -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), - errmsg("out of memory"), - errdetail("Cannot enlarge string buffer containing %d bytes by %d more bytes.", - str->len, needed))); -#else - fprintf(stderr, - _("out of memory\n\nCannot enlarge string buffer containing %d bytes by %d more bytes.\n"), - str->len, needed); - exit(EXIT_FAILURE); -#endif - } - - needed += str->len + 1; /* total space required now */ - - /* Because of the above test, we now have needed <= MaxAllocSize */ - - if (needed <= str->maxlen) - return; /* got enough space already */ - - /* - * We don't want to allocate just a little more space with each append; - * for efficiency, double the buffer size each time it overflows. - * Actually, we might need to more than double it if 'needed' is big... - */ - newlen = 2 * str->maxlen; - while (needed > newlen) - newlen = 2 * newlen; - - /* - * Clamp to MaxAllocSize in case we went past it. Note we are assuming - * here that MaxAllocSize <= INT_MAX/2, else the above loop could - * overflow. We will still have newlen >= needed. - */ - if (newlen > (int) MaxAllocSize) - newlen = (int) MaxAllocSize; - - str->data = (char *) repalloc(str->data, newlen); - - str->maxlen = newlen; -} diff --git a/contrib/libs/libpq/src/common/unicode_norm.c b/contrib/libs/libpq/src/common/unicode_norm.c deleted file mode 100644 index 6b40bdfeb4..0000000000 --- a/contrib/libs/libpq/src/common/unicode_norm.c +++ /dev/null @@ -1,634 +0,0 @@ -/*------------------------------------------------------------------------- - * unicode_norm.c - * Normalize a Unicode string - * - * This implements Unicode normalization, per the documentation at - * https://www.unicode.org/reports/tr15/. - * - * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/unicode_norm.c - * - *------------------------------------------------------------------------- - */ -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "common/unicode_norm.h" -#ifndef FRONTEND -#error #include "common/unicode_norm_hashfunc.h" -#error #include "common/unicode_normprops_table.h" -#include "port/pg_bswap.h" -#else -#include "common/unicode_norm_table.h" -#endif - -#ifndef FRONTEND -#define ALLOC(size) palloc(size) -#define FREE(size) pfree(size) -#else -#define ALLOC(size) malloc(size) -#define FREE(size) free(size) -#endif - -/* Constants for calculations with Hangul characters */ -#define SBASE 0xAC00 /* U+AC00 */ -#define LBASE 0x1100 /* U+1100 */ -#define VBASE 0x1161 /* U+1161 */ -#define TBASE 0x11A7 /* U+11A7 */ -#define LCOUNT 19 -#define VCOUNT 21 -#define TCOUNT 28 -#define NCOUNT VCOUNT * TCOUNT -#define SCOUNT LCOUNT * NCOUNT - -#ifdef FRONTEND -/* comparison routine for bsearch() of decomposition lookup table. */ -static int -conv_compare(const void *p1, const void *p2) -{ - uint32 v1, - v2; - - v1 = *(const uint32 *) p1; - v2 = ((const pg_unicode_decomposition *) p2)->codepoint; - return (v1 > v2) ? 1 : ((v1 == v2) ? 0 : -1); -} - -#endif - -/* - * get_code_entry - * - * Get the entry corresponding to code in the decomposition lookup table. - * The backend version of this code uses a perfect hash function for the - * lookup, while the frontend version uses a binary search. - */ -static const pg_unicode_decomposition * -get_code_entry(pg_wchar code) -{ -#ifndef FRONTEND - int h; - uint32 hashkey; - pg_unicode_decompinfo decompinfo = UnicodeDecompInfo; - - /* - * Compute the hash function. The hash key is the codepoint with the bytes - * in network order. - */ - hashkey = pg_hton32(code); - h = decompinfo.hash(&hashkey); - - /* An out-of-range result implies no match */ - if (h < 0 || h >= decompinfo.num_decomps) - return NULL; - - /* - * Since it's a perfect hash, we need only match to the specific codepoint - * it identifies. - */ - if (code != decompinfo.decomps[h].codepoint) - return NULL; - - /* Success! */ - return &decompinfo.decomps[h]; -#else - return bsearch(&(code), - UnicodeDecompMain, - lengthof(UnicodeDecompMain), - sizeof(pg_unicode_decomposition), - conv_compare); -#endif -} - -/* - * Get the combining class of the given codepoint. - */ -static uint8 -get_canonical_class(pg_wchar code) -{ - const pg_unicode_decomposition *entry = get_code_entry(code); - - /* - * If no entries are found, the character used is either an Hangul - * character or a character with a class of 0 and no decompositions. - */ - if (!entry) - return 0; - else - return entry->comb_class; -} - -/* - * Given a decomposition entry looked up earlier, get the decomposed - * characters. - * - * Note: the returned pointer can point to statically allocated buffer, and - * is only valid until next call to this function! - */ -static const pg_wchar * -get_code_decomposition(const pg_unicode_decomposition *entry, int *dec_size) -{ - static pg_wchar x; - - if (DECOMPOSITION_IS_INLINE(entry)) - { - Assert(DECOMPOSITION_SIZE(entry) == 1); - x = (pg_wchar) entry->dec_index; - *dec_size = 1; - return &x; - } - else - { - *dec_size = DECOMPOSITION_SIZE(entry); - return &UnicodeDecomp_codepoints[entry->dec_index]; - } -} - -/* - * Calculate how many characters a given character will decompose to. - * - * This needs to recurse, if the character decomposes into characters that - * are, in turn, decomposable. - */ -static int -get_decomposed_size(pg_wchar code, bool compat) -{ - const pg_unicode_decomposition *entry; - int size = 0; - int i; - const uint32 *decomp; - int dec_size; - - /* - * Fast path for Hangul characters not stored in tables to save memory as - * decomposition is algorithmic. See - * https://www.unicode.org/reports/tr15/tr15-18.html, annex 10 for details - * on the matter. - */ - if (code >= SBASE && code < SBASE + SCOUNT) - { - uint32 tindex, - sindex; - - sindex = code - SBASE; - tindex = sindex % TCOUNT; - - if (tindex != 0) - return 3; - return 2; - } - - entry = get_code_entry(code); - - /* - * Just count current code if no other decompositions. A NULL entry is - * equivalent to a character with class 0 and no decompositions. - */ - if (entry == NULL || DECOMPOSITION_SIZE(entry) == 0 || - (!compat && DECOMPOSITION_IS_COMPAT(entry))) - return 1; - - /* - * If this entry has other decomposition codes look at them as well. First - * get its decomposition in the list of tables available. - */ - decomp = get_code_decomposition(entry, &dec_size); - for (i = 0; i < dec_size; i++) - { - uint32 lcode = decomp[i]; - - size += get_decomposed_size(lcode, compat); - } - - return size; -} - -/* - * Recompose a set of characters. For hangul characters, the calculation - * is algorithmic. For others, an inverse lookup at the decomposition - * table is necessary. Returns true if a recomposition can be done, and - * false otherwise. - */ -static bool -recompose_code(uint32 start, uint32 code, uint32 *result) -{ - /* - * Handle Hangul characters algorithmically, per the Unicode spec. - * - * Check if two current characters are L and V. - */ - if (start >= LBASE && start < LBASE + LCOUNT && - code >= VBASE && code < VBASE + VCOUNT) - { - /* make syllable of form LV */ - uint32 lindex = start - LBASE; - uint32 vindex = code - VBASE; - - *result = SBASE + (lindex * VCOUNT + vindex) * TCOUNT; - return true; - } - /* Check if two current characters are LV and T */ - else if (start >= SBASE && start < (SBASE + SCOUNT) && - ((start - SBASE) % TCOUNT) == 0 && - code >= TBASE && code < (TBASE + TCOUNT)) - { - /* make syllable of form LVT */ - uint32 tindex = code - TBASE; - - *result = start + tindex; - return true; - } - else - { - const pg_unicode_decomposition *entry; - - /* - * Do an inverse lookup of the decomposition tables to see if anything - * matches. The comparison just needs to be a perfect match on the - * sub-table of size two, because the start character has already been - * recomposed partially. This lookup uses a perfect hash function for - * the backend code. - */ -#ifndef FRONTEND - - int h, - inv_lookup_index; - uint64 hashkey; - pg_unicode_recompinfo recompinfo = UnicodeRecompInfo; - - /* - * Compute the hash function. The hash key is formed by concatenating - * bytes of the two codepoints in network order. See also - * src/common/unicode/generate-unicode_norm_table.pl. - */ - hashkey = pg_hton64(((uint64) start << 32) | (uint64) code); - h = recompinfo.hash(&hashkey); - - /* An out-of-range result implies no match */ - if (h < 0 || h >= recompinfo.num_recomps) - return false; - - inv_lookup_index = recompinfo.inverse_lookup[h]; - entry = &UnicodeDecompMain[inv_lookup_index]; - - if (start == UnicodeDecomp_codepoints[entry->dec_index] && - code == UnicodeDecomp_codepoints[entry->dec_index + 1]) - { - *result = entry->codepoint; - return true; - } - -#else - - int i; - - for (i = 0; i < lengthof(UnicodeDecompMain); i++) - { - entry = &UnicodeDecompMain[i]; - - if (DECOMPOSITION_SIZE(entry) != 2) - continue; - - if (DECOMPOSITION_NO_COMPOSE(entry)) - continue; - - if (start == UnicodeDecomp_codepoints[entry->dec_index] && - code == UnicodeDecomp_codepoints[entry->dec_index + 1]) - { - *result = entry->codepoint; - return true; - } - } -#endif /* !FRONTEND */ - } - - return false; -} - -/* - * Decompose the given code into the array given by caller. The - * decomposition begins at the position given by caller, saving one - * lookup on the decomposition table. The current position needs to be - * updated here to let the caller know from where to continue filling - * in the array result. - */ -static void -decompose_code(pg_wchar code, bool compat, pg_wchar **result, int *current) -{ - const pg_unicode_decomposition *entry; - int i; - const uint32 *decomp; - int dec_size; - - /* - * Fast path for Hangul characters not stored in tables to save memory as - * decomposition is algorithmic. See - * https://www.unicode.org/reports/tr15/tr15-18.html, annex 10 for details - * on the matter. - */ - if (code >= SBASE && code < SBASE + SCOUNT) - { - uint32 l, - v, - tindex, - sindex; - pg_wchar *res = *result; - - sindex = code - SBASE; - l = LBASE + sindex / (VCOUNT * TCOUNT); - v = VBASE + (sindex % (VCOUNT * TCOUNT)) / TCOUNT; - tindex = sindex % TCOUNT; - - res[*current] = l; - (*current)++; - res[*current] = v; - (*current)++; - - if (tindex != 0) - { - res[*current] = TBASE + tindex; - (*current)++; - } - - return; - } - - entry = get_code_entry(code); - - /* - * Just fill in with the current decomposition if there are no - * decomposition codes to recurse to. A NULL entry is equivalent to a - * character with class 0 and no decompositions, so just leave also in - * this case. - */ - if (entry == NULL || DECOMPOSITION_SIZE(entry) == 0 || - (!compat && DECOMPOSITION_IS_COMPAT(entry))) - { - pg_wchar *res = *result; - - res[*current] = code; - (*current)++; - return; - } - - /* - * If this entry has other decomposition codes look at them as well. - */ - decomp = get_code_decomposition(entry, &dec_size); - for (i = 0; i < dec_size; i++) - { - pg_wchar lcode = (pg_wchar) decomp[i]; - - /* Leave if no more decompositions */ - decompose_code(lcode, compat, result, current); - } -} - -/* - * unicode_normalize - Normalize a Unicode string to the specified form. - * - * The input is a 0-terminated array of codepoints. - * - * In frontend, returns a 0-terminated array of codepoints, allocated with - * malloc. Or NULL if we run out of memory. In backend, the returned - * string is palloc'd instead, and OOM is reported with ereport(). - */ -pg_wchar * -unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input) -{ - bool compat = (form == UNICODE_NFKC || form == UNICODE_NFKD); - bool recompose = (form == UNICODE_NFC || form == UNICODE_NFKC); - pg_wchar *decomp_chars; - pg_wchar *recomp_chars; - int decomp_size, - current_size; - int count; - const pg_wchar *p; - - /* variables for recomposition */ - int last_class; - int starter_pos; - int target_pos; - uint32 starter_ch; - - /* First, do character decomposition */ - - /* - * Calculate how many characters long the decomposed version will be. - */ - decomp_size = 0; - for (p = input; *p; p++) - decomp_size += get_decomposed_size(*p, compat); - - decomp_chars = (pg_wchar *) ALLOC((decomp_size + 1) * sizeof(pg_wchar)); - if (decomp_chars == NULL) - return NULL; - - /* - * Now fill in each entry recursively. This needs a second pass on the - * decomposition table. - */ - current_size = 0; - for (p = input; *p; p++) - decompose_code(*p, compat, &decomp_chars, ¤t_size); - decomp_chars[decomp_size] = '\0'; - Assert(decomp_size == current_size); - - /* Leave if there is nothing to decompose */ - if (decomp_size == 0) - return decomp_chars; - - /* - * Now apply canonical ordering. - */ - for (count = 1; count < decomp_size; count++) - { - pg_wchar prev = decomp_chars[count - 1]; - pg_wchar next = decomp_chars[count]; - pg_wchar tmp; - const uint8 prevClass = get_canonical_class(prev); - const uint8 nextClass = get_canonical_class(next); - - /* - * Per Unicode (https://www.unicode.org/reports/tr15/tr15-18.html) - * annex 4, a sequence of two adjacent characters in a string is an - * exchangeable pair if the combining class (from the Unicode - * Character Database) for the first character is greater than the - * combining class for the second, and the second is not a starter. A - * character is a starter if its combining class is 0. - */ - if (prevClass == 0 || nextClass == 0) - continue; - - if (prevClass <= nextClass) - continue; - - /* exchange can happen */ - tmp = decomp_chars[count - 1]; - decomp_chars[count - 1] = decomp_chars[count]; - decomp_chars[count] = tmp; - - /* backtrack to check again */ - if (count > 1) - count -= 2; - } - - if (!recompose) - return decomp_chars; - - /* - * The last phase of NFC and NFKC is the recomposition of the reordered - * Unicode string using combining classes. The recomposed string cannot be - * longer than the decomposed one, so make the allocation of the output - * string based on that assumption. - */ - recomp_chars = (pg_wchar *) ALLOC((decomp_size + 1) * sizeof(pg_wchar)); - if (!recomp_chars) - { - FREE(decomp_chars); - return NULL; - } - - last_class = -1; /* this eliminates a special check */ - starter_pos = 0; - target_pos = 1; - starter_ch = recomp_chars[0] = decomp_chars[0]; - - for (count = 1; count < decomp_size; count++) - { - pg_wchar ch = decomp_chars[count]; - int ch_class = get_canonical_class(ch); - pg_wchar composite; - - if (last_class < ch_class && - recompose_code(starter_ch, ch, &composite)) - { - recomp_chars[starter_pos] = composite; - starter_ch = composite; - } - else if (ch_class == 0) - { - starter_pos = target_pos; - starter_ch = ch; - last_class = -1; - recomp_chars[target_pos++] = ch; - } - else - { - last_class = ch_class; - recomp_chars[target_pos++] = ch; - } - } - recomp_chars[target_pos] = (pg_wchar) '\0'; - - FREE(decomp_chars); - - return recomp_chars; -} - -/* - * Normalization "quick check" algorithm; see - * <http://www.unicode.org/reports/tr15/#Detecting_Normalization_Forms> - */ - -/* We only need this in the backend. */ -#ifndef FRONTEND - -static const pg_unicode_normprops * -qc_hash_lookup(pg_wchar ch, const pg_unicode_norminfo *norminfo) -{ - int h; - uint32 hashkey; - - /* - * Compute the hash function. The hash key is the codepoint with the bytes - * in network order. - */ - hashkey = pg_hton32(ch); - h = norminfo->hash(&hashkey); - - /* An out-of-range result implies no match */ - if (h < 0 || h >= norminfo->num_normprops) - return NULL; - - /* - * Since it's a perfect hash, we need only match to the specific codepoint - * it identifies. - */ - if (ch != norminfo->normprops[h].codepoint) - return NULL; - - /* Success! */ - return &norminfo->normprops[h]; -} - -/* - * Look up the normalization quick check character property - */ -static UnicodeNormalizationQC -qc_is_allowed(UnicodeNormalizationForm form, pg_wchar ch) -{ - const pg_unicode_normprops *found = NULL; - - switch (form) - { - case UNICODE_NFC: - found = qc_hash_lookup(ch, &UnicodeNormInfo_NFC_QC); - break; - case UNICODE_NFKC: - found = qc_hash_lookup(ch, &UnicodeNormInfo_NFKC_QC); - break; - default: - Assert(false); - break; - } - - if (found) - return found->quickcheck; - else - return UNICODE_NORM_QC_YES; -} - -UnicodeNormalizationQC -unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input) -{ - uint8 lastCanonicalClass = 0; - UnicodeNormalizationQC result = UNICODE_NORM_QC_YES; - - /* - * For the "D" forms, we don't run the quickcheck. We don't include the - * lookup tables for those because they are huge, checking for these - * particular forms is less common, and running the slow path is faster - * for the "D" forms than the "C" forms because you don't need to - * recompose, which is slow. - */ - if (form == UNICODE_NFD || form == UNICODE_NFKD) - return UNICODE_NORM_QC_MAYBE; - - for (const pg_wchar *p = input; *p; p++) - { - pg_wchar ch = *p; - uint8 canonicalClass; - UnicodeNormalizationQC check; - - canonicalClass = get_canonical_class(ch); - if (lastCanonicalClass > canonicalClass && canonicalClass != 0) - return UNICODE_NORM_QC_NO; - - check = qc_is_allowed(form, ch); - if (check == UNICODE_NORM_QC_NO) - return UNICODE_NORM_QC_NO; - else if (check == UNICODE_NORM_QC_MAYBE) - result = UNICODE_NORM_QC_MAYBE; - - lastCanonicalClass = canonicalClass; - } - return result; -} - -#endif /* !FRONTEND */ diff --git a/contrib/libs/libpq/src/common/username.c b/contrib/libs/libpq/src/common/username.c deleted file mode 100644 index e8ac4c4977..0000000000 --- a/contrib/libs/libpq/src/common/username.c +++ /dev/null @@ -1,87 +0,0 @@ -/*------------------------------------------------------------------------- - * - * username.c - * get user name - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/common/username.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <pwd.h> -#include <unistd.h> - -#include "common/username.h" - -/* - * Returns the current user name in a static buffer - * On error, returns NULL and sets *errstr to point to a palloc'd message - */ -const char * -get_user_name(char **errstr) -{ -#ifndef WIN32 - struct passwd *pw; - uid_t user_id = geteuid(); - - *errstr = NULL; - - errno = 0; /* clear errno before call */ - pw = getpwuid(user_id); - if (!pw) - { - *errstr = psprintf(_("could not look up effective user ID %ld: %s"), - (long) user_id, - errno ? strerror(errno) : _("user does not exist")); - return NULL; - } - - return pw->pw_name; -#else - /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */ - /* "static" variable remains after function exit */ - static char username[256 + 1]; - DWORD len = sizeof(username); - - *errstr = NULL; - - if (!GetUserName(username, &len)) - { - *errstr = psprintf(_("user name lookup failure: error code %lu"), - GetLastError()); - return NULL; - } - - return username; -#endif -} - - -/* - * Returns the current user name in a static buffer or exits - */ -const char * -get_user_name_or_exit(const char *progname) -{ - const char *user_name; - char *errstr; - - user_name = get_user_name(&errstr); - - if (!user_name) - { - fprintf(stderr, "%s: %s\n", progname, errstr); - exit(1); - } - return user_name; -} diff --git a/contrib/libs/libpq/src/common/wait_error.c b/contrib/libs/libpq/src/common/wait_error.c deleted file mode 100644 index a90b745f07..0000000000 --- a/contrib/libs/libpq/src/common/wait_error.c +++ /dev/null @@ -1,148 +0,0 @@ -/*------------------------------------------------------------------------- - * - * wait_error.c - * Convert a wait/waitpid(2) result code to a human-readable string - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/common/wait_error.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <signal.h> -#include <sys/wait.h> - -/* - * Return a human-readable string explaining the reason a child process - * terminated. The argument is a return code returned by wait(2) or - * waitpid(2), which also applies to pclose(3) and system(3). The result is a - * translated, palloc'd or malloc'd string. - */ -char * -wait_result_to_str(int exitstatus) -{ - char str[512]; - - /* - * To simplify using this after pclose() and system(), handle status -1 - * first. In that case, there is no wait result but some error indicated - * by errno. - */ - if (exitstatus == -1) - { - snprintf(str, sizeof(str), "%m"); - } - else if (WIFEXITED(exitstatus)) - { - /* - * Give more specific error message for some common exit codes that - * have a special meaning in shells. - */ - switch (WEXITSTATUS(exitstatus)) - { - case 126: - snprintf(str, sizeof(str), _("command not executable")); - break; - - case 127: - snprintf(str, sizeof(str), _("command not found")); - break; - - default: - snprintf(str, sizeof(str), - _("child process exited with exit code %d"), - WEXITSTATUS(exitstatus)); - } - } - else if (WIFSIGNALED(exitstatus)) - { -#if defined(WIN32) - snprintf(str, sizeof(str), - _("child process was terminated by exception 0x%X"), - WTERMSIG(exitstatus)); -#else - snprintf(str, sizeof(str), - _("child process was terminated by signal %d: %s"), - WTERMSIG(exitstatus), pg_strsignal(WTERMSIG(exitstatus))); -#endif - } - else - snprintf(str, sizeof(str), - _("child process exited with unrecognized status %d"), - exitstatus); - - return pstrdup(str); -} - -/* - * Return true if a wait(2) result indicates that the child process - * died due to the specified signal. - * - * The reason this is worth having a wrapper function for is that - * there are two cases: the signal might have been received by our - * immediate child process, or there might've been a shell process - * between us and the child that died. The shell will, per POSIX, - * report the child death using exit code 128 + signal number. - * - * If there is no possibility of an intermediate shell, this function - * need not (and probably should not) be used. - */ -bool -wait_result_is_signal(int exit_status, int signum) -{ - if (WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum) - return true; - if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 128 + signum) - return true; - return false; -} - -/* - * Return true if a wait(2) result indicates that the child process - * died due to any signal. We consider either direct child death - * or a shell report of child process death as matching the condition. - * - * If include_command_not_found is true, also return true for shell - * exit codes indicating "command not found" and the like - * (specifically, exit codes 126 and 127; see above). - */ -bool -wait_result_is_any_signal(int exit_status, bool include_command_not_found) -{ - if (WIFSIGNALED(exit_status)) - return true; - if (WIFEXITED(exit_status) && - WEXITSTATUS(exit_status) > (include_command_not_found ? 125 : 128)) - return true; - return false; -} - -/* - * Return the shell exit code (normally 0 to 255) that corresponds to the - * given wait status. The argument is a wait status as returned by wait(2) - * or waitpid(2), which also applies to pclose(3) and system(3). To support - * the latter two cases, we pass through "-1" unchanged. - */ -int -wait_result_to_exit_code(int exit_status) -{ - if (exit_status == -1) - return -1; /* failure of pclose() or system() */ - if (WIFEXITED(exit_status)) - return WEXITSTATUS(exit_status); - if (WIFSIGNALED(exit_status)) - return 128 + WTERMSIG(exit_status); - /* On many systems, this is unreachable */ - return -1; -} diff --git a/contrib/libs/libpq/src/common/wchar.c b/contrib/libs/libpq/src/common/wchar.c deleted file mode 100644 index fbac11deb4..0000000000 --- a/contrib/libs/libpq/src/common/wchar.c +++ /dev/null @@ -1,2194 +0,0 @@ -/*------------------------------------------------------------------------- - * - * wchar.c - * Functions for working with multibyte characters in various encodings. - * - * Portions Copyright (c) 1998-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/common/wchar.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include "mb/pg_wchar.h" -#include "utils/ascii.h" - - -/* - * Operations on multi-byte encodings are driven by a table of helper - * functions. - * - * To add an encoding support, define mblen(), dsplen(), verifychar() and - * verifystr() for the encoding. For server-encodings, also define mb2wchar() - * and wchar2mb() conversion functions. - * - * These functions generally assume that their input is validly formed. - * The "verifier" functions, further down in the file, have to be more - * paranoid. - * - * We expect that mblen() does not need to examine more than the first byte - * of the character to discover the correct length. GB18030 is an exception - * to that rule, though, as it also looks at second byte. But even that - * behaves in a predictable way, if you only pass the first byte: it will - * treat 4-byte encoded characters as two 2-byte encoded characters, which is - * good enough for all current uses. - * - * Note: for the display output of psql to work properly, the return values - * of the dsplen functions must conform to the Unicode standard. In particular - * the NUL character is zero width and control characters are generally - * width -1. It is recommended that non-ASCII encodings refer their ASCII - * subset to the ASCII routines to ensure consistency. - */ - -/* - * SQL/ASCII - */ -static int -pg_ascii2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - *to++ = *from++; - len--; - cnt++; - } - *to = 0; - return cnt; -} - -static int -pg_ascii_mblen(const unsigned char *s) -{ - return 1; -} - -static int -pg_ascii_dsplen(const unsigned char *s) -{ - if (*s == '\0') - return 0; - if (*s < 0x20 || *s == 0x7f) - return -1; - - return 1; -} - -/* - * EUC - */ -static int -pg_euc2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - if (*from == SS2 && len >= 2) /* JIS X 0201 (so called "1 byte - * KANA") */ - { - from++; - *to = (SS2 << 8) | *from++; - len -= 2; - } - else if (*from == SS3 && len >= 3) /* JIS X 0212 KANJI */ - { - from++; - *to = (SS3 << 16) | (*from++ << 8); - *to |= *from++; - len -= 3; - } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* JIS X 0208 KANJI */ - { - *to = *from++ << 8; - *to |= *from++; - len -= 2; - } - else /* must be ASCII */ - { - *to = *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - -static inline int -pg_euc_mblen(const unsigned char *s) -{ - int len; - - if (*s == SS2) - len = 2; - else if (*s == SS3) - len = 3; - else if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = 1; - return len; -} - -static inline int -pg_euc_dsplen(const unsigned char *s) -{ - int len; - - if (*s == SS2) - len = 2; - else if (*s == SS3) - len = 2; - else if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = pg_ascii_dsplen(s); - return len; -} - -/* - * EUC_JP - */ -static int -pg_eucjp2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - return pg_euc2wchar_with_len(from, to, len); -} - -static int -pg_eucjp_mblen(const unsigned char *s) -{ - return pg_euc_mblen(s); -} - -static int -pg_eucjp_dsplen(const unsigned char *s) -{ - int len; - - if (*s == SS2) - len = 1; - else if (*s == SS3) - len = 2; - else if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = pg_ascii_dsplen(s); - return len; -} - -/* - * EUC_KR - */ -static int -pg_euckr2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - return pg_euc2wchar_with_len(from, to, len); -} - -static int -pg_euckr_mblen(const unsigned char *s) -{ - return pg_euc_mblen(s); -} - -static int -pg_euckr_dsplen(const unsigned char *s) -{ - return pg_euc_dsplen(s); -} - -/* - * EUC_CN - * - */ -static int -pg_euccn2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - if (*from == SS2 && len >= 3) /* code set 2 (unused?) */ - { - from++; - *to = (SS2 << 16) | (*from++ << 8); - *to |= *from++; - len -= 3; - } - else if (*from == SS3 && len >= 3) /* code set 3 (unused ?) */ - { - from++; - *to = (SS3 << 16) | (*from++ << 8); - *to |= *from++; - len -= 3; - } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 1 */ - { - *to = *from++ << 8; - *to |= *from++; - len -= 2; - } - else - { - *to = *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - -static int -pg_euccn_mblen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = 1; - return len; -} - -static int -pg_euccn_dsplen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = pg_ascii_dsplen(s); - return len; -} - -/* - * EUC_TW - * - */ -static int -pg_euctw2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - if (*from == SS2 && len >= 4) /* code set 2 */ - { - from++; - *to = (((uint32) SS2) << 24) | (*from++ << 16); - *to |= *from++ << 8; - *to |= *from++; - len -= 4; - } - else if (*from == SS3 && len >= 3) /* code set 3 (unused?) */ - { - from++; - *to = (SS3 << 16) | (*from++ << 8); - *to |= *from++; - len -= 3; - } - else if (IS_HIGHBIT_SET(*from) && len >= 2) /* code set 2 */ - { - *to = *from++ << 8; - *to |= *from++; - len -= 2; - } - else - { - *to = *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - -static int -pg_euctw_mblen(const unsigned char *s) -{ - int len; - - if (*s == SS2) - len = 4; - else if (*s == SS3) - len = 3; - else if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = 1; - return len; -} - -static int -pg_euctw_dsplen(const unsigned char *s) -{ - int len; - - if (*s == SS2) - len = 2; - else if (*s == SS3) - len = 2; - else if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = pg_ascii_dsplen(s); - return len; -} - -/* - * Convert pg_wchar to EUC_* encoding. - * caller must allocate enough space for "to", including a trailing zero! - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_wchar2euc_with_len(const pg_wchar *from, unsigned char *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - unsigned char c; - - if ((c = (*from >> 24))) - { - *to++ = c; - *to++ = (*from >> 16) & 0xff; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 4; - } - else if ((c = (*from >> 16))) - { - *to++ = c; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 3; - } - else if ((c = (*from >> 8))) - { - *to++ = c; - *to++ = *from & 0xff; - cnt += 2; - } - else - { - *to++ = *from; - cnt++; - } - from++; - len--; - } - *to = 0; - return cnt; -} - - -/* - * JOHAB - */ -static int -pg_johab_mblen(const unsigned char *s) -{ - return pg_euc_mblen(s); -} - -static int -pg_johab_dsplen(const unsigned char *s) -{ - return pg_euc_dsplen(s); -} - -/* - * convert UTF8 string to pg_wchar (UCS-4) - * caller must allocate enough space for "to", including a trailing zero! - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - uint32 c1, - c2, - c3, - c4; - - while (len > 0 && *from) - { - if ((*from & 0x80) == 0) - { - *to = *from++; - len--; - } - else if ((*from & 0xe0) == 0xc0) - { - if (len < 2) - break; /* drop trailing incomplete char */ - c1 = *from++ & 0x1f; - c2 = *from++ & 0x3f; - *to = (c1 << 6) | c2; - len -= 2; - } - else if ((*from & 0xf0) == 0xe0) - { - if (len < 3) - break; /* drop trailing incomplete char */ - c1 = *from++ & 0x0f; - c2 = *from++ & 0x3f; - c3 = *from++ & 0x3f; - *to = (c1 << 12) | (c2 << 6) | c3; - len -= 3; - } - else if ((*from & 0xf8) == 0xf0) - { - if (len < 4) - break; /* drop trailing incomplete char */ - c1 = *from++ & 0x07; - c2 = *from++ & 0x3f; - c3 = *from++ & 0x3f; - c4 = *from++ & 0x3f; - *to = (c1 << 18) | (c2 << 12) | (c3 << 6) | c4; - len -= 4; - } - else - { - /* treat a bogus char as length 1; not ours to raise error */ - *to = *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - - -/* - * Map a Unicode code point to UTF-8. utf8string must have 4 bytes of - * space allocated. - */ -unsigned char * -unicode_to_utf8(pg_wchar c, unsigned char *utf8string) -{ - if (c <= 0x7F) - { - utf8string[0] = c; - } - else if (c <= 0x7FF) - { - utf8string[0] = 0xC0 | ((c >> 6) & 0x1F); - utf8string[1] = 0x80 | (c & 0x3F); - } - else if (c <= 0xFFFF) - { - utf8string[0] = 0xE0 | ((c >> 12) & 0x0F); - utf8string[1] = 0x80 | ((c >> 6) & 0x3F); - utf8string[2] = 0x80 | (c & 0x3F); - } - else - { - utf8string[0] = 0xF0 | ((c >> 18) & 0x07); - utf8string[1] = 0x80 | ((c >> 12) & 0x3F); - utf8string[2] = 0x80 | ((c >> 6) & 0x3F); - utf8string[3] = 0x80 | (c & 0x3F); - } - - return utf8string; -} - -/* - * Trivial conversion from pg_wchar to UTF-8. - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_wchar2utf_with_len(const pg_wchar *from, unsigned char *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - int char_len; - - unicode_to_utf8(*from, to); - char_len = pg_utf_mblen(to); - cnt += char_len; - to += char_len; - from++; - len--; - } - *to = 0; - return cnt; -} - -/* - * Return the byte length of a UTF8 character pointed to by s - * - * Note: in the current implementation we do not support UTF8 sequences - * of more than 4 bytes; hence do NOT return a value larger than 4. - * We return "1" for any leading byte that is either flat-out illegal or - * indicates a length larger than we support. - * - * pg_utf2wchar_with_len(), utf8_to_unicode(), pg_utf8_islegal(), and perhaps - * other places would need to be fixed to change this. - */ -int -pg_utf_mblen(const unsigned char *s) -{ - int len; - - if ((*s & 0x80) == 0) - len = 1; - else if ((*s & 0xe0) == 0xc0) - len = 2; - else if ((*s & 0xf0) == 0xe0) - len = 3; - else if ((*s & 0xf8) == 0xf0) - len = 4; -#ifdef NOT_USED - else if ((*s & 0xfc) == 0xf8) - len = 5; - else if ((*s & 0xfe) == 0xfc) - len = 6; -#endif - else - len = 1; - return len; -} - -/* - * This is an implementation of wcwidth() and wcswidth() as defined in - * "The Single UNIX Specification, Version 2, The Open Group, 1997" - * <http://www.unix.org/online.html> - * - * Markus Kuhn -- 2001-09-08 -- public domain - * - * customised for PostgreSQL - * - * original available at : http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - */ - -struct mbinterval -{ - unsigned int first; - unsigned int last; -}; - -/* auxiliary function for binary search in interval table */ -static int -mbbisearch(pg_wchar ucs, const struct mbinterval *table, int max) -{ - int min = 0; - int mid; - - if (ucs < table[0].first || ucs > table[max].last) - return 0; - while (max >= min) - { - mid = (min + max) / 2; - if (ucs > table[mid].last) - min = mid + 1; - else if (ucs < table[mid].first) - max = mid - 1; - else - return 1; - } - - return 0; -} - - -/* The following functions define the column width of an ISO 10646 - * character as follows: - * - * - The null character (U+0000) has a column width of 0. - * - * - Other C0/C1 control characters and DEL will lead to a return - * value of -1. - * - * - Non-spacing and enclosing combining characters (general - * category code Mn, Me or Cf in the Unicode database) have a - * column width of 0. - * - * - Spacing characters in the East Asian Wide (W) or East Asian - * FullWidth (F) category as defined in Unicode Technical - * Report #11 have a column width of 2. - * - * - All remaining characters (including all printable - * ISO 8859-1 and WGL4 characters, Unicode control characters, - * etc.) have a column width of 1. - * - * This implementation assumes that wchar_t characters are encoded - * in ISO 10646. - */ - -static int -ucs_wcwidth(pg_wchar ucs) -{ -#include "common/unicode_nonspacing_table.h" -#include "common/unicode_east_asian_fw_table.h" - - /* test for 8-bit control characters */ - if (ucs == 0) - return 0; - - if (ucs < 0x20 || (ucs >= 0x7f && ucs < 0xa0) || ucs > 0x0010ffff) - return -1; - - /* - * binary search in table of non-spacing characters - * - * XXX: In the official Unicode sources, it is possible for a character to - * be described as both non-spacing and wide at the same time. As of - * Unicode 13.0, treating the non-spacing property as the determining - * factor for display width leads to the correct behavior, so do that - * search first. - */ - if (mbbisearch(ucs, nonspacing, - sizeof(nonspacing) / sizeof(struct mbinterval) - 1)) - return 0; - - /* binary search in table of wide characters */ - if (mbbisearch(ucs, east_asian_fw, - sizeof(east_asian_fw) / sizeof(struct mbinterval) - 1)) - return 2; - - return 1; -} - -/* - * Convert a UTF-8 character to a Unicode code point. - * This is a one-character version of pg_utf2wchar_with_len. - * - * No error checks here, c must point to a long-enough string. - */ -pg_wchar -utf8_to_unicode(const unsigned char *c) -{ - if ((*c & 0x80) == 0) - return (pg_wchar) c[0]; - else if ((*c & 0xe0) == 0xc0) - return (pg_wchar) (((c[0] & 0x1f) << 6) | - (c[1] & 0x3f)); - else if ((*c & 0xf0) == 0xe0) - return (pg_wchar) (((c[0] & 0x0f) << 12) | - ((c[1] & 0x3f) << 6) | - (c[2] & 0x3f)); - else if ((*c & 0xf8) == 0xf0) - return (pg_wchar) (((c[0] & 0x07) << 18) | - ((c[1] & 0x3f) << 12) | - ((c[2] & 0x3f) << 6) | - (c[3] & 0x3f)); - else - /* that is an invalid code on purpose */ - return 0xffffffff; -} - -static int -pg_utf_dsplen(const unsigned char *s) -{ - return ucs_wcwidth(utf8_to_unicode(s)); -} - -/* - * convert mule internal code to pg_wchar - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_mule2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - if (IS_LC1(*from) && len >= 2) - { - *to = *from++ << 16; - *to |= *from++; - len -= 2; - } - else if (IS_LCPRV1(*from) && len >= 3) - { - from++; - *to = *from++ << 16; - *to |= *from++; - len -= 3; - } - else if (IS_LC2(*from) && len >= 3) - { - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - len -= 3; - } - else if (IS_LCPRV2(*from) && len >= 4) - { - from++; - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - len -= 4; - } - else - { /* assume ASCII */ - *to = (unsigned char) *from++; - len--; - } - to++; - cnt++; - } - *to = 0; - return cnt; -} - -/* - * convert pg_wchar to mule internal code - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_wchar2mule_with_len(const pg_wchar *from, unsigned char *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - unsigned char lb; - - lb = (*from >> 16) & 0xff; - if (IS_LC1(lb)) - { - *to++ = lb; - *to++ = *from & 0xff; - cnt += 2; - } - else if (IS_LC2(lb)) - { - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV1_A_RANGE(lb)) - { - *to++ = LCPRV1_A; - *to++ = lb; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV1_B_RANGE(lb)) - { - *to++ = LCPRV1_B; - *to++ = lb; - *to++ = *from & 0xff; - cnt += 3; - } - else if (IS_LCPRV2_A_RANGE(lb)) - { - *to++ = LCPRV2_A; - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 4; - } - else if (IS_LCPRV2_B_RANGE(lb)) - { - *to++ = LCPRV2_B; - *to++ = lb; - *to++ = (*from >> 8) & 0xff; - *to++ = *from & 0xff; - cnt += 4; - } - else - { - *to++ = *from & 0xff; - cnt += 1; - } - from++; - len--; - } - *to = 0; - return cnt; -} - -/* exported for direct use by conv.c */ -int -pg_mule_mblen(const unsigned char *s) -{ - int len; - - if (IS_LC1(*s)) - len = 2; - else if (IS_LCPRV1(*s)) - len = 3; - else if (IS_LC2(*s)) - len = 3; - else if (IS_LCPRV2(*s)) - len = 4; - else - len = 1; /* assume ASCII */ - return len; -} - -static int -pg_mule_dsplen(const unsigned char *s) -{ - int len; - - /* - * Note: it's not really appropriate to assume that all multibyte charsets - * are double-wide on screen. But this seems an okay approximation for - * the MULE charsets we currently support. - */ - - if (IS_LC1(*s)) - len = 1; - else if (IS_LCPRV1(*s)) - len = 1; - else if (IS_LC2(*s)) - len = 2; - else if (IS_LCPRV2(*s)) - len = 2; - else - len = 1; /* assume ASCII */ - - return len; -} - -/* - * ISO8859-1 - */ -static int -pg_latin12wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - *to++ = *from++; - len--; - cnt++; - } - *to = 0; - return cnt; -} - -/* - * Trivial conversion from pg_wchar to single byte encoding. Just ignores - * high bits. - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. - */ -static int -pg_wchar2single_with_len(const pg_wchar *from, unsigned char *to, int len) -{ - int cnt = 0; - - while (len > 0 && *from) - { - *to++ = *from++; - len--; - cnt++; - } - *to = 0; - return cnt; -} - -static int -pg_latin1_mblen(const unsigned char *s) -{ - return 1; -} - -static int -pg_latin1_dsplen(const unsigned char *s) -{ - return pg_ascii_dsplen(s); -} - -/* - * SJIS - */ -static int -pg_sjis_mblen(const unsigned char *s) -{ - int len; - - if (*s >= 0xa1 && *s <= 0xdf) - len = 1; /* 1 byte kana? */ - else if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = 1; /* should be ASCII */ - return len; -} - -static int -pg_sjis_dsplen(const unsigned char *s) -{ - int len; - - if (*s >= 0xa1 && *s <= 0xdf) - len = 1; /* 1 byte kana? */ - else if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = pg_ascii_dsplen(s); /* should be ASCII */ - return len; -} - -/* - * Big5 - */ -static int -pg_big5_mblen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = 1; /* should be ASCII */ - return len; -} - -static int -pg_big5_dsplen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = pg_ascii_dsplen(s); /* should be ASCII */ - return len; -} - -/* - * GBK - */ -static int -pg_gbk_mblen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = 1; /* should be ASCII */ - return len; -} - -static int -pg_gbk_dsplen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* kanji? */ - else - len = pg_ascii_dsplen(s); /* should be ASCII */ - return len; -} - -/* - * UHC - */ -static int -pg_uhc_mblen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* 2byte? */ - else - len = 1; /* should be ASCII */ - return len; -} - -static int -pg_uhc_dsplen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; /* 2byte? */ - else - len = pg_ascii_dsplen(s); /* should be ASCII */ - return len; -} - -/* - * GB18030 - * Added by Bill Huang <bhuang@redhat.com>,<bill_huanghb@ybb.ne.jp> - */ - -/* - * Unlike all other mblen() functions, this also looks at the second byte of - * the input. However, if you only pass the first byte of a multi-byte - * string, and \0 as the second byte, this still works in a predictable way: - * a 4-byte character will be reported as two 2-byte characters. That's - * enough for all current uses, as a client-only encoding. It works that - * way, because in any valid 4-byte GB18030-encoded character, the third and - * fourth byte look like a 2-byte encoded character, when looked at - * separately. - */ -static int -pg_gb18030_mblen(const unsigned char *s) -{ - int len; - - if (!IS_HIGHBIT_SET(*s)) - len = 1; /* ASCII */ - else if (*(s + 1) >= 0x30 && *(s + 1) <= 0x39) - len = 4; - else - len = 2; - return len; -} - -static int -pg_gb18030_dsplen(const unsigned char *s) -{ - int len; - - if (IS_HIGHBIT_SET(*s)) - len = 2; - else - len = pg_ascii_dsplen(s); /* ASCII */ - return len; -} - -/* - *------------------------------------------------------------------- - * multibyte sequence validators - * - * The verifychar functions accept "s", a pointer to the first byte of a - * string, and "len", the remaining length of the string. If there is a - * validly encoded character beginning at *s, return its length in bytes; - * else return -1. - * - * The verifystr functions also accept "s", a pointer to a string and "len", - * the length of the string. They verify the whole string, and return the - * number of input bytes (<= len) that are valid. In other words, if the - * whole string is valid, verifystr returns "len", otherwise it returns the - * byte offset of the first invalid character. The verifystr functions must - * test for and reject zeroes in the input. - * - * The verifychar functions can assume that len > 0 and that *s != '\0', but - * they must test for and reject zeroes in any additional bytes of a - * multibyte character. Note that this definition allows the function for a - * single-byte encoding to be just "return 1". - *------------------------------------------------------------------- - */ -static int -pg_ascii_verifychar(const unsigned char *s, int len) -{ - return 1; -} - -static int -pg_ascii_verifystr(const unsigned char *s, int len) -{ - const unsigned char *nullpos = memchr(s, 0, len); - - if (nullpos == NULL) - return len; - else - return nullpos - s; -} - -#define IS_EUC_RANGE_VALID(c) ((c) >= 0xa1 && (c) <= 0xfe) - -static int -pg_eucjp_verifychar(const unsigned char *s, int len) -{ - int l; - unsigned char c1, - c2; - - c1 = *s++; - - switch (c1) - { - case SS2: /* JIS X 0201 */ - l = 2; - if (l > len) - return -1; - c2 = *s++; - if (c2 < 0xa1 || c2 > 0xdf) - return -1; - break; - - case SS3: /* JIS X 0212 */ - l = 3; - if (l > len) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - break; - - default: - if (IS_HIGHBIT_SET(c1)) /* JIS X 0208? */ - { - l = 2; - if (l > len) - return -1; - if (!IS_EUC_RANGE_VALID(c1)) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - } - else - /* must be ASCII */ - { - l = 1; - } - break; - } - - return l; -} - -static int -pg_eucjp_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_eucjp_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_euckr_verifychar(const unsigned char *s, int len) -{ - int l; - unsigned char c1, - c2; - - c1 = *s++; - - if (IS_HIGHBIT_SET(c1)) - { - l = 2; - if (l > len) - return -1; - if (!IS_EUC_RANGE_VALID(c1)) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - } - else - /* must be ASCII */ - { - l = 1; - } - - return l; -} - -static int -pg_euckr_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_euckr_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -/* EUC-CN byte sequences are exactly same as EUC-KR */ -#define pg_euccn_verifychar pg_euckr_verifychar -#define pg_euccn_verifystr pg_euckr_verifystr - -static int -pg_euctw_verifychar(const unsigned char *s, int len) -{ - int l; - unsigned char c1, - c2; - - c1 = *s++; - - switch (c1) - { - case SS2: /* CNS 11643 Plane 1-7 */ - l = 4; - if (l > len) - return -1; - c2 = *s++; - if (c2 < 0xa1 || c2 > 0xa7) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - break; - - case SS3: /* unused */ - return -1; - - default: - if (IS_HIGHBIT_SET(c1)) /* CNS 11643 Plane 1 */ - { - l = 2; - if (l > len) - return -1; - /* no further range check on c1? */ - c2 = *s++; - if (!IS_EUC_RANGE_VALID(c2)) - return -1; - } - else - /* must be ASCII */ - { - l = 1; - } - break; - } - return l; -} - -static int -pg_euctw_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_euctw_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_johab_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - unsigned char c; - - l = mbl = pg_johab_mblen(s); - - if (len < l) - return -1; - - if (!IS_HIGHBIT_SET(*s)) - return mbl; - - while (--l > 0) - { - c = *++s; - if (!IS_EUC_RANGE_VALID(c)) - return -1; - } - return mbl; -} - -static int -pg_johab_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_johab_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_mule_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - unsigned char c; - - l = mbl = pg_mule_mblen(s); - - if (len < l) - return -1; - - while (--l > 0) - { - c = *++s; - if (!IS_HIGHBIT_SET(c)) - return -1; - } - return mbl; -} - -static int -pg_mule_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_mule_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_latin1_verifychar(const unsigned char *s, int len) -{ - return 1; -} - -static int -pg_latin1_verifystr(const unsigned char *s, int len) -{ - const unsigned char *nullpos = memchr(s, 0, len); - - if (nullpos == NULL) - return len; - else - return nullpos - s; -} - -static int -pg_sjis_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - unsigned char c1, - c2; - - l = mbl = pg_sjis_mblen(s); - - if (len < l) - return -1; - - if (l == 1) /* pg_sjis_mblen already verified it */ - return mbl; - - c1 = *s++; - c2 = *s; - if (!ISSJISHEAD(c1) || !ISSJISTAIL(c2)) - return -1; - return mbl; -} - -static int -pg_sjis_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_sjis_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_big5_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - - l = mbl = pg_big5_mblen(s); - - if (len < l) - return -1; - - while (--l > 0) - { - if (*++s == '\0') - return -1; - } - - return mbl; -} - -static int -pg_big5_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_big5_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_gbk_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - - l = mbl = pg_gbk_mblen(s); - - if (len < l) - return -1; - - while (--l > 0) - { - if (*++s == '\0') - return -1; - } - - return mbl; -} - -static int -pg_gbk_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_gbk_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_uhc_verifychar(const unsigned char *s, int len) -{ - int l, - mbl; - - l = mbl = pg_uhc_mblen(s); - - if (len < l) - return -1; - - while (--l > 0) - { - if (*++s == '\0') - return -1; - } - - return mbl; -} - -static int -pg_uhc_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_uhc_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_gb18030_verifychar(const unsigned char *s, int len) -{ - int l; - - if (!IS_HIGHBIT_SET(*s)) - l = 1; /* ASCII */ - else if (len >= 4 && *(s + 1) >= 0x30 && *(s + 1) <= 0x39) - { - /* Should be 4-byte, validate remaining bytes */ - if (*s >= 0x81 && *s <= 0xfe && - *(s + 2) >= 0x81 && *(s + 2) <= 0xfe && - *(s + 3) >= 0x30 && *(s + 3) <= 0x39) - l = 4; - else - l = -1; - } - else if (len >= 2 && *s >= 0x81 && *s <= 0xfe) - { - /* Should be 2-byte, validate */ - if ((*(s + 1) >= 0x40 && *(s + 1) <= 0x7e) || - (*(s + 1) >= 0x80 && *(s + 1) <= 0xfe)) - l = 2; - else - l = -1; - } - else - l = -1; - return l; -} - -static int -pg_gb18030_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_gb18030_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -static int -pg_utf8_verifychar(const unsigned char *s, int len) -{ - int l; - - if ((*s & 0x80) == 0) - { - if (*s == '\0') - return -1; - return 1; - } - else if ((*s & 0xe0) == 0xc0) - l = 2; - else if ((*s & 0xf0) == 0xe0) - l = 3; - else if ((*s & 0xf8) == 0xf0) - l = 4; - else - l = 1; - - if (l > len) - return -1; - - if (!pg_utf8_islegal(s, l)) - return -1; - - return l; -} - -/* - * The fast path of the UTF-8 verifier uses a deterministic finite automaton - * (DFA) for multibyte characters. In a traditional table-driven DFA, the - * input byte and current state are used to compute an index into an array of - * state transitions. Since the address of the next transition is dependent - * on this computation, there is latency in executing the load instruction, - * and the CPU is not kept busy. - * - * Instead, we use a "shift-based" DFA as described by Per Vognsen: - * - * https://gist.github.com/pervognsen/218ea17743e1442e59bb60d29b1aa725 - * - * In a shift-based DFA, the input byte is an index into array of integers - * whose bit pattern encodes the state transitions. To compute the next - * state, we simply right-shift the integer by the current state and apply a - * mask. In this scheme, the address of the transition only depends on the - * input byte, so there is better pipelining. - * - * The naming convention for states and transitions was adopted from a UTF-8 - * to UTF-16/32 transcoder, whose table is reproduced below: - * - * https://github.com/BobSteagall/utf_utils/blob/6b7a465265de2f5fa6133d653df0c9bdd73bbcf8/src/utf_utils.cpp - * - * ILL ASC CR1 CR2 CR3 L2A L3A L3B L3C L4A L4B L4C CLASS / STATE - * ========================================================================== - * err, END, err, err, err, CS1, P3A, CS2, P3B, P4A, CS3, P4B, | BGN/END - * err, err, err, err, err, err, err, err, err, err, err, err, | ERR - * | - * err, err, END, END, END, err, err, err, err, err, err, err, | CS1 - * err, err, CS1, CS1, CS1, err, err, err, err, err, err, err, | CS2 - * err, err, CS2, CS2, CS2, err, err, err, err, err, err, err, | CS3 - * | - * err, err, err, err, CS1, err, err, err, err, err, err, err, | P3A - * err, err, CS1, CS1, err, err, err, err, err, err, err, err, | P3B - * | - * err, err, err, CS2, CS2, err, err, err, err, err, err, err, | P4A - * err, err, CS2, err, err, err, err, err, err, err, err, err, | P4B - * - * In the most straightforward implementation, a shift-based DFA for UTF-8 - * requires 64-bit integers to encode the transitions, but with an SMT solver - * it's possible to find state numbers such that the transitions fit within - * 32-bit integers, as Dougall Johnson demonstrated: - * - * https://gist.github.com/dougallj/166e326de6ad4cf2c94be97a204c025f - * - * This packed representation is the reason for the seemingly odd choice of - * state values below. - */ - -/* Error */ -#define ERR 0 -/* Begin */ -#define BGN 11 -/* Continuation states, expect 1/2/3 continuation bytes */ -#define CS1 16 -#define CS2 1 -#define CS3 5 -/* Partial states, where the first continuation byte has a restricted range */ -#define P3A 6 /* Lead was E0, check for 3-byte overlong */ -#define P3B 20 /* Lead was ED, check for surrogate */ -#define P4A 25 /* Lead was F0, check for 4-byte overlong */ -#define P4B 30 /* Lead was F4, check for too-large */ -/* Begin and End are the same state */ -#define END BGN - -/* the encoded state transitions for the lookup table */ - -/* ASCII */ -#define ASC (END << BGN) -/* 2-byte lead */ -#define L2A (CS1 << BGN) -/* 3-byte lead */ -#define L3A (P3A << BGN) -#define L3B (CS2 << BGN) -#define L3C (P3B << BGN) -/* 4-byte lead */ -#define L4A (P4A << BGN) -#define L4B (CS3 << BGN) -#define L4C (P4B << BGN) -/* continuation byte */ -#define CR1 (END << CS1) | (CS1 << CS2) | (CS2 << CS3) | (CS1 << P3B) | (CS2 << P4B) -#define CR2 (END << CS1) | (CS1 << CS2) | (CS2 << CS3) | (CS1 << P3B) | (CS2 << P4A) -#define CR3 (END << CS1) | (CS1 << CS2) | (CS2 << CS3) | (CS1 << P3A) | (CS2 << P4A) -/* invalid byte */ -#define ILL ERR - -static const uint32 Utf8Transition[256] = -{ - /* ASCII */ - - ILL, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, - - /* continuation bytes */ - - /* 80..8F */ - CR1, CR1, CR1, CR1, CR1, CR1, CR1, CR1, - CR1, CR1, CR1, CR1, CR1, CR1, CR1, CR1, - - /* 90..9F */ - CR2, CR2, CR2, CR2, CR2, CR2, CR2, CR2, - CR2, CR2, CR2, CR2, CR2, CR2, CR2, CR2, - - /* A0..BF */ - CR3, CR3, CR3, CR3, CR3, CR3, CR3, CR3, - CR3, CR3, CR3, CR3, CR3, CR3, CR3, CR3, - CR3, CR3, CR3, CR3, CR3, CR3, CR3, CR3, - CR3, CR3, CR3, CR3, CR3, CR3, CR3, CR3, - - /* leading bytes */ - - /* C0..DF */ - ILL, ILL, L2A, L2A, L2A, L2A, L2A, L2A, - L2A, L2A, L2A, L2A, L2A, L2A, L2A, L2A, - L2A, L2A, L2A, L2A, L2A, L2A, L2A, L2A, - L2A, L2A, L2A, L2A, L2A, L2A, L2A, L2A, - - /* E0..EF */ - L3A, L3B, L3B, L3B, L3B, L3B, L3B, L3B, - L3B, L3B, L3B, L3B, L3B, L3C, L3B, L3B, - - /* F0..FF */ - L4A, L4B, L4B, L4B, L4C, ILL, ILL, ILL, - ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL -}; - -static void -utf8_advance(const unsigned char *s, uint32 *state, int len) -{ - /* Note: We deliberately don't check the state's value here. */ - while (len > 0) - { - /* - * It's important that the mask value is 31: In most instruction sets, - * a shift by a 32-bit operand is understood to be a shift by its mod - * 32, so the compiler should elide the mask operation. - */ - *state = Utf8Transition[*s++] >> (*state & 31); - len--; - } - - *state &= 31; -} - -static int -pg_utf8_verifystr(const unsigned char *s, int len) -{ - const unsigned char *start = s; - const int orig_len = len; - uint32 state = BGN; - -/* - * With a stride of two vector widths, gcc will unroll the loop. Even if - * the compiler can unroll a longer loop, it's not worth it because we - * must fall back to the byte-wise algorithm if we find any non-ASCII. - */ -#define STRIDE_LENGTH (2 * sizeof(Vector8)) - - if (len >= STRIDE_LENGTH) - { - while (len >= STRIDE_LENGTH) - { - /* - * If the chunk is all ASCII, we can skip the full UTF-8 check, - * but we must first check for a non-END state, which means the - * previous chunk ended in the middle of a multibyte sequence. - */ - if (state != END || !is_valid_ascii(s, STRIDE_LENGTH)) - utf8_advance(s, &state, STRIDE_LENGTH); - - s += STRIDE_LENGTH; - len -= STRIDE_LENGTH; - } - - /* The error state persists, so we only need to check for it here. */ - if (state == ERR) - { - /* - * Start over from the beginning with the slow path so we can - * count the valid bytes. - */ - len = orig_len; - s = start; - } - else if (state != END) - { - /* - * The fast path exited in the middle of a multibyte sequence. - * Walk backwards to find the leading byte so that the slow path - * can resume checking from there. We must always backtrack at - * least one byte, since the current byte could be e.g. an ASCII - * byte after a 2-byte lead, which is invalid. - */ - do - { - Assert(s > start); - s--; - len++; - Assert(IS_HIGHBIT_SET(*s)); - } while (pg_utf_mblen(s) <= 1); - } - } - - /* check remaining bytes */ - while (len > 0) - { - int l; - - /* fast path for ASCII-subset characters */ - if (!IS_HIGHBIT_SET(*s)) - { - if (*s == '\0') - break; - l = 1; - } - else - { - l = pg_utf8_verifychar(s, len); - if (l == -1) - break; - } - s += l; - len -= l; - } - - return s - start; -} - -/* - * Check for validity of a single UTF-8 encoded character - * - * This directly implements the rules in RFC3629. The bizarre-looking - * restrictions on the second byte are meant to ensure that there isn't - * more than one encoding of a given Unicode character point; that is, - * you may not use a longer-than-necessary byte sequence with high order - * zero bits to represent a character that would fit in fewer bytes. - * To do otherwise is to create security hazards (eg, create an apparent - * non-ASCII character that decodes to plain ASCII). - * - * length is assumed to have been obtained by pg_utf_mblen(), and the - * caller must have checked that that many bytes are present in the buffer. - */ -bool -pg_utf8_islegal(const unsigned char *source, int length) -{ - unsigned char a; - - switch (length) - { - default: - /* reject lengths 5 and 6 for now */ - return false; - case 4: - a = source[3]; - if (a < 0x80 || a > 0xBF) - return false; - /* FALL THRU */ - case 3: - a = source[2]; - if (a < 0x80 || a > 0xBF) - return false; - /* FALL THRU */ - case 2: - a = source[1]; - switch (*source) - { - case 0xE0: - if (a < 0xA0 || a > 0xBF) - return false; - break; - case 0xED: - if (a < 0x80 || a > 0x9F) - return false; - break; - case 0xF0: - if (a < 0x90 || a > 0xBF) - return false; - break; - case 0xF4: - if (a < 0x80 || a > 0x8F) - return false; - break; - default: - if (a < 0x80 || a > 0xBF) - return false; - break; - } - /* FALL THRU */ - case 1: - a = *source; - if (a >= 0x80 && a < 0xC2) - return false; - if (a > 0xF4) - return false; - break; - } - return true; -} - - -/* - *------------------------------------------------------------------- - * encoding info table - * XXX must be sorted by the same order as enum pg_enc (in mb/pg_wchar.h) - *------------------------------------------------------------------- - */ -const pg_wchar_tbl pg_wchar_table[] = { - {pg_ascii2wchar_with_len, pg_wchar2single_with_len, pg_ascii_mblen, pg_ascii_dsplen, pg_ascii_verifychar, pg_ascii_verifystr, 1}, /* PG_SQL_ASCII */ - {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifychar, pg_eucjp_verifystr, 3}, /* PG_EUC_JP */ - {pg_euccn2wchar_with_len, pg_wchar2euc_with_len, pg_euccn_mblen, pg_euccn_dsplen, pg_euccn_verifychar, pg_euccn_verifystr, 2}, /* PG_EUC_CN */ - {pg_euckr2wchar_with_len, pg_wchar2euc_with_len, pg_euckr_mblen, pg_euckr_dsplen, pg_euckr_verifychar, pg_euckr_verifystr, 3}, /* PG_EUC_KR */ - {pg_euctw2wchar_with_len, pg_wchar2euc_with_len, pg_euctw_mblen, pg_euctw_dsplen, pg_euctw_verifychar, pg_euctw_verifystr, 4}, /* PG_EUC_TW */ - {pg_eucjp2wchar_with_len, pg_wchar2euc_with_len, pg_eucjp_mblen, pg_eucjp_dsplen, pg_eucjp_verifychar, pg_eucjp_verifystr, 3}, /* PG_EUC_JIS_2004 */ - {pg_utf2wchar_with_len, pg_wchar2utf_with_len, pg_utf_mblen, pg_utf_dsplen, pg_utf8_verifychar, pg_utf8_verifystr, 4}, /* PG_UTF8 */ - {pg_mule2wchar_with_len, pg_wchar2mule_with_len, pg_mule_mblen, pg_mule_dsplen, pg_mule_verifychar, pg_mule_verifystr, 4}, /* PG_MULE_INTERNAL */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN1 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN2 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN3 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN4 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN5 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN6 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN7 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN8 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN9 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_LATIN10 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1256 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1258 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN866 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN874 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_KOI8R */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1251 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1252 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* ISO-8859-5 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* ISO-8859-6 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* ISO-8859-7 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* ISO-8859-8 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1250 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1253 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1254 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1255 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_WIN1257 */ - {pg_latin12wchar_with_len, pg_wchar2single_with_len, pg_latin1_mblen, pg_latin1_dsplen, pg_latin1_verifychar, pg_latin1_verifystr, 1}, /* PG_KOI8U */ - {0, 0, pg_sjis_mblen, pg_sjis_dsplen, pg_sjis_verifychar, pg_sjis_verifystr, 2}, /* PG_SJIS */ - {0, 0, pg_big5_mblen, pg_big5_dsplen, pg_big5_verifychar, pg_big5_verifystr, 2}, /* PG_BIG5 */ - {0, 0, pg_gbk_mblen, pg_gbk_dsplen, pg_gbk_verifychar, pg_gbk_verifystr, 2}, /* PG_GBK */ - {0, 0, pg_uhc_mblen, pg_uhc_dsplen, pg_uhc_verifychar, pg_uhc_verifystr, 2}, /* PG_UHC */ - {0, 0, pg_gb18030_mblen, pg_gb18030_dsplen, pg_gb18030_verifychar, pg_gb18030_verifystr, 4}, /* PG_GB18030 */ - {0, 0, pg_johab_mblen, pg_johab_dsplen, pg_johab_verifychar, pg_johab_verifystr, 3}, /* PG_JOHAB */ - {0, 0, pg_sjis_mblen, pg_sjis_dsplen, pg_sjis_verifychar, pg_sjis_verifystr, 2} /* PG_SHIFT_JIS_2004 */ -}; - -/* - * Returns the byte length of a multibyte character. - * - * Caution: when dealing with text that is not certainly valid in the - * specified encoding, the result may exceed the actual remaining - * string length. Callers that are not prepared to deal with that - * should use pg_encoding_mblen_bounded() instead. - */ -int -pg_encoding_mblen(int encoding, const char *mbstr) -{ - return (PG_VALID_ENCODING(encoding) ? - pg_wchar_table[encoding].mblen((const unsigned char *) mbstr) : - pg_wchar_table[PG_SQL_ASCII].mblen((const unsigned char *) mbstr)); -} - -/* - * Returns the byte length of a multibyte character; but not more than - * the distance to end of string. - */ -int -pg_encoding_mblen_bounded(int encoding, const char *mbstr) -{ - return strnlen(mbstr, pg_encoding_mblen(encoding, mbstr)); -} - -/* - * Returns the display length of a multibyte character. - */ -int -pg_encoding_dsplen(int encoding, const char *mbstr) -{ - return (PG_VALID_ENCODING(encoding) ? - pg_wchar_table[encoding].dsplen((const unsigned char *) mbstr) : - pg_wchar_table[PG_SQL_ASCII].dsplen((const unsigned char *) mbstr)); -} - -/* - * Verify the first multibyte character of the given string. - * Return its byte length if good, -1 if bad. (See comments above for - * full details of the mbverifychar API.) - */ -int -pg_encoding_verifymbchar(int encoding, const char *mbstr, int len) -{ - return (PG_VALID_ENCODING(encoding) ? - pg_wchar_table[encoding].mbverifychar((const unsigned char *) mbstr, len) : - pg_wchar_table[PG_SQL_ASCII].mbverifychar((const unsigned char *) mbstr, len)); -} - -/* - * Verify that a string is valid for the given encoding. - * Returns the number of input bytes (<= len) that form a valid string. - * (See comments above for full details of the mbverifystr API.) - */ -int -pg_encoding_verifymbstr(int encoding, const char *mbstr, int len) -{ - return (PG_VALID_ENCODING(encoding) ? - pg_wchar_table[encoding].mbverifystr((const unsigned char *) mbstr, len) : - pg_wchar_table[PG_SQL_ASCII].mbverifystr((const unsigned char *) mbstr, len)); -} - -/* - * fetch maximum length of a given encoding - */ -int -pg_encoding_max_length(int encoding) -{ - Assert(PG_VALID_ENCODING(encoding)); - - return pg_wchar_table[encoding].maxmblen; -} diff --git a/contrib/libs/libpq/src/include/access/rmgr.h b/contrib/libs/libpq/src/include/access/rmgr.h deleted file mode 100644 index 3b6a497e1b..0000000000 --- a/contrib/libs/libpq/src/include/access/rmgr.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * rmgr.h - * - * Resource managers definition - * - * src/include/access/rmgr.h - */ -#ifndef RMGR_H -#define RMGR_H - -typedef uint8 RmgrId; - -/* - * Built-in resource managers - * - * The actual numerical values for each rmgr ID are defined by the order - * of entries in rmgrlist.h. - * - * Note: RM_MAX_ID must fit in RmgrId; widening that type will affect the XLOG - * file format. - */ -#define PG_RMGR(symname,name,redo,desc,identify,startup,cleanup,mask,decode) \ - symname, - -typedef enum RmgrIds -{ -#include "access/rmgrlist.h" - RM_NEXT_ID -} RmgrIds; - -#undef PG_RMGR - -#define RM_MAX_ID UINT8_MAX -#define RM_MAX_BUILTIN_ID (RM_NEXT_ID - 1) -#define RM_MIN_CUSTOM_ID 128 -#define RM_MAX_CUSTOM_ID UINT8_MAX -#define RM_N_IDS (UINT8_MAX + 1) -#define RM_N_BUILTIN_IDS (RM_MAX_BUILTIN_ID + 1) -#define RM_N_CUSTOM_IDS (RM_MAX_CUSTOM_ID - RM_MIN_CUSTOM_ID + 1) - -static inline bool -RmgrIdIsBuiltin(int rmid) -{ - return rmid <= RM_MAX_BUILTIN_ID; -} - -static inline bool -RmgrIdIsCustom(int rmid) -{ - return rmid >= RM_MIN_CUSTOM_ID && rmid <= RM_MAX_CUSTOM_ID; -} - -#define RmgrIdIsValid(rmid) (RmgrIdIsBuiltin((rmid)) || RmgrIdIsCustom((rmid))) - -/* - * RmgrId to use for extensions that require an RmgrId, but are still in - * development and have not reserved their own unique RmgrId yet. See: - * https://wiki.postgresql.org/wiki/CustomWALResourceManagers - */ -#define RM_EXPERIMENTAL_ID 128 - -#endif /* RMGR_H */ diff --git a/contrib/libs/libpq/src/include/access/rmgrlist.h b/contrib/libs/libpq/src/include/access/rmgrlist.h deleted file mode 100644 index 463bcb67c5..0000000000 --- a/contrib/libs/libpq/src/include/access/rmgrlist.h +++ /dev/null @@ -1,49 +0,0 @@ -/*--------------------------------------------------------------------------- - * rmgrlist.h - * - * The resource manager list is kept in its own source file for possible - * use by automatic tools. The exact representation of a rmgr is determined - * by the PG_RMGR macro, which is not defined in this file; it can be - * defined by the caller for special purposes. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/access/rmgrlist.h - *--------------------------------------------------------------------------- - */ - -/* there is deliberately not an #ifndef RMGRLIST_H here */ - -/* - * List of resource manager entries. Note that order of entries defines the - * numerical values of each rmgr's ID, which is stored in WAL records. New - * entries should be added at the end, to avoid changing IDs of existing - * entries. - * - * Changes to this list possibly need an XLOG_PAGE_MAGIC bump. - */ - -/* symbol name, textual name, redo, desc, identify, startup, cleanup, mask, decode */ -PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, xlog_identify, NULL, NULL, NULL, xlog_decode) -PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, xact_identify, NULL, NULL, NULL, xact_decode) -PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, clog_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, dbase_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, tblspc_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_MULTIXACT_ID, "MultiXact", multixact_redo, multixact_desc, multixact_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_RELMAP_ID, "RelMap", relmap_redo, relmap_desc, relmap_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_STANDBY_ID, "Standby", standby_redo, standby_desc, standby_identify, NULL, NULL, NULL, standby_decode) -PG_RMGR(RM_HEAP2_ID, "Heap2", heap2_redo, heap2_desc, heap2_identify, NULL, NULL, heap_mask, heap2_decode) -PG_RMGR(RM_HEAP_ID, "Heap", heap_redo, heap_desc, heap_identify, NULL, NULL, heap_mask, heap_decode) -PG_RMGR(RM_BTREE_ID, "Btree", btree_redo, btree_desc, btree_identify, btree_xlog_startup, btree_xlog_cleanup, btree_mask, NULL) -PG_RMGR(RM_HASH_ID, "Hash", hash_redo, hash_desc, hash_identify, NULL, NULL, hash_mask, NULL) -PG_RMGR(RM_GIN_ID, "Gin", gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup, gin_mask, NULL) -PG_RMGR(RM_GIST_ID, "Gist", gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup, gist_mask, NULL) -PG_RMGR(RM_SEQ_ID, "Sequence", seq_redo, seq_desc, seq_identify, NULL, NULL, seq_mask, NULL) -PG_RMGR(RM_SPGIST_ID, "SPGist", spg_redo, spg_desc, spg_identify, spg_xlog_startup, spg_xlog_cleanup, spg_mask, NULL) -PG_RMGR(RM_BRIN_ID, "BRIN", brin_redo, brin_desc, brin_identify, NULL, NULL, brin_mask, NULL) -PG_RMGR(RM_COMMIT_TS_ID, "CommitTs", commit_ts_redo, commit_ts_desc, commit_ts_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_REPLORIGIN_ID, "ReplicationOrigin", replorigin_redo, replorigin_desc, replorigin_identify, NULL, NULL, NULL, NULL) -PG_RMGR(RM_GENERIC_ID, "Generic", generic_redo, generic_desc, generic_identify, NULL, NULL, generic_mask, NULL) -PG_RMGR(RM_LOGICALMSG_ID, "LogicalMessage", logicalmsg_redo, logicalmsg_desc, logicalmsg_identify, NULL, NULL, NULL, logicalmsg_decode) diff --git a/contrib/libs/libpq/src/include/access/transam.h b/contrib/libs/libpq/src/include/access/transam.h deleted file mode 100644 index f5af6d3055..0000000000 --- a/contrib/libs/libpq/src/include/access/transam.h +++ /dev/null @@ -1,375 +0,0 @@ -/*------------------------------------------------------------------------- - * - * transam.h - * postgres transaction access method support code - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/access/transam.h - * - *------------------------------------------------------------------------- - */ -#ifndef TRANSAM_H -#define TRANSAM_H - -#include "access/xlogdefs.h" - - -/* ---------------- - * Special transaction ID values - * - * BootstrapTransactionId is the XID for "bootstrap" operations, and - * FrozenTransactionId is used for very old tuples. Both should - * always be considered valid. - * - * FirstNormalTransactionId is the first "normal" transaction id. - * Note: if you need to change it, you must change pg_class.h as well. - * ---------------- - */ -#define InvalidTransactionId ((TransactionId) 0) -#define BootstrapTransactionId ((TransactionId) 1) -#define FrozenTransactionId ((TransactionId) 2) -#define FirstNormalTransactionId ((TransactionId) 3) -#define MaxTransactionId ((TransactionId) 0xFFFFFFFF) - -/* ---------------- - * transaction ID manipulation macros - * ---------------- - */ -#define TransactionIdIsValid(xid) ((xid) != InvalidTransactionId) -#define TransactionIdIsNormal(xid) ((xid) >= FirstNormalTransactionId) -#define TransactionIdEquals(id1, id2) ((id1) == (id2)) -#define TransactionIdStore(xid, dest) (*(dest) = (xid)) -#define StoreInvalidTransactionId(dest) (*(dest) = InvalidTransactionId) - -#define EpochFromFullTransactionId(x) ((uint32) ((x).value >> 32)) -#define XidFromFullTransactionId(x) ((uint32) (x).value) -#define U64FromFullTransactionId(x) ((x).value) -#define FullTransactionIdEquals(a, b) ((a).value == (b).value) -#define FullTransactionIdPrecedes(a, b) ((a).value < (b).value) -#define FullTransactionIdPrecedesOrEquals(a, b) ((a).value <= (b).value) -#define FullTransactionIdFollows(a, b) ((a).value > (b).value) -#define FullTransactionIdFollowsOrEquals(a, b) ((a).value >= (b).value) -#define FullTransactionIdIsValid(x) TransactionIdIsValid(XidFromFullTransactionId(x)) -#define InvalidFullTransactionId FullTransactionIdFromEpochAndXid(0, InvalidTransactionId) -#define FirstNormalFullTransactionId FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId) -#define FullTransactionIdIsNormal(x) FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId) - -/* - * A 64 bit value that contains an epoch and a TransactionId. This is - * wrapped in a struct to prevent implicit conversion to/from TransactionId. - * Not all values represent valid normal XIDs. - */ -typedef struct FullTransactionId -{ - uint64 value; -} FullTransactionId; - -static inline FullTransactionId -FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid) -{ - FullTransactionId result; - - result.value = ((uint64) epoch) << 32 | xid; - - return result; -} - -static inline FullTransactionId -FullTransactionIdFromU64(uint64 value) -{ - FullTransactionId result; - - result.value = value; - - return result; -} - -/* advance a transaction ID variable, handling wraparound correctly */ -#define TransactionIdAdvance(dest) \ - do { \ - (dest)++; \ - if ((dest) < FirstNormalTransactionId) \ - (dest) = FirstNormalTransactionId; \ - } while(0) - -/* - * Retreat a FullTransactionId variable, stepping over xids that would appear - * to be special only when viewed as 32bit XIDs. - */ -static inline void -FullTransactionIdRetreat(FullTransactionId *dest) -{ - dest->value--; - - /* - * In contrast to 32bit XIDs don't step over the "actual" special xids. - * For 64bit xids these can't be reached as part of a wraparound as they - * can in the 32bit case. - */ - if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId)) - return; - - /* - * But we do need to step over XIDs that'd appear special only for 32bit - * XIDs. - */ - while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId) - dest->value--; -} - -/* - * Advance a FullTransactionId variable, stepping over xids that would appear - * to be special only when viewed as 32bit XIDs. - */ -static inline void -FullTransactionIdAdvance(FullTransactionId *dest) -{ - dest->value++; - - /* see FullTransactionIdAdvance() */ - if (FullTransactionIdPrecedes(*dest, FirstNormalFullTransactionId)) - return; - - while (XidFromFullTransactionId(*dest) < FirstNormalTransactionId) - dest->value++; -} - -/* back up a transaction ID variable, handling wraparound correctly */ -#define TransactionIdRetreat(dest) \ - do { \ - (dest)--; \ - } while ((dest) < FirstNormalTransactionId) - -/* compare two XIDs already known to be normal; this is a macro for speed */ -#define NormalTransactionIdPrecedes(id1, id2) \ - (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ - (int32) ((id1) - (id2)) < 0) - -/* compare two XIDs already known to be normal; this is a macro for speed */ -#define NormalTransactionIdFollows(id1, id2) \ - (AssertMacro(TransactionIdIsNormal(id1) && TransactionIdIsNormal(id2)), \ - (int32) ((id1) - (id2)) > 0) - -/* ---------- - * Object ID (OID) zero is InvalidOid. - * - * OIDs 1-9999 are reserved for manual assignment (see .dat files in - * src/include/catalog/). Of these, 8000-9999 are reserved for - * development purposes (such as in-progress patches and forks); - * they should not appear in released versions. - * - * OIDs 10000-11999 are reserved for assignment by genbki.pl, for use - * when the .dat files in src/include/catalog/ do not specify an OID - * for a catalog entry that requires one. Note that genbki.pl assigns - * these OIDs independently in each catalog, so they're not guaranteed - * to be globally unique. Furthermore, the bootstrap backend and - * initdb's post-bootstrap processing can also assign OIDs in this range. - * The normal OID-generation logic takes care of any OID conflicts that - * might arise from that. - * - * OIDs 12000-16383 are reserved for unpinned objects created by initdb's - * post-bootstrap processing. initdb forces the OID generator up to - * 12000 as soon as it's made the pinned objects it's responsible for. - * - * OIDs beginning at 16384 are assigned from the OID generator - * during normal multiuser operation. (We force the generator up to - * 16384 as soon as we are in normal operation.) - * - * The choices of 8000, 10000 and 12000 are completely arbitrary, and can be - * moved if we run low on OIDs in any category. Changing the macros below, - * and updating relevant documentation (see bki.sgml and RELEASE_CHANGES), - * should be sufficient to do this. Moving the 16384 boundary between - * initdb-assigned OIDs and user-defined objects would be substantially - * more painful, however, since some user-defined OIDs will appear in - * on-disk data; such a change would probably break pg_upgrade. - * - * NOTE: if the OID generator wraps around, we skip over OIDs 0-16383 - * and resume with 16384. This minimizes the odds of OID conflict, by not - * reassigning OIDs that might have been assigned during initdb. Critically, - * it also ensures that no user-created object will be considered pinned. - * ---------- - */ -#define FirstGenbkiObjectId 10000 -#define FirstUnpinnedObjectId 12000 -#define FirstNormalObjectId 16384 - -/* - * VariableCache is a data structure in shared memory that is used to track - * OID and XID assignment state. For largely historical reasons, there is - * just one struct with different fields that are protected by different - * LWLocks. - * - * Note: xidWrapLimit and oldestXidDB are not "active" values, but are - * used just to generate useful messages when xidWarnLimit or xidStopLimit - * are exceeded. - */ -typedef struct VariableCacheData -{ - /* - * These fields are protected by OidGenLock. - */ - Oid nextOid; /* next OID to assign */ - uint32 oidCount; /* OIDs available before must do XLOG work */ - - /* - * These fields are protected by XidGenLock. - */ - FullTransactionId nextXid; /* next XID to assign */ - - TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ - TransactionId xidVacLimit; /* start forcing autovacuums here */ - TransactionId xidWarnLimit; /* start complaining here */ - TransactionId xidStopLimit; /* refuse to advance nextXid beyond here */ - TransactionId xidWrapLimit; /* where the world ends */ - Oid oldestXidDB; /* database with minimum datfrozenxid */ - - /* - * These fields are protected by CommitTsLock - */ - TransactionId oldestCommitTsXid; - TransactionId newestCommitTsXid; - - /* - * These fields are protected by ProcArrayLock. - */ - FullTransactionId latestCompletedXid; /* newest full XID that has - * committed or aborted */ - - /* - * Number of top-level transactions with xids (i.e. which may have - * modified the database) that completed in some form since the start of - * the server. This currently is solely used to check whether - * GetSnapshotData() needs to recompute the contents of the snapshot, or - * not. There are likely other users of this. Always above 1. - */ - uint64 xactCompletionCount; - - /* - * These fields are protected by XactTruncationLock - */ - TransactionId oldestClogXid; /* oldest it's safe to look up in clog */ - -} VariableCacheData; - -typedef VariableCacheData *VariableCache; - - -/* ---------------- - * extern declarations - * ---------------- - */ - -/* in transam/xact.c */ -extern bool TransactionStartedDuringRecovery(void); - -/* in transam/varsup.c */ -extern PGDLLIMPORT VariableCache ShmemVariableCache; - -/* - * prototypes for functions in transam/transam.c - */ -extern bool TransactionIdDidCommit(TransactionId transactionId); -extern bool TransactionIdDidAbort(TransactionId transactionId); -extern void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids); -extern void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn); -extern void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids); -extern bool TransactionIdPrecedes(TransactionId id1, TransactionId id2); -extern bool TransactionIdPrecedesOrEquals(TransactionId id1, TransactionId id2); -extern bool TransactionIdFollows(TransactionId id1, TransactionId id2); -extern bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2); -extern TransactionId TransactionIdLatest(TransactionId mainxid, - int nxids, const TransactionId *xids); -extern XLogRecPtr TransactionIdGetCommitLSN(TransactionId xid); - -/* in transam/varsup.c */ -extern FullTransactionId GetNewTransactionId(bool isSubXact); -extern void AdvanceNextFullTransactionIdPastXid(TransactionId xid); -extern FullTransactionId ReadNextFullTransactionId(void); -extern void SetTransactionIdLimit(TransactionId oldest_datfrozenxid, - Oid oldest_datoid); -extern void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid); -extern bool ForceTransactionIdLimitUpdate(void); -extern Oid GetNewObjectId(void); -extern void StopGeneratingPinnedObjectIds(void); - -#ifdef USE_ASSERT_CHECKING -extern void AssertTransactionIdInAllowableRange(TransactionId xid); -#else -#define AssertTransactionIdInAllowableRange(xid) ((void)true) -#endif - -/* - * Some frontend programs include this header. For compilers that emit static - * inline functions even when they're unused, that leads to unsatisfied - * external references; hence hide them with #ifndef FRONTEND. - */ -#ifndef FRONTEND - -/* - * For callers that just need the XID part of the next transaction ID. - */ -static inline TransactionId -ReadNextTransactionId(void) -{ - return XidFromFullTransactionId(ReadNextFullTransactionId()); -} - -/* return transaction ID backed up by amount, handling wraparound correctly */ -static inline TransactionId -TransactionIdRetreatedBy(TransactionId xid, uint32 amount) -{ - xid -= amount; - - while (xid < FirstNormalTransactionId) - xid--; - - return xid; -} - -/* return the older of the two IDs */ -static inline TransactionId -TransactionIdOlder(TransactionId a, TransactionId b) -{ - if (!TransactionIdIsValid(a)) - return b; - - if (!TransactionIdIsValid(b)) - return a; - - if (TransactionIdPrecedes(a, b)) - return a; - return b; -} - -/* return the older of the two IDs, assuming they're both normal */ -static inline TransactionId -NormalTransactionIdOlder(TransactionId a, TransactionId b) -{ - Assert(TransactionIdIsNormal(a)); - Assert(TransactionIdIsNormal(b)); - if (NormalTransactionIdPrecedes(a, b)) - return a; - return b; -} - -/* return the newer of the two IDs */ -static inline FullTransactionId -FullTransactionIdNewer(FullTransactionId a, FullTransactionId b) -{ - if (!FullTransactionIdIsValid(a)) - return b; - - if (!FullTransactionIdIsValid(b)) - return a; - - if (FullTransactionIdFollows(a, b)) - return a; - return b; -} - -#endif /* FRONTEND */ - -#endif /* TRANSAM_H */ diff --git a/contrib/libs/libpq/src/include/access/xlog_internal.h b/contrib/libs/libpq/src/include/access/xlog_internal.h deleted file mode 100644 index b0fd338a00..0000000000 --- a/contrib/libs/libpq/src/include/access/xlog_internal.h +++ /dev/null @@ -1,404 +0,0 @@ -/* - * xlog_internal.h - * - * PostgreSQL write-ahead log internal declarations - * - * NOTE: this file is intended to contain declarations useful for - * manipulating the XLOG files directly, but it is not supposed to be - * needed by rmgr routines (redo support for individual record types). - * So the XLogRecord typedef and associated stuff appear in xlogrecord.h. - * - * Note: This file must be includable in both frontend and backend contexts, - * to allow stand-alone tools like pg_receivewal to deal with WAL files. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/access/xlog_internal.h - */ -#ifndef XLOG_INTERNAL_H -#define XLOG_INTERNAL_H - -#include "access/xlogdefs.h" -#include "access/xlogreader.h" -#include "datatype/timestamp.h" -#include "lib/stringinfo.h" -#include "pgtime.h" -#include "storage/block.h" -#include "storage/relfilelocator.h" - - -/* - * Each page of XLOG file has a header like this: - */ -#define XLOG_PAGE_MAGIC 0xD113 /* can be used as WAL version indicator */ - -typedef struct XLogPageHeaderData -{ - uint16 xlp_magic; /* magic value for correctness checks */ - uint16 xlp_info; /* flag bits, see below */ - TimeLineID xlp_tli; /* TimeLineID of first record on page */ - XLogRecPtr xlp_pageaddr; /* XLOG address of this page */ - - /* - * When there is not enough space on current page for whole record, we - * continue on the next page. xlp_rem_len is the number of bytes - * remaining from a previous page; it tracks xl_tot_len in the initial - * header. Note that the continuation data isn't necessarily aligned. - */ - uint32 xlp_rem_len; /* total len of remaining data for record */ -} XLogPageHeaderData; - -#define SizeOfXLogShortPHD MAXALIGN(sizeof(XLogPageHeaderData)) - -typedef XLogPageHeaderData *XLogPageHeader; - -/* - * When the XLP_LONG_HEADER flag is set, we store additional fields in the - * page header. (This is ordinarily done just in the first page of an - * XLOG file.) The additional fields serve to identify the file accurately. - */ -typedef struct XLogLongPageHeaderData -{ - XLogPageHeaderData std; /* standard header fields */ - uint64 xlp_sysid; /* system identifier from pg_control */ - uint32 xlp_seg_size; /* just as a cross-check */ - uint32 xlp_xlog_blcksz; /* just as a cross-check */ -} XLogLongPageHeaderData; - -#define SizeOfXLogLongPHD MAXALIGN(sizeof(XLogLongPageHeaderData)) - -typedef XLogLongPageHeaderData *XLogLongPageHeader; - -/* When record crosses page boundary, set this flag in new page's header */ -#define XLP_FIRST_IS_CONTRECORD 0x0001 -/* This flag indicates a "long" page header */ -#define XLP_LONG_HEADER 0x0002 -/* This flag indicates backup blocks starting in this page are optional */ -#define XLP_BKP_REMOVABLE 0x0004 -/* Replaces a missing contrecord; see CreateOverwriteContrecordRecord */ -#define XLP_FIRST_IS_OVERWRITE_CONTRECORD 0x0008 -/* All defined flag bits in xlp_info (used for validity checking of header) */ -#define XLP_ALL_FLAGS 0x000F - -#define XLogPageHeaderSize(hdr) \ - (((hdr)->xlp_info & XLP_LONG_HEADER) ? SizeOfXLogLongPHD : SizeOfXLogShortPHD) - -/* wal_segment_size can range from 1MB to 1GB */ -#define WalSegMinSize 1024 * 1024 -#define WalSegMaxSize 1024 * 1024 * 1024 -/* default number of min and max wal segments */ -#define DEFAULT_MIN_WAL_SEGS 5 -#define DEFAULT_MAX_WAL_SEGS 64 - -/* check that the given size is a valid wal_segment_size */ -#define IsPowerOf2(x) (x > 0 && ((x) & ((x)-1)) == 0) -#define IsValidWalSegSize(size) \ - (IsPowerOf2(size) && \ - ((size) >= WalSegMinSize && (size) <= WalSegMaxSize)) - -#define XLogSegmentsPerXLogId(wal_segsz_bytes) \ - (UINT64CONST(0x100000000) / (wal_segsz_bytes)) - -#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest) \ - (dest) = (segno) * (wal_segsz_bytes) + (offset) - -#define XLogSegmentOffset(xlogptr, wal_segsz_bytes) \ - ((xlogptr) & ((wal_segsz_bytes) - 1)) - -/* - * Compute a segment number from an XLogRecPtr. - * - * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, - * a boundary byte is taken to be in the previous segment. This is suitable - * for deciding which segment to write given a pointer to a record end, - * for example. - */ -#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes) \ - logSegNo = (xlrp) / (wal_segsz_bytes) - -#define XLByteToPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ - logSegNo = ((xlrp) - 1) / (wal_segsz_bytes) - -/* - * Convert values of GUCs measured in megabytes to equiv. segment count. - * Rounds down. - */ -#define XLogMBVarToSegs(mbvar, wal_segsz_bytes) \ - ((mbvar) / ((wal_segsz_bytes) / (1024 * 1024))) - -/* - * Is an XLogRecPtr within a particular XLOG segment? - * - * For XLByteInSeg, do the computation at face value. For XLByteInPrevSeg, - * a boundary byte is taken to be in the previous segment. - */ -#define XLByteInSeg(xlrp, logSegNo, wal_segsz_bytes) \ - (((xlrp) / (wal_segsz_bytes)) == (logSegNo)) - -#define XLByteInPrevSeg(xlrp, logSegNo, wal_segsz_bytes) \ - ((((xlrp) - 1) / (wal_segsz_bytes)) == (logSegNo)) - -/* Check if an XLogRecPtr value is in a plausible range */ -#define XRecOffIsValid(xlrp) \ - ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD) - -/* - * The XLog directory and control file (relative to $PGDATA) - */ -#define XLOGDIR "pg_wal" -#define XLOG_CONTROL_FILE "global/pg_control" - -/* - * These macros encapsulate knowledge about the exact layout of XLog file - * names, timeline history file names, and archive-status file names. - */ -#define MAXFNAMELEN 64 - -/* Length of XLog file name */ -#define XLOG_FNAME_LEN 24 - -/* - * Generate a WAL segment file name. Do not use this function in a helper - * function allocating the result generated. - */ -static inline void -XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes) -{ - snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, - (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes))); -} - -static inline void -XLogFileNameById(char *fname, TimeLineID tli, uint32 log, uint32 seg) -{ - snprintf(fname, MAXFNAMELEN, "%08X%08X%08X", tli, log, seg); -} - -static inline bool -IsXLogFileName(const char *fname) -{ - return (strlen(fname) == XLOG_FNAME_LEN && \ - strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN); -} - -/* - * XLOG segment with .partial suffix. Used by pg_receivewal and at end of - * archive recovery, when we want to archive a WAL segment but it might not - * be complete yet. - */ -static inline bool -IsPartialXLogFileName(const char *fname) -{ - return (strlen(fname) == XLOG_FNAME_LEN + strlen(".partial") && - strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && - strcmp(fname + XLOG_FNAME_LEN, ".partial") == 0); -} - -static inline void -XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes) -{ - uint32 log; - uint32 seg; - - sscanf(fname, "%08X%08X%08X", tli, &log, &seg); - *logSegNo = (uint64) log * XLogSegmentsPerXLogId(wal_segsz_bytes) + seg; -} - -static inline void -XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes) -{ - snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, - (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes))); -} - -static inline void -TLHistoryFileName(char *fname, TimeLineID tli) -{ - snprintf(fname, MAXFNAMELEN, "%08X.history", tli); -} - -static inline bool -IsTLHistoryFileName(const char *fname) -{ - return (strlen(fname) == 8 + strlen(".history") && - strspn(fname, "0123456789ABCDEF") == 8 && - strcmp(fname + 8, ".history") == 0); -} - -static inline void -TLHistoryFilePath(char *path, TimeLineID tli) -{ - snprintf(path, MAXPGPATH, XLOGDIR "/%08X.history", tli); -} - -static inline void -StatusFilePath(char *path, const char *xlog, const char *suffix) -{ - snprintf(path, MAXPGPATH, XLOGDIR "/archive_status/%s%s", xlog, suffix); -} - -static inline void -BackupHistoryFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes) -{ - snprintf(fname, MAXFNAMELEN, "%08X%08X%08X.%08X.backup", tli, - (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (XLogSegmentOffset(startpoint, wal_segsz_bytes))); -} - -static inline bool -IsBackupHistoryFileName(const char *fname) -{ - return (strlen(fname) > XLOG_FNAME_LEN && - strspn(fname, "0123456789ABCDEF") == XLOG_FNAME_LEN && - strcmp(fname + strlen(fname) - strlen(".backup"), ".backup") == 0); -} - -static inline void -BackupHistoryFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, XLogRecPtr startpoint, int wal_segsz_bytes) -{ - snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X.%08X.backup", tli, - (uint32) (logSegNo / XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (logSegNo % XLogSegmentsPerXLogId(wal_segsz_bytes)), - (uint32) (XLogSegmentOffset((startpoint), wal_segsz_bytes))); -} - -/* - * Information logged when we detect a change in one of the parameters - * important for Hot Standby. - */ -typedef struct xl_parameter_change -{ - int MaxConnections; - int max_worker_processes; - int max_wal_senders; - int max_prepared_xacts; - int max_locks_per_xact; - int wal_level; - bool wal_log_hints; - bool track_commit_timestamp; -} xl_parameter_change; - -/* logs restore point */ -typedef struct xl_restore_point -{ - TimestampTz rp_time; - char rp_name[MAXFNAMELEN]; -} xl_restore_point; - -/* Overwrite of prior contrecord */ -typedef struct xl_overwrite_contrecord -{ - XLogRecPtr overwritten_lsn; - TimestampTz overwrite_time; -} xl_overwrite_contrecord; - -/* End of recovery mark, when we don't do an END_OF_RECOVERY checkpoint */ -typedef struct xl_end_of_recovery -{ - TimestampTz end_time; - TimeLineID ThisTimeLineID; /* new TLI */ - TimeLineID PrevTimeLineID; /* previous TLI we forked off from */ -} xl_end_of_recovery; - -/* - * The functions in xloginsert.c construct a chain of XLogRecData structs - * to represent the final WAL record. - */ -typedef struct XLogRecData -{ - struct XLogRecData *next; /* next struct in chain, or NULL */ - char *data; /* start of rmgr data to include */ - uint32 len; /* length of rmgr data to include */ -} XLogRecData; - -/* - * Recovery target action. - */ -typedef enum -{ - RECOVERY_TARGET_ACTION_PAUSE, - RECOVERY_TARGET_ACTION_PROMOTE, - RECOVERY_TARGET_ACTION_SHUTDOWN -} RecoveryTargetAction; - -struct LogicalDecodingContext; -struct XLogRecordBuffer; - -/* - * Method table for resource managers. - * - * This struct must be kept in sync with the PG_RMGR definition in - * rmgr.c. - * - * rm_identify must return a name for the record based on xl_info (without - * reference to the rmid). For example, XLOG_BTREE_VACUUM would be named - * "VACUUM". rm_desc can then be called to obtain additional detail for the - * record, if available (e.g. the last block). - * - * rm_mask takes as input a page modified by the resource manager and masks - * out bits that shouldn't be flagged by wal_consistency_checking. - * - * RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). If rm_name is - * NULL, the corresponding RmgrTable entry is considered invalid. - */ -typedef struct RmgrData -{ - const char *rm_name; - void (*rm_redo) (XLogReaderState *record); - void (*rm_desc) (StringInfo buf, XLogReaderState *record); - const char *(*rm_identify) (uint8 info); - void (*rm_startup) (void); - void (*rm_cleanup) (void); - void (*rm_mask) (char *pagedata, BlockNumber blkno); - void (*rm_decode) (struct LogicalDecodingContext *ctx, - struct XLogRecordBuffer *buf); -} RmgrData; - -extern PGDLLIMPORT RmgrData RmgrTable[]; -extern void RmgrStartup(void); -extern void RmgrCleanup(void); -extern void RmgrNotFound(RmgrId rmid); -extern void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr); - -#ifndef FRONTEND -static inline bool -RmgrIdExists(RmgrId rmid) -{ - return RmgrTable[rmid].rm_name != NULL; -} - -static inline RmgrData -GetRmgr(RmgrId rmid) -{ - if (unlikely(!RmgrIdExists(rmid))) - RmgrNotFound(rmid); - return RmgrTable[rmid]; -} -#endif - -/* - * Exported to support xlog switching from checkpointer - */ -extern pg_time_t GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN); -extern XLogRecPtr RequestXLogSwitch(bool mark_unimportant); - -extern void GetOldestRestartPoint(XLogRecPtr *oldrecptr, TimeLineID *oldtli); - -extern void XLogRecGetBlockRefInfo(XLogReaderState *record, bool pretty, - bool detailed_format, StringInfo buf, - uint32 *fpi_len); - -/* - * Exported for the functions in timeline.c and xlogarchive.c. Only valid - * in the startup process. - */ -extern PGDLLIMPORT bool ArchiveRecoveryRequested; -extern PGDLLIMPORT bool InArchiveRecovery; -extern PGDLLIMPORT bool StandbyMode; -extern PGDLLIMPORT char *recoveryRestoreCommand; - -#endif /* XLOG_INTERNAL_H */ diff --git a/contrib/libs/libpq/src/include/access/xlogdefs.h b/contrib/libs/libpq/src/include/access/xlogdefs.h deleted file mode 100644 index fe794c7740..0000000000 --- a/contrib/libs/libpq/src/include/access/xlogdefs.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * xlogdefs.h - * - * Postgres write-ahead log manager record pointer and - * timeline number definitions - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/access/xlogdefs.h - */ -#ifndef XLOG_DEFS_H -#define XLOG_DEFS_H - -#include <fcntl.h> /* need open() flags */ - -/* - * Pointer to a location in the XLOG. These pointers are 64 bits wide, - * because we don't want them ever to overflow. - */ -typedef uint64 XLogRecPtr; - -/* - * Zero is used indicate an invalid pointer. Bootstrap skips the first possible - * WAL segment, initializing the first WAL page at WAL segment size, so no XLOG - * record can begin at zero. - */ -#define InvalidXLogRecPtr 0 -#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr) - -/* - * First LSN to use for "fake" LSNs. - * - * Values smaller than this can be used for special per-AM purposes. - */ -#define FirstNormalUnloggedLSN ((XLogRecPtr) 1000) - -/* - * Handy macro for printing XLogRecPtr in conventional format, e.g., - * - * printf("%X/%X", LSN_FORMAT_ARGS(lsn)); - */ -#define LSN_FORMAT_ARGS(lsn) (AssertVariableIsOfTypeMacro((lsn), XLogRecPtr), (uint32) ((lsn) >> 32)), ((uint32) (lsn)) - -/* - * XLogSegNo - physical log file sequence number. - */ -typedef uint64 XLogSegNo; - -/* - * TimeLineID (TLI) - identifies different database histories to prevent - * confusion after restoring a prior state of a database installation. - * TLI does not change in a normal stop/restart of the database (including - * crash-and-recover cases); but we must assign a new TLI after doing - * a recovery to a prior state, a/k/a point-in-time recovery. This makes - * the new WAL logfile sequence we generate distinguishable from the - * sequence that was generated in the previous incarnation. - */ -typedef uint32 TimeLineID; - -/* - * Replication origin id - this is located in this file to avoid having to - * include origin.h in a bunch of xlog related places. - */ -typedef uint16 RepOriginId; - -/* - * This chunk of hackery attempts to determine which file sync methods - * are available on the current platform, and to choose an appropriate - * default method. - * - * Note that we define our own O_DSYNC on Windows, but not O_SYNC. - */ -#if defined(PLATFORM_DEFAULT_SYNC_METHOD) -#define DEFAULT_SYNC_METHOD PLATFORM_DEFAULT_SYNC_METHOD -#elif defined(O_DSYNC) && (!defined(O_SYNC) || O_DSYNC != O_SYNC) -#define DEFAULT_SYNC_METHOD SYNC_METHOD_OPEN_DSYNC -#else -#define DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC -#endif - -#endif /* XLOG_DEFS_H */ diff --git a/contrib/libs/libpq/src/include/access/xlogreader.h b/contrib/libs/libpq/src/include/access/xlogreader.h deleted file mode 100644 index da32c7db77..0000000000 --- a/contrib/libs/libpq/src/include/access/xlogreader.h +++ /dev/null @@ -1,444 +0,0 @@ -/*------------------------------------------------------------------------- - * - * xlogreader.h - * Definitions for the generic XLog reading facility - * - * Portions Copyright (c) 2013-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/access/xlogreader.h - * - * NOTES - * See the definition of the XLogReaderState struct for instructions on - * how to use the XLogReader infrastructure. - * - * The basic idea is to allocate an XLogReaderState via - * XLogReaderAllocate(), position the reader to the first record with - * XLogBeginRead() or XLogFindNextRecord(), and call XLogReadRecord() - * until it returns NULL. - * - * Callers supply a page_read callback if they want to call - * XLogReadRecord or XLogFindNextRecord; it can be passed in as NULL - * otherwise. The WALRead function can be used as a helper to write - * page_read callbacks, but it is not mandatory; callers that use it, - * must supply segment_open callbacks. The segment_close callback - * must always be supplied. - * - * After reading a record with XLogReadRecord(), it's decomposed into - * the per-block and main data parts, and the parts can be accessed - * with the XLogRec* macros and functions. You can also decode a - * record that's already constructed in memory, without reading from - * disk, by calling the DecodeXLogRecord() function. - *------------------------------------------------------------------------- - */ -#ifndef XLOGREADER_H -#define XLOGREADER_H - -#ifndef FRONTEND -#include "access/transam.h" -#endif - -#include "access/xlogrecord.h" -#include "storage/buf.h" - -/* WALOpenSegment represents a WAL segment being read. */ -typedef struct WALOpenSegment -{ - int ws_file; /* segment file descriptor */ - XLogSegNo ws_segno; /* segment number */ - TimeLineID ws_tli; /* timeline ID of the currently open file */ -} WALOpenSegment; - -/* WALSegmentContext carries context information about WAL segments to read */ -typedef struct WALSegmentContext -{ - char ws_dir[MAXPGPATH]; - int ws_segsize; -} WALSegmentContext; - -typedef struct XLogReaderState XLogReaderState; - -/* Function type definitions for various xlogreader interactions */ -typedef int (*XLogPageReadCB) (XLogReaderState *xlogreader, - XLogRecPtr targetPagePtr, - int reqLen, - XLogRecPtr targetRecPtr, - char *readBuf); -typedef void (*WALSegmentOpenCB) (XLogReaderState *xlogreader, - XLogSegNo nextSegNo, - TimeLineID *tli_p); -typedef void (*WALSegmentCloseCB) (XLogReaderState *xlogreader); - -typedef struct XLogReaderRoutine -{ - /* - * Data input callback - * - * This callback shall read at least reqLen valid bytes of the xlog page - * starting at targetPagePtr, and store them in readBuf. The callback - * shall return the number of bytes read (never more than XLOG_BLCKSZ), or - * -1 on failure. The callback shall sleep, if necessary, to wait for the - * requested bytes to become available. The callback will not be invoked - * again for the same page unless more than the returned number of bytes - * are needed. - * - * targetRecPtr is the position of the WAL record we're reading. Usually - * it is equal to targetPagePtr + reqLen, but sometimes xlogreader needs - * to read and verify the page or segment header, before it reads the - * actual WAL record it's interested in. In that case, targetRecPtr can - * be used to determine which timeline to read the page from. - * - * The callback shall set ->seg.ws_tli to the TLI of the file the page was - * read from. - */ - XLogPageReadCB page_read; - - /* - * Callback to open the specified WAL segment for reading. ->seg.ws_file - * shall be set to the file descriptor of the opened segment. In case of - * failure, an error shall be raised by the callback and it shall not - * return. - * - * "nextSegNo" is the number of the segment to be opened. - * - * "tli_p" is an input/output argument. WALRead() uses it to pass the - * timeline in which the new segment should be found, but the callback can - * use it to return the TLI that it actually opened. - */ - WALSegmentOpenCB segment_open; - - /* - * WAL segment close callback. ->seg.ws_file shall be set to a negative - * number. - */ - WALSegmentCloseCB segment_close; -} XLogReaderRoutine; - -#define XL_ROUTINE(...) &(XLogReaderRoutine){__VA_ARGS__} - -typedef struct -{ - /* Is this block ref in use? */ - bool in_use; - - /* Identify the block this refers to */ - RelFileLocator rlocator; - ForkNumber forknum; - BlockNumber blkno; - - /* Prefetching workspace. */ - Buffer prefetch_buffer; - - /* copy of the fork_flags field from the XLogRecordBlockHeader */ - uint8 flags; - - /* Information on full-page image, if any */ - bool has_image; /* has image, even for consistency checking */ - bool apply_image; /* has image that should be restored */ - char *bkp_image; - uint16 hole_offset; - uint16 hole_length; - uint16 bimg_len; - uint8 bimg_info; - - /* Buffer holding the rmgr-specific data associated with this block */ - bool has_data; - char *data; - uint16 data_len; - uint16 data_bufsz; -} DecodedBkpBlock; - -/* - * The decoded contents of a record. This occupies a contiguous region of - * memory, with main_data and blocks[n].data pointing to memory after the - * members declared here. - */ -typedef struct DecodedXLogRecord -{ - /* Private member used for resource management. */ - size_t size; /* total size of decoded record */ - bool oversized; /* outside the regular decode buffer? */ - struct DecodedXLogRecord *next; /* decoded record queue link */ - - /* Public members. */ - XLogRecPtr lsn; /* location */ - XLogRecPtr next_lsn; /* location of next record */ - XLogRecord header; /* header */ - RepOriginId record_origin; - TransactionId toplevel_xid; /* XID of top-level transaction */ - char *main_data; /* record's main data portion */ - uint32 main_data_len; /* main data portion's length */ - int max_block_id; /* highest block_id in use (-1 if none) */ - DecodedBkpBlock blocks[FLEXIBLE_ARRAY_MEMBER]; -} DecodedXLogRecord; - -struct XLogReaderState -{ - /* - * Operational callbacks - */ - XLogReaderRoutine routine; - - /* ---------------------------------------- - * Public parameters - * ---------------------------------------- - */ - - /* - * System identifier of the xlog files we're about to read. Set to zero - * (the default value) if unknown or unimportant. - */ - uint64 system_identifier; - - /* - * Opaque data for callbacks to use. Not used by XLogReader. - */ - void *private_data; - - /* - * Start and end point of last record read. EndRecPtr is also used as the - * position to read next. Calling XLogBeginRead() sets EndRecPtr to the - * starting position and ReadRecPtr to invalid. - * - * Start and end point of last record returned by XLogReadRecord(). These - * are also available as record->lsn and record->next_lsn. - */ - XLogRecPtr ReadRecPtr; /* start of last record read */ - XLogRecPtr EndRecPtr; /* end+1 of last record read */ - - /* - * Set at the end of recovery: the start point of a partial record at the - * end of WAL (InvalidXLogRecPtr if there wasn't one), and the start - * location of its first contrecord that went missing. - */ - XLogRecPtr abortedRecPtr; - XLogRecPtr missingContrecPtr; - /* Set when XLP_FIRST_IS_OVERWRITE_CONTRECORD is found */ - XLogRecPtr overwrittenRecPtr; - - - /* ---------------------------------------- - * Decoded representation of current record - * - * Use XLogRecGet* functions to investigate the record; these fields - * should not be accessed directly. - * ---------------------------------------- - * Start and end point of the last record read and decoded by - * XLogReadRecordInternal(). NextRecPtr is also used as the position to - * decode next. Calling XLogBeginRead() sets NextRecPtr and EndRecPtr to - * the requested starting position. - */ - XLogRecPtr DecodeRecPtr; /* start of last record decoded */ - XLogRecPtr NextRecPtr; /* end+1 of last record decoded */ - XLogRecPtr PrevRecPtr; /* start of previous record decoded */ - - /* Last record returned by XLogReadRecord(). */ - DecodedXLogRecord *record; - - /* ---------------------------------------- - * private/internal state - * ---------------------------------------- - */ - - /* - * Buffer for decoded records. This is a circular buffer, though - * individual records can't be split in the middle, so some space is often - * wasted at the end. Oversized records that don't fit in this space are - * allocated separately. - */ - char *decode_buffer; - size_t decode_buffer_size; - bool free_decode_buffer; /* need to free? */ - char *decode_buffer_head; /* data is read from the head */ - char *decode_buffer_tail; /* new data is written at the tail */ - - /* - * Queue of records that have been decoded. This is a linked list that - * usually consists of consecutive records in decode_buffer, but may also - * contain oversized records allocated with palloc(). - */ - DecodedXLogRecord *decode_queue_head; /* oldest decoded record */ - DecodedXLogRecord *decode_queue_tail; /* newest decoded record */ - - /* - * Buffer for currently read page (XLOG_BLCKSZ bytes, valid up to at least - * readLen bytes) - */ - char *readBuf; - uint32 readLen; - - /* last read XLOG position for data currently in readBuf */ - WALSegmentContext segcxt; - WALOpenSegment seg; - uint32 segoff; - - /* - * beginning of prior page read, and its TLI. Doesn't necessarily - * correspond to what's in readBuf; used for timeline sanity checks. - */ - XLogRecPtr latestPagePtr; - TimeLineID latestPageTLI; - - /* beginning of the WAL record being read. */ - XLogRecPtr currRecPtr; - /* timeline to read it from, 0 if a lookup is required */ - TimeLineID currTLI; - - /* - * Safe point to read to in currTLI if current TLI is historical - * (tliSwitchPoint) or InvalidXLogRecPtr if on current timeline. - * - * Actually set to the start of the segment containing the timeline switch - * that ends currTLI's validity, not the LSN of the switch its self, since - * we can't assume the old segment will be present. - */ - XLogRecPtr currTLIValidUntil; - - /* - * If currTLI is not the most recent known timeline, the next timeline to - * read from when currTLIValidUntil is reached. - */ - TimeLineID nextTLI; - - /* - * Buffer for current ReadRecord result (expandable), used when a record - * crosses a page boundary. - */ - char *readRecordBuf; - uint32 readRecordBufSize; - - /* Buffer to hold error message */ - char *errormsg_buf; - bool errormsg_deferred; - - /* - * Flag to indicate to XLogPageReadCB that it should not block waiting for - * data. - */ - bool nonblocking; -}; - -/* - * Check if XLogNextRecord() has any more queued records or an error to return. - */ -static inline bool -XLogReaderHasQueuedRecordOrError(XLogReaderState *state) -{ - return (state->decode_queue_head != NULL) || state->errormsg_deferred; -} - -/* Get a new XLogReader */ -extern XLogReaderState *XLogReaderAllocate(int wal_segment_size, - const char *waldir, - XLogReaderRoutine *routine, - void *private_data); - -/* Free an XLogReader */ -extern void XLogReaderFree(XLogReaderState *state); - -/* Optionally provide a circular decoding buffer to allow readahead. */ -extern void XLogReaderSetDecodeBuffer(XLogReaderState *state, - void *buffer, - size_t size); - -/* Position the XLogReader to given record */ -extern void XLogBeginRead(XLogReaderState *state, XLogRecPtr RecPtr); -extern XLogRecPtr XLogFindNextRecord(XLogReaderState *state, XLogRecPtr RecPtr); - -/* Return values from XLogPageReadCB. */ -typedef enum XLogPageReadResult -{ - XLREAD_SUCCESS = 0, /* record is successfully read */ - XLREAD_FAIL = -1, /* failed during reading a record */ - XLREAD_WOULDBLOCK = -2 /* nonblocking mode only, no data */ -} XLogPageReadResult; - -/* Read the next XLog record. Returns NULL on end-of-WAL or failure */ -extern struct XLogRecord *XLogReadRecord(XLogReaderState *state, - char **errormsg); - -/* Consume the next record or error. */ -extern DecodedXLogRecord *XLogNextRecord(XLogReaderState *state, - char **errormsg); - -/* Release the previously returned record, if necessary. */ -extern XLogRecPtr XLogReleasePreviousRecord(XLogReaderState *state); - -/* Try to read ahead, if there is data and space. */ -extern DecodedXLogRecord *XLogReadAhead(XLogReaderState *state, - bool nonblocking); - -/* Validate a page */ -extern bool XLogReaderValidatePageHeader(XLogReaderState *state, - XLogRecPtr recptr, char *phdr); - -/* Forget error produced by XLogReaderValidatePageHeader(). */ -extern void XLogReaderResetError(XLogReaderState *state); - -/* - * Error information from WALRead that both backend and frontend caller can - * process. Currently only errors from pg_pread can be reported. - */ -typedef struct WALReadError -{ - int wre_errno; /* errno set by the last pg_pread() */ - int wre_off; /* Offset we tried to read from. */ - int wre_req; /* Bytes requested to be read. */ - int wre_read; /* Bytes read by the last read(). */ - WALOpenSegment wre_seg; /* Segment we tried to read from. */ -} WALReadError; - -extern bool WALRead(XLogReaderState *state, - char *buf, XLogRecPtr startptr, Size count, - TimeLineID tli, WALReadError *errinfo); - -/* Functions for decoding an XLogRecord */ - -extern size_t DecodeXLogRecordRequiredSpace(size_t xl_tot_len); -extern bool DecodeXLogRecord(XLogReaderState *state, - DecodedXLogRecord *decoded, - XLogRecord *record, - XLogRecPtr lsn, - char **errormsg); - -/* - * Macros that provide access to parts of the record most recently returned by - * XLogReadRecord() or XLogNextRecord(). - */ -#define XLogRecGetTotalLen(decoder) ((decoder)->record->header.xl_tot_len) -#define XLogRecGetPrev(decoder) ((decoder)->record->header.xl_prev) -#define XLogRecGetInfo(decoder) ((decoder)->record->header.xl_info) -#define XLogRecGetRmid(decoder) ((decoder)->record->header.xl_rmid) -#define XLogRecGetXid(decoder) ((decoder)->record->header.xl_xid) -#define XLogRecGetOrigin(decoder) ((decoder)->record->record_origin) -#define XLogRecGetTopXid(decoder) ((decoder)->record->toplevel_xid) -#define XLogRecGetData(decoder) ((decoder)->record->main_data) -#define XLogRecGetDataLen(decoder) ((decoder)->record->main_data_len) -#define XLogRecHasAnyBlockRefs(decoder) ((decoder)->record->max_block_id >= 0) -#define XLogRecMaxBlockId(decoder) ((decoder)->record->max_block_id) -#define XLogRecGetBlock(decoder, i) (&(decoder)->record->blocks[(i)]) -#define XLogRecHasBlockRef(decoder, block_id) \ - (((decoder)->record->max_block_id >= (block_id)) && \ - ((decoder)->record->blocks[block_id].in_use)) -#define XLogRecHasBlockImage(decoder, block_id) \ - ((decoder)->record->blocks[block_id].has_image) -#define XLogRecBlockImageApply(decoder, block_id) \ - ((decoder)->record->blocks[block_id].apply_image) -#define XLogRecHasBlockData(decoder, block_id) \ - ((decoder)->record->blocks[block_id].has_data) - -#ifndef FRONTEND -extern FullTransactionId XLogRecGetFullXid(XLogReaderState *record); -#endif - -extern bool RestoreBlockImage(XLogReaderState *record, uint8 block_id, char *page); -extern char *XLogRecGetBlockData(XLogReaderState *record, uint8 block_id, Size *len); -extern void XLogRecGetBlockTag(XLogReaderState *record, uint8 block_id, - RelFileLocator *rlocator, ForkNumber *forknum, - BlockNumber *blknum); -extern bool XLogRecGetBlockTagExtended(XLogReaderState *record, uint8 block_id, - RelFileLocator *rlocator, ForkNumber *forknum, - BlockNumber *blknum, - Buffer *prefetch_buffer); - -#endif /* XLOGREADER_H */ diff --git a/contrib/libs/libpq/src/include/access/xlogrecord.h b/contrib/libs/libpq/src/include/access/xlogrecord.h deleted file mode 100644 index f355e08e1d..0000000000 --- a/contrib/libs/libpq/src/include/access/xlogrecord.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - * xlogrecord.h - * - * Definitions for the WAL record format. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/access/xlogrecord.h - */ -#ifndef XLOGRECORD_H -#define XLOGRECORD_H - -#include "access/rmgr.h" -#include "access/xlogdefs.h" -#include "port/pg_crc32c.h" -#include "storage/block.h" -#include "storage/relfilelocator.h" - -/* - * The overall layout of an XLOG record is: - * Fixed-size header (XLogRecord struct) - * XLogRecordBlockHeader struct - * XLogRecordBlockHeader struct - * ... - * XLogRecordDataHeader[Short|Long] struct - * block data - * block data - * ... - * main data - * - * There can be zero or more XLogRecordBlockHeaders, and 0 or more bytes of - * rmgr-specific data not associated with a block. XLogRecord structs - * always start on MAXALIGN boundaries in the WAL files, but the rest of - * the fields are not aligned. - * - * The XLogRecordBlockHeader, XLogRecordDataHeaderShort and - * XLogRecordDataHeaderLong structs all begin with a single 'id' byte. It's - * used to distinguish between block references, and the main data structs. - */ -typedef struct XLogRecord -{ - uint32 xl_tot_len; /* total len of entire record */ - TransactionId xl_xid; /* xact id */ - XLogRecPtr xl_prev; /* ptr to previous record in log */ - uint8 xl_info; /* flag bits, see below */ - RmgrId xl_rmid; /* resource manager for this record */ - /* 2 bytes of padding here, initialize to zero */ - pg_crc32c xl_crc; /* CRC for this record */ - - /* XLogRecordBlockHeaders and XLogRecordDataHeader follow, no padding */ - -} XLogRecord; - -#define SizeOfXLogRecord (offsetof(XLogRecord, xl_crc) + sizeof(pg_crc32c)) - -/* - * The high 4 bits in xl_info may be used freely by rmgr. The - * XLR_SPECIAL_REL_UPDATE and XLR_CHECK_CONSISTENCY bits can be passed by - * XLogInsert caller. The rest are set internally by XLogInsert. - */ -#define XLR_INFO_MASK 0x0F -#define XLR_RMGR_INFO_MASK 0xF0 - -/* - * XLogReader needs to allocate all the data of a WAL record in a single - * chunk. This means that a single XLogRecord cannot exceed MaxAllocSize - * in length if we ignore any allocation overhead of the XLogReader. - * - * To accommodate some overhead, this value allows for 4M of allocation - * overhead, that should be plenty enough for what - * DecodeXLogRecordRequiredSpace() expects as extra. - */ -#define XLogRecordMaxSize (1020 * 1024 * 1024) - -/* - * If a WAL record modifies any relation files, in ways not covered by the - * usual block references, this flag is set. This is not used for anything - * by PostgreSQL itself, but it allows external tools that read WAL and keep - * track of modified blocks to recognize such special record types. - */ -#define XLR_SPECIAL_REL_UPDATE 0x01 - -/* - * Enforces consistency checks of replayed WAL at recovery. If enabled, - * each record will log a full-page write for each block modified by the - * record and will reuse it afterwards for consistency checks. The caller - * of XLogInsert can use this value if necessary, but if - * wal_consistency_checking is enabled for a rmgr this is set unconditionally. - */ -#define XLR_CHECK_CONSISTENCY 0x02 - -/* - * Header info for block data appended to an XLOG record. - * - * 'data_length' is the length of the rmgr-specific payload data associated - * with this block. It does not include the possible full page image, nor - * XLogRecordBlockHeader struct itself. - * - * Note that we don't attempt to align the XLogRecordBlockHeader struct! - * So, the struct must be copied to aligned local storage before use. - */ -typedef struct XLogRecordBlockHeader -{ - uint8 id; /* block reference ID */ - uint8 fork_flags; /* fork within the relation, and flags */ - uint16 data_length; /* number of payload bytes (not including page - * image) */ - - /* If BKPBLOCK_HAS_IMAGE, an XLogRecordBlockImageHeader struct follows */ - /* If BKPBLOCK_SAME_REL is not set, a RelFileLocator follows */ - /* BlockNumber follows */ -} XLogRecordBlockHeader; - -#define SizeOfXLogRecordBlockHeader (offsetof(XLogRecordBlockHeader, data_length) + sizeof(uint16)) - -/* - * Additional header information when a full-page image is included - * (i.e. when BKPBLOCK_HAS_IMAGE is set). - * - * The XLOG code is aware that PG data pages usually contain an unused "hole" - * in the middle, which contains only zero bytes. Since we know that the - * "hole" is all zeros, we remove it from the stored data (and it's not counted - * in the XLOG record's CRC, either). Hence, the amount of block data actually - * present is (BLCKSZ - <length of "hole" bytes>). - * - * Additionally, when wal_compression is enabled, we will try to compress full - * page images using one of the supported algorithms, after removing the - * "hole". This can reduce the WAL volume, but at some extra cost of CPU spent - * on the compression during WAL logging. In this case, since the "hole" - * length cannot be calculated by subtracting the number of page image bytes - * from BLCKSZ, basically it needs to be stored as an extra information. - * But when no "hole" exists, we can assume that the "hole" length is zero - * and no such an extra information needs to be stored. Note that - * the original version of page image is stored in WAL instead of the - * compressed one if the number of bytes saved by compression is less than - * the length of extra information. Hence, when a page image is successfully - * compressed, the amount of block data actually present is less than - * BLCKSZ - the length of "hole" bytes - the length of extra information. - */ -typedef struct XLogRecordBlockImageHeader -{ - uint16 length; /* number of page image bytes */ - uint16 hole_offset; /* number of bytes before "hole" */ - uint8 bimg_info; /* flag bits, see below */ - - /* - * If BKPIMAGE_HAS_HOLE and BKPIMAGE_COMPRESSED(), an - * XLogRecordBlockCompressHeader struct follows. - */ -} XLogRecordBlockImageHeader; - -#define SizeOfXLogRecordBlockImageHeader \ - (offsetof(XLogRecordBlockImageHeader, bimg_info) + sizeof(uint8)) - -/* Information stored in bimg_info */ -#define BKPIMAGE_HAS_HOLE 0x01 /* page image has "hole" */ -#define BKPIMAGE_APPLY 0x02 /* page image should be restored - * during replay */ -/* compression methods supported */ -#define BKPIMAGE_COMPRESS_PGLZ 0x04 -#define BKPIMAGE_COMPRESS_LZ4 0x08 -#define BKPIMAGE_COMPRESS_ZSTD 0x10 - -#define BKPIMAGE_COMPRESSED(info) \ - ((info & (BKPIMAGE_COMPRESS_PGLZ | BKPIMAGE_COMPRESS_LZ4 | \ - BKPIMAGE_COMPRESS_ZSTD)) != 0) - -/* - * Extra header information used when page image has "hole" and - * is compressed. - */ -typedef struct XLogRecordBlockCompressHeader -{ - uint16 hole_length; /* number of bytes in "hole" */ -} XLogRecordBlockCompressHeader; - -#define SizeOfXLogRecordBlockCompressHeader \ - sizeof(XLogRecordBlockCompressHeader) - -/* - * Maximum size of the header for a block reference. This is used to size a - * temporary buffer for constructing the header. - */ -#define MaxSizeOfXLogRecordBlockHeader \ - (SizeOfXLogRecordBlockHeader + \ - SizeOfXLogRecordBlockImageHeader + \ - SizeOfXLogRecordBlockCompressHeader + \ - sizeof(RelFileLocator) + \ - sizeof(BlockNumber)) - -/* - * The fork number fits in the lower 4 bits in the fork_flags field. The upper - * bits are used for flags. - */ -#define BKPBLOCK_FORK_MASK 0x0F -#define BKPBLOCK_FLAG_MASK 0xF0 -#define BKPBLOCK_HAS_IMAGE 0x10 /* block data is an XLogRecordBlockImage */ -#define BKPBLOCK_HAS_DATA 0x20 -#define BKPBLOCK_WILL_INIT 0x40 /* redo will re-init the page */ -#define BKPBLOCK_SAME_REL 0x80 /* RelFileLocator omitted, same as - * previous */ - -/* - * XLogRecordDataHeaderShort/Long are used for the "main data" portion of - * the record. If the length of the data is less than 256 bytes, the short - * form is used, with a single byte to hold the length. Otherwise the long - * form is used. - * - * (These structs are currently not used in the code, they are here just for - * documentation purposes). - */ -typedef struct XLogRecordDataHeaderShort -{ - uint8 id; /* XLR_BLOCK_ID_DATA_SHORT */ - uint8 data_length; /* number of payload bytes */ -} XLogRecordDataHeaderShort; - -#define SizeOfXLogRecordDataHeaderShort (sizeof(uint8) * 2) - -typedef struct XLogRecordDataHeaderLong -{ - uint8 id; /* XLR_BLOCK_ID_DATA_LONG */ - /* followed by uint32 data_length, unaligned */ -} XLogRecordDataHeaderLong; - -#define SizeOfXLogRecordDataHeaderLong (sizeof(uint8) + sizeof(uint32)) - -/* - * Block IDs used to distinguish different kinds of record fragments. Block - * references are numbered from 0 to XLR_MAX_BLOCK_ID. A rmgr is free to use - * any ID number in that range (although you should stick to small numbers, - * because the WAL machinery is optimized for that case). A few ID - * numbers are reserved to denote the "main" data portion of the record, - * as well as replication-supporting transaction metadata. - * - * The maximum is currently set at 32, quite arbitrarily. Most records only - * need a handful of block references, but there are a few exceptions that - * need more. - */ -#define XLR_MAX_BLOCK_ID 32 - -#define XLR_BLOCK_ID_DATA_SHORT 255 -#define XLR_BLOCK_ID_DATA_LONG 254 -#define XLR_BLOCK_ID_ORIGIN 253 -#define XLR_BLOCK_ID_TOPLEVEL_XID 252 - -#endif /* XLOGRECORD_H */ diff --git a/contrib/libs/libpq/src/include/c.h b/contrib/libs/libpq/src/include/c.h deleted file mode 100644 index ab459d646e..0000000000 --- a/contrib/libs/libpq/src/include/c.h +++ /dev/null @@ -1,1383 +0,0 @@ -/*------------------------------------------------------------------------- - * - * c.h - * Fundamental C definitions. This is included by every .c file in - * PostgreSQL (via either postgres.h or postgres_fe.h, as appropriate). - * - * Note that the definitions here are not intended to be exposed to clients - * of the frontend interface libraries --- so we don't worry much about - * polluting the namespace with lots of stuff... - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/c.h - * - *------------------------------------------------------------------------- - */ -/* - *---------------------------------------------------------------- - * TABLE OF CONTENTS - * - * When adding stuff to this file, please try to put stuff - * into the relevant section, or add new sections as appropriate. - * - * section description - * ------- ------------------------------------------------ - * 0) pg_config.h and standard system headers - * 1) compiler characteristics - * 2) bool, true, false - * 3) standard system types - * 4) IsValid macros for system types - * 5) lengthof, alignment - * 6) assertions - * 7) widely useful macros - * 8) random stuff - * 9) system-specific hacks - * - * NOTE: since this file is included by both frontend and backend modules, - * it's usually wrong to put an "extern" declaration here, unless it's - * ifdef'd so that it's seen in only one case or the other. - * typedefs and macros are the kind of thing that might go here. - * - *---------------------------------------------------------------- - */ -#ifndef C_H -#define C_H - -#include "postgres_ext.h" - -/* Must undef pg_config_ext.h symbols before including pg_config.h */ -#undef PG_INT64_TYPE - -#include "pg_config.h" -#include "pg_config_manual.h" /* must be after pg_config.h */ -#include "pg_config_os.h" /* must be before any system header files */ - -/* System header files that should be available everywhere in Postgres */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stddef.h> -#include <stdarg.h> -#ifdef HAVE_STRINGS_H -#include <strings.h> -#endif -#include <stdint.h> -#include <sys/types.h> -#include <errno.h> -#if defined(WIN32) || defined(__CYGWIN__) -#include <fcntl.h> /* ensure O_BINARY is available */ -#endif -#include <locale.h> -#ifdef ENABLE_NLS -#include <libintl.h> -#endif - - -/* ---------------------------------------------------------------- - * Section 1: compiler characteristics - * - * type prefixes (const, signed, volatile, inline) are handled in pg_config.h. - * ---------------------------------------------------------------- - */ - -/* - * Disable "inline" if PG_FORCE_DISABLE_INLINE is defined. - * This is used to work around compiler bugs and might also be useful for - * investigatory purposes. - */ -#ifdef PG_FORCE_DISABLE_INLINE -#undef inline -#define inline -#endif - -/* - * Attribute macros - * - * GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html - * GCC: https://gcc.gnu.org/onlinedocs/gcc/Type-Attributes.html - * Clang: https://clang.llvm.org/docs/AttributeReference.html - * Sunpro: https://docs.oracle.com/cd/E18659_01/html/821-1384/gjzke.html - * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/function_attributes.html - * XLC: https://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.2/com.ibm.xlc131.aix.doc/language_ref/type_attrib.html - */ - -/* - * For compilers which don't support __has_attribute, we just define - * __has_attribute(x) to 0 so that we can define macros for various - * __attribute__s more easily below. - */ -#ifndef __has_attribute -#define __has_attribute(attribute) 0 -#endif - -/* only GCC supports the unused attribute */ -#ifdef __GNUC__ -#define pg_attribute_unused() __attribute__((unused)) -#else -#define pg_attribute_unused() -#endif - -/* - * pg_nodiscard means the compiler should warn if the result of a function - * call is ignored. The name "nodiscard" is chosen in alignment with - * (possibly future) C and C++ standards. For maximum compatibility, use it - * as a function declaration specifier, so it goes before the return type. - */ -#ifdef __GNUC__ -#define pg_nodiscard __attribute__((warn_unused_result)) -#else -#define pg_nodiscard -#endif - -/* - * Place this macro before functions that should be allowed to make misaligned - * accesses. Think twice before using it on non-x86-specific code! - * Testing can be done with "-fsanitize=alignment -fsanitize-trap=alignment" - * on clang, or "-fsanitize=alignment -fno-sanitize-recover=alignment" on gcc. - */ -#if __clang_major__ >= 7 || __GNUC__ >= 8 -#define pg_attribute_no_sanitize_alignment() __attribute__((no_sanitize("alignment"))) -#else -#define pg_attribute_no_sanitize_alignment() -#endif - -/* - * pg_attribute_nonnull means the compiler should warn if the function is - * called with the listed arguments set to NULL. If no arguments are - * listed, the compiler should warn if any pointer arguments are set to NULL. - */ -#if __has_attribute (nonnull) -#define pg_attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) -#else -#define pg_attribute_nonnull(...) -#endif - -/* - * Append PG_USED_FOR_ASSERTS_ONLY to definitions of variables that are only - * used in assert-enabled builds, to avoid compiler warnings about unused - * variables in assert-disabled builds. - */ -#ifdef USE_ASSERT_CHECKING -#define PG_USED_FOR_ASSERTS_ONLY -#else -#define PG_USED_FOR_ASSERTS_ONLY pg_attribute_unused() -#endif - -/* GCC and XLC support format attributes */ -#if defined(__GNUC__) || defined(__IBMC__) -#define pg_attribute_format_arg(a) __attribute__((format_arg(a))) -#define pg_attribute_printf(f,a) __attribute__((format(PG_PRINTF_ATTRIBUTE, f, a))) -#else -#define pg_attribute_format_arg(a) -#define pg_attribute_printf(f,a) -#endif - -/* GCC, Sunpro and XLC support aligned, packed and noreturn */ -#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__) -#define pg_attribute_aligned(a) __attribute__((aligned(a))) -#define pg_attribute_noreturn() __attribute__((noreturn)) -#define pg_attribute_packed() __attribute__((packed)) -#define HAVE_PG_ATTRIBUTE_NORETURN 1 -#elif defined(_MSC_VER) -/* - * MSVC supports aligned. noreturn is also possible but in MSVC it is - * declared before the definition while pg_attribute_noreturn() macro - * is currently used after the definition. - * - * Packing is also possible but only by wrapping the entire struct definition - * which doesn't fit into our current macro declarations. - */ -#define pg_attribute_aligned(a) __declspec(align(a)) -#define pg_attribute_noreturn() -#else -/* - * NB: aligned and packed are not given default definitions because they - * affect code functionality; they *must* be implemented by the compiler - * if they are to be used. - */ -#define pg_attribute_noreturn() -#endif - -/* - * Use "pg_attribute_always_inline" in place of "inline" for functions that - * we wish to force inlining of, even when the compiler's heuristics would - * choose not to. But, if possible, don't force inlining in unoptimized - * debug builds. - */ -#if (defined(__GNUC__) && __GNUC__ > 3 && defined(__OPTIMIZE__)) || defined(__SUNPRO_C) || defined(__IBMC__) -/* GCC > 3, Sunpro and XLC support always_inline via __attribute__ */ -#define pg_attribute_always_inline __attribute__((always_inline)) inline -#elif defined(_MSC_VER) -/* MSVC has a special keyword for this */ -#define pg_attribute_always_inline __forceinline -#else -/* Otherwise, the best we can do is to say "inline" */ -#define pg_attribute_always_inline inline -#endif - -/* - * Forcing a function not to be inlined can be useful if it's the slow path of - * a performance-critical function, or should be visible in profiles to allow - * for proper cost attribution. Note that unlike the pg_attribute_XXX macros - * above, this should be placed before the function's return type and name. - */ -/* GCC, Sunpro and XLC support noinline via __attribute__ */ -#if (defined(__GNUC__) && __GNUC__ > 2) || defined(__SUNPRO_C) || defined(__IBMC__) -#define pg_noinline __attribute__((noinline)) -/* msvc via declspec */ -#elif defined(_MSC_VER) -#define pg_noinline __declspec(noinline) -#else -#define pg_noinline -#endif - -/* - * For now, just define pg_attribute_cold and pg_attribute_hot to be empty - * macros on minGW 8.1. There appears to be a compiler bug that results in - * compilation failure. At this time, we still have at least one buildfarm - * animal running that compiler, so this should make that green again. It's - * likely this compiler is not popular enough to warrant keeping this code - * around forever, so let's just remove it once the last buildfarm animal - * upgrades. - */ -#if defined(__MINGW64__) && __GNUC__ == 8 && __GNUC_MINOR__ == 1 - -#define pg_attribute_cold -#define pg_attribute_hot - -#else -/* - * Marking certain functions as "hot" or "cold" can be useful to assist the - * compiler in arranging the assembly code in a more efficient way. - */ -#if __has_attribute (cold) -#define pg_attribute_cold __attribute__((cold)) -#else -#define pg_attribute_cold -#endif - -#if __has_attribute (hot) -#define pg_attribute_hot __attribute__((hot)) -#else -#define pg_attribute_hot -#endif - -#endif /* defined(__MINGW64__) && __GNUC__ == 8 && - * __GNUC_MINOR__ == 1 */ -/* - * Mark a point as unreachable in a portable fashion. This should preferably - * be something that the compiler understands, to aid code generation. - * In assert-enabled builds, we prefer abort() for debugging reasons. - */ -#if defined(HAVE__BUILTIN_UNREACHABLE) && !defined(USE_ASSERT_CHECKING) -#define pg_unreachable() __builtin_unreachable() -#elif defined(_MSC_VER) && !defined(USE_ASSERT_CHECKING) -#define pg_unreachable() __assume(0) -#else -#define pg_unreachable() abort() -#endif - -/* - * Hints to the compiler about the likelihood of a branch. Both likely() and - * unlikely() return the boolean value of the contained expression. - * - * These should only be used sparingly, in very hot code paths. It's very easy - * to mis-estimate likelihoods. - */ -#if __GNUC__ >= 3 -#define likely(x) __builtin_expect((x) != 0, 1) -#define unlikely(x) __builtin_expect((x) != 0, 0) -#else -#define likely(x) ((x) != 0) -#define unlikely(x) ((x) != 0) -#endif - -/* - * CppAsString - * Convert the argument to a string, using the C preprocessor. - * CppAsString2 - * Convert the argument to a string, after one round of macro expansion. - * CppConcat - * Concatenate two arguments together, using the C preprocessor. - * - * Note: There used to be support here for pre-ANSI C compilers that didn't - * support # and ##. Nowadays, these macros are just for clarity and/or - * backward compatibility with existing PostgreSQL code. - */ -#define CppAsString(identifier) #identifier -#define CppAsString2(x) CppAsString(x) -#define CppConcat(x, y) x##y - -/* - * VA_ARGS_NARGS - * Returns the number of macro arguments it is passed. - * - * An empty argument still counts as an argument, so effectively, this is - * "one more than the number of commas in the argument list". - * - * This works for up to 63 arguments. Internally, VA_ARGS_NARGS_() is passed - * 64+N arguments, and the C99 standard only requires macros to allow up to - * 127 arguments, so we can't portably go higher. The implementation is - * pretty trivial: VA_ARGS_NARGS_() returns its 64th argument, and we set up - * the call so that that is the appropriate one of the list of constants. - * This idea is due to Laurent Deniau. - * - * MSVC has an implementation of __VA_ARGS__ that doesn't conform to the - * standard unless you use the /Zc:preprocessor compiler flag, but that - * isn't available before Visual Studio 2019. For now, use a different - * definition that also works on older compilers. - */ -#ifdef _MSC_VER -#define EXPAND(args) args -#define VA_ARGS_NARGS(...) \ - VA_ARGS_NARGS_ EXPAND((__VA_ARGS__, \ - 63,62,61,60, \ - 59,58,57,56,55,54,53,52,51,50, \ - 49,48,47,46,45,44,43,42,41,40, \ - 39,38,37,36,35,34,33,32,31,30, \ - 29,28,27,26,25,24,23,22,21,20, \ - 19,18,17,16,15,14,13,12,11,10, \ - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) -#else - -#define VA_ARGS_NARGS(...) \ - VA_ARGS_NARGS_(__VA_ARGS__, \ - 63,62,61,60, \ - 59,58,57,56,55,54,53,52,51,50, \ - 49,48,47,46,45,44,43,42,41,40, \ - 39,38,37,36,35,34,33,32,31,30, \ - 29,28,27,26,25,24,23,22,21,20, \ - 19,18,17,16,15,14,13,12,11,10, \ - 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) -#endif - -#define VA_ARGS_NARGS_( \ - _01,_02,_03,_04,_05,_06,_07,_08,_09,_10, \ - _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ - _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ - _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ - _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ - _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ - _61,_62,_63, N, ...) \ - (N) - -/* - * Generic function pointer. This can be used in the rare cases where it's - * necessary to cast a function pointer to a seemingly incompatible function - * pointer type while avoiding gcc's -Wcast-function-type warnings. - */ -typedef void (*pg_funcptr_t) (void); - -/* - * We require C99, hence the compiler should understand flexible array - * members. However, for documentation purposes we still consider it to be - * project style to write "field[FLEXIBLE_ARRAY_MEMBER]" not just "field[]". - * When computing the size of such an object, use "offsetof(struct s, f)" - * for portability. Don't use "offsetof(struct s, f[0])", as this doesn't - * work with MSVC and with C++ compilers. - */ -#define FLEXIBLE_ARRAY_MEMBER /* empty */ - -/* - * Does the compiler support #pragma GCC system_header? We optionally use it - * to avoid warnings that we can't fix (e.g. in the perl headers). - * See https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html - * - * Headers for which we do not want to show compiler warnings can, - * conditionally, use #pragma GCC system_header to avoid warnings. Obviously - * this should only be used for external headers over which we do not have - * control. - * - * Support for the pragma is tested here, instead of during configure, as gcc - * also warns about the pragma being used in a .c file. It's surprisingly hard - * to get autoconf to use .h as the file-ending. Looks like gcc has - * implemented the pragma since the 2000, so this test should suffice. - * - * - * Alternatively, we could add the include paths for problematic headers with - * -isystem, but that is a larger hammer and is harder to search for. - * - * A more granular alternative would be to use #pragma GCC diagnostic - * push/ignored/pop, but gcc warns about unknown warnings being ignored, so - * every to-be-ignored-temporarily compiler warning would require its own - * pg_config.h symbol and #ifdef. - */ -#ifdef __GNUC__ -#define HAVE_PRAGMA_GCC_SYSTEM_HEADER 1 -#endif - - -/* ---------------------------------------------------------------- - * Section 2: bool, true, false - * ---------------------------------------------------------------- - */ - -/* - * bool - * Boolean value, either true or false. - * - * We use stdbool.h if available and its bool has size 1. That's useful for - * better compiler and debugger output and for compatibility with third-party - * libraries. But PostgreSQL currently cannot deal with bool of other sizes; - * there are static assertions around the code to prevent that. - * - * For C++ compilers, we assume the compiler has a compatible built-in - * definition of bool. - * - * See also the version of this code in src/interfaces/ecpg/include/ecpglib.h. - */ - -#ifndef __cplusplus - -#ifdef PG_USE_STDBOOL -#include <stdbool.h> -#else - -#ifndef bool -typedef unsigned char bool; -#endif - -#ifndef true -#define true ((bool) 1) -#endif - -#ifndef false -#define false ((bool) 0) -#endif - -#endif /* not PG_USE_STDBOOL */ -#endif /* not C++ */ - - -/* ---------------------------------------------------------------- - * Section 3: standard system types - * ---------------------------------------------------------------- - */ - -/* - * Pointer - * Variable holding address of any memory resident object. - * - * XXX Pointer arithmetic is done with this, so it can't be void * - * under "true" ANSI compilers. - */ -typedef char *Pointer; - -/* - * intN - * Signed integer, EXACTLY N BITS IN SIZE, - * used for numerical computations and the - * frontend/backend protocol. - */ -#ifndef HAVE_INT8 -typedef signed char int8; /* == 8 bits */ -typedef signed short int16; /* == 16 bits */ -typedef signed int int32; /* == 32 bits */ -#endif /* not HAVE_INT8 */ - -/* - * uintN - * Unsigned integer, EXACTLY N BITS IN SIZE, - * used for numerical computations and the - * frontend/backend protocol. - */ -#ifndef HAVE_UINT8 -typedef unsigned char uint8; /* == 8 bits */ -typedef unsigned short uint16; /* == 16 bits */ -typedef unsigned int uint32; /* == 32 bits */ -#endif /* not HAVE_UINT8 */ - -/* - * bitsN - * Unit of bitwise operation, AT LEAST N BITS IN SIZE. - */ -typedef uint8 bits8; /* >= 8 bits */ -typedef uint16 bits16; /* >= 16 bits */ -typedef uint32 bits32; /* >= 32 bits */ - -/* - * 64-bit integers - */ -#ifdef HAVE_LONG_INT_64 -/* Plain "long int" fits, use it */ - -#ifndef HAVE_INT64 -typedef long int int64; -#endif -#ifndef HAVE_UINT64 -typedef unsigned long int uint64; -#endif -#define INT64CONST(x) (x##L) -#define UINT64CONST(x) (x##UL) -#elif defined(HAVE_LONG_LONG_INT_64) -/* We have working support for "long long int", use that */ - -#ifndef HAVE_INT64 -typedef long long int int64; -#endif -#ifndef HAVE_UINT64 -typedef unsigned long long int uint64; -#endif -#define INT64CONST(x) (x##LL) -#define UINT64CONST(x) (x##ULL) -#else -/* neither HAVE_LONG_INT_64 nor HAVE_LONG_LONG_INT_64 */ -#error must have a working 64-bit integer datatype -#endif - -/* snprintf format strings to use for 64-bit integers */ -#define INT64_FORMAT "%" INT64_MODIFIER "d" -#define UINT64_FORMAT "%" INT64_MODIFIER "u" - -/* - * 128-bit signed and unsigned integers - * There currently is only limited support for such types. - * E.g. 128bit literals and snprintf are not supported; but math is. - * Also, because we exclude such types when choosing MAXIMUM_ALIGNOF, - * it must be possible to coerce the compiler to allocate them on no - * more than MAXALIGN boundaries. - */ -#if defined(PG_INT128_TYPE) -#if defined(pg_attribute_aligned) || ALIGNOF_PG_INT128_TYPE <= MAXIMUM_ALIGNOF -#define HAVE_INT128 1 - -typedef PG_INT128_TYPE int128 -#if defined(pg_attribute_aligned) - pg_attribute_aligned(MAXIMUM_ALIGNOF) -#endif - ; - -typedef unsigned PG_INT128_TYPE uint128 -#if defined(pg_attribute_aligned) - pg_attribute_aligned(MAXIMUM_ALIGNOF) -#endif - ; - -#endif -#endif - -/* - * stdint.h limits aren't guaranteed to have compatible types with our fixed - * width types. So just define our own. - */ -#define PG_INT8_MIN (-0x7F-1) -#define PG_INT8_MAX (0x7F) -#define PG_UINT8_MAX (0xFF) -#define PG_INT16_MIN (-0x7FFF-1) -#define PG_INT16_MAX (0x7FFF) -#define PG_UINT16_MAX (0xFFFF) -#define PG_INT32_MIN (-0x7FFFFFFF-1) -#define PG_INT32_MAX (0x7FFFFFFF) -#define PG_UINT32_MAX (0xFFFFFFFFU) -#define PG_INT64_MIN (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1) -#define PG_INT64_MAX INT64CONST(0x7FFFFFFFFFFFFFFF) -#define PG_UINT64_MAX UINT64CONST(0xFFFFFFFFFFFFFFFF) - -/* - * We now always use int64 timestamps, but keep this symbol defined for the - * benefit of external code that might test it. - */ -#define HAVE_INT64_TIMESTAMP - -/* - * Size - * Size of any memory resident object, as returned by sizeof. - */ -typedef size_t Size; - -/* - * Index - * Index into any memory resident array. - * - * Note: - * Indices are non negative. - */ -typedef unsigned int Index; - -/* - * Offset - * Offset into any memory resident array. - * - * Note: - * This differs from an Index in that an Index is always - * non negative, whereas Offset may be negative. - */ -typedef signed int Offset; - -/* - * Common Postgres datatype names (as used in the catalogs) - */ -typedef float float4; -typedef double float8; - -#ifdef USE_FLOAT8_BYVAL -#define FLOAT8PASSBYVAL true -#else -#define FLOAT8PASSBYVAL false -#endif - -/* - * Oid, RegProcedure, TransactionId, SubTransactionId, MultiXactId, - * CommandId - */ - -/* typedef Oid is in postgres_ext.h */ - -/* - * regproc is the type name used in the include/catalog headers, but - * RegProcedure is the preferred name in C code. - */ -typedef Oid regproc; -typedef regproc RegProcedure; - -typedef uint32 TransactionId; - -typedef uint32 LocalTransactionId; - -typedef uint32 SubTransactionId; - -#define InvalidSubTransactionId ((SubTransactionId) 0) -#define TopSubTransactionId ((SubTransactionId) 1) - -/* MultiXactId must be equivalent to TransactionId, to fit in t_xmax */ -typedef TransactionId MultiXactId; - -typedef uint32 MultiXactOffset; - -typedef uint32 CommandId; - -#define FirstCommandId ((CommandId) 0) -#define InvalidCommandId (~(CommandId)0) - - -/* ---------------- - * Variable-length datatypes all share the 'struct varlena' header. - * - * NOTE: for TOASTable types, this is an oversimplification, since the value - * may be compressed or moved out-of-line. However datatype-specific routines - * are mostly content to deal with de-TOASTed values only, and of course - * client-side routines should never see a TOASTed value. But even in a - * de-TOASTed value, beware of touching vl_len_ directly, as its - * representation is no longer convenient. It's recommended that code always - * use macros VARDATA_ANY, VARSIZE_ANY, VARSIZE_ANY_EXHDR, VARDATA, VARSIZE, - * and SET_VARSIZE instead of relying on direct mentions of the struct fields. - * See postgres.h for details of the TOASTed form. - * ---------------- - */ -struct varlena -{ - char vl_len_[4]; /* Do not touch this field directly! */ - char vl_dat[FLEXIBLE_ARRAY_MEMBER]; /* Data content is here */ -}; - -#define VARHDRSZ ((int32) sizeof(int32)) - -/* - * These widely-used datatypes are just a varlena header and the data bytes. - * There is no terminating null or anything like that --- the data length is - * always VARSIZE_ANY_EXHDR(ptr). - */ -typedef struct varlena bytea; -typedef struct varlena text; -typedef struct varlena BpChar; /* blank-padded char, ie SQL char(n) */ -typedef struct varlena VarChar; /* var-length char, ie SQL varchar(n) */ - -/* - * Specialized array types. These are physically laid out just the same - * as regular arrays (so that the regular array subscripting code works - * with them). They exist as distinct types mostly for historical reasons: - * they have nonstandard I/O behavior which we don't want to change for fear - * of breaking applications that look at the system catalogs. There is also - * an implementation issue for oidvector: it's part of the primary key for - * pg_proc, and we can't use the normal btree array support routines for that - * without circularity. - */ -typedef struct -{ - int32 vl_len_; /* these fields must match ArrayType! */ - int ndim; /* always 1 for int2vector */ - int32 dataoffset; /* always 0 for int2vector */ - Oid elemtype; - int dim1; - int lbound1; - int16 values[FLEXIBLE_ARRAY_MEMBER]; -} int2vector; - -typedef struct -{ - int32 vl_len_; /* these fields must match ArrayType! */ - int ndim; /* always 1 for oidvector */ - int32 dataoffset; /* always 0 for oidvector */ - Oid elemtype; - int dim1; - int lbound1; - Oid values[FLEXIBLE_ARRAY_MEMBER]; -} oidvector; - -/* - * Representation of a Name: effectively just a C string, but null-padded to - * exactly NAMEDATALEN bytes. The use of a struct is historical. - */ -typedef struct nameData -{ - char data[NAMEDATALEN]; -} NameData; -typedef NameData *Name; - -#define NameStr(name) ((name).data) - - -/* ---------------------------------------------------------------- - * Section 4: IsValid macros for system types - * ---------------------------------------------------------------- - */ -/* - * BoolIsValid - * True iff bool is valid. - */ -#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true) - -/* - * PointerIsValid - * True iff pointer is valid. - */ -#define PointerIsValid(pointer) ((const void*)(pointer) != NULL) - -/* - * PointerIsAligned - * True iff pointer is properly aligned to point to the given type. - */ -#define PointerIsAligned(pointer, type) \ - (((uintptr_t)(pointer) % (sizeof (type))) == 0) - -#define OffsetToPointer(base, offset) \ - ((void *)((char *) base + offset)) - -#define OidIsValid(objectId) ((bool) ((objectId) != InvalidOid)) - -#define RegProcedureIsValid(p) OidIsValid(p) - - -/* ---------------------------------------------------------------- - * Section 5: lengthof, alignment - * ---------------------------------------------------------------- - */ -/* - * lengthof - * Number of elements in an array. - */ -#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) - -/* ---------------- - * Alignment macros: align a length or address appropriately for a given type. - * The fooALIGN() macros round up to a multiple of the required alignment, - * while the fooALIGN_DOWN() macros round down. The latter are more useful - * for problems like "how many X-sized structures will fit in a page?". - * - * NOTE: TYPEALIGN[_DOWN] will not work if ALIGNVAL is not a power of 2. - * That case seems extremely unlikely to be needed in practice, however. - * - * NOTE: MAXIMUM_ALIGNOF, and hence MAXALIGN(), intentionally exclude any - * larger-than-8-byte types the compiler might have. - * ---------------- - */ - -#define TYPEALIGN(ALIGNVAL,LEN) \ - (((uintptr_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uintptr_t) ((ALIGNVAL) - 1))) - -#define SHORTALIGN(LEN) TYPEALIGN(ALIGNOF_SHORT, (LEN)) -#define INTALIGN(LEN) TYPEALIGN(ALIGNOF_INT, (LEN)) -#define LONGALIGN(LEN) TYPEALIGN(ALIGNOF_LONG, (LEN)) -#define DOUBLEALIGN(LEN) TYPEALIGN(ALIGNOF_DOUBLE, (LEN)) -#define MAXALIGN(LEN) TYPEALIGN(MAXIMUM_ALIGNOF, (LEN)) -/* MAXALIGN covers only built-in types, not buffers */ -#define BUFFERALIGN(LEN) TYPEALIGN(ALIGNOF_BUFFER, (LEN)) -#define CACHELINEALIGN(LEN) TYPEALIGN(PG_CACHE_LINE_SIZE, (LEN)) - -#define TYPEALIGN_DOWN(ALIGNVAL,LEN) \ - (((uintptr_t) (LEN)) & ~((uintptr_t) ((ALIGNVAL) - 1))) - -#define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_SHORT, (LEN)) -#define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_INT, (LEN)) -#define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_LONG, (LEN)) -#define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_DOUBLE, (LEN)) -#define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(MAXIMUM_ALIGNOF, (LEN)) -#define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(ALIGNOF_BUFFER, (LEN)) - -/* - * The above macros will not work with types wider than uintptr_t, like with - * uint64 on 32-bit platforms. That's not problem for the usual use where a - * pointer or a length is aligned, but for the odd case that you need to - * align something (potentially) wider, use TYPEALIGN64. - */ -#define TYPEALIGN64(ALIGNVAL,LEN) \ - (((uint64) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64) ((ALIGNVAL) - 1))) - -/* we don't currently need wider versions of the other ALIGN macros */ -#define MAXALIGN64(LEN) TYPEALIGN64(MAXIMUM_ALIGNOF, (LEN)) - - -/* ---------------------------------------------------------------- - * Section 6: assertions - * ---------------------------------------------------------------- - */ - -/* - * USE_ASSERT_CHECKING, if defined, turns on all the assertions. - * - plai 9/5/90 - * - * It should _NOT_ be defined in releases or in benchmark copies - */ - -/* - * Assert() can be used in both frontend and backend code. In frontend code it - * just calls the standard assert, if it's available. If use of assertions is - * not configured, it does nothing. - */ -#ifndef USE_ASSERT_CHECKING - -#define Assert(condition) ((void)true) -#define AssertMacro(condition) ((void)true) - -#elif defined(FRONTEND) - -#include <assert.h> -#define Assert(p) assert(p) -#define AssertMacro(p) ((void) assert(p)) - -#else /* USE_ASSERT_CHECKING && !FRONTEND */ - -/* - * Assert - * Generates a fatal exception if the given condition is false. - */ -#define Assert(condition) \ - do { \ - if (!(condition)) \ - ExceptionalCondition(#condition, __FILE__, __LINE__); \ - } while (0) - -/* - * AssertMacro is the same as Assert but it's suitable for use in - * expression-like macros, for example: - * - * #define foo(x) (AssertMacro(x != 0), bar(x)) - */ -#define AssertMacro(condition) \ - ((void) ((condition) || \ - (ExceptionalCondition(#condition, __FILE__, __LINE__), 0))) - -#endif /* USE_ASSERT_CHECKING && !FRONTEND */ - -/* - * Check that `ptr' is `bndr' aligned. - */ -#define AssertPointerAlignment(ptr, bndr) \ - Assert(TYPEALIGN(bndr, (uintptr_t)(ptr)) == (uintptr_t)(ptr)) - -/* - * ExceptionalCondition is compiled into the backend whether or not - * USE_ASSERT_CHECKING is defined, so as to support use of extensions - * that are built with that #define with a backend that isn't. Hence, - * we should declare it as long as !FRONTEND. - */ -#ifndef FRONTEND -extern void ExceptionalCondition(const char *conditionName, - const char *fileName, int lineNumber) pg_attribute_noreturn(); -#endif - -/* - * Macros to support compile-time assertion checks. - * - * If the "condition" (a compile-time-constant expression) evaluates to false, - * throw a compile error using the "errmessage" (a string literal). - * - * C11 has _Static_assert(), and most C99 compilers already support that. For - * portability, we wrap it into StaticAssertDecl(). _Static_assert() is a - * "declaration", and so it must be placed where for example a variable - * declaration would be valid. As long as we compile with - * -Wno-declaration-after-statement, that also means it cannot be placed after - * statements in a function. Macros StaticAssertStmt() and StaticAssertExpr() - * make it safe to use as a statement or in an expression, respectively. - * - * For compilers without _Static_assert(), we fall back on a kluge that - * assumes the compiler will complain about a negative width for a struct - * bit-field. This will not include a helpful error message, but it beats not - * getting an error at all. - */ -#ifndef __cplusplus -#ifdef HAVE__STATIC_ASSERT -#define StaticAssertDecl(condition, errmessage) \ - _Static_assert(condition, errmessage) -#define StaticAssertStmt(condition, errmessage) \ - do { _Static_assert(condition, errmessage); } while(0) -#define StaticAssertExpr(condition, errmessage) \ - ((void) ({ StaticAssertStmt(condition, errmessage); true; })) -#else /* !HAVE__STATIC_ASSERT */ -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) -#define StaticAssertStmt(condition, errmessage) \ - ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) -#define StaticAssertExpr(condition, errmessage) \ - StaticAssertStmt(condition, errmessage) -#endif /* HAVE__STATIC_ASSERT */ -#else /* C++ */ -#if defined(__cpp_static_assert) && __cpp_static_assert >= 200410 -#define StaticAssertDecl(condition, errmessage) \ - static_assert(condition, errmessage) -#define StaticAssertStmt(condition, errmessage) \ - static_assert(condition, errmessage) -#define StaticAssertExpr(condition, errmessage) \ - ({ static_assert(condition, errmessage); }) -#else /* !__cpp_static_assert */ -#define StaticAssertDecl(condition, errmessage) \ - extern void static_assert_func(int static_assert_failure[(condition) ? 1 : -1]) -#define StaticAssertStmt(condition, errmessage) \ - do { struct static_assert_struct { int static_assert_failure : (condition) ? 1 : -1; }; } while(0) -#define StaticAssertExpr(condition, errmessage) \ - ((void) ({ StaticAssertStmt(condition, errmessage); })) -#endif /* __cpp_static_assert */ -#endif /* C++ */ - -#ifdef _MSC_VER -#undef StaticAssertStmt -#undef StaticAssertDecl -#define StaticAssertStmt(condition, errmessage) -#define StaticAssertDecl(condition, errmessage) -#endif - -/* - * Compile-time checks that a variable (or expression) has the specified type. - * - * AssertVariableIsOfType() can be used as a statement. - * AssertVariableIsOfTypeMacro() is intended for use in macros, eg - * #define foo(x) (AssertVariableIsOfTypeMacro(x, int), bar(x)) - * - * If we don't have __builtin_types_compatible_p, we can still assert that - * the types have the same size. This is far from ideal (especially on 32-bit - * platforms) but it provides at least some coverage. - */ -#ifdef HAVE__BUILTIN_TYPES_COMPATIBLE_P -#define AssertVariableIsOfType(varname, typename) \ - StaticAssertStmt(__builtin_types_compatible_p(__typeof__(varname), typename), \ - CppAsString(varname) " does not have type " CppAsString(typename)) -#define AssertVariableIsOfTypeMacro(varname, typename) \ - (StaticAssertExpr(__builtin_types_compatible_p(__typeof__(varname), typename), \ - CppAsString(varname) " does not have type " CppAsString(typename))) -#else /* !HAVE__BUILTIN_TYPES_COMPATIBLE_P */ -#define AssertVariableIsOfType(varname, typename) \ - StaticAssertStmt(sizeof(varname) == sizeof(typename), \ - CppAsString(varname) " does not have type " CppAsString(typename)) -#define AssertVariableIsOfTypeMacro(varname, typename) \ - (StaticAssertExpr(sizeof(varname) == sizeof(typename), \ - CppAsString(varname) " does not have type " CppAsString(typename))) -#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ - - -/* ---------------------------------------------------------------- - * Section 7: widely useful macros - * ---------------------------------------------------------------- - */ -/* - * Max - * Return the maximum of two numbers. - */ -#define Max(x, y) ((x) > (y) ? (x) : (y)) - -/* - * Min - * Return the minimum of two numbers. - */ -#define Min(x, y) ((x) < (y) ? (x) : (y)) - - -/* Get a bit mask of the bits set in non-long aligned addresses */ -#define LONG_ALIGN_MASK (sizeof(long) - 1) - -/* - * MemSet - * Exactly the same as standard library function memset(), but considerably - * faster for zeroing small word-aligned structures (such as parsetree nodes). - * This has to be a macro because the main point is to avoid function-call - * overhead. However, we have also found that the loop is faster than - * native libc memset() on some platforms, even those with assembler - * memset() functions. More research needs to be done, perhaps with - * MEMSET_LOOP_LIMIT tests in configure. - */ -#define MemSet(start, val, len) \ - do \ - { \ - /* must be void* because we don't know if it is integer aligned yet */ \ - void *_vstart = (void *) (start); \ - int _val = (val); \ - Size _len = (len); \ -\ - if ((((uintptr_t) _vstart) & LONG_ALIGN_MASK) == 0 && \ - (_len & LONG_ALIGN_MASK) == 0 && \ - _val == 0 && \ - _len <= MEMSET_LOOP_LIMIT && \ - /* \ - * If MEMSET_LOOP_LIMIT == 0, optimizer should find \ - * the whole "if" false at compile time. \ - */ \ - MEMSET_LOOP_LIMIT != 0) \ - { \ - long *_start = (long *) _vstart; \ - long *_stop = (long *) ((char *) _start + _len); \ - while (_start < _stop) \ - *_start++ = 0; \ - } \ - else \ - memset(_vstart, _val, _len); \ - } while (0) - -/* - * MemSetAligned is the same as MemSet except it omits the test to see if - * "start" is word-aligned. This is okay to use if the caller knows a-priori - * that the pointer is suitably aligned (typically, because he just got it - * from palloc(), which always delivers a max-aligned pointer). - */ -#define MemSetAligned(start, val, len) \ - do \ - { \ - long *_start = (long *) (start); \ - int _val = (val); \ - Size _len = (len); \ -\ - if ((_len & LONG_ALIGN_MASK) == 0 && \ - _val == 0 && \ - _len <= MEMSET_LOOP_LIMIT && \ - MEMSET_LOOP_LIMIT != 0) \ - { \ - long *_stop = (long *) ((char *) _start + _len); \ - while (_start < _stop) \ - *_start++ = 0; \ - } \ - else \ - memset(_start, _val, _len); \ - } while (0) - - -/* - * MemSetTest/MemSetLoop are a variant version that allow all the tests in - * MemSet to be done at compile time in cases where "val" and "len" are - * constants *and* we know the "start" pointer must be word-aligned. - * If MemSetTest succeeds, then it is okay to use MemSetLoop, otherwise use - * MemSetAligned. Beware of multiple evaluations of the arguments when using - * this approach. - */ -#define MemSetTest(val, len) \ - ( ((len) & LONG_ALIGN_MASK) == 0 && \ - (len) <= MEMSET_LOOP_LIMIT && \ - MEMSET_LOOP_LIMIT != 0 && \ - (val) == 0 ) - -#define MemSetLoop(start, val, len) \ - do \ - { \ - long * _start = (long *) (start); \ - long * _stop = (long *) ((char *) _start + (Size) (len)); \ - \ - while (_start < _stop) \ - *_start++ = 0; \ - } while (0) - -/* - * Macros for range-checking float values before converting to integer. - * We must be careful here that the boundary values are expressed exactly - * in the float domain. PG_INTnn_MIN is an exact power of 2, so it will - * be represented exactly; but PG_INTnn_MAX isn't, and might get rounded - * off, so avoid using that. - * The input must be rounded to an integer beforehand, typically with rint(), - * else we might draw the wrong conclusion about close-to-the-limit values. - * These macros will do the right thing for Inf, but not necessarily for NaN, - * so check isnan(num) first if that's a possibility. - */ -#define FLOAT4_FITS_IN_INT16(num) \ - ((num) >= (float4) PG_INT16_MIN && (num) < -((float4) PG_INT16_MIN)) -#define FLOAT4_FITS_IN_INT32(num) \ - ((num) >= (float4) PG_INT32_MIN && (num) < -((float4) PG_INT32_MIN)) -#define FLOAT4_FITS_IN_INT64(num) \ - ((num) >= (float4) PG_INT64_MIN && (num) < -((float4) PG_INT64_MIN)) -#define FLOAT8_FITS_IN_INT16(num) \ - ((num) >= (float8) PG_INT16_MIN && (num) < -((float8) PG_INT16_MIN)) -#define FLOAT8_FITS_IN_INT32(num) \ - ((num) >= (float8) PG_INT32_MIN && (num) < -((float8) PG_INT32_MIN)) -#define FLOAT8_FITS_IN_INT64(num) \ - ((num) >= (float8) PG_INT64_MIN && (num) < -((float8) PG_INT64_MIN)) - - -/* ---------------------------------------------------------------- - * Section 8: random stuff - * ---------------------------------------------------------------- - */ - -/* - * Invert the sign of a qsort-style comparison result, ie, exchange negative - * and positive integer values, being careful not to get the wrong answer - * for INT_MIN. The argument should be an integral variable. - */ -#define INVERT_COMPARE_RESULT(var) \ - ((var) = ((var) < 0) ? 1 : -(var)) - -/* - * Use this, not "char buf[BLCKSZ]", to declare a field or local variable - * holding a page buffer, if that page might be accessed as a page. Otherwise - * the variable might be under-aligned, causing problems on alignment-picky - * hardware. We include both "double" and "int64" in the union to ensure that - * the compiler knows the value must be MAXALIGN'ed (cf. configure's - * computation of MAXIMUM_ALIGNOF). - */ -typedef union PGAlignedBlock -{ - char data[BLCKSZ]; - double force_align_d; - int64 force_align_i64; -} PGAlignedBlock; - -/* - * Use this to declare a field or local variable holding a page buffer, if that - * page might be accessed as a page or passed to an SMgr I/O function. If - * allocating using the MemoryContext API, the aligned allocation functions - * should be used with PG_IO_ALIGN_SIZE. This alignment may be more efficient - * for I/O in general, but may be strictly required on some platforms when - * using direct I/O. - */ -typedef union PGIOAlignedBlock -{ -#ifdef pg_attribute_aligned - pg_attribute_aligned(PG_IO_ALIGN_SIZE) -#endif - char data[BLCKSZ]; - double force_align_d; - int64 force_align_i64; -} PGIOAlignedBlock; - -/* Same, but for an XLOG_BLCKSZ-sized buffer */ -typedef union PGAlignedXLogBlock -{ -#ifdef pg_attribute_aligned - pg_attribute_aligned(PG_IO_ALIGN_SIZE) -#endif - char data[XLOG_BLCKSZ]; - double force_align_d; - int64 force_align_i64; -} PGAlignedXLogBlock; - -/* msb for char */ -#define HIGHBIT (0x80) -#define IS_HIGHBIT_SET(ch) ((unsigned char)(ch) & HIGHBIT) - -/* - * Support macros for escaping strings. escape_backslash should be true - * if generating a non-standard-conforming string. Prefixing a string - * with ESCAPE_STRING_SYNTAX guarantees it is non-standard-conforming. - * Beware of multiple evaluation of the "ch" argument! - */ -#define SQL_STR_DOUBLE(ch, escape_backslash) \ - ((ch) == '\'' || ((ch) == '\\' && (escape_backslash))) - -#define ESCAPE_STRING_SYNTAX 'E' - - -#define STATUS_OK (0) -#define STATUS_ERROR (-1) -#define STATUS_EOF (-2) - -/* - * gettext support - */ - -#ifndef ENABLE_NLS -/* stuff we'd otherwise get from <libintl.h> */ -#define gettext(x) (x) -#define dgettext(d,x) (x) -#define ngettext(s,p,n) ((n) == 1 ? (s) : (p)) -#define dngettext(d,s,p,n) ((n) == 1 ? (s) : (p)) -#endif - -#define _(x) gettext(x) - -/* - * Use this to mark string constants as needing translation at some later - * time, rather than immediately. This is useful for cases where you need - * access to the original string and translated string, and for cases where - * immediate translation is not possible, like when initializing global - * variables. - * - * https://www.gnu.org/software/gettext/manual/html_node/Special-cases.html - */ -#define gettext_noop(x) (x) - -/* - * To better support parallel installations of major PostgreSQL - * versions as well as parallel installations of major library soname - * versions, we mangle the gettext domain name by appending those - * version numbers. The coding rule ought to be that wherever the - * domain name is mentioned as a literal, it must be wrapped into - * PG_TEXTDOMAIN(). The macros below do not work on non-literals; but - * that is somewhat intentional because it avoids having to worry - * about multiple states of premangling and postmangling as the values - * are being passed around. - * - * Make sure this matches the installation rules in nls-global.mk. - */ -#ifdef SO_MAJOR_VERSION -#define PG_TEXTDOMAIN(domain) (domain CppAsString2(SO_MAJOR_VERSION) "-" PG_MAJORVERSION) -#else -#define PG_TEXTDOMAIN(domain) (domain "-" PG_MAJORVERSION) -#endif - -/* - * Macro that allows to cast constness and volatile away from an expression, but doesn't - * allow changing the underlying type. Enforcement of the latter - * currently only works for gcc like compilers. - * - * Please note IT IS NOT SAFE to cast constness away if the result will ever - * be modified (it would be undefined behaviour). Doing so anyway can cause - * compiler misoptimizations or runtime crashes (modifying readonly memory). - * It is only safe to use when the result will not be modified, but API - * design or language restrictions prevent you from declaring that - * (e.g. because a function returns both const and non-const variables). - * - * Note that this only works in function scope, not for global variables (it'd - * be nice, but not trivial, to improve that). - */ -#if defined(HAVE__BUILTIN_TYPES_COMPATIBLE_P) -#define unconstify(underlying_type, expr) \ - (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), const underlying_type), \ - "wrong cast"), \ - (underlying_type) (expr)) -#define unvolatize(underlying_type, expr) \ - (StaticAssertExpr(__builtin_types_compatible_p(__typeof(expr), volatile underlying_type), \ - "wrong cast"), \ - (underlying_type) (expr)) -#else -#define unconstify(underlying_type, expr) \ - ((underlying_type) (expr)) -#define unvolatize(underlying_type, expr) \ - ((underlying_type) (expr)) -#endif - -/* ---------------------------------------------------------------- - * Section 9: system-specific hacks - * - * This should be limited to things that absolutely have to be - * included in every source file. The port-specific header file - * is usually a better place for this sort of thing. - * ---------------------------------------------------------------- - */ - -/* - * NOTE: this is also used for opening text files. - * WIN32 treats Control-Z as EOF in files opened in text mode. - * Therefore, we open files in binary mode on Win32 so we can read - * literal control-Z. The other affect is that we see CRLF, but - * that is OK because we can already handle those cleanly. - */ -#if defined(WIN32) || defined(__CYGWIN__) -#define PG_BINARY O_BINARY -#define PG_BINARY_A "ab" -#define PG_BINARY_R "rb" -#define PG_BINARY_W "wb" -#else -#define PG_BINARY 0 -#define PG_BINARY_A "a" -#define PG_BINARY_R "r" -#define PG_BINARY_W "w" -#endif - -/* - * Provide prototypes for routines not present in a particular machine's - * standard C library. - */ - -#if !HAVE_DECL_FDATASYNC -extern int fdatasync(int fildes); -#endif - -/* - * Thin wrappers that convert strings to exactly 64-bit integers, matching our - * definition of int64. (For the naming, compare that POSIX has - * strtoimax()/strtoumax() which return intmax_t/uintmax_t.) - */ -#ifdef HAVE_LONG_INT_64 -#define strtoi64(str, endptr, base) ((int64) strtol(str, endptr, base)) -#define strtou64(str, endptr, base) ((uint64) strtoul(str, endptr, base)) -#else -#define strtoi64(str, endptr, base) ((int64) strtoll(str, endptr, base)) -#define strtou64(str, endptr, base) ((uint64) strtoull(str, endptr, base)) -#endif - -/* - * Similarly, wrappers around labs()/llabs() matching our int64. - */ -#ifdef HAVE_LONG_INT_64 -#define i64abs(i) labs(i) -#else -#define i64abs(i) llabs(i) -#endif - -/* - * Use "extern PGDLLIMPORT ..." to declare variables that are defined - * in the core backend and need to be accessible by loadable modules. - * No special marking is required on most ports. - */ -#ifndef PGDLLIMPORT -#define PGDLLIMPORT -#endif - -/* - * Use "extern PGDLLEXPORT ..." to declare functions that are defined in - * loadable modules and need to be callable by the core backend or other - * loadable modules. - * If the compiler knows __attribute__((visibility("*"))), we use that, - * unless we already have a platform-specific definition. Otherwise, - * no special marking is required. - */ -#ifndef PGDLLEXPORT -#ifdef HAVE_VISIBILITY_ATTRIBUTE -#define PGDLLEXPORT __attribute__((visibility("default"))) -#else -#define PGDLLEXPORT -#endif -#endif - -/* - * The following is used as the arg list for signal handlers. Any ports - * that take something other than an int argument should override this in - * their pg_config_os.h file. Note that variable names are required - * because it is used in both the prototypes as well as the definitions. - * Note also the long name. We expect that this won't collide with - * other names causing compiler warnings. - */ - -#ifndef SIGNAL_ARGS -#define SIGNAL_ARGS int postgres_signal_arg -#endif - -/* - * When there is no sigsetjmp, its functionality is provided by plain - * setjmp. We now support the case only on Windows. However, it seems - * that MinGW-64 has some longstanding issues in its setjmp support, - * so on that toolchain we cheat and use gcc's builtins. - */ -#ifdef WIN32 -#ifdef __MINGW64__ -typedef intptr_t sigjmp_buf[5]; -#define sigsetjmp(x,y) __builtin_setjmp(x) -#define siglongjmp __builtin_longjmp -#else /* !__MINGW64__ */ -#define sigjmp_buf jmp_buf -#define sigsetjmp(x,y) setjmp(x) -#define siglongjmp longjmp -#endif /* __MINGW64__ */ -#endif /* WIN32 */ - -/* /port compatibility functions */ -#include "port.h" - -#endif /* C_H */ diff --git a/contrib/libs/libpq/src/include/catalog/catversion.h b/contrib/libs/libpq/src/include/catalog/catversion.h deleted file mode 100644 index cc1de6e65a..0000000000 --- a/contrib/libs/libpq/src/include/catalog/catversion.h +++ /dev/null @@ -1,62 +0,0 @@ -/*------------------------------------------------------------------------- - * - * catversion.h - * "Catalog version number" for PostgreSQL. - * - * The catalog version number is used to flag incompatible changes in - * the PostgreSQL system catalogs. Whenever anyone changes the format of - * a system catalog relation, or adds, deletes, or modifies standard - * catalog entries in such a way that an updated backend wouldn't work - * with an old database (or vice versa), the catalog version number - * should be changed. The version number stored in pg_control by initdb - * is checked against the version number compiled into the backend at - * startup time, so that a backend can refuse to run in an incompatible - * database. - * - * The point of this feature is to provide a finer grain of compatibility - * checking than is possible from looking at the major version number - * stored in PG_VERSION. It shouldn't matter to end users, but during - * development cycles we usually make quite a few incompatible changes - * to the contents of the system catalogs, and we don't want to bump the - * major version number for each one. What we can do instead is bump - * this internal version number. This should save some grief for - * developers who might otherwise waste time tracking down "bugs" that - * are really just code-vs-database incompatibilities. - * - * The rule for developers is: if you commit a change that requires - * an initdb, you should update the catalog version number (as well as - * notifying the pgsql-hackers mailing list, which has been the - * informal practice for a long time). - * - * The catalog version number is placed here since modifying files in - * include/catalog is the most common kind of initdb-forcing change. - * But it could be used to protect any kind of incompatible change in - * database contents or layout, such as altering tuple headers. - * Another common reason for a catversion update is a change in parsetree - * external representation, since serialized parsetrees appear in stored - * rules and new-style SQL functions. Almost any change in primnodes.h or - * parsenodes.h will warrant a catversion update. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/catalog/catversion.h - * - *------------------------------------------------------------------------- - */ -#ifndef CATVERSION_H -#define CATVERSION_H - -/* - * We could use anything we wanted for version numbers, but I recommend - * following the "YYYYMMDDN" style often used for DNS zone serial numbers. - * YYYYMMDD are the date of the change, and N is the number of the change - * on that day. (Hopefully we'll never commit ten independent sets of - * catalog changes on the same day...) - */ - -/* yyyymmddN */ -#define CATALOG_VERSION_NO 202307071 - -#endif diff --git a/contrib/libs/libpq/src/include/catalog/pg_control.h b/contrib/libs/libpq/src/include/catalog/pg_control.h deleted file mode 100644 index dc953977c5..0000000000 --- a/contrib/libs/libpq/src/include/catalog/pg_control.h +++ /dev/null @@ -1,258 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_control.h - * The system control file "pg_control" is not a heap relation. - * However, we define it here so that the format is documented. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/catalog/pg_control.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_CONTROL_H -#define PG_CONTROL_H - -#include "access/transam.h" -#include "access/xlogdefs.h" -#include "pgtime.h" /* for pg_time_t */ -#include "port/pg_crc32c.h" - - -/* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 1300 - -/* Nonce key length, see below */ -#define MOCK_AUTH_NONCE_LEN 32 - -/* - * Body of CheckPoint XLOG records. This is declared here because we keep - * a copy of the latest one in pg_control for possible disaster recovery. - * Changing this struct requires a PG_CONTROL_VERSION bump. - */ -typedef struct CheckPoint -{ - XLogRecPtr redo; /* next RecPtr available when we began to - * create CheckPoint (i.e. REDO start point) */ - TimeLineID ThisTimeLineID; /* current TLI */ - TimeLineID PrevTimeLineID; /* previous TLI, if this record begins a new - * timeline (equals ThisTimeLineID otherwise) */ - bool fullPageWrites; /* current full_page_writes */ - FullTransactionId nextXid; /* next free transaction ID */ - Oid nextOid; /* next free OID */ - MultiXactId nextMulti; /* next free MultiXactId */ - MultiXactOffset nextMultiOffset; /* next free MultiXact offset */ - TransactionId oldestXid; /* cluster-wide minimum datfrozenxid */ - Oid oldestXidDB; /* database with minimum datfrozenxid */ - MultiXactId oldestMulti; /* cluster-wide minimum datminmxid */ - Oid oldestMultiDB; /* database with minimum datminmxid */ - pg_time_t time; /* time stamp of checkpoint */ - TransactionId oldestCommitTsXid; /* oldest Xid with valid commit - * timestamp */ - TransactionId newestCommitTsXid; /* newest Xid with valid commit - * timestamp */ - - /* - * Oldest XID still running. This is only needed to initialize hot standby - * mode from an online checkpoint, so we only bother calculating this for - * online checkpoints and only when wal_level is replica. Otherwise it's - * set to InvalidTransactionId. - */ - TransactionId oldestActiveXid; -} CheckPoint; - -/* XLOG info values for XLOG rmgr */ -#define XLOG_CHECKPOINT_SHUTDOWN 0x00 -#define XLOG_CHECKPOINT_ONLINE 0x10 -#define XLOG_NOOP 0x20 -#define XLOG_NEXTOID 0x30 -#define XLOG_SWITCH 0x40 -#define XLOG_BACKUP_END 0x50 -#define XLOG_PARAMETER_CHANGE 0x60 -#define XLOG_RESTORE_POINT 0x70 -#define XLOG_FPW_CHANGE 0x80 -#define XLOG_END_OF_RECOVERY 0x90 -#define XLOG_FPI_FOR_HINT 0xA0 -#define XLOG_FPI 0xB0 -/* 0xC0 is used in Postgres 9.5-11 */ -#define XLOG_OVERWRITE_CONTRECORD 0xD0 - - -/* - * System status indicator. Note this is stored in pg_control; if you change - * it, you must bump PG_CONTROL_VERSION - */ -typedef enum DBState -{ - DB_STARTUP = 0, - DB_SHUTDOWNED, - DB_SHUTDOWNED_IN_RECOVERY, - DB_SHUTDOWNING, - DB_IN_CRASH_RECOVERY, - DB_IN_ARCHIVE_RECOVERY, - DB_IN_PRODUCTION -} DBState; - -/* - * Contents of pg_control. - */ - -typedef struct ControlFileData -{ - /* - * Unique system identifier --- to ensure we match up xlog files with the - * installation that produced them. - */ - uint64 system_identifier; - - /* - * Version identifier information. Keep these fields at the same offset, - * especially pg_control_version; they won't be real useful if they move - * around. (For historical reasons they must be 8 bytes into the file - * rather than immediately at the front.) - * - * pg_control_version identifies the format of pg_control itself. - * catalog_version_no identifies the format of the system catalogs. - * - * There are additional version identifiers in individual files; for - * example, WAL logs contain per-page magic numbers that can serve as - * version cues for the WAL log. - */ - uint32 pg_control_version; /* PG_CONTROL_VERSION */ - uint32 catalog_version_no; /* see catversion.h */ - - /* - * System status data - */ - DBState state; /* see enum above */ - pg_time_t time; /* time stamp of last pg_control update */ - XLogRecPtr checkPoint; /* last check point record ptr */ - - CheckPoint checkPointCopy; /* copy of last check point record */ - - XLogRecPtr unloggedLSN; /* current fake LSN value, for unlogged rels */ - - /* - * These two values determine the minimum point we must recover up to - * before starting up: - * - * minRecoveryPoint is updated to the latest replayed LSN whenever we - * flush a data change during archive recovery. That guards against - * starting archive recovery, aborting it, and restarting with an earlier - * stop location. If we've already flushed data changes from WAL record X - * to disk, we mustn't start up until we reach X again. Zero when not - * doing archive recovery. - * - * backupStartPoint is the redo pointer of the backup start checkpoint, if - * we are recovering from an online backup and haven't reached the end of - * backup yet. It is reset to zero when the end of backup is reached, and - * we mustn't start up before that. A boolean would suffice otherwise, but - * we use the redo pointer as a cross-check when we see an end-of-backup - * record, to make sure the end-of-backup record corresponds the base - * backup we're recovering from. - * - * backupEndPoint is the backup end location, if we are recovering from an - * online backup which was taken from the standby and haven't reached the - * end of backup yet. It is initialized to the minimum recovery point in - * pg_control which was backed up last. It is reset to zero when the end - * of backup is reached, and we mustn't start up before that. - * - * If backupEndRequired is true, we know for sure that we're restoring - * from a backup, and must see a backup-end record before we can safely - * start up. - */ - XLogRecPtr minRecoveryPoint; - TimeLineID minRecoveryPointTLI; - XLogRecPtr backupStartPoint; - XLogRecPtr backupEndPoint; - bool backupEndRequired; - - /* - * Parameter settings that determine if the WAL can be used for archival - * or hot standby. - */ - int wal_level; - bool wal_log_hints; - int MaxConnections; - int max_worker_processes; - int max_wal_senders; - int max_prepared_xacts; - int max_locks_per_xact; - bool track_commit_timestamp; - - /* - * This data is used to check for hardware-architecture compatibility of - * the database and the backend executable. We need not check endianness - * explicitly, since the pg_control version will surely look wrong to a - * machine of different endianness, but we do need to worry about MAXALIGN - * and floating-point format. (Note: storage layout nominally also - * depends on SHORTALIGN and INTALIGN, but in practice these are the same - * on all architectures of interest.) - * - * Testing just one double value is not a very bulletproof test for - * floating-point compatibility, but it will catch most cases. - */ - uint32 maxAlign; /* alignment requirement for tuples */ - double floatFormat; /* constant 1234567.0 */ -#define FLOATFORMAT_VALUE 1234567.0 - - /* - * This data is used to make sure that configuration of this database is - * compatible with the backend executable. - */ - uint32 blcksz; /* data block size for this DB */ - uint32 relseg_size; /* blocks per segment of large relation */ - - uint32 xlog_blcksz; /* block size within WAL files */ - uint32 xlog_seg_size; /* size of each WAL segment */ - - uint32 nameDataLen; /* catalog name field width */ - uint32 indexMaxKeys; /* max number of columns in an index */ - - uint32 toast_max_chunk_size; /* chunk size in TOAST tables */ - uint32 loblksize; /* chunk size in pg_largeobject */ - - bool float8ByVal; /* float8, int8, etc pass-by-value? */ - - /* Are data pages protected by checksums? Zero if no checksum version */ - uint32 data_checksum_version; - - /* - * Random nonce, used in authentication requests that need to proceed - * based on values that are cluster-unique, like a SASL exchange that - * failed at an early stage. - */ - char mock_authentication_nonce[MOCK_AUTH_NONCE_LEN]; - - /* CRC of all above ... MUST BE LAST! */ - pg_crc32c crc; -} ControlFileData; - -/* - * Maximum safe value of sizeof(ControlFileData). For reliability's sake, - * it's critical that pg_control updates be atomic writes. That generally - * means the active data can't be more than one disk sector, which is 512 - * bytes on common hardware. Be very careful about raising this limit. - */ -#define PG_CONTROL_MAX_SAFE_SIZE 512 - -/* - * Physical size of the pg_control file. Note that this is considerably - * bigger than the actually used size (ie, sizeof(ControlFileData)). - * The idea is to keep the physical size constant independent of format - * changes, so that ReadControlFile will deliver a suitable wrong-version - * message instead of a read error if it's looking at an incompatible file. - */ -#define PG_CONTROL_FILE_SIZE 8192 - -/* - * Ensure that the size of the pg_control data structure is sane. - */ -StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_MAX_SAFE_SIZE, - "pg_control is too large for atomic disk writes"); -StaticAssertDecl(sizeof(ControlFileData) <= PG_CONTROL_FILE_SIZE, - "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE"); - -#endif /* PG_CONTROL_H */ diff --git a/contrib/libs/libpq/src/include/common/archive.h b/contrib/libs/libpq/src/include/common/archive.h deleted file mode 100644 index 95196772c9..0000000000 --- a/contrib/libs/libpq/src/include/common/archive.h +++ /dev/null @@ -1,21 +0,0 @@ -/*------------------------------------------------------------------------- - * - * archive.h - * Common WAL archive routines - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/archive.h - * - *------------------------------------------------------------------------- - */ -#ifndef ARCHIVE_H -#define ARCHIVE_H - -extern char *BuildRestoreCommand(const char *restoreCommand, - const char *xlogpath, /* %p */ - const char *xlogfname, /* %f */ - const char *lastRestartPointFname); /* %r */ - -#endif /* ARCHIVE_H */ diff --git a/contrib/libs/libpq/src/include/common/base64.h b/contrib/libs/libpq/src/include/common/base64.h deleted file mode 100644 index 5bd8186c79..0000000000 --- a/contrib/libs/libpq/src/include/common/base64.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * base64.h - * Encoding and decoding routines for base64 without whitespace - * support. - * - * Portions Copyright (c) 2001-2023, PostgreSQL Global Development Group - * - * src/include/common/base64.h - */ -#ifndef BASE64_H -#define BASE64_H - -/* base 64 */ -extern int pg_b64_encode(const char *src, int len, char *dst, int dstlen); -extern int pg_b64_decode(const char *src, int len, char *dst, int dstlen); -extern int pg_b64_enc_len(int srclen); -extern int pg_b64_dec_len(int srclen); - -#endif /* BASE64_H */ diff --git a/contrib/libs/libpq/src/include/common/checksum_helper.h b/contrib/libs/libpq/src/include/common/checksum_helper.h deleted file mode 100644 index a74deef67b..0000000000 --- a/contrib/libs/libpq/src/include/common/checksum_helper.h +++ /dev/null @@ -1,72 +0,0 @@ -/*------------------------------------------------------------------------- - * - * checksum_helper.h - * Compute a checksum of any of various types using common routines - * - * Portions Copyright (c) 2016-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/common/checksum_helper.h - * - *------------------------------------------------------------------------- - */ - -#ifndef CHECKSUM_HELPER_H -#define CHECKSUM_HELPER_H - -#include "common/cryptohash.h" -#include "common/sha2.h" -#include "port/pg_crc32c.h" - -/* - * Supported checksum types. It's not necessarily the case that code using - * these functions needs a cryptographically strong checksum; it may only - * need to detect accidental modification. That's why we include CRC-32C: it's - * much faster than any of the other algorithms. On the other hand, we omit - * MD5 here because any new that does need a cryptographically strong checksum - * should use something better. - */ -typedef enum pg_checksum_type -{ - CHECKSUM_TYPE_NONE, - CHECKSUM_TYPE_CRC32C, - CHECKSUM_TYPE_SHA224, - CHECKSUM_TYPE_SHA256, - CHECKSUM_TYPE_SHA384, - CHECKSUM_TYPE_SHA512 -} pg_checksum_type; - -/* - * This is just a union of all applicable context types. - */ -typedef union pg_checksum_raw_context -{ - pg_crc32c c_crc32c; - pg_cryptohash_ctx *c_sha2; -} pg_checksum_raw_context; - -/* - * This structure provides a convenient way to pass the checksum type and the - * checksum context around together. - */ -typedef struct pg_checksum_context -{ - pg_checksum_type type; - pg_checksum_raw_context raw_context; -} pg_checksum_context; - -/* - * This is the longest possible output for any checksum algorithm supported - * by this file. - */ -#define PG_CHECKSUM_MAX_LENGTH PG_SHA512_DIGEST_LENGTH - -extern bool pg_checksum_parse_type(char *name, pg_checksum_type *); -extern char *pg_checksum_type_name(pg_checksum_type); - -extern int pg_checksum_init(pg_checksum_context *, pg_checksum_type); -extern int pg_checksum_update(pg_checksum_context *, const uint8 *input, - size_t len); -extern int pg_checksum_final(pg_checksum_context *, uint8 *output); - -#endif diff --git a/contrib/libs/libpq/src/include/common/compression.h b/contrib/libs/libpq/src/include/common/compression.h deleted file mode 100644 index 38aae9dd87..0000000000 --- a/contrib/libs/libpq/src/include/common/compression.h +++ /dev/null @@ -1,53 +0,0 @@ -/*------------------------------------------------------------------------- - * - * compression.h - * - * Shared definitions for compression methods and specifications. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/common/compression.h - *------------------------------------------------------------------------- - */ - -#ifndef PG_COMPRESSION_H -#define PG_COMPRESSION_H - -/* - * These values are stored in disk, for example in files generated by pg_dump. - * Create the necessary backwards compatibility layers if their order changes. - */ -typedef enum pg_compress_algorithm -{ - PG_COMPRESSION_NONE, - PG_COMPRESSION_GZIP, - PG_COMPRESSION_LZ4, - PG_COMPRESSION_ZSTD -} pg_compress_algorithm; - -#define PG_COMPRESSION_OPTION_WORKERS (1 << 0) -#define PG_COMPRESSION_OPTION_LONG_DISTANCE (1 << 1) - -typedef struct pg_compress_specification -{ - pg_compress_algorithm algorithm; - unsigned options; /* OR of PG_COMPRESSION_OPTION constants */ - int level; - int workers; - bool long_distance; - char *parse_error; /* NULL if parsing was OK, else message */ -} pg_compress_specification; - -extern void parse_compress_options(const char *option, char **algorithm, - char **detail); -extern bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm); -extern const char *get_compress_algorithm_name(pg_compress_algorithm algorithm); - -extern void parse_compress_specification(pg_compress_algorithm algorithm, - char *specification, - pg_compress_specification *result); - -extern char *validate_compress_specification(pg_compress_specification *); - -#endif diff --git a/contrib/libs/libpq/src/include/common/config_info.h b/contrib/libs/libpq/src/include/common/config_info.h deleted file mode 100644 index a6d076d5e9..0000000000 --- a/contrib/libs/libpq/src/include/common/config_info.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * config_info.h - * Common code for pg_config output - * - * Copyright (c) 2016-2023, PostgreSQL Global Development Group - * - * src/include/common/config_info.h - */ -#ifndef COMMON_CONFIG_INFO_H -#define COMMON_CONFIG_INFO_H - -typedef struct ConfigData -{ - char *name; - char *setting; -} ConfigData; - -extern ConfigData *get_configdata(const char *my_exec_path, - size_t *configdata_len); - -#endif /* COMMON_CONFIG_INFO_H */ diff --git a/contrib/libs/libpq/src/include/common/controldata_utils.h b/contrib/libs/libpq/src/include/common/controldata_utils.h deleted file mode 100644 index 49e7c52d31..0000000000 --- a/contrib/libs/libpq/src/include/common/controldata_utils.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * controldata_utils.h - * Common code for pg_controldata output - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/controldata_utils.h - */ -#ifndef COMMON_CONTROLDATA_UTILS_H -#define COMMON_CONTROLDATA_UTILS_H - -#include "catalog/pg_control.h" - -extern ControlFileData *get_controlfile(const char *DataDir, bool *crc_ok_p); -extern void update_controlfile(const char *DataDir, - ControlFileData *ControlFile, bool do_sync); - -#endif /* COMMON_CONTROLDATA_UTILS_H */ diff --git a/contrib/libs/libpq/src/include/common/cryptohash.h b/contrib/libs/libpq/src/include/common/cryptohash.h deleted file mode 100644 index 24b6dbebbd..0000000000 --- a/contrib/libs/libpq/src/include/common/cryptohash.h +++ /dev/null @@ -1,39 +0,0 @@ -/*------------------------------------------------------------------------- - * - * cryptohash.h - * Generic headers for cryptographic hash functions. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/common/cryptohash.h - * - *------------------------------------------------------------------------- - */ - -#ifndef PG_CRYPTOHASH_H -#define PG_CRYPTOHASH_H - -/* Context Structures for each hash function */ -typedef enum -{ - PG_MD5 = 0, - PG_SHA1, - PG_SHA224, - PG_SHA256, - PG_SHA384, - PG_SHA512 -} pg_cryptohash_type; - -/* opaque context, private to each cryptohash implementation */ -typedef struct pg_cryptohash_ctx pg_cryptohash_ctx; - -extern pg_cryptohash_ctx *pg_cryptohash_create(pg_cryptohash_type type); -extern int pg_cryptohash_init(pg_cryptohash_ctx *ctx); -extern int pg_cryptohash_update(pg_cryptohash_ctx *ctx, const uint8 *data, size_t len); -extern int pg_cryptohash_final(pg_cryptohash_ctx *ctx, uint8 *dest, size_t len); -extern void pg_cryptohash_free(pg_cryptohash_ctx *ctx); -extern const char *pg_cryptohash_error(pg_cryptohash_ctx *ctx); - -#endif /* PG_CRYPTOHASH_H */ diff --git a/contrib/libs/libpq/src/include/common/fe_memutils.h b/contrib/libs/libpq/src/include/common/fe_memutils.h deleted file mode 100644 index 89601cc778..0000000000 --- a/contrib/libs/libpq/src/include/common/fe_memutils.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * fe_memutils.h - * memory management support for frontend code - * - * Copyright (c) 2003-2023, PostgreSQL Global Development Group - * - * src/include/common/fe_memutils.h - */ -#ifndef FE_MEMUTILS_H -#define FE_MEMUTILS_H - -/* - * Flags for pg_malloc_extended and palloc_extended, deliberately named - * the same as the backend flags. - */ -#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) not - * actually used for frontends */ -#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ -#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */ - -/* - * "Safe" memory allocation functions --- these exit(1) on failure - * (except pg_malloc_extended with MCXT_ALLOC_NO_OOM) - */ -extern char *pg_strdup(const char *in); -extern void *pg_malloc(size_t size); -extern void *pg_malloc0(size_t size); -extern void *pg_malloc_extended(size_t size, int flags); -extern void *pg_realloc(void *ptr, size_t size); -extern void pg_free(void *ptr); - -/* - * Variants with easier notation and more type safety - */ - -/* - * Allocate space for one object of type "type" - */ -#define pg_malloc_object(type) ((type *) pg_malloc(sizeof(type))) -#define pg_malloc0_object(type) ((type *) pg_malloc0(sizeof(type))) - -/* - * Allocate space for "count" objects of type "type" - */ -#define pg_malloc_array(type, count) ((type *) pg_malloc(sizeof(type) * (count))) -#define pg_malloc0_array(type, count) ((type *) pg_malloc0(sizeof(type) * (count))) - -/* - * Change size of allocation pointed to by "pointer" to have space for "count" - * objects of type "type" - */ -#define pg_realloc_array(pointer, type, count) ((type *) pg_realloc(pointer, sizeof(type) * (count))) - -/* Equivalent functions, deliberately named the same as backend functions */ -extern char *pstrdup(const char *in); -extern char *pnstrdup(const char *in, Size size); -extern void *palloc(Size size); -extern void *palloc0(Size size); -extern void *palloc_extended(Size size, int flags); -extern void *repalloc(void *pointer, Size size); -extern void pfree(void *pointer); - -#define palloc_object(type) ((type *) palloc(sizeof(type))) -#define palloc0_object(type) ((type *) palloc0(sizeof(type))) -#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count))) -#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count))) -#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) - -/* sprintf into a palloc'd buffer --- these are in psprintf.c */ -extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); -extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); - -#endif /* FE_MEMUTILS_H */ diff --git a/contrib/libs/libpq/src/include/common/file_perm.h b/contrib/libs/libpq/src/include/common/file_perm.h deleted file mode 100644 index 978c0d072f..0000000000 --- a/contrib/libs/libpq/src/include/common/file_perm.h +++ /dev/null @@ -1,56 +0,0 @@ -/*------------------------------------------------------------------------- - * - * File and directory permission definitions - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/file_perm.h - * - *------------------------------------------------------------------------- - */ -#ifndef FILE_PERM_H -#define FILE_PERM_H - -#include <sys/stat.h> - -/* - * Mode mask for data directory permissions that only allows the owner to - * read/write directories and files. - * - * This is the default. - */ -#define PG_MODE_MASK_OWNER (S_IRWXG | S_IRWXO) - -/* - * Mode mask for data directory permissions that also allows group read/execute. - */ -#define PG_MODE_MASK_GROUP (S_IWGRP | S_IRWXO) - -/* Default mode for creating directories */ -#define PG_DIR_MODE_OWNER S_IRWXU - -/* Mode for creating directories that allows group read/execute */ -#define PG_DIR_MODE_GROUP (S_IRWXU | S_IRGRP | S_IXGRP) - -/* Default mode for creating files */ -#define PG_FILE_MODE_OWNER (S_IRUSR | S_IWUSR) - -/* Mode for creating files that allows group read */ -#define PG_FILE_MODE_GROUP (S_IRUSR | S_IWUSR | S_IRGRP) - -/* Modes for creating directories and files in the data directory */ -extern PGDLLIMPORT int pg_dir_create_mode; -extern PGDLLIMPORT int pg_file_create_mode; - -/* Mode mask to pass to umask() */ -extern PGDLLIMPORT int pg_mode_mask; - -/* Set permissions and mask based on the provided mode */ -extern void SetDataDirectoryCreatePerm(int dataDirMode); - -/* Set permissions and mask based on the mode of the data directory */ -extern bool GetDataDirectoryCreatePerm(const char *dataDir); - -#endif /* FILE_PERM_H */ diff --git a/contrib/libs/libpq/src/include/common/file_utils.h b/contrib/libs/libpq/src/include/common/file_utils.h deleted file mode 100644 index b7efa1226d..0000000000 --- a/contrib/libs/libpq/src/include/common/file_utils.h +++ /dev/null @@ -1,49 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Assorted utility functions to work on files. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/file_utils.h - * - *------------------------------------------------------------------------- - */ -#ifndef FILE_UTILS_H -#define FILE_UTILS_H - -#include <dirent.h> - -typedef enum PGFileType -{ - PGFILETYPE_ERROR, - PGFILETYPE_UNKNOWN, - PGFILETYPE_REG, - PGFILETYPE_DIR, - PGFILETYPE_LNK -} PGFileType; - -struct iovec; /* avoid including port/pg_iovec.h here */ - -#ifdef FRONTEND -extern int fsync_fname(const char *fname, bool isdir); -extern void fsync_pgdata(const char *pg_data, int serverVersion); -extern void fsync_dir_recurse(const char *dir); -extern int durable_rename(const char *oldfile, const char *newfile); -extern int fsync_parent_path(const char *fname); -#endif - -extern PGFileType get_dirent_type(const char *path, - const struct dirent *de, - bool look_through_symlinks, - int elevel); - -extern ssize_t pg_pwritev_with_retry(int fd, - const struct iovec *iov, - int iovcnt, - off_t offset); - -extern ssize_t pg_pwrite_zeros(int fd, size_t size, off_t offset); - -#endif /* FILE_UTILS_H */ diff --git a/contrib/libs/libpq/src/include/common/hashfn.h b/contrib/libs/libpq/src/include/common/hashfn.h deleted file mode 100644 index 5e89aef987..0000000000 --- a/contrib/libs/libpq/src/include/common/hashfn.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Utilities for working with hash values. - * - * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group - */ - -#ifndef HASHFN_H -#define HASHFN_H - - -/* - * Rotate the high 32 bits and the low 32 bits separately. The standard - * hash function sometimes rotates the low 32 bits by one bit when - * combining elements. We want extended hash functions to be compatible with - * that algorithm when the seed is 0, so we can't just do a normal rotation. - * This works, though. - */ -#define ROTATE_HIGH_AND_LOW_32BITS(v) \ - ((((v) << 1) & UINT64CONST(0xfffffffefffffffe)) | \ - (((v) >> 31) & UINT64CONST(0x100000001))) - - -extern uint32 hash_bytes(const unsigned char *k, int keylen); -extern uint64 hash_bytes_extended(const unsigned char *k, - int keylen, uint64 seed); -extern uint32 hash_bytes_uint32(uint32 k); -extern uint64 hash_bytes_uint32_extended(uint32 k, uint64 seed); - -#ifndef FRONTEND -static inline Datum -hash_any(const unsigned char *k, int keylen) -{ - return UInt32GetDatum(hash_bytes(k, keylen)); -} - -static inline Datum -hash_any_extended(const unsigned char *k, int keylen, uint64 seed) -{ - return UInt64GetDatum(hash_bytes_extended(k, keylen, seed)); -} - -static inline Datum -hash_uint32(uint32 k) -{ - return UInt32GetDatum(hash_bytes_uint32(k)); -} - -static inline Datum -hash_uint32_extended(uint32 k, uint64 seed) -{ - return UInt64GetDatum(hash_bytes_uint32_extended(k, seed)); -} -#endif - -extern uint32 string_hash(const void *key, Size keysize); -extern uint32 tag_hash(const void *key, Size keysize); -extern uint32 uint32_hash(const void *key, Size keysize); - -#define oid_hash uint32_hash /* Remove me eventually */ - -/* - * Combine two 32-bit hash values, resulting in another hash value, with - * decent bit mixing. - * - * Similar to boost's hash_combine(). - */ -static inline uint32 -hash_combine(uint32 a, uint32 b) -{ - a ^= b + 0x9e3779b9 + (a << 6) + (a >> 2); - return a; -} - -/* - * Combine two 64-bit hash values, resulting in another hash value, using the - * same kind of technique as hash_combine(). Testing shows that this also - * produces good bit mixing. - */ -static inline uint64 -hash_combine64(uint64 a, uint64 b) -{ - /* 0x49a0f4dd15e5a8e3 is 64bit random data */ - a ^= b + UINT64CONST(0x49a0f4dd15e5a8e3) + (a << 54) + (a >> 7); - return a; -} - -/* - * Simple inline murmur hash implementation hashing a 32 bit integer, for - * performance. - */ -static inline uint32 -murmurhash32(uint32 data) -{ - uint32 h = data; - - h ^= h >> 16; - h *= 0x85ebca6b; - h ^= h >> 13; - h *= 0xc2b2ae35; - h ^= h >> 16; - return h; -} - -#endif /* HASHFN_H */ diff --git a/contrib/libs/libpq/src/include/common/hmac.h b/contrib/libs/libpq/src/include/common/hmac.h deleted file mode 100644 index e0b2ed2024..0000000000 --- a/contrib/libs/libpq/src/include/common/hmac.h +++ /dev/null @@ -1,30 +0,0 @@ -/*------------------------------------------------------------------------- - * - * hmac.h - * Generic headers for HMAC - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/common/hmac.h - * - *------------------------------------------------------------------------- - */ - -#ifndef PG_HMAC_H -#define PG_HMAC_H - -#include "common/cryptohash.h" - -/* opaque context, private to each HMAC implementation */ -typedef struct pg_hmac_ctx pg_hmac_ctx; - -extern pg_hmac_ctx *pg_hmac_create(pg_cryptohash_type type); -extern int pg_hmac_init(pg_hmac_ctx *ctx, const uint8 *key, size_t len); -extern int pg_hmac_update(pg_hmac_ctx *ctx, const uint8 *data, size_t len); -extern int pg_hmac_final(pg_hmac_ctx *ctx, uint8 *dest, size_t len); -extern void pg_hmac_free(pg_hmac_ctx *ctx); -extern const char *pg_hmac_error(pg_hmac_ctx *ctx); - -#endif /* PG_HMAC_H */ diff --git a/contrib/libs/libpq/src/include/common/ip.h b/contrib/libs/libpq/src/include/common/ip.h deleted file mode 100644 index 9f2ed5fe0a..0000000000 --- a/contrib/libs/libpq/src/include/common/ip.h +++ /dev/null @@ -1,33 +0,0 @@ -/*------------------------------------------------------------------------- - * - * ip.h - * Definitions for IPv6-aware network access. - * - * These definitions are used by both frontend and backend code. - * - * Copyright (c) 2003-2023, PostgreSQL Global Development Group - * - * src/include/common/ip.h - * - *------------------------------------------------------------------------- - */ -#ifndef IP_H -#define IP_H - -#include <netdb.h> -#include <sys/socket.h> - -#include "libpq/pqcomm.h" /* pgrminclude ignore */ - - -extern int pg_getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo *hintp, - struct addrinfo **result); -extern void pg_freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); - -extern int pg_getnameinfo_all(const struct sockaddr_storage *addr, int salen, - char *node, int nodelen, - char *service, int servicelen, - int flags); - -#endif /* IP_H */ diff --git a/contrib/libs/libpq/src/include/common/jsonapi.h b/contrib/libs/libpq/src/include/common/jsonapi.h deleted file mode 100644 index 4310084b2b..0000000000 --- a/contrib/libs/libpq/src/include/common/jsonapi.h +++ /dev/null @@ -1,177 +0,0 @@ -/*------------------------------------------------------------------------- - * - * jsonapi.h - * Declarations for JSON API support. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/jsonapi.h - * - *------------------------------------------------------------------------- - */ - -#ifndef JSONAPI_H -#define JSONAPI_H - -#include "lib/stringinfo.h" - -typedef enum JsonTokenType -{ - JSON_TOKEN_INVALID, - JSON_TOKEN_STRING, - JSON_TOKEN_NUMBER, - JSON_TOKEN_OBJECT_START, - JSON_TOKEN_OBJECT_END, - JSON_TOKEN_ARRAY_START, - JSON_TOKEN_ARRAY_END, - JSON_TOKEN_COMMA, - JSON_TOKEN_COLON, - JSON_TOKEN_TRUE, - JSON_TOKEN_FALSE, - JSON_TOKEN_NULL, - JSON_TOKEN_END -} JsonTokenType; - -typedef enum JsonParseErrorType -{ - JSON_SUCCESS, - JSON_ESCAPING_INVALID, - JSON_ESCAPING_REQUIRED, - JSON_EXPECTED_ARRAY_FIRST, - JSON_EXPECTED_ARRAY_NEXT, - JSON_EXPECTED_COLON, - JSON_EXPECTED_END, - JSON_EXPECTED_JSON, - JSON_EXPECTED_MORE, - JSON_EXPECTED_OBJECT_FIRST, - JSON_EXPECTED_OBJECT_NEXT, - JSON_EXPECTED_STRING, - JSON_INVALID_TOKEN, - JSON_UNICODE_CODE_POINT_ZERO, - JSON_UNICODE_ESCAPE_FORMAT, - JSON_UNICODE_HIGH_ESCAPE, - JSON_UNICODE_UNTRANSLATABLE, - JSON_UNICODE_HIGH_SURROGATE, - JSON_UNICODE_LOW_SURROGATE, - JSON_SEM_ACTION_FAILED /* error should already be reported */ -} JsonParseErrorType; - - -/* - * All the fields in this structure should be treated as read-only. - * - * If strval is not null, then it should contain the de-escaped value - * of the lexeme if it's a string. Otherwise most of these field names - * should be self-explanatory. - * - * line_number and line_start are principally for use by the parser's - * error reporting routines. - * token_terminator and prev_token_terminator point to the character - * AFTER the end of the token, i.e. where there would be a nul byte - * if we were using nul-terminated strings. - */ -typedef struct JsonLexContext -{ - char *input; - int input_length; - int input_encoding; - char *token_start; - char *token_terminator; - char *prev_token_terminator; - JsonTokenType token_type; - int lex_level; - int line_number; /* line number, starting from 1 */ - char *line_start; /* where that line starts within input */ - StringInfo strval; -} JsonLexContext; - -typedef JsonParseErrorType (*json_struct_action) (void *state); -typedef JsonParseErrorType (*json_ofield_action) (void *state, char *fname, bool isnull); -typedef JsonParseErrorType (*json_aelem_action) (void *state, bool isnull); -typedef JsonParseErrorType (*json_scalar_action) (void *state, char *token, JsonTokenType tokentype); - - -/* - * Semantic Action structure for use in parsing json. - * - * Any of these actions can be NULL, in which case nothing is done at that - * point, Likewise, semstate can be NULL. Using an all-NULL structure amounts - * to doing a pure parse with no side-effects, and is therefore exactly - * what the json input routines do. - * - * The 'fname' and 'token' strings passed to these actions are palloc'd. - * They are not free'd or used further by the parser, so the action function - * is free to do what it wishes with them. - * - * All action functions return JsonParseErrorType. If the result isn't - * JSON_SUCCESS, the parse is abandoned and that error code is returned. - * If it is JSON_SEM_ACTION_FAILED, the action function is responsible - * for having reported the error in some appropriate way. - */ -typedef struct JsonSemAction -{ - void *semstate; - json_struct_action object_start; - json_struct_action object_end; - json_struct_action array_start; - json_struct_action array_end; - json_ofield_action object_field_start; - json_ofield_action object_field_end; - json_aelem_action array_element_start; - json_aelem_action array_element_end; - json_scalar_action scalar; -} JsonSemAction; - -/* - * pg_parse_json will parse the string in the lex calling the - * action functions in sem at the appropriate points. It is - * up to them to keep what state they need in semstate. If they - * need access to the state of the lexer, then its pointer - * should be passed to them as a member of whatever semstate - * points to. If the action pointers are NULL the parser - * does nothing and just continues. - */ -extern JsonParseErrorType pg_parse_json(JsonLexContext *lex, - JsonSemAction *sem); - -/* the null action object used for pure validation */ -extern PGDLLIMPORT JsonSemAction nullSemAction; - -/* - * json_count_array_elements performs a fast secondary parse to determine the - * number of elements in passed array lex context. It should be called from an - * array_start action. - * - * The return value indicates whether any error occurred, while the number - * of elements is stored into *elements (but only if the return value is - * JSON_SUCCESS). - */ -extern JsonParseErrorType json_count_array_elements(JsonLexContext *lex, - int *elements); - -/* - * constructor for JsonLexContext, with or without strval element. - * If supplied, the strval element will contain a de-escaped version of - * the lexeme. However, doing this imposes a performance penalty, so - * it should be avoided if the de-escaped lexeme is not required. - */ -extern JsonLexContext *makeJsonLexContextCstringLen(char *json, - int len, - int encoding, - bool need_escapes); - -/* lex one token */ -extern JsonParseErrorType json_lex(JsonLexContext *lex); - -/* construct an error detail string for a json error */ -extern char *json_errdetail(JsonParseErrorType error, JsonLexContext *lex); - -/* - * Utility function to check if a string is a valid JSON number. - * - * str argument does not need to be nul-terminated. - */ -extern bool IsValidJsonNumber(const char *str, int len); - -#endif /* JSONAPI_H */ diff --git a/contrib/libs/libpq/src/include/common/keywords.h b/contrib/libs/libpq/src/include/common/keywords.h deleted file mode 100644 index 6bb12d8edb..0000000000 --- a/contrib/libs/libpq/src/include/common/keywords.h +++ /dev/null @@ -1,29 +0,0 @@ -/*------------------------------------------------------------------------- - * - * keywords.h - * PostgreSQL's list of SQL keywords - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/keywords.h - * - *------------------------------------------------------------------------- - */ -#ifndef KEYWORDS_H -#define KEYWORDS_H - -#include "common/kwlookup.h" - -/* Keyword categories --- should match lists in gram.y */ -#define UNRESERVED_KEYWORD 0 -#define COL_NAME_KEYWORD 1 -#define TYPE_FUNC_NAME_KEYWORD 2 -#define RESERVED_KEYWORD 3 - -extern PGDLLIMPORT const ScanKeywordList ScanKeywords; -extern PGDLLIMPORT const uint8 ScanKeywordCategories[]; -extern PGDLLIMPORT const bool ScanKeywordBareLabel[]; - -#endif /* KEYWORDS_H */ diff --git a/contrib/libs/libpq/src/include/common/kwlookup.h b/contrib/libs/libpq/src/include/common/kwlookup.h deleted file mode 100644 index 3fc3faa043..0000000000 --- a/contrib/libs/libpq/src/include/common/kwlookup.h +++ /dev/null @@ -1,44 +0,0 @@ -/*------------------------------------------------------------------------- - * - * kwlookup.h - * Key word lookup for PostgreSQL - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/kwlookup.h - * - *------------------------------------------------------------------------- - */ -#ifndef KWLOOKUP_H -#define KWLOOKUP_H - -/* Hash function used by ScanKeywordLookup */ -typedef int (*ScanKeywordHashFunc) (const void *key, size_t keylen); - -/* - * This struct contains the data needed by ScanKeywordLookup to perform a - * search within a set of keywords. The contents are typically generated by - * src/tools/gen_keywordlist.pl from a header containing PG_KEYWORD macros. - */ -typedef struct ScanKeywordList -{ - const char *kw_string; /* all keywords in order, separated by \0 */ - const uint16 *kw_offsets; /* offsets to the start of each keyword */ - ScanKeywordHashFunc hash; /* perfect hash function for keywords */ - int num_keywords; /* number of keywords */ - int max_kw_len; /* length of longest keyword */ -} ScanKeywordList; - - -extern int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords); - -/* Code that wants to retrieve the text of the N'th keyword should use this. */ -static inline const char * -GetScanKeyword(int n, const ScanKeywordList *keywords) -{ - return keywords->kw_string + keywords->kw_offsets[n]; -} - -#endif /* KWLOOKUP_H */ diff --git a/contrib/libs/libpq/src/include/common/link-canary.h b/contrib/libs/libpq/src/include/common/link-canary.h deleted file mode 100644 index 178d123b1a..0000000000 --- a/contrib/libs/libpq/src/include/common/link-canary.h +++ /dev/null @@ -1,17 +0,0 @@ -/*------------------------------------------------------------------------- - * - * link-canary.h - * Detect whether src/common functions came from frontend or backend. - * - * Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * src/include/common/link-canary.h - * - *------------------------------------------------------------------------- - */ -#ifndef LINK_CANARY_H -#define LINK_CANARY_H - -extern bool pg_link_canary_is_frontend(void); - -#endif /* LINK_CANARY_H */ diff --git a/contrib/libs/libpq/src/include/common/logging.h b/contrib/libs/libpq/src/include/common/logging.h deleted file mode 100644 index 99e888af93..0000000000 --- a/contrib/libs/libpq/src/include/common/logging.h +++ /dev/null @@ -1,156 +0,0 @@ -/*------------------------------------------------------------------------- - * Logging framework for frontend programs - * - * Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * src/include/common/logging.h - * - *------------------------------------------------------------------------- - */ -#ifndef COMMON_LOGGING_H -#define COMMON_LOGGING_H - -/* - * Log levels are informational only. They do not affect program flow. - */ -enum pg_log_level -{ - /* - * Not initialized yet (not to be used as an actual message log level). - */ - PG_LOG_NOTSET = 0, - - /* - * Low level messages that are normally off by default. - */ - PG_LOG_DEBUG, - - /* - * Any program messages that go to stderr, shown by default. (The - * program's normal output should go to stdout and not use the logging - * system.) - */ - PG_LOG_INFO, - - /* - * Warnings and "almost" errors, depends on the program - */ - PG_LOG_WARNING, - - /* - * Errors - */ - PG_LOG_ERROR, - - /* - * Turn all logging off (not to be used as an actual message log level). - */ - PG_LOG_OFF, -}; - -/* - * __pg_log_level is the minimum log level that will actually be shown. - */ -extern enum pg_log_level __pg_log_level; - -/* - * A log message can have several parts. The primary message is required, - * others are optional. When emitting multiple parts, do so in the order of - * this enum, for consistency. - */ -enum pg_log_part -{ - /* - * The primary message. Try to keep it to one line; follow the backend's - * style guideline for primary messages. - */ - PG_LOG_PRIMARY, - - /* - * Additional detail. Follow the backend's style guideline for detail - * messages. - */ - PG_LOG_DETAIL, - - /* - * Hint (not guaranteed correct) about how to fix the problem. Follow the - * backend's style guideline for hint messages. - */ - PG_LOG_HINT, -}; - -/* - * Kind of a hack to be able to produce the psql output exactly as required by - * the regression tests. - */ -#define PG_LOG_FLAG_TERSE 1 - -void pg_logging_init(const char *argv0); -void pg_logging_config(int new_flags); -void pg_logging_set_level(enum pg_log_level new_level); -void pg_logging_increase_verbosity(void); -void pg_logging_set_pre_callback(void (*cb) (void)); -void pg_logging_set_locus_callback(void (*cb) (const char **filename, uint64 *lineno)); - -void pg_log_generic(enum pg_log_level level, enum pg_log_part part, - const char *pg_restrict fmt,...) - pg_attribute_printf(3, 4); -void pg_log_generic_v(enum pg_log_level level, enum pg_log_part part, - const char *pg_restrict fmt, va_list ap) - pg_attribute_printf(3, 0); - -/* - * Preferred style is to use these macros to perform logging; don't call - * pg_log_generic[_v] directly, except perhaps in error interface code. - */ -#define pg_log_error(...) \ - pg_log_generic(PG_LOG_ERROR, PG_LOG_PRIMARY, __VA_ARGS__) - -#define pg_log_error_detail(...) \ - pg_log_generic(PG_LOG_ERROR, PG_LOG_DETAIL, __VA_ARGS__) - -#define pg_log_error_hint(...) \ - pg_log_generic(PG_LOG_ERROR, PG_LOG_HINT, __VA_ARGS__) - -#define pg_log_warning(...) \ - pg_log_generic(PG_LOG_WARNING, PG_LOG_PRIMARY, __VA_ARGS__) - -#define pg_log_warning_detail(...) \ - pg_log_generic(PG_LOG_WARNING, PG_LOG_DETAIL, __VA_ARGS__) - -#define pg_log_warning_hint(...) \ - pg_log_generic(PG_LOG_WARNING, PG_LOG_HINT, __VA_ARGS__) - -#define pg_log_info(...) \ - pg_log_generic(PG_LOG_INFO, PG_LOG_PRIMARY, __VA_ARGS__) - -#define pg_log_info_detail(...) \ - pg_log_generic(PG_LOG_INFO, PG_LOG_DETAIL, __VA_ARGS__) - -#define pg_log_info_hint(...) \ - pg_log_generic(PG_LOG_INFO, PG_LOG_HINT, __VA_ARGS__) - -#define pg_log_debug(...) do { \ - if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ - pg_log_generic(PG_LOG_DEBUG, PG_LOG_PRIMARY, __VA_ARGS__); \ - } while(0) - -#define pg_log_debug_detail(...) do { \ - if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ - pg_log_generic(PG_LOG_DEBUG, PG_LOG_DETAIL, __VA_ARGS__); \ - } while(0) - -#define pg_log_debug_hint(...) do { \ - if (unlikely(__pg_log_level <= PG_LOG_DEBUG)) \ - pg_log_generic(PG_LOG_DEBUG, PG_LOG_HINT, __VA_ARGS__); \ - } while(0) - -/* - * A common shortcut: pg_log_error() and immediately exit(1). - */ -#define pg_fatal(...) do { \ - pg_log_generic(PG_LOG_ERROR, PG_LOG_PRIMARY, __VA_ARGS__); \ - exit(1); \ - } while(0) - -#endif /* COMMON_LOGGING_H */ diff --git a/contrib/libs/libpq/src/include/common/md5.h b/contrib/libs/libpq/src/include/common/md5.h deleted file mode 100644 index b6089bacff..0000000000 --- a/contrib/libs/libpq/src/include/common/md5.h +++ /dev/null @@ -1,37 +0,0 @@ -/*------------------------------------------------------------------------- - * - * md5.h - * Constants and common utilities related to MD5. - * - * These definitions are needed by both frontend and backend code to work - * with MD5-encrypted passwords. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/md5.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_MD5_H -#define PG_MD5_H - -/* Size of result generated by MD5 computation */ -#define MD5_DIGEST_LENGTH 16 -/* Block size for MD5 */ -#define MD5_BLOCK_SIZE 64 - -/* password-related data */ -#define MD5_PASSWD_CHARSET "0123456789abcdef" -#define MD5_PASSWD_LEN 35 - -/* Utilities common to all the MD5 implementations, as of md5_common.c */ -extern bool pg_md5_hash(const void *buff, size_t len, char *hexsum, - const char **errstr); -extern bool pg_md5_binary(const void *buff, size_t len, void *outbuf, - const char **errstr); -extern bool pg_md5_encrypt(const char *passwd, const char *salt, - size_t salt_len, char *buf, - const char **errstr); - -#endif /* PG_MD5_H */ diff --git a/contrib/libs/libpq/src/include/common/openssl.h b/contrib/libs/libpq/src/include/common/openssl.h deleted file mode 100644 index 060675ab33..0000000000 --- a/contrib/libs/libpq/src/include/common/openssl.h +++ /dev/null @@ -1,49 +0,0 @@ -/*------------------------------------------------------------------------- - * - * openssl.h - * OpenSSL supporting functionality shared between frontend and backend - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/common/openssl.h - * - *------------------------------------------------------------------------- - */ -#ifndef COMMON_OPENSSL_H -#define COMMON_OPENSSL_H - -#ifdef USE_OPENSSL -#include <openssl/ssl.h> - -/* - * OpenSSL doesn't provide any very nice way to identify the min/max - * protocol versions the library supports, so we fake it as best we can. - * Note in particular that this doesn't account for restrictions that - * might be specified in the installation's openssl.cnf. - * - * We disable SSLv3 and older in library setup, so TLSv1 is the oldest - * protocol version of interest. - */ -#define MIN_OPENSSL_TLS_VERSION "TLSv1" - -#if defined(TLS1_3_VERSION) -#define MAX_OPENSSL_TLS_VERSION "TLSv1.3" -#elif defined(TLS1_2_VERSION) -#define MAX_OPENSSL_TLS_VERSION "TLSv1.2" -#elif defined(TLS1_1_VERSION) -#define MAX_OPENSSL_TLS_VERSION "TLSv1.1" -#else -#define MAX_OPENSSL_TLS_VERSION "TLSv1" -#endif - -/* src/common/protocol_openssl.c */ -#ifndef SSL_CTX_set_min_proto_version -extern int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version); -extern int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); -#endif - -#endif /* USE_OPENSSL */ - -#endif /* COMMON_OPENSSL_H */ diff --git a/contrib/libs/libpq/src/include/common/percentrepl.h b/contrib/libs/libpq/src/include/common/percentrepl.h deleted file mode 100644 index 0efb6ecb5b..0000000000 --- a/contrib/libs/libpq/src/include/common/percentrepl.h +++ /dev/null @@ -1,18 +0,0 @@ -/*------------------------------------------------------------------------- - * - * percentrepl.h - * Common routines to replace percent placeholders in strings - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/percentrepl.h - * - *------------------------------------------------------------------------- - */ -#ifndef PERCENTREPL_H -#define PERCENTREPL_H - -extern char *replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...); - -#endif /* PERCENTREPL_H */ diff --git a/contrib/libs/libpq/src/include/common/pg_lzcompress.h b/contrib/libs/libpq/src/include/common/pg_lzcompress.h deleted file mode 100644 index 2a12b33a00..0000000000 --- a/contrib/libs/libpq/src/include/common/pg_lzcompress.h +++ /dev/null @@ -1,93 +0,0 @@ -/* ---------- - * pg_lzcompress.h - - * - * Definitions for the builtin LZ compressor - * - * src/include/common/pg_lzcompress.h - * ---------- - */ - -#ifndef _PG_LZCOMPRESS_H_ -#define _PG_LZCOMPRESS_H_ - - -/* ---------- - * PGLZ_MAX_OUTPUT - - * - * Macro to compute the buffer size required by pglz_compress(). - * We allow 4 bytes for overrun before detecting compression failure. - * ---------- - */ -#define PGLZ_MAX_OUTPUT(_dlen) ((_dlen) + 4) - - -/* ---------- - * PGLZ_Strategy - - * - * Some values that control the compression algorithm. - * - * min_input_size Minimum input data size to consider compression. - * - * max_input_size Maximum input data size to consider compression. - * - * min_comp_rate Minimum compression rate (0-99%) to require. - * Regardless of min_comp_rate, the output must be - * smaller than the input, else we don't store - * compressed. - * - * first_success_by Abandon compression if we find no compressible - * data within the first this-many bytes. - * - * match_size_good The initial GOOD match size when starting history - * lookup. When looking up the history to find a - * match that could be expressed as a tag, the - * algorithm does not always walk back entirely. - * A good match fast is usually better than the - * best possible one very late. For each iteration - * in the lookup, this value is lowered so the - * longer the lookup takes, the smaller matches - * are considered good. - * - * match_size_drop The percentage by which match_size_good is lowered - * after each history check. Allowed values are - * 0 (no change until end) to 100 (only check - * latest history entry at all). - * ---------- - */ -typedef struct PGLZ_Strategy -{ - int32 min_input_size; - int32 max_input_size; - int32 min_comp_rate; - int32 first_success_by; - int32 match_size_good; - int32 match_size_drop; -} PGLZ_Strategy; - - -/* ---------- - * The standard strategies - * - * PGLZ_strategy_default Recommended default strategy for TOAST. - * - * PGLZ_strategy_always Try to compress inputs of any length. - * Fallback to uncompressed storage only if - * output would be larger than input. - * ---------- - */ -extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_default; -extern PGDLLIMPORT const PGLZ_Strategy *const PGLZ_strategy_always; - - -/* ---------- - * Global function declarations - * ---------- - */ -extern int32 pglz_compress(const char *source, int32 slen, char *dest, - const PGLZ_Strategy *strategy); -extern int32 pglz_decompress(const char *source, int32 slen, char *dest, - int32 rawsize, bool check_complete); -extern int32 pglz_maximum_compressed_size(int32 rawsize, - int32 total_compressed_size); - -#endif /* _PG_LZCOMPRESS_H_ */ diff --git a/contrib/libs/libpq/src/include/common/pg_prng.h b/contrib/libs/libpq/src/include/common/pg_prng.h deleted file mode 100644 index b5c0b8d288..0000000000 --- a/contrib/libs/libpq/src/include/common/pg_prng.h +++ /dev/null @@ -1,61 +0,0 @@ -/*------------------------------------------------------------------------- - * - * Pseudo-Random Number Generator - * - * Copyright (c) 2021-2023, PostgreSQL Global Development Group - * - * src/include/common/pg_prng.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_PRNG_H -#define PG_PRNG_H - -/* - * State vector for PRNG generation. Callers should treat this as an - * opaque typedef, but we expose its definition to allow it to be - * embedded in other structs. - */ -typedef struct pg_prng_state -{ - uint64 s0, - s1; -} pg_prng_state; - -/* - * Callers not needing local PRNG series may use this global state vector, - * after initializing it with one of the pg_prng_...seed functions. - */ -extern PGDLLIMPORT pg_prng_state pg_global_prng_state; - -extern void pg_prng_seed(pg_prng_state *state, uint64 seed); -extern void pg_prng_fseed(pg_prng_state *state, double fseed); -extern bool pg_prng_seed_check(pg_prng_state *state); - -/* - * Initialize the PRNG state from the pg_strong_random source, - * taking care that we don't produce all-zeroes. If this returns false, - * caller should initialize the PRNG state from some other random seed, - * using pg_prng_[f]seed. - * - * We implement this as a macro, so that the pg_strong_random() call is - * in the caller. If it were in pg_prng.c, programs using pg_prng.c - * but not needing strong seeding would nonetheless be forced to pull in - * pg_strong_random.c and thence OpenSSL. - */ -#define pg_prng_strong_seed(state) \ - (pg_strong_random((void *) (state), sizeof(pg_prng_state)) ? \ - pg_prng_seed_check(state) : false) - -extern uint64 pg_prng_uint64(pg_prng_state *state); -extern uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax); -extern int64 pg_prng_int64(pg_prng_state *state); -extern int64 pg_prng_int64p(pg_prng_state *state); -extern uint32 pg_prng_uint32(pg_prng_state *state); -extern int32 pg_prng_int32(pg_prng_state *state); -extern int32 pg_prng_int32p(pg_prng_state *state); -extern double pg_prng_double(pg_prng_state *state); -extern double pg_prng_double_normal(pg_prng_state *state); -extern bool pg_prng_bool(pg_prng_state *state); - -#endif /* PG_PRNG_H */ diff --git a/contrib/libs/libpq/src/include/common/relpath.h b/contrib/libs/libpq/src/include/common/relpath.h deleted file mode 100644 index 511c21682e..0000000000 --- a/contrib/libs/libpq/src/include/common/relpath.h +++ /dev/null @@ -1,97 +0,0 @@ -/*------------------------------------------------------------------------- - * - * relpath.h - * Declarations for GetRelationPath() and friends - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/relpath.h - * - *------------------------------------------------------------------------- - */ -#ifndef RELPATH_H -#define RELPATH_H - -/* - * 'pgrminclude ignore' needed here because CppAsString2() does not throw - * an error if the symbol is not defined. - */ -#include "catalog/catversion.h" /* pgrminclude ignore */ - -/* - * RelFileNumber data type identifies the specific relation file name. - */ -typedef Oid RelFileNumber; -#define InvalidRelFileNumber ((RelFileNumber) InvalidOid) -#define RelFileNumberIsValid(relnumber) \ - ((bool) ((relnumber) != InvalidRelFileNumber)) - -/* - * Name of major-version-specific tablespace subdirectories - */ -#define TABLESPACE_VERSION_DIRECTORY "PG_" PG_MAJORVERSION "_" \ - CppAsString2(CATALOG_VERSION_NO) - -/* Characters to allow for an OID in a relation path */ -#define OIDCHARS 10 /* max chars printed by %u */ - -/* - * Stuff for fork names. - * - * The physical storage of a relation consists of one or more forks. - * The main fork is always created, but in addition to that there can be - * additional forks for storing various metadata. ForkNumber is used when - * we need to refer to a specific fork in a relation. - */ -typedef enum ForkNumber -{ - InvalidForkNumber = -1, - MAIN_FORKNUM = 0, - FSM_FORKNUM, - VISIBILITYMAP_FORKNUM, - INIT_FORKNUM - - /* - * NOTE: if you add a new fork, change MAX_FORKNUM and possibly - * FORKNAMECHARS below, and update the forkNames array in - * src/common/relpath.c - */ -} ForkNumber; - -#define MAX_FORKNUM INIT_FORKNUM - -#define FORKNAMECHARS 4 /* max chars for a fork name */ - -extern PGDLLIMPORT const char *const forkNames[]; - -extern ForkNumber forkname_to_number(const char *forkName); -extern int forkname_chars(const char *str, ForkNumber *fork); - -/* - * Stuff for computing filesystem pathnames for relations. - */ -extern char *GetDatabasePath(Oid dbOid, Oid spcOid); - -extern char *GetRelationPath(Oid dbOid, Oid spcOid, RelFileNumber relNumber, - int backendId, ForkNumber forkNumber); - -/* - * Wrapper macros for GetRelationPath. Beware of multiple - * evaluation of the RelFileLocator or RelFileLocatorBackend argument! - */ - -/* First argument is a RelFileLocator */ -#define relpathbackend(rlocator, backend, forknum) \ - GetRelationPath((rlocator).dbOid, (rlocator).spcOid, (rlocator).relNumber, \ - backend, forknum) - -/* First argument is a RelFileLocator */ -#define relpathperm(rlocator, forknum) \ - relpathbackend(rlocator, InvalidBackendId, forknum) - -/* First argument is a RelFileLocatorBackend */ -#define relpath(rlocator, forknum) \ - relpathbackend((rlocator).locator, (rlocator).backend, forknum) - -#endif /* RELPATH_H */ diff --git a/contrib/libs/libpq/src/include/common/restricted_token.h b/contrib/libs/libpq/src/include/common/restricted_token.h deleted file mode 100644 index d4077c7661..0000000000 --- a/contrib/libs/libpq/src/include/common/restricted_token.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * restricted_token.h - * helper routine to ensure restricted token on Windows - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/restricted_token.h - */ -#ifndef COMMON_RESTRICTED_TOKEN_H -#define COMMON_RESTRICTED_TOKEN_H - -/* - * On Windows make sure that we are running with a restricted token, - * On other platforms do nothing. - */ -void get_restricted_token(void); - -#ifdef WIN32 -/* Create a restricted token and execute the specified process with it. */ -HANDLE CreateRestrictedProcess(char *cmd, PROCESS_INFORMATION *processInfo); -#endif - -#endif /* COMMON_RESTRICTED_TOKEN_H */ diff --git a/contrib/libs/libpq/src/include/common/saslprep.h b/contrib/libs/libpq/src/include/common/saslprep.h deleted file mode 100644 index f622db962f..0000000000 --- a/contrib/libs/libpq/src/include/common/saslprep.h +++ /dev/null @@ -1,30 +0,0 @@ -/*------------------------------------------------------------------------- - * - * saslprep.h - * SASLprep normalization, for SCRAM authentication - * - * These definitions are used by both frontend and backend code. - * - * Copyright (c) 2017-2023, PostgreSQL Global Development Group - * - * src/include/common/saslprep.h - * - *------------------------------------------------------------------------- - */ -#ifndef SASLPREP_H -#define SASLPREP_H - -/* - * Return codes for pg_saslprep() function. - */ -typedef enum -{ - SASLPREP_SUCCESS = 0, - SASLPREP_OOM = -1, /* out of memory (only in frontend) */ - SASLPREP_INVALID_UTF8 = -2, /* input is not a valid UTF-8 string */ - SASLPREP_PROHIBITED = -3 /* output would contain prohibited characters */ -} pg_saslprep_rc; - -extern pg_saslprep_rc pg_saslprep(const char *input, char **output); - -#endif /* SASLPREP_H */ diff --git a/contrib/libs/libpq/src/include/common/scram-common.h b/contrib/libs/libpq/src/include/common/scram-common.h deleted file mode 100644 index 5ccff96ece..0000000000 --- a/contrib/libs/libpq/src/include/common/scram-common.h +++ /dev/null @@ -1,70 +0,0 @@ -/*------------------------------------------------------------------------- - * - * scram-common.h - * Declarations for helper functions used for SCRAM authentication - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/scram-common.h - * - *------------------------------------------------------------------------- - */ -#ifndef SCRAM_COMMON_H -#define SCRAM_COMMON_H - -#include "common/cryptohash.h" -#include "common/sha2.h" - -/* Name of SCRAM mechanisms per IANA */ -#define SCRAM_SHA_256_NAME "SCRAM-SHA-256" -#define SCRAM_SHA_256_PLUS_NAME "SCRAM-SHA-256-PLUS" /* with channel binding */ - -/* Length of SCRAM keys (client and server) */ -#define SCRAM_SHA_256_KEY_LEN PG_SHA256_DIGEST_LENGTH - -/* - * Size of buffers used internally by SCRAM routines, that should be the - * maximum of SCRAM_SHA_*_KEY_LEN among the hash methods supported. - */ -#define SCRAM_MAX_KEY_LEN SCRAM_SHA_256_KEY_LEN - -/* - * Size of random nonce generated in the authentication exchange. This - * is in "raw" number of bytes, the actual nonces sent over the wire are - * encoded using only ASCII-printable characters. - */ -#define SCRAM_RAW_NONCE_LEN 18 - -/* - * Length of salt when generating new secrets, in bytes. (It will be stored - * and sent over the wire encoded in Base64.) 16 bytes is what the example in - * RFC 7677 uses. - */ -#define SCRAM_DEFAULT_SALT_LEN 16 - -/* - * Default number of iterations when generating secret. Should be at least - * 4096 per RFC 7677. - */ -#define SCRAM_SHA_256_DEFAULT_ITERATIONS 4096 - -extern int scram_SaltedPassword(const char *password, - pg_cryptohash_type hash_type, int key_length, - const char *salt, int saltlen, int iterations, - uint8 *result, const char **errstr); -extern int scram_H(const uint8 *input, pg_cryptohash_type hash_type, - int key_length, uint8 *result, - const char **errstr); -extern int scram_ClientKey(const uint8 *salted_password, - pg_cryptohash_type hash_type, int key_length, - uint8 *result, const char **errstr); -extern int scram_ServerKey(const uint8 *salted_password, - pg_cryptohash_type hash_type, int key_length, - uint8 *result, const char **errstr); - -extern char *scram_build_secret(pg_cryptohash_type hash_type, int key_length, - const char *salt, int saltlen, int iterations, - const char *password, const char **errstr); - -#endif /* SCRAM_COMMON_H */ diff --git a/contrib/libs/libpq/src/include/common/sha1.h b/contrib/libs/libpq/src/include/common/sha1.h deleted file mode 100644 index e6933d96bb..0000000000 --- a/contrib/libs/libpq/src/include/common/sha1.h +++ /dev/null @@ -1,21 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sha1.h - * Constants related to SHA1. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/sha1.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_SHA1_H -#define PG_SHA1_H - -/* Size of result generated by SHA1 computation */ -#define SHA1_DIGEST_LENGTH 20 -/* Block size for SHA1 */ -#define SHA1_BLOCK_SIZE 64 - -#endif /* PG_SHA1_H */ diff --git a/contrib/libs/libpq/src/include/common/sha2.h b/contrib/libs/libpq/src/include/common/sha2.h deleted file mode 100644 index 9b46cd1a37..0000000000 --- a/contrib/libs/libpq/src/include/common/sha2.h +++ /dev/null @@ -1,32 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sha2.h - * Constants related to SHA224, 256, 384 AND 512. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/common/sha2.h - * - *------------------------------------------------------------------------- - */ - -#ifndef _PG_SHA2_H_ -#define _PG_SHA2_H_ - -/*** SHA224/256/384/512 Various Length Definitions ***********************/ -#define PG_SHA224_BLOCK_LENGTH 64 -#define PG_SHA224_DIGEST_LENGTH 28 -#define PG_SHA224_DIGEST_STRING_LENGTH (PG_SHA224_DIGEST_LENGTH * 2 + 1) -#define PG_SHA256_BLOCK_LENGTH 64 -#define PG_SHA256_DIGEST_LENGTH 32 -#define PG_SHA256_DIGEST_STRING_LENGTH (PG_SHA256_DIGEST_LENGTH * 2 + 1) -#define PG_SHA384_BLOCK_LENGTH 128 -#define PG_SHA384_DIGEST_LENGTH 48 -#define PG_SHA384_DIGEST_STRING_LENGTH (PG_SHA384_DIGEST_LENGTH * 2 + 1) -#define PG_SHA512_BLOCK_LENGTH 128 -#define PG_SHA512_DIGEST_LENGTH 64 -#define PG_SHA512_DIGEST_STRING_LENGTH (PG_SHA512_DIGEST_LENGTH * 2 + 1) - -#endif /* _PG_SHA2_H_ */ diff --git a/contrib/libs/libpq/src/include/common/shortest_dec.h b/contrib/libs/libpq/src/include/common/shortest_dec.h deleted file mode 100644 index 8479b98575..0000000000 --- a/contrib/libs/libpq/src/include/common/shortest_dec.h +++ /dev/null @@ -1,63 +0,0 @@ -/*--------------------------------------------------------------------------- - * - * Ryu floating-point output. - * - * Portions Copyright (c) 2018-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/common/shortest_dec.h - * - * This is a modification of code taken from github.com/ulfjack/ryu under the - * terms of the Boost license (not the Apache license). The original copyright - * notice follows: - * - * Copyright 2018 Ulf Adams - * - * The contents of this file may be used under the terms of the Apache - * License, Version 2.0. - * - * (See accompanying file LICENSE-Apache or copy at - * http://www.apache.org/licenses/LICENSE-2.0) - * - * Alternatively, the contents of this file may be used under the terms of the - * Boost Software License, Version 1.0. - * - * (See accompanying file LICENSE-Boost or copy at - * https://www.boost.org/LICENSE_1_0.txt) - * - * Unless required by applicable law or agreed to in writing, this software is - * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. - * - *--------------------------------------------------------------------------- - */ -#ifndef SHORTEST_DEC_H -#define SHORTEST_DEC_H - -/*---- - * The length of 25 comes from: - * - * Case 1: -9.9999999999999999e-299 = 24 bytes, plus 1 for null - * - * Case 2: -0.00099999999999999999 = 23 bytes, plus 1 for null - */ -#define DOUBLE_SHORTEST_DECIMAL_LEN 25 - -int double_to_shortest_decimal_bufn(double f, char *result); -int double_to_shortest_decimal_buf(double f, char *result); -char *double_to_shortest_decimal(double f); - -/* - * The length of 16 comes from: - * - * Case 1: -9.99999999e+29 = 15 bytes, plus 1 for null - * - * Case 2: -0.000999999999 = 15 bytes, plus 1 for null - */ -#define FLOAT_SHORTEST_DECIMAL_LEN 16 - -int float_to_shortest_decimal_bufn(float f, char *result); -int float_to_shortest_decimal_buf(float f, char *result); -char *float_to_shortest_decimal(float f); - -#endif /* SHORTEST_DEC_H */ diff --git a/contrib/libs/libpq/src/include/common/string.h b/contrib/libs/libpq/src/include/common/string.h deleted file mode 100644 index 977ef327d0..0000000000 --- a/contrib/libs/libpq/src/include/common/string.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * string.h - * string handling helpers - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/string.h - */ -#ifndef COMMON_STRING_H -#define COMMON_STRING_H - -#include <signal.h> - -struct StringInfoData; /* avoid including stringinfo.h here */ - -typedef struct PromptInterruptContext -{ - /* To avoid including <setjmp.h> here, jmpbuf is declared "void *" */ - void *jmpbuf; /* existing longjmp buffer */ - volatile sig_atomic_t *enabled; /* flag that enables longjmp-on-interrupt */ - bool canceled; /* indicates whether cancellation occurred */ -} PromptInterruptContext; - -/* functions in src/common/string.c */ -extern bool pg_str_endswith(const char *str, const char *end); -extern int strtoint(const char *pg_restrict str, char **pg_restrict endptr, - int base); -extern char *pg_clean_ascii(const char *str, int alloc_flags); -extern int pg_strip_crlf(char *str); -extern bool pg_is_ascii(const char *str); - -/* functions in src/common/pg_get_line.c */ -extern char *pg_get_line(FILE *stream, PromptInterruptContext *prompt_ctx); -extern bool pg_get_line_buf(FILE *stream, struct StringInfoData *buf); -extern bool pg_get_line_append(FILE *stream, struct StringInfoData *buf, - PromptInterruptContext *prompt_ctx); - -/* functions in src/common/sprompt.c */ -extern char *simple_prompt(const char *prompt, bool echo); -extern char *simple_prompt_extended(const char *prompt, bool echo, - PromptInterruptContext *prompt_ctx); - -#endif /* COMMON_STRING_H */ diff --git a/contrib/libs/libpq/src/include/common/unicode_east_asian_fw_table.h b/contrib/libs/libpq/src/include/common/unicode_east_asian_fw_table.h deleted file mode 100644 index f77e6dfd42..0000000000 --- a/contrib/libs/libpq/src/include/common/unicode_east_asian_fw_table.h +++ /dev/null @@ -1,125 +0,0 @@ -/* generated by src/common/unicode/generate-unicode_east_asian_fw_table.pl, do not edit */ - -static const struct mbinterval east_asian_fw[] = { - {0x1100, 0x115F}, - {0x231A, 0x231B}, - {0x2329, 0x232A}, - {0x23E9, 0x23EC}, - {0x23F0, 0x23F0}, - {0x23F3, 0x23F3}, - {0x25FD, 0x25FE}, - {0x2614, 0x2615}, - {0x2648, 0x2653}, - {0x267F, 0x267F}, - {0x2693, 0x2693}, - {0x26A1, 0x26A1}, - {0x26AA, 0x26AB}, - {0x26BD, 0x26BE}, - {0x26C4, 0x26C5}, - {0x26CE, 0x26CE}, - {0x26D4, 0x26D4}, - {0x26EA, 0x26EA}, - {0x26F2, 0x26F3}, - {0x26F5, 0x26F5}, - {0x26FA, 0x26FA}, - {0x26FD, 0x26FD}, - {0x2705, 0x2705}, - {0x270A, 0x270B}, - {0x2728, 0x2728}, - {0x274C, 0x274C}, - {0x274E, 0x274E}, - {0x2753, 0x2755}, - {0x2757, 0x2757}, - {0x2795, 0x2797}, - {0x27B0, 0x27B0}, - {0x27BF, 0x27BF}, - {0x2B1B, 0x2B1C}, - {0x2B50, 0x2B50}, - {0x2B55, 0x2B55}, - {0x2E80, 0x2E99}, - {0x2E9B, 0x2EF3}, - {0x2F00, 0x2FD5}, - {0x2FF0, 0x2FFB}, - {0x3000, 0x303E}, - {0x3041, 0x3096}, - {0x3099, 0x30FF}, - {0x3105, 0x312F}, - {0x3131, 0x318E}, - {0x3190, 0x31E3}, - {0x31F0, 0x321E}, - {0x3220, 0x3247}, - {0x3250, 0x4DBF}, - {0x4E00, 0xA48C}, - {0xA490, 0xA4C6}, - {0xA960, 0xA97C}, - {0xAC00, 0xD7A3}, - {0xF900, 0xFAFF}, - {0xFE10, 0xFE19}, - {0xFE30, 0xFE52}, - {0xFE54, 0xFE66}, - {0xFE68, 0xFE6B}, - {0xFF01, 0xFF60}, - {0xFFE0, 0xFFE6}, - {0x16FE0, 0x16FE4}, - {0x16FF0, 0x16FF1}, - {0x17000, 0x187F7}, - {0x18800, 0x18CD5}, - {0x18D00, 0x18D08}, - {0x1AFF0, 0x1AFF3}, - {0x1AFF5, 0x1AFFB}, - {0x1AFFD, 0x1AFFE}, - {0x1B000, 0x1B122}, - {0x1B132, 0x1B132}, - {0x1B150, 0x1B152}, - {0x1B155, 0x1B155}, - {0x1B164, 0x1B167}, - {0x1B170, 0x1B2FB}, - {0x1F004, 0x1F004}, - {0x1F0CF, 0x1F0CF}, - {0x1F18E, 0x1F18E}, - {0x1F191, 0x1F19A}, - {0x1F200, 0x1F202}, - {0x1F210, 0x1F23B}, - {0x1F240, 0x1F248}, - {0x1F250, 0x1F251}, - {0x1F260, 0x1F265}, - {0x1F300, 0x1F320}, - {0x1F32D, 0x1F335}, - {0x1F337, 0x1F37C}, - {0x1F37E, 0x1F393}, - {0x1F3A0, 0x1F3CA}, - {0x1F3CF, 0x1F3D3}, - {0x1F3E0, 0x1F3F0}, - {0x1F3F4, 0x1F3F4}, - {0x1F3F8, 0x1F43E}, - {0x1F440, 0x1F440}, - {0x1F442, 0x1F4FC}, - {0x1F4FF, 0x1F53D}, - {0x1F54B, 0x1F54E}, - {0x1F550, 0x1F567}, - {0x1F57A, 0x1F57A}, - {0x1F595, 0x1F596}, - {0x1F5A4, 0x1F5A4}, - {0x1F5FB, 0x1F64F}, - {0x1F680, 0x1F6C5}, - {0x1F6CC, 0x1F6CC}, - {0x1F6D0, 0x1F6D2}, - {0x1F6D5, 0x1F6D7}, - {0x1F6DC, 0x1F6DF}, - {0x1F6EB, 0x1F6EC}, - {0x1F6F4, 0x1F6FC}, - {0x1F7E0, 0x1F7EB}, - {0x1F7F0, 0x1F7F0}, - {0x1F90C, 0x1F93A}, - {0x1F93C, 0x1F945}, - {0x1F947, 0x1F9FF}, - {0x1FA70, 0x1FA7C}, - {0x1FA80, 0x1FA88}, - {0x1FA90, 0x1FABD}, - {0x1FABF, 0x1FAC5}, - {0x1FACE, 0x1FADB}, - {0x1FAE0, 0x1FAE8}, - {0x1FAF0, 0x1FAF8}, - {0x20000, 0x2FFFD}, - {0x30000, 0x3FFFD}, -}; diff --git a/contrib/libs/libpq/src/include/common/unicode_nonspacing_table.h b/contrib/libs/libpq/src/include/common/unicode_nonspacing_table.h deleted file mode 100644 index 8d00e127fc..0000000000 --- a/contrib/libs/libpq/src/include/common/unicode_nonspacing_table.h +++ /dev/null @@ -1,326 +0,0 @@ -/* generated by src/common/unicode/generate-unicode_nonspacing_table.pl, do not edit */ - -static const struct mbinterval nonspacing[] = { - {0x00AD, 0x00AD}, - {0x0300, 0x036F}, - {0x0483, 0x0489}, - {0x0591, 0x05BD}, - {0x05BF, 0x05BF}, - {0x05C1, 0x05C2}, - {0x05C4, 0x05C5}, - {0x05C7, 0x05C7}, - {0x0600, 0x0605}, - {0x0610, 0x061A}, - {0x061C, 0x061C}, - {0x064B, 0x065F}, - {0x0670, 0x0670}, - {0x06D6, 0x06DD}, - {0x06DF, 0x06E4}, - {0x06E7, 0x06E8}, - {0x06EA, 0x06ED}, - {0x070F, 0x070F}, - {0x0711, 0x0711}, - {0x0730, 0x074A}, - {0x07A6, 0x07B0}, - {0x07EB, 0x07F3}, - {0x07FD, 0x07FD}, - {0x0816, 0x0819}, - {0x081B, 0x0823}, - {0x0825, 0x0827}, - {0x0829, 0x082D}, - {0x0859, 0x085B}, - {0x0890, 0x089F}, - {0x08CA, 0x0902}, - {0x093A, 0x093A}, - {0x093C, 0x093C}, - {0x0941, 0x0948}, - {0x094D, 0x094D}, - {0x0951, 0x0957}, - {0x0962, 0x0963}, - {0x0981, 0x0981}, - {0x09BC, 0x09BC}, - {0x09C1, 0x09C4}, - {0x09CD, 0x09CD}, - {0x09E2, 0x09E3}, - {0x09FE, 0x0A02}, - {0x0A3C, 0x0A3C}, - {0x0A41, 0x0A51}, - {0x0A70, 0x0A71}, - {0x0A75, 0x0A75}, - {0x0A81, 0x0A82}, - {0x0ABC, 0x0ABC}, - {0x0AC1, 0x0AC8}, - {0x0ACD, 0x0ACD}, - {0x0AE2, 0x0AE3}, - {0x0AFA, 0x0B01}, - {0x0B3C, 0x0B3C}, - {0x0B3F, 0x0B3F}, - {0x0B41, 0x0B44}, - {0x0B4D, 0x0B56}, - {0x0B62, 0x0B63}, - {0x0B82, 0x0B82}, - {0x0BC0, 0x0BC0}, - {0x0BCD, 0x0BCD}, - {0x0C00, 0x0C00}, - {0x0C04, 0x0C04}, - {0x0C3C, 0x0C3C}, - {0x0C3E, 0x0C40}, - {0x0C46, 0x0C56}, - {0x0C62, 0x0C63}, - {0x0C81, 0x0C81}, - {0x0CBC, 0x0CBC}, - {0x0CBF, 0x0CBF}, - {0x0CC6, 0x0CC6}, - {0x0CCC, 0x0CCD}, - {0x0CE2, 0x0CE3}, - {0x0D00, 0x0D01}, - {0x0D3B, 0x0D3C}, - {0x0D41, 0x0D44}, - {0x0D4D, 0x0D4D}, - {0x0D62, 0x0D63}, - {0x0D81, 0x0D81}, - {0x0DCA, 0x0DCA}, - {0x0DD2, 0x0DD6}, - {0x0E31, 0x0E31}, - {0x0E34, 0x0E3A}, - {0x0E47, 0x0E4E}, - {0x0EB1, 0x0EB1}, - {0x0EB4, 0x0EBC}, - {0x0EC8, 0x0ECE}, - {0x0F18, 0x0F19}, - {0x0F35, 0x0F35}, - {0x0F37, 0x0F37}, - {0x0F39, 0x0F39}, - {0x0F71, 0x0F7E}, - {0x0F80, 0x0F84}, - {0x0F86, 0x0F87}, - {0x0F8D, 0x0FBC}, - {0x0FC6, 0x0FC6}, - {0x102D, 0x1030}, - {0x1032, 0x1037}, - {0x1039, 0x103A}, - {0x103D, 0x103E}, - {0x1058, 0x1059}, - {0x105E, 0x1060}, - {0x1071, 0x1074}, - {0x1082, 0x1082}, - {0x1085, 0x1086}, - {0x108D, 0x108D}, - {0x109D, 0x109D}, - {0x135D, 0x135F}, - {0x1712, 0x1714}, - {0x1732, 0x1733}, - {0x1752, 0x1753}, - {0x1772, 0x1773}, - {0x17B4, 0x17B5}, - {0x17B7, 0x17BD}, - {0x17C6, 0x17C6}, - {0x17C9, 0x17D3}, - {0x17DD, 0x17DD}, - {0x180B, 0x180F}, - {0x1885, 0x1886}, - {0x18A9, 0x18A9}, - {0x1920, 0x1922}, - {0x1927, 0x1928}, - {0x1932, 0x1932}, - {0x1939, 0x193B}, - {0x1A17, 0x1A18}, - {0x1A1B, 0x1A1B}, - {0x1A56, 0x1A56}, - {0x1A58, 0x1A60}, - {0x1A62, 0x1A62}, - {0x1A65, 0x1A6C}, - {0x1A73, 0x1A7F}, - {0x1AB0, 0x1B03}, - {0x1B34, 0x1B34}, - {0x1B36, 0x1B3A}, - {0x1B3C, 0x1B3C}, - {0x1B42, 0x1B42}, - {0x1B6B, 0x1B73}, - {0x1B80, 0x1B81}, - {0x1BA2, 0x1BA5}, - {0x1BA8, 0x1BA9}, - {0x1BAB, 0x1BAD}, - {0x1BE6, 0x1BE6}, - {0x1BE8, 0x1BE9}, - {0x1BED, 0x1BED}, - {0x1BEF, 0x1BF1}, - {0x1C2C, 0x1C33}, - {0x1C36, 0x1C37}, - {0x1CD0, 0x1CD2}, - {0x1CD4, 0x1CE0}, - {0x1CE2, 0x1CE8}, - {0x1CED, 0x1CED}, - {0x1CF4, 0x1CF4}, - {0x1CF8, 0x1CF9}, - {0x1DC0, 0x1DFF}, - {0x200B, 0x200F}, - {0x202A, 0x202E}, - {0x2060, 0x206F}, - {0x20D0, 0x20F0}, - {0x2CEF, 0x2CF1}, - {0x2D7F, 0x2D7F}, - {0x2DE0, 0x2DFF}, - {0x302A, 0x302D}, - {0x3099, 0x309A}, - {0xA66F, 0xA672}, - {0xA674, 0xA67D}, - {0xA69E, 0xA69F}, - {0xA6F0, 0xA6F1}, - {0xA802, 0xA802}, - {0xA806, 0xA806}, - {0xA80B, 0xA80B}, - {0xA825, 0xA826}, - {0xA82C, 0xA82C}, - {0xA8C4, 0xA8C5}, - {0xA8E0, 0xA8F1}, - {0xA8FF, 0xA8FF}, - {0xA926, 0xA92D}, - {0xA947, 0xA951}, - {0xA980, 0xA982}, - {0xA9B3, 0xA9B3}, - {0xA9B6, 0xA9B9}, - {0xA9BC, 0xA9BD}, - {0xA9E5, 0xA9E5}, - {0xAA29, 0xAA2E}, - {0xAA31, 0xAA32}, - {0xAA35, 0xAA36}, - {0xAA43, 0xAA43}, - {0xAA4C, 0xAA4C}, - {0xAA7C, 0xAA7C}, - {0xAAB0, 0xAAB0}, - {0xAAB2, 0xAAB4}, - {0xAAB7, 0xAAB8}, - {0xAABE, 0xAABF}, - {0xAAC1, 0xAAC1}, - {0xAAEC, 0xAAED}, - {0xAAF6, 0xAAF6}, - {0xABE5, 0xABE5}, - {0xABE8, 0xABE8}, - {0xABED, 0xABED}, - {0xFB1E, 0xFB1E}, - {0xFE00, 0xFE0F}, - {0xFE20, 0xFE2F}, - {0xFEFF, 0xFEFF}, - {0xFFF9, 0xFFFB}, - {0x101FD, 0x101FD}, - {0x102E0, 0x102E0}, - {0x10376, 0x1037A}, - {0x10A01, 0x10A0F}, - {0x10A38, 0x10A3F}, - {0x10AE5, 0x10AE6}, - {0x10D24, 0x10D27}, - {0x10EAB, 0x10EAC}, - {0x10EFD, 0x10EFF}, - {0x10F46, 0x10F50}, - {0x10F82, 0x10F85}, - {0x11001, 0x11001}, - {0x11038, 0x11046}, - {0x11070, 0x11070}, - {0x11073, 0x11074}, - {0x1107F, 0x11081}, - {0x110B3, 0x110B6}, - {0x110B9, 0x110BA}, - {0x110BD, 0x110BD}, - {0x110C2, 0x110CD}, - {0x11100, 0x11102}, - {0x11127, 0x1112B}, - {0x1112D, 0x11134}, - {0x11173, 0x11173}, - {0x11180, 0x11181}, - {0x111B6, 0x111BE}, - {0x111C9, 0x111CC}, - {0x111CF, 0x111CF}, - {0x1122F, 0x11231}, - {0x11234, 0x11234}, - {0x11236, 0x11237}, - {0x1123E, 0x1123E}, - {0x11241, 0x11241}, - {0x112DF, 0x112DF}, - {0x112E3, 0x112EA}, - {0x11300, 0x11301}, - {0x1133B, 0x1133C}, - {0x11340, 0x11340}, - {0x11366, 0x11374}, - {0x11438, 0x1143F}, - {0x11442, 0x11444}, - {0x11446, 0x11446}, - {0x1145E, 0x1145E}, - {0x114B3, 0x114B8}, - {0x114BA, 0x114BA}, - {0x114BF, 0x114C0}, - {0x114C2, 0x114C3}, - {0x115B2, 0x115B5}, - {0x115BC, 0x115BD}, - {0x115BF, 0x115C0}, - {0x115DC, 0x115DD}, - {0x11633, 0x1163A}, - {0x1163D, 0x1163D}, - {0x1163F, 0x11640}, - {0x116AB, 0x116AB}, - {0x116AD, 0x116AD}, - {0x116B0, 0x116B5}, - {0x116B7, 0x116B7}, - {0x1171D, 0x1171F}, - {0x11722, 0x11725}, - {0x11727, 0x1172B}, - {0x1182F, 0x11837}, - {0x11839, 0x1183A}, - {0x1193B, 0x1193C}, - {0x1193E, 0x1193E}, - {0x11943, 0x11943}, - {0x119D4, 0x119DB}, - {0x119E0, 0x119E0}, - {0x11A01, 0x11A0A}, - {0x11A33, 0x11A38}, - {0x11A3B, 0x11A3E}, - {0x11A47, 0x11A47}, - {0x11A51, 0x11A56}, - {0x11A59, 0x11A5B}, - {0x11A8A, 0x11A96}, - {0x11A98, 0x11A99}, - {0x11C30, 0x11C3D}, - {0x11C3F, 0x11C3F}, - {0x11C92, 0x11CA7}, - {0x11CAA, 0x11CB0}, - {0x11CB2, 0x11CB3}, - {0x11CB5, 0x11CB6}, - {0x11D31, 0x11D45}, - {0x11D47, 0x11D47}, - {0x11D90, 0x11D91}, - {0x11D95, 0x11D95}, - {0x11D97, 0x11D97}, - {0x11EF3, 0x11EF4}, - {0x11F00, 0x11F01}, - {0x11F36, 0x11F3A}, - {0x11F40, 0x11F40}, - {0x11F42, 0x11F42}, - {0x13430, 0x13440}, - {0x13447, 0x13455}, - {0x16AF0, 0x16AF4}, - {0x16B30, 0x16B36}, - {0x16F4F, 0x16F4F}, - {0x16F8F, 0x16F92}, - {0x16FE4, 0x16FE4}, - {0x1BC9D, 0x1BC9E}, - {0x1BCA0, 0x1CF46}, - {0x1D167, 0x1D169}, - {0x1D173, 0x1D182}, - {0x1D185, 0x1D18B}, - {0x1D1AA, 0x1D1AD}, - {0x1D242, 0x1D244}, - {0x1DA00, 0x1DA36}, - {0x1DA3B, 0x1DA6C}, - {0x1DA75, 0x1DA75}, - {0x1DA84, 0x1DA84}, - {0x1DA9B, 0x1DAAF}, - {0x1E000, 0x1E02A}, - {0x1E08F, 0x1E08F}, - {0x1E130, 0x1E136}, - {0x1E2AE, 0x1E2AE}, - {0x1E2EC, 0x1E2EF}, - {0x1E4EC, 0x1E4EF}, - {0x1E8D0, 0x1E8D6}, - {0x1E944, 0x1E94A}, - {0xE0001, 0xE01EF}, -}; diff --git a/contrib/libs/libpq/src/include/common/unicode_norm.h b/contrib/libs/libpq/src/include/common/unicode_norm.h deleted file mode 100644 index c6627aeb7c..0000000000 --- a/contrib/libs/libpq/src/include/common/unicode_norm.h +++ /dev/null @@ -1,39 +0,0 @@ -/*------------------------------------------------------------------------- - * - * unicode_norm.h - * Routines for normalizing Unicode strings - * - * These definitions are used by both frontend and backend code. - * - * Copyright (c) 2017-2023, PostgreSQL Global Development Group - * - * src/include/common/unicode_norm.h - * - *------------------------------------------------------------------------- - */ -#ifndef UNICODE_NORM_H -#define UNICODE_NORM_H - -#include "mb/pg_wchar.h" - -typedef enum -{ - UNICODE_NFC = 0, - UNICODE_NFD = 1, - UNICODE_NFKC = 2, - UNICODE_NFKD = 3, -} UnicodeNormalizationForm; - -/* see UAX #15 */ -typedef enum -{ - UNICODE_NORM_QC_NO = 0, - UNICODE_NORM_QC_YES = 1, - UNICODE_NORM_QC_MAYBE = -1, -} UnicodeNormalizationQC; - -extern pg_wchar *unicode_normalize(UnicodeNormalizationForm form, const pg_wchar *input); - -extern UnicodeNormalizationQC unicode_is_normalized_quickcheck(UnicodeNormalizationForm form, const pg_wchar *input); - -#endif /* UNICODE_NORM_H */ diff --git a/contrib/libs/libpq/src/include/common/unicode_norm_table.h b/contrib/libs/libpq/src/include/common/unicode_norm_table.h deleted file mode 100644 index 36b6ca4044..0000000000 --- a/contrib/libs/libpq/src/include/common/unicode_norm_table.h +++ /dev/null @@ -1,9114 +0,0 @@ -/*------------------------------------------------------------------------- - * - * unicode_norm_table.h - * Composition table used for Unicode normalization - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/common/unicode_norm_table.h - * - *------------------------------------------------------------------------- - */ - -/* - * File auto-generated by src/common/unicode/generate-unicode_norm_table.pl, - * do not edit. There is deliberately not an #ifndef PG_UNICODE_NORM_TABLE_H - * here. - */ -typedef struct -{ - uint32 codepoint; /* Unicode codepoint */ - uint8 comb_class; /* combining class of character */ - uint8 dec_size_flags; /* size and flags of decomposition code list */ - uint16 dec_index; /* index into UnicodeDecomp_codepoints, or the - * decomposition itself if DECOMP_INLINE */ -} pg_unicode_decomposition; - -#define DECOMP_NO_COMPOSE 0x80 /* don't use for re-composition */ -#define DECOMP_INLINE 0x40 /* decomposition is stored inline in - * dec_index */ -#define DECOMP_COMPAT 0x20 /* compatibility mapping */ - -#define DECOMPOSITION_SIZE(x) ((x)->dec_size_flags & 0x1F) -#define DECOMPOSITION_NO_COMPOSE(x) (((x)->dec_size_flags & (DECOMP_NO_COMPOSE | DECOMP_COMPAT)) != 0) -#define DECOMPOSITION_IS_INLINE(x) (((x)->dec_size_flags & DECOMP_INLINE) != 0) -#define DECOMPOSITION_IS_COMPAT(x) (((x)->dec_size_flags & DECOMP_COMPAT) != 0) - -/* Table of Unicode codepoints and their decompositions */ -static const pg_unicode_decomposition UnicodeDecompMain[6775] = -{ - {0x00A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x00A8, 0, 2 | DECOMP_COMPAT, 0}, - {0x00AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x00AF, 0, 2 | DECOMP_COMPAT, 2}, - {0x00B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x00B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x00B4, 0, 2 | DECOMP_COMPAT, 4}, - {0x00B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x00B8, 0, 2 | DECOMP_COMPAT, 6}, - {0x00B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x00BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x00BC, 0, 3 | DECOMP_COMPAT, 8}, - {0x00BD, 0, 3 | DECOMP_COMPAT, 11}, - {0x00BE, 0, 3 | DECOMP_COMPAT, 14}, - {0x00C0, 0, 2, 17}, - {0x00C1, 0, 2, 19}, - {0x00C2, 0, 2, 21}, - {0x00C3, 0, 2, 23}, - {0x00C4, 0, 2, 25}, - {0x00C5, 0, 2, 27}, - {0x00C7, 0, 2, 29}, - {0x00C8, 0, 2, 31}, - {0x00C9, 0, 2, 33}, - {0x00CA, 0, 2, 35}, - {0x00CB, 0, 2, 37}, - {0x00CC, 0, 2, 39}, - {0x00CD, 0, 2, 41}, - {0x00CE, 0, 2, 43}, - {0x00CF, 0, 2, 45}, - {0x00D1, 0, 2, 47}, - {0x00D2, 0, 2, 49}, - {0x00D3, 0, 2, 51}, - {0x00D4, 0, 2, 53}, - {0x00D5, 0, 2, 55}, - {0x00D6, 0, 2, 57}, - {0x00D9, 0, 2, 59}, - {0x00DA, 0, 2, 61}, - {0x00DB, 0, 2, 63}, - {0x00DC, 0, 2, 65}, - {0x00DD, 0, 2, 67}, - {0x00E0, 0, 2, 69}, - {0x00E1, 0, 2, 71}, - {0x00E2, 0, 2, 73}, - {0x00E3, 0, 2, 75}, - {0x00E4, 0, 2, 77}, - {0x00E5, 0, 2, 79}, - {0x00E7, 0, 2, 81}, - {0x00E8, 0, 2, 83}, - {0x00E9, 0, 2, 85}, - {0x00EA, 0, 2, 87}, - {0x00EB, 0, 2, 89}, - {0x00EC, 0, 2, 91}, - {0x00ED, 0, 2, 93}, - {0x00EE, 0, 2, 95}, - {0x00EF, 0, 2, 97}, - {0x00F1, 0, 2, 99}, - {0x00F2, 0, 2, 101}, - {0x00F3, 0, 2, 103}, - {0x00F4, 0, 2, 105}, - {0x00F5, 0, 2, 107}, - {0x00F6, 0, 2, 109}, - {0x00F9, 0, 2, 111}, - {0x00FA, 0, 2, 113}, - {0x00FB, 0, 2, 115}, - {0x00FC, 0, 2, 117}, - {0x00FD, 0, 2, 119}, - {0x00FF, 0, 2, 121}, - {0x0100, 0, 2, 123}, - {0x0101, 0, 2, 125}, - {0x0102, 0, 2, 127}, - {0x0103, 0, 2, 129}, - {0x0104, 0, 2, 131}, - {0x0105, 0, 2, 133}, - {0x0106, 0, 2, 135}, - {0x0107, 0, 2, 137}, - {0x0108, 0, 2, 139}, - {0x0109, 0, 2, 141}, - {0x010A, 0, 2, 143}, - {0x010B, 0, 2, 145}, - {0x010C, 0, 2, 147}, - {0x010D, 0, 2, 149}, - {0x010E, 0, 2, 151}, - {0x010F, 0, 2, 153}, - {0x0112, 0, 2, 155}, - {0x0113, 0, 2, 157}, - {0x0114, 0, 2, 159}, - {0x0115, 0, 2, 161}, - {0x0116, 0, 2, 163}, - {0x0117, 0, 2, 165}, - {0x0118, 0, 2, 167}, - {0x0119, 0, 2, 169}, - {0x011A, 0, 2, 171}, - {0x011B, 0, 2, 173}, - {0x011C, 0, 2, 175}, - {0x011D, 0, 2, 177}, - {0x011E, 0, 2, 179}, - {0x011F, 0, 2, 181}, - {0x0120, 0, 2, 183}, - {0x0121, 0, 2, 185}, - {0x0122, 0, 2, 187}, - {0x0123, 0, 2, 189}, - {0x0124, 0, 2, 191}, - {0x0125, 0, 2, 193}, - {0x0128, 0, 2, 195}, - {0x0129, 0, 2, 197}, - {0x012A, 0, 2, 199}, - {0x012B, 0, 2, 201}, - {0x012C, 0, 2, 203}, - {0x012D, 0, 2, 205}, - {0x012E, 0, 2, 207}, - {0x012F, 0, 2, 209}, - {0x0130, 0, 2, 211}, - {0x0132, 0, 2 | DECOMP_COMPAT, 213}, - {0x0133, 0, 2 | DECOMP_COMPAT, 215}, - {0x0134, 0, 2, 217}, - {0x0135, 0, 2, 219}, - {0x0136, 0, 2, 221}, - {0x0137, 0, 2, 223}, - {0x0139, 0, 2, 225}, - {0x013A, 0, 2, 227}, - {0x013B, 0, 2, 229}, - {0x013C, 0, 2, 231}, - {0x013D, 0, 2, 233}, - {0x013E, 0, 2, 235}, - {0x013F, 0, 2 | DECOMP_COMPAT, 237}, - {0x0140, 0, 2 | DECOMP_COMPAT, 239}, - {0x0143, 0, 2, 241}, - {0x0144, 0, 2, 243}, - {0x0145, 0, 2, 245}, - {0x0146, 0, 2, 247}, - {0x0147, 0, 2, 249}, - {0x0148, 0, 2, 251}, - {0x0149, 0, 2 | DECOMP_COMPAT, 253}, - {0x014C, 0, 2, 255}, - {0x014D, 0, 2, 257}, - {0x014E, 0, 2, 259}, - {0x014F, 0, 2, 261}, - {0x0150, 0, 2, 263}, - {0x0151, 0, 2, 265}, - {0x0154, 0, 2, 267}, - {0x0155, 0, 2, 269}, - {0x0156, 0, 2, 271}, - {0x0157, 0, 2, 273}, - {0x0158, 0, 2, 275}, - {0x0159, 0, 2, 277}, - {0x015A, 0, 2, 279}, - {0x015B, 0, 2, 281}, - {0x015C, 0, 2, 283}, - {0x015D, 0, 2, 285}, - {0x015E, 0, 2, 287}, - {0x015F, 0, 2, 289}, - {0x0160, 0, 2, 291}, - {0x0161, 0, 2, 293}, - {0x0162, 0, 2, 295}, - {0x0163, 0, 2, 297}, - {0x0164, 0, 2, 299}, - {0x0165, 0, 2, 301}, - {0x0168, 0, 2, 303}, - {0x0169, 0, 2, 305}, - {0x016A, 0, 2, 307}, - {0x016B, 0, 2, 309}, - {0x016C, 0, 2, 311}, - {0x016D, 0, 2, 313}, - {0x016E, 0, 2, 315}, - {0x016F, 0, 2, 317}, - {0x0170, 0, 2, 319}, - {0x0171, 0, 2, 321}, - {0x0172, 0, 2, 323}, - {0x0173, 0, 2, 325}, - {0x0174, 0, 2, 327}, - {0x0175, 0, 2, 329}, - {0x0176, 0, 2, 331}, - {0x0177, 0, 2, 333}, - {0x0178, 0, 2, 335}, - {0x0179, 0, 2, 337}, - {0x017A, 0, 2, 339}, - {0x017B, 0, 2, 341}, - {0x017C, 0, 2, 343}, - {0x017D, 0, 2, 345}, - {0x017E, 0, 2, 347}, - {0x017F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x01A0, 0, 2, 349}, - {0x01A1, 0, 2, 351}, - {0x01AF, 0, 2, 353}, - {0x01B0, 0, 2, 355}, - {0x01C4, 0, 2 | DECOMP_COMPAT, 357}, - {0x01C5, 0, 2 | DECOMP_COMPAT, 359}, - {0x01C6, 0, 2 | DECOMP_COMPAT, 361}, - {0x01C7, 0, 2 | DECOMP_COMPAT, 363}, - {0x01C8, 0, 2 | DECOMP_COMPAT, 365}, - {0x01C9, 0, 2 | DECOMP_COMPAT, 367}, - {0x01CA, 0, 2 | DECOMP_COMPAT, 369}, - {0x01CB, 0, 2 | DECOMP_COMPAT, 371}, - {0x01CC, 0, 2 | DECOMP_COMPAT, 373}, - {0x01CD, 0, 2, 375}, - {0x01CE, 0, 2, 377}, - {0x01CF, 0, 2, 379}, - {0x01D0, 0, 2, 381}, - {0x01D1, 0, 2, 383}, - {0x01D2, 0, 2, 385}, - {0x01D3, 0, 2, 387}, - {0x01D4, 0, 2, 389}, - {0x01D5, 0, 2, 391}, - {0x01D6, 0, 2, 393}, - {0x01D7, 0, 2, 395}, - {0x01D8, 0, 2, 397}, - {0x01D9, 0, 2, 399}, - {0x01DA, 0, 2, 401}, - {0x01DB, 0, 2, 403}, - {0x01DC, 0, 2, 405}, - {0x01DE, 0, 2, 407}, - {0x01DF, 0, 2, 409}, - {0x01E0, 0, 2, 411}, - {0x01E1, 0, 2, 413}, - {0x01E2, 0, 2, 415}, - {0x01E3, 0, 2, 417}, - {0x01E6, 0, 2, 419}, - {0x01E7, 0, 2, 421}, - {0x01E8, 0, 2, 423}, - {0x01E9, 0, 2, 425}, - {0x01EA, 0, 2, 427}, - {0x01EB, 0, 2, 429}, - {0x01EC, 0, 2, 431}, - {0x01ED, 0, 2, 433}, - {0x01EE, 0, 2, 435}, - {0x01EF, 0, 2, 437}, - {0x01F0, 0, 2, 439}, - {0x01F1, 0, 2 | DECOMP_COMPAT, 441}, - {0x01F2, 0, 2 | DECOMP_COMPAT, 443}, - {0x01F3, 0, 2 | DECOMP_COMPAT, 445}, - {0x01F4, 0, 2, 447}, - {0x01F5, 0, 2, 449}, - {0x01F8, 0, 2, 451}, - {0x01F9, 0, 2, 453}, - {0x01FA, 0, 2, 455}, - {0x01FB, 0, 2, 457}, - {0x01FC, 0, 2, 459}, - {0x01FD, 0, 2, 461}, - {0x01FE, 0, 2, 463}, - {0x01FF, 0, 2, 465}, - {0x0200, 0, 2, 467}, - {0x0201, 0, 2, 469}, - {0x0202, 0, 2, 471}, - {0x0203, 0, 2, 473}, - {0x0204, 0, 2, 475}, - {0x0205, 0, 2, 477}, - {0x0206, 0, 2, 479}, - {0x0207, 0, 2, 481}, - {0x0208, 0, 2, 483}, - {0x0209, 0, 2, 485}, - {0x020A, 0, 2, 487}, - {0x020B, 0, 2, 489}, - {0x020C, 0, 2, 491}, - {0x020D, 0, 2, 493}, - {0x020E, 0, 2, 495}, - {0x020F, 0, 2, 497}, - {0x0210, 0, 2, 499}, - {0x0211, 0, 2, 501}, - {0x0212, 0, 2, 503}, - {0x0213, 0, 2, 505}, - {0x0214, 0, 2, 507}, - {0x0215, 0, 2, 509}, - {0x0216, 0, 2, 511}, - {0x0217, 0, 2, 513}, - {0x0218, 0, 2, 515}, - {0x0219, 0, 2, 517}, - {0x021A, 0, 2, 519}, - {0x021B, 0, 2, 521}, - {0x021E, 0, 2, 523}, - {0x021F, 0, 2, 525}, - {0x0226, 0, 2, 527}, - {0x0227, 0, 2, 529}, - {0x0228, 0, 2, 531}, - {0x0229, 0, 2, 533}, - {0x022A, 0, 2, 535}, - {0x022B, 0, 2, 537}, - {0x022C, 0, 2, 539}, - {0x022D, 0, 2, 541}, - {0x022E, 0, 2, 543}, - {0x022F, 0, 2, 545}, - {0x0230, 0, 2, 547}, - {0x0231, 0, 2, 549}, - {0x0232, 0, 2, 551}, - {0x0233, 0, 2, 553}, - {0x02B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x02B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0266}, - {0x02B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x02B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x02B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0279}, - {0x02B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027B}, - {0x02B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0281}, - {0x02B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x02B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x02D8, 0, 2 | DECOMP_COMPAT, 555}, - {0x02D9, 0, 2 | DECOMP_COMPAT, 557}, - {0x02DA, 0, 2 | DECOMP_COMPAT, 559}, - {0x02DB, 0, 2 | DECOMP_COMPAT, 561}, - {0x02DC, 0, 2 | DECOMP_COMPAT, 563}, - {0x02DD, 0, 2 | DECOMP_COMPAT, 565}, - {0x02E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0263}, - {0x02E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x02E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x02E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x02E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0295}, - {0x0300, 230, 0, 0}, - {0x0301, 230, 0, 0}, - {0x0302, 230, 0, 0}, - {0x0303, 230, 0, 0}, - {0x0304, 230, 0, 0}, - {0x0305, 230, 0, 0}, - {0x0306, 230, 0, 0}, - {0x0307, 230, 0, 0}, - {0x0308, 230, 0, 0}, - {0x0309, 230, 0, 0}, - {0x030A, 230, 0, 0}, - {0x030B, 230, 0, 0}, - {0x030C, 230, 0, 0}, - {0x030D, 230, 0, 0}, - {0x030E, 230, 0, 0}, - {0x030F, 230, 0, 0}, - {0x0310, 230, 0, 0}, - {0x0311, 230, 0, 0}, - {0x0312, 230, 0, 0}, - {0x0313, 230, 0, 0}, - {0x0314, 230, 0, 0}, - {0x0315, 232, 0, 0}, - {0x0316, 220, 0, 0}, - {0x0317, 220, 0, 0}, - {0x0318, 220, 0, 0}, - {0x0319, 220, 0, 0}, - {0x031A, 232, 0, 0}, - {0x031B, 216, 0, 0}, - {0x031C, 220, 0, 0}, - {0x031D, 220, 0, 0}, - {0x031E, 220, 0, 0}, - {0x031F, 220, 0, 0}, - {0x0320, 220, 0, 0}, - {0x0321, 202, 0, 0}, - {0x0322, 202, 0, 0}, - {0x0323, 220, 0, 0}, - {0x0324, 220, 0, 0}, - {0x0325, 220, 0, 0}, - {0x0326, 220, 0, 0}, - {0x0327, 202, 0, 0}, - {0x0328, 202, 0, 0}, - {0x0329, 220, 0, 0}, - {0x032A, 220, 0, 0}, - {0x032B, 220, 0, 0}, - {0x032C, 220, 0, 0}, - {0x032D, 220, 0, 0}, - {0x032E, 220, 0, 0}, - {0x032F, 220, 0, 0}, - {0x0330, 220, 0, 0}, - {0x0331, 220, 0, 0}, - {0x0332, 220, 0, 0}, - {0x0333, 220, 0, 0}, - {0x0334, 1, 0, 0}, - {0x0335, 1, 0, 0}, - {0x0336, 1, 0, 0}, - {0x0337, 1, 0, 0}, - {0x0338, 1, 0, 0}, - {0x0339, 220, 0, 0}, - {0x033A, 220, 0, 0}, - {0x033B, 220, 0, 0}, - {0x033C, 220, 0, 0}, - {0x033D, 230, 0, 0}, - {0x033E, 230, 0, 0}, - {0x033F, 230, 0, 0}, - {0x0340, 230, 1 | DECOMP_INLINE, 0x0300}, - {0x0341, 230, 1 | DECOMP_INLINE, 0x0301}, - {0x0342, 230, 0, 0}, - {0x0343, 230, 1 | DECOMP_INLINE, 0x0313}, - {0x0344, 230, 2 | DECOMP_NO_COMPOSE, 567}, /* non-starter decomposition */ - {0x0345, 240, 0, 0}, - {0x0346, 230, 0, 0}, - {0x0347, 220, 0, 0}, - {0x0348, 220, 0, 0}, - {0x0349, 220, 0, 0}, - {0x034A, 230, 0, 0}, - {0x034B, 230, 0, 0}, - {0x034C, 230, 0, 0}, - {0x034D, 220, 0, 0}, - {0x034E, 220, 0, 0}, - {0x0350, 230, 0, 0}, - {0x0351, 230, 0, 0}, - {0x0352, 230, 0, 0}, - {0x0353, 220, 0, 0}, - {0x0354, 220, 0, 0}, - {0x0355, 220, 0, 0}, - {0x0356, 220, 0, 0}, - {0x0357, 230, 0, 0}, - {0x0358, 232, 0, 0}, - {0x0359, 220, 0, 0}, - {0x035A, 220, 0, 0}, - {0x035B, 230, 0, 0}, - {0x035C, 233, 0, 0}, - {0x035D, 234, 0, 0}, - {0x035E, 234, 0, 0}, - {0x035F, 233, 0, 0}, - {0x0360, 234, 0, 0}, - {0x0361, 234, 0, 0}, - {0x0362, 233, 0, 0}, - {0x0363, 230, 0, 0}, - {0x0364, 230, 0, 0}, - {0x0365, 230, 0, 0}, - {0x0366, 230, 0, 0}, - {0x0367, 230, 0, 0}, - {0x0368, 230, 0, 0}, - {0x0369, 230, 0, 0}, - {0x036A, 230, 0, 0}, - {0x036B, 230, 0, 0}, - {0x036C, 230, 0, 0}, - {0x036D, 230, 0, 0}, - {0x036E, 230, 0, 0}, - {0x036F, 230, 0, 0}, - {0x0374, 0, 1 | DECOMP_INLINE, 0x02B9}, - {0x037A, 0, 2 | DECOMP_COMPAT, 569}, - {0x037E, 0, 1 | DECOMP_INLINE, 0x003B}, - {0x0384, 0, 2 | DECOMP_COMPAT, 571}, - {0x0385, 0, 2, 573}, - {0x0386, 0, 2, 575}, - {0x0387, 0, 1 | DECOMP_INLINE, 0x00B7}, - {0x0388, 0, 2, 577}, - {0x0389, 0, 2, 579}, - {0x038A, 0, 2, 581}, - {0x038C, 0, 2, 583}, - {0x038E, 0, 2, 585}, - {0x038F, 0, 2, 587}, - {0x0390, 0, 2, 589}, - {0x03AA, 0, 2, 591}, - {0x03AB, 0, 2, 593}, - {0x03AC, 0, 2, 595}, - {0x03AD, 0, 2, 597}, - {0x03AE, 0, 2, 599}, - {0x03AF, 0, 2, 601}, - {0x03B0, 0, 2, 603}, - {0x03CA, 0, 2, 605}, - {0x03CB, 0, 2, 607}, - {0x03CC, 0, 2, 609}, - {0x03CD, 0, 2, 611}, - {0x03CE, 0, 2, 613}, - {0x03D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x03D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x03D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x03D3, 0, 2, 615}, - {0x03D4, 0, 2, 617}, - {0x03D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x03D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x03F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x03F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x03F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x03F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x03F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x03F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x0400, 0, 2, 619}, - {0x0401, 0, 2, 621}, - {0x0403, 0, 2, 623}, - {0x0407, 0, 2, 625}, - {0x040C, 0, 2, 627}, - {0x040D, 0, 2, 629}, - {0x040E, 0, 2, 631}, - {0x0419, 0, 2, 633}, - {0x0439, 0, 2, 635}, - {0x0450, 0, 2, 637}, - {0x0451, 0, 2, 639}, - {0x0453, 0, 2, 641}, - {0x0457, 0, 2, 643}, - {0x045C, 0, 2, 645}, - {0x045D, 0, 2, 647}, - {0x045E, 0, 2, 649}, - {0x0476, 0, 2, 651}, - {0x0477, 0, 2, 653}, - {0x0483, 230, 0, 0}, - {0x0484, 230, 0, 0}, - {0x0485, 230, 0, 0}, - {0x0486, 230, 0, 0}, - {0x0487, 230, 0, 0}, - {0x04C1, 0, 2, 655}, - {0x04C2, 0, 2, 657}, - {0x04D0, 0, 2, 659}, - {0x04D1, 0, 2, 661}, - {0x04D2, 0, 2, 663}, - {0x04D3, 0, 2, 665}, - {0x04D6, 0, 2, 667}, - {0x04D7, 0, 2, 669}, - {0x04DA, 0, 2, 671}, - {0x04DB, 0, 2, 673}, - {0x04DC, 0, 2, 675}, - {0x04DD, 0, 2, 677}, - {0x04DE, 0, 2, 679}, - {0x04DF, 0, 2, 681}, - {0x04E2, 0, 2, 683}, - {0x04E3, 0, 2, 685}, - {0x04E4, 0, 2, 687}, - {0x04E5, 0, 2, 689}, - {0x04E6, 0, 2, 691}, - {0x04E7, 0, 2, 693}, - {0x04EA, 0, 2, 695}, - {0x04EB, 0, 2, 697}, - {0x04EC, 0, 2, 699}, - {0x04ED, 0, 2, 701}, - {0x04EE, 0, 2, 703}, - {0x04EF, 0, 2, 705}, - {0x04F0, 0, 2, 707}, - {0x04F1, 0, 2, 709}, - {0x04F2, 0, 2, 711}, - {0x04F3, 0, 2, 713}, - {0x04F4, 0, 2, 715}, - {0x04F5, 0, 2, 717}, - {0x04F8, 0, 2, 719}, - {0x04F9, 0, 2, 721}, - {0x0587, 0, 2 | DECOMP_COMPAT, 723}, - {0x0591, 220, 0, 0}, - {0x0592, 230, 0, 0}, - {0x0593, 230, 0, 0}, - {0x0594, 230, 0, 0}, - {0x0595, 230, 0, 0}, - {0x0596, 220, 0, 0}, - {0x0597, 230, 0, 0}, - {0x0598, 230, 0, 0}, - {0x0599, 230, 0, 0}, - {0x059A, 222, 0, 0}, - {0x059B, 220, 0, 0}, - {0x059C, 230, 0, 0}, - {0x059D, 230, 0, 0}, - {0x059E, 230, 0, 0}, - {0x059F, 230, 0, 0}, - {0x05A0, 230, 0, 0}, - {0x05A1, 230, 0, 0}, - {0x05A2, 220, 0, 0}, - {0x05A3, 220, 0, 0}, - {0x05A4, 220, 0, 0}, - {0x05A5, 220, 0, 0}, - {0x05A6, 220, 0, 0}, - {0x05A7, 220, 0, 0}, - {0x05A8, 230, 0, 0}, - {0x05A9, 230, 0, 0}, - {0x05AA, 220, 0, 0}, - {0x05AB, 230, 0, 0}, - {0x05AC, 230, 0, 0}, - {0x05AD, 222, 0, 0}, - {0x05AE, 228, 0, 0}, - {0x05AF, 230, 0, 0}, - {0x05B0, 10, 0, 0}, - {0x05B1, 11, 0, 0}, - {0x05B2, 12, 0, 0}, - {0x05B3, 13, 0, 0}, - {0x05B4, 14, 0, 0}, - {0x05B5, 15, 0, 0}, - {0x05B6, 16, 0, 0}, - {0x05B7, 17, 0, 0}, - {0x05B8, 18, 0, 0}, - {0x05B9, 19, 0, 0}, - {0x05BA, 19, 0, 0}, - {0x05BB, 20, 0, 0}, - {0x05BC, 21, 0, 0}, - {0x05BD, 22, 0, 0}, - {0x05BF, 23, 0, 0}, - {0x05C1, 24, 0, 0}, - {0x05C2, 25, 0, 0}, - {0x05C4, 230, 0, 0}, - {0x05C5, 220, 0, 0}, - {0x05C7, 18, 0, 0}, - {0x0610, 230, 0, 0}, - {0x0611, 230, 0, 0}, - {0x0612, 230, 0, 0}, - {0x0613, 230, 0, 0}, - {0x0614, 230, 0, 0}, - {0x0615, 230, 0, 0}, - {0x0616, 230, 0, 0}, - {0x0617, 230, 0, 0}, - {0x0618, 30, 0, 0}, - {0x0619, 31, 0, 0}, - {0x061A, 32, 0, 0}, - {0x0622, 0, 2, 725}, - {0x0623, 0, 2, 727}, - {0x0624, 0, 2, 729}, - {0x0625, 0, 2, 731}, - {0x0626, 0, 2, 733}, - {0x064B, 27, 0, 0}, - {0x064C, 28, 0, 0}, - {0x064D, 29, 0, 0}, - {0x064E, 30, 0, 0}, - {0x064F, 31, 0, 0}, - {0x0650, 32, 0, 0}, - {0x0651, 33, 0, 0}, - {0x0652, 34, 0, 0}, - {0x0653, 230, 0, 0}, - {0x0654, 230, 0, 0}, - {0x0655, 220, 0, 0}, - {0x0656, 220, 0, 0}, - {0x0657, 230, 0, 0}, - {0x0658, 230, 0, 0}, - {0x0659, 230, 0, 0}, - {0x065A, 230, 0, 0}, - {0x065B, 230, 0, 0}, - {0x065C, 220, 0, 0}, - {0x065D, 230, 0, 0}, - {0x065E, 230, 0, 0}, - {0x065F, 220, 0, 0}, - {0x0670, 35, 0, 0}, - {0x0675, 0, 2 | DECOMP_COMPAT, 735}, - {0x0676, 0, 2 | DECOMP_COMPAT, 737}, - {0x0677, 0, 2 | DECOMP_COMPAT, 739}, - {0x0678, 0, 2 | DECOMP_COMPAT, 741}, - {0x06C0, 0, 2, 743}, - {0x06C2, 0, 2, 745}, - {0x06D3, 0, 2, 747}, - {0x06D6, 230, 0, 0}, - {0x06D7, 230, 0, 0}, - {0x06D8, 230, 0, 0}, - {0x06D9, 230, 0, 0}, - {0x06DA, 230, 0, 0}, - {0x06DB, 230, 0, 0}, - {0x06DC, 230, 0, 0}, - {0x06DF, 230, 0, 0}, - {0x06E0, 230, 0, 0}, - {0x06E1, 230, 0, 0}, - {0x06E2, 230, 0, 0}, - {0x06E3, 220, 0, 0}, - {0x06E4, 230, 0, 0}, - {0x06E7, 230, 0, 0}, - {0x06E8, 230, 0, 0}, - {0x06EA, 220, 0, 0}, - {0x06EB, 230, 0, 0}, - {0x06EC, 230, 0, 0}, - {0x06ED, 220, 0, 0}, - {0x0711, 36, 0, 0}, - {0x0730, 230, 0, 0}, - {0x0731, 220, 0, 0}, - {0x0732, 230, 0, 0}, - {0x0733, 230, 0, 0}, - {0x0734, 220, 0, 0}, - {0x0735, 230, 0, 0}, - {0x0736, 230, 0, 0}, - {0x0737, 220, 0, 0}, - {0x0738, 220, 0, 0}, - {0x0739, 220, 0, 0}, - {0x073A, 230, 0, 0}, - {0x073B, 220, 0, 0}, - {0x073C, 220, 0, 0}, - {0x073D, 230, 0, 0}, - {0x073E, 220, 0, 0}, - {0x073F, 230, 0, 0}, - {0x0740, 230, 0, 0}, - {0x0741, 230, 0, 0}, - {0x0742, 220, 0, 0}, - {0x0743, 230, 0, 0}, - {0x0744, 220, 0, 0}, - {0x0745, 230, 0, 0}, - {0x0746, 220, 0, 0}, - {0x0747, 230, 0, 0}, - {0x0748, 220, 0, 0}, - {0x0749, 230, 0, 0}, - {0x074A, 230, 0, 0}, - {0x07EB, 230, 0, 0}, - {0x07EC, 230, 0, 0}, - {0x07ED, 230, 0, 0}, - {0x07EE, 230, 0, 0}, - {0x07EF, 230, 0, 0}, - {0x07F0, 230, 0, 0}, - {0x07F1, 230, 0, 0}, - {0x07F2, 220, 0, 0}, - {0x07F3, 230, 0, 0}, - {0x07FD, 220, 0, 0}, - {0x0816, 230, 0, 0}, - {0x0817, 230, 0, 0}, - {0x0818, 230, 0, 0}, - {0x0819, 230, 0, 0}, - {0x081B, 230, 0, 0}, - {0x081C, 230, 0, 0}, - {0x081D, 230, 0, 0}, - {0x081E, 230, 0, 0}, - {0x081F, 230, 0, 0}, - {0x0820, 230, 0, 0}, - {0x0821, 230, 0, 0}, - {0x0822, 230, 0, 0}, - {0x0823, 230, 0, 0}, - {0x0825, 230, 0, 0}, - {0x0826, 230, 0, 0}, - {0x0827, 230, 0, 0}, - {0x0829, 230, 0, 0}, - {0x082A, 230, 0, 0}, - {0x082B, 230, 0, 0}, - {0x082C, 230, 0, 0}, - {0x082D, 230, 0, 0}, - {0x0859, 220, 0, 0}, - {0x085A, 220, 0, 0}, - {0x085B, 220, 0, 0}, - {0x0898, 230, 0, 0}, - {0x0899, 220, 0, 0}, - {0x089A, 220, 0, 0}, - {0x089B, 220, 0, 0}, - {0x089C, 230, 0, 0}, - {0x089D, 230, 0, 0}, - {0x089E, 230, 0, 0}, - {0x089F, 230, 0, 0}, - {0x08CA, 230, 0, 0}, - {0x08CB, 230, 0, 0}, - {0x08CC, 230, 0, 0}, - {0x08CD, 230, 0, 0}, - {0x08CE, 230, 0, 0}, - {0x08CF, 220, 0, 0}, - {0x08D0, 220, 0, 0}, - {0x08D1, 220, 0, 0}, - {0x08D2, 220, 0, 0}, - {0x08D3, 220, 0, 0}, - {0x08D4, 230, 0, 0}, - {0x08D5, 230, 0, 0}, - {0x08D6, 230, 0, 0}, - {0x08D7, 230, 0, 0}, - {0x08D8, 230, 0, 0}, - {0x08D9, 230, 0, 0}, - {0x08DA, 230, 0, 0}, - {0x08DB, 230, 0, 0}, - {0x08DC, 230, 0, 0}, - {0x08DD, 230, 0, 0}, - {0x08DE, 230, 0, 0}, - {0x08DF, 230, 0, 0}, - {0x08E0, 230, 0, 0}, - {0x08E1, 230, 0, 0}, - {0x08E3, 220, 0, 0}, - {0x08E4, 230, 0, 0}, - {0x08E5, 230, 0, 0}, - {0x08E6, 220, 0, 0}, - {0x08E7, 230, 0, 0}, - {0x08E8, 230, 0, 0}, - {0x08E9, 220, 0, 0}, - {0x08EA, 230, 0, 0}, - {0x08EB, 230, 0, 0}, - {0x08EC, 230, 0, 0}, - {0x08ED, 220, 0, 0}, - {0x08EE, 220, 0, 0}, - {0x08EF, 220, 0, 0}, - {0x08F0, 27, 0, 0}, - {0x08F1, 28, 0, 0}, - {0x08F2, 29, 0, 0}, - {0x08F3, 230, 0, 0}, - {0x08F4, 230, 0, 0}, - {0x08F5, 230, 0, 0}, - {0x08F6, 220, 0, 0}, - {0x08F7, 230, 0, 0}, - {0x08F8, 230, 0, 0}, - {0x08F9, 220, 0, 0}, - {0x08FA, 220, 0, 0}, - {0x08FB, 230, 0, 0}, - {0x08FC, 230, 0, 0}, - {0x08FD, 230, 0, 0}, - {0x08FE, 230, 0, 0}, - {0x08FF, 230, 0, 0}, - {0x0929, 0, 2, 749}, - {0x0931, 0, 2, 751}, - {0x0934, 0, 2, 753}, - {0x093C, 7, 0, 0}, - {0x094D, 9, 0, 0}, - {0x0951, 230, 0, 0}, - {0x0952, 220, 0, 0}, - {0x0953, 230, 0, 0}, - {0x0954, 230, 0, 0}, - {0x0958, 0, 2 | DECOMP_NO_COMPOSE, 755}, /* in exclusion list */ - {0x0959, 0, 2 | DECOMP_NO_COMPOSE, 757}, /* in exclusion list */ - {0x095A, 0, 2 | DECOMP_NO_COMPOSE, 759}, /* in exclusion list */ - {0x095B, 0, 2 | DECOMP_NO_COMPOSE, 761}, /* in exclusion list */ - {0x095C, 0, 2 | DECOMP_NO_COMPOSE, 763}, /* in exclusion list */ - {0x095D, 0, 2 | DECOMP_NO_COMPOSE, 765}, /* in exclusion list */ - {0x095E, 0, 2 | DECOMP_NO_COMPOSE, 767}, /* in exclusion list */ - {0x095F, 0, 2 | DECOMP_NO_COMPOSE, 769}, /* in exclusion list */ - {0x09BC, 7, 0, 0}, - {0x09CB, 0, 2, 771}, - {0x09CC, 0, 2, 773}, - {0x09CD, 9, 0, 0}, - {0x09DC, 0, 2 | DECOMP_NO_COMPOSE, 775}, /* in exclusion list */ - {0x09DD, 0, 2 | DECOMP_NO_COMPOSE, 777}, /* in exclusion list */ - {0x09DF, 0, 2 | DECOMP_NO_COMPOSE, 779}, /* in exclusion list */ - {0x09FE, 230, 0, 0}, - {0x0A33, 0, 2 | DECOMP_NO_COMPOSE, 781}, /* in exclusion list */ - {0x0A36, 0, 2 | DECOMP_NO_COMPOSE, 783}, /* in exclusion list */ - {0x0A3C, 7, 0, 0}, - {0x0A4D, 9, 0, 0}, - {0x0A59, 0, 2 | DECOMP_NO_COMPOSE, 785}, /* in exclusion list */ - {0x0A5A, 0, 2 | DECOMP_NO_COMPOSE, 787}, /* in exclusion list */ - {0x0A5B, 0, 2 | DECOMP_NO_COMPOSE, 789}, /* in exclusion list */ - {0x0A5E, 0, 2 | DECOMP_NO_COMPOSE, 791}, /* in exclusion list */ - {0x0ABC, 7, 0, 0}, - {0x0ACD, 9, 0, 0}, - {0x0B3C, 7, 0, 0}, - {0x0B48, 0, 2, 793}, - {0x0B4B, 0, 2, 795}, - {0x0B4C, 0, 2, 797}, - {0x0B4D, 9, 0, 0}, - {0x0B5C, 0, 2 | DECOMP_NO_COMPOSE, 799}, /* in exclusion list */ - {0x0B5D, 0, 2 | DECOMP_NO_COMPOSE, 801}, /* in exclusion list */ - {0x0B94, 0, 2, 803}, - {0x0BCA, 0, 2, 805}, - {0x0BCB, 0, 2, 807}, - {0x0BCC, 0, 2, 809}, - {0x0BCD, 9, 0, 0}, - {0x0C3C, 7, 0, 0}, - {0x0C48, 0, 2, 811}, - {0x0C4D, 9, 0, 0}, - {0x0C55, 84, 0, 0}, - {0x0C56, 91, 0, 0}, - {0x0CBC, 7, 0, 0}, - {0x0CC0, 0, 2, 813}, - {0x0CC7, 0, 2, 815}, - {0x0CC8, 0, 2, 817}, - {0x0CCA, 0, 2, 819}, - {0x0CCB, 0, 2, 821}, - {0x0CCD, 9, 0, 0}, - {0x0D3B, 9, 0, 0}, - {0x0D3C, 9, 0, 0}, - {0x0D4A, 0, 2, 823}, - {0x0D4B, 0, 2, 825}, - {0x0D4C, 0, 2, 827}, - {0x0D4D, 9, 0, 0}, - {0x0DCA, 9, 0, 0}, - {0x0DDA, 0, 2, 829}, - {0x0DDC, 0, 2, 831}, - {0x0DDD, 0, 2, 833}, - {0x0DDE, 0, 2, 835}, - {0x0E33, 0, 2 | DECOMP_COMPAT, 837}, - {0x0E38, 103, 0, 0}, - {0x0E39, 103, 0, 0}, - {0x0E3A, 9, 0, 0}, - {0x0E48, 107, 0, 0}, - {0x0E49, 107, 0, 0}, - {0x0E4A, 107, 0, 0}, - {0x0E4B, 107, 0, 0}, - {0x0EB3, 0, 2 | DECOMP_COMPAT, 839}, - {0x0EB8, 118, 0, 0}, - {0x0EB9, 118, 0, 0}, - {0x0EBA, 9, 0, 0}, - {0x0EC8, 122, 0, 0}, - {0x0EC9, 122, 0, 0}, - {0x0ECA, 122, 0, 0}, - {0x0ECB, 122, 0, 0}, - {0x0EDC, 0, 2 | DECOMP_COMPAT, 841}, - {0x0EDD, 0, 2 | DECOMP_COMPAT, 843}, - {0x0F0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0F0B}, - {0x0F18, 220, 0, 0}, - {0x0F19, 220, 0, 0}, - {0x0F35, 220, 0, 0}, - {0x0F37, 220, 0, 0}, - {0x0F39, 216, 0, 0}, - {0x0F43, 0, 2 | DECOMP_NO_COMPOSE, 845}, /* in exclusion list */ - {0x0F4D, 0, 2 | DECOMP_NO_COMPOSE, 847}, /* in exclusion list */ - {0x0F52, 0, 2 | DECOMP_NO_COMPOSE, 849}, /* in exclusion list */ - {0x0F57, 0, 2 | DECOMP_NO_COMPOSE, 851}, /* in exclusion list */ - {0x0F5C, 0, 2 | DECOMP_NO_COMPOSE, 853}, /* in exclusion list */ - {0x0F69, 0, 2 | DECOMP_NO_COMPOSE, 855}, /* in exclusion list */ - {0x0F71, 129, 0, 0}, - {0x0F72, 130, 0, 0}, - {0x0F73, 0, 2 | DECOMP_NO_COMPOSE, 857}, /* non-starter decomposition */ - {0x0F74, 132, 0, 0}, - {0x0F75, 0, 2 | DECOMP_NO_COMPOSE, 859}, /* non-starter decomposition */ - {0x0F76, 0, 2 | DECOMP_NO_COMPOSE, 861}, /* in exclusion list */ - {0x0F77, 0, 2 | DECOMP_COMPAT, 863}, - {0x0F78, 0, 2 | DECOMP_NO_COMPOSE, 865}, /* in exclusion list */ - {0x0F79, 0, 2 | DECOMP_COMPAT, 867}, - {0x0F7A, 130, 0, 0}, - {0x0F7B, 130, 0, 0}, - {0x0F7C, 130, 0, 0}, - {0x0F7D, 130, 0, 0}, - {0x0F80, 130, 0, 0}, - {0x0F81, 0, 2 | DECOMP_NO_COMPOSE, 869}, /* non-starter decomposition */ - {0x0F82, 230, 0, 0}, - {0x0F83, 230, 0, 0}, - {0x0F84, 9, 0, 0}, - {0x0F86, 230, 0, 0}, - {0x0F87, 230, 0, 0}, - {0x0F93, 0, 2 | DECOMP_NO_COMPOSE, 871}, /* in exclusion list */ - {0x0F9D, 0, 2 | DECOMP_NO_COMPOSE, 873}, /* in exclusion list */ - {0x0FA2, 0, 2 | DECOMP_NO_COMPOSE, 875}, /* in exclusion list */ - {0x0FA7, 0, 2 | DECOMP_NO_COMPOSE, 877}, /* in exclusion list */ - {0x0FAC, 0, 2 | DECOMP_NO_COMPOSE, 879}, /* in exclusion list */ - {0x0FB9, 0, 2 | DECOMP_NO_COMPOSE, 881}, /* in exclusion list */ - {0x0FC6, 220, 0, 0}, - {0x1026, 0, 2, 883}, - {0x1037, 7, 0, 0}, - {0x1039, 9, 0, 0}, - {0x103A, 9, 0, 0}, - {0x108D, 220, 0, 0}, - {0x10FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x10DC}, - {0x135D, 230, 0, 0}, - {0x135E, 230, 0, 0}, - {0x135F, 230, 0, 0}, - {0x1714, 9, 0, 0}, - {0x1715, 9, 0, 0}, - {0x1734, 9, 0, 0}, - {0x17D2, 9, 0, 0}, - {0x17DD, 230, 0, 0}, - {0x18A9, 228, 0, 0}, - {0x1939, 222, 0, 0}, - {0x193A, 230, 0, 0}, - {0x193B, 220, 0, 0}, - {0x1A17, 230, 0, 0}, - {0x1A18, 220, 0, 0}, - {0x1A60, 9, 0, 0}, - {0x1A75, 230, 0, 0}, - {0x1A76, 230, 0, 0}, - {0x1A77, 230, 0, 0}, - {0x1A78, 230, 0, 0}, - {0x1A79, 230, 0, 0}, - {0x1A7A, 230, 0, 0}, - {0x1A7B, 230, 0, 0}, - {0x1A7C, 230, 0, 0}, - {0x1A7F, 220, 0, 0}, - {0x1AB0, 230, 0, 0}, - {0x1AB1, 230, 0, 0}, - {0x1AB2, 230, 0, 0}, - {0x1AB3, 230, 0, 0}, - {0x1AB4, 230, 0, 0}, - {0x1AB5, 220, 0, 0}, - {0x1AB6, 220, 0, 0}, - {0x1AB7, 220, 0, 0}, - {0x1AB8, 220, 0, 0}, - {0x1AB9, 220, 0, 0}, - {0x1ABA, 220, 0, 0}, - {0x1ABB, 230, 0, 0}, - {0x1ABC, 230, 0, 0}, - {0x1ABD, 220, 0, 0}, - {0x1ABF, 220, 0, 0}, - {0x1AC0, 220, 0, 0}, - {0x1AC1, 230, 0, 0}, - {0x1AC2, 230, 0, 0}, - {0x1AC3, 220, 0, 0}, - {0x1AC4, 220, 0, 0}, - {0x1AC5, 230, 0, 0}, - {0x1AC6, 230, 0, 0}, - {0x1AC7, 230, 0, 0}, - {0x1AC8, 230, 0, 0}, - {0x1AC9, 230, 0, 0}, - {0x1ACA, 220, 0, 0}, - {0x1ACB, 230, 0, 0}, - {0x1ACC, 230, 0, 0}, - {0x1ACD, 230, 0, 0}, - {0x1ACE, 230, 0, 0}, - {0x1B06, 0, 2, 885}, - {0x1B08, 0, 2, 887}, - {0x1B0A, 0, 2, 889}, - {0x1B0C, 0, 2, 891}, - {0x1B0E, 0, 2, 893}, - {0x1B12, 0, 2, 895}, - {0x1B34, 7, 0, 0}, - {0x1B3B, 0, 2, 897}, - {0x1B3D, 0, 2, 899}, - {0x1B40, 0, 2, 901}, - {0x1B41, 0, 2, 903}, - {0x1B43, 0, 2, 905}, - {0x1B44, 9, 0, 0}, - {0x1B6B, 230, 0, 0}, - {0x1B6C, 220, 0, 0}, - {0x1B6D, 230, 0, 0}, - {0x1B6E, 230, 0, 0}, - {0x1B6F, 230, 0, 0}, - {0x1B70, 230, 0, 0}, - {0x1B71, 230, 0, 0}, - {0x1B72, 230, 0, 0}, - {0x1B73, 230, 0, 0}, - {0x1BAA, 9, 0, 0}, - {0x1BAB, 9, 0, 0}, - {0x1BE6, 7, 0, 0}, - {0x1BF2, 9, 0, 0}, - {0x1BF3, 9, 0, 0}, - {0x1C37, 7, 0, 0}, - {0x1CD0, 230, 0, 0}, - {0x1CD1, 230, 0, 0}, - {0x1CD2, 230, 0, 0}, - {0x1CD4, 1, 0, 0}, - {0x1CD5, 220, 0, 0}, - {0x1CD6, 220, 0, 0}, - {0x1CD7, 220, 0, 0}, - {0x1CD8, 220, 0, 0}, - {0x1CD9, 220, 0, 0}, - {0x1CDA, 230, 0, 0}, - {0x1CDB, 230, 0, 0}, - {0x1CDC, 220, 0, 0}, - {0x1CDD, 220, 0, 0}, - {0x1CDE, 220, 0, 0}, - {0x1CDF, 220, 0, 0}, - {0x1CE0, 230, 0, 0}, - {0x1CE2, 1, 0, 0}, - {0x1CE3, 1, 0, 0}, - {0x1CE4, 1, 0, 0}, - {0x1CE5, 1, 0, 0}, - {0x1CE6, 1, 0, 0}, - {0x1CE7, 1, 0, 0}, - {0x1CE8, 1, 0, 0}, - {0x1CED, 220, 0, 0}, - {0x1CF4, 230, 0, 0}, - {0x1CF8, 230, 0, 0}, - {0x1CF9, 230, 0, 0}, - {0x1D2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00C6}, - {0x1D2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x018E}, - {0x1D33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0222}, - {0x1D3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0250}, - {0x1D45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0251}, - {0x1D46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D02}, - {0x1D47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0259}, - {0x1D4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025B}, - {0x1D4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025C}, - {0x1D4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x014B}, - {0x1D52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0254}, - {0x1D54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D16}, - {0x1D55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D17}, - {0x1D56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D1D}, - {0x1D5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026F}, - {0x1D5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D25}, - {0x1D5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043D}, - {0x1D9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0252}, - {0x1D9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0255}, - {0x1D9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00F0}, - {0x1D9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025C}, - {0x1DA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1DA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025F}, - {0x1DA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0261}, - {0x1DA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0265}, - {0x1DA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0268}, - {0x1DA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0269}, - {0x1DA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026A}, - {0x1DA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D7B}, - {0x1DA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029D}, - {0x1DA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026D}, - {0x1DAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D85}, - {0x1DAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029F}, - {0x1DAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0271}, - {0x1DAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0270}, - {0x1DAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0272}, - {0x1DAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0273}, - {0x1DB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0274}, - {0x1DB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0275}, - {0x1DB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0278}, - {0x1DB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0282}, - {0x1DB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0283}, - {0x1DB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01AB}, - {0x1DB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0289}, - {0x1DB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028A}, - {0x1DB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D1C}, - {0x1DB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028B}, - {0x1DBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028C}, - {0x1DBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1DBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0290}, - {0x1DBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0291}, - {0x1DBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0292}, - {0x1DBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1DC0, 230, 0, 0}, - {0x1DC1, 230, 0, 0}, - {0x1DC2, 220, 0, 0}, - {0x1DC3, 230, 0, 0}, - {0x1DC4, 230, 0, 0}, - {0x1DC5, 230, 0, 0}, - {0x1DC6, 230, 0, 0}, - {0x1DC7, 230, 0, 0}, - {0x1DC8, 230, 0, 0}, - {0x1DC9, 230, 0, 0}, - {0x1DCA, 220, 0, 0}, - {0x1DCB, 230, 0, 0}, - {0x1DCC, 230, 0, 0}, - {0x1DCD, 234, 0, 0}, - {0x1DCE, 214, 0, 0}, - {0x1DCF, 220, 0, 0}, - {0x1DD0, 202, 0, 0}, - {0x1DD1, 230, 0, 0}, - {0x1DD2, 230, 0, 0}, - {0x1DD3, 230, 0, 0}, - {0x1DD4, 230, 0, 0}, - {0x1DD5, 230, 0, 0}, - {0x1DD6, 230, 0, 0}, - {0x1DD7, 230, 0, 0}, - {0x1DD8, 230, 0, 0}, - {0x1DD9, 230, 0, 0}, - {0x1DDA, 230, 0, 0}, - {0x1DDB, 230, 0, 0}, - {0x1DDC, 230, 0, 0}, - {0x1DDD, 230, 0, 0}, - {0x1DDE, 230, 0, 0}, - {0x1DDF, 230, 0, 0}, - {0x1DE0, 230, 0, 0}, - {0x1DE1, 230, 0, 0}, - {0x1DE2, 230, 0, 0}, - {0x1DE3, 230, 0, 0}, - {0x1DE4, 230, 0, 0}, - {0x1DE5, 230, 0, 0}, - {0x1DE6, 230, 0, 0}, - {0x1DE7, 230, 0, 0}, - {0x1DE8, 230, 0, 0}, - {0x1DE9, 230, 0, 0}, - {0x1DEA, 230, 0, 0}, - {0x1DEB, 230, 0, 0}, - {0x1DEC, 230, 0, 0}, - {0x1DED, 230, 0, 0}, - {0x1DEE, 230, 0, 0}, - {0x1DEF, 230, 0, 0}, - {0x1DF0, 230, 0, 0}, - {0x1DF1, 230, 0, 0}, - {0x1DF2, 230, 0, 0}, - {0x1DF3, 230, 0, 0}, - {0x1DF4, 230, 0, 0}, - {0x1DF5, 230, 0, 0}, - {0x1DF6, 232, 0, 0}, - {0x1DF7, 228, 0, 0}, - {0x1DF8, 228, 0, 0}, - {0x1DF9, 220, 0, 0}, - {0x1DFA, 218, 0, 0}, - {0x1DFB, 230, 0, 0}, - {0x1DFC, 233, 0, 0}, - {0x1DFD, 220, 0, 0}, - {0x1DFE, 230, 0, 0}, - {0x1DFF, 220, 0, 0}, - {0x1E00, 0, 2, 907}, - {0x1E01, 0, 2, 909}, - {0x1E02, 0, 2, 911}, - {0x1E03, 0, 2, 913}, - {0x1E04, 0, 2, 915}, - {0x1E05, 0, 2, 917}, - {0x1E06, 0, 2, 919}, - {0x1E07, 0, 2, 921}, - {0x1E08, 0, 2, 923}, - {0x1E09, 0, 2, 925}, - {0x1E0A, 0, 2, 927}, - {0x1E0B, 0, 2, 929}, - {0x1E0C, 0, 2, 931}, - {0x1E0D, 0, 2, 933}, - {0x1E0E, 0, 2, 935}, - {0x1E0F, 0, 2, 937}, - {0x1E10, 0, 2, 939}, - {0x1E11, 0, 2, 941}, - {0x1E12, 0, 2, 943}, - {0x1E13, 0, 2, 945}, - {0x1E14, 0, 2, 947}, - {0x1E15, 0, 2, 949}, - {0x1E16, 0, 2, 951}, - {0x1E17, 0, 2, 953}, - {0x1E18, 0, 2, 955}, - {0x1E19, 0, 2, 957}, - {0x1E1A, 0, 2, 959}, - {0x1E1B, 0, 2, 961}, - {0x1E1C, 0, 2, 963}, - {0x1E1D, 0, 2, 965}, - {0x1E1E, 0, 2, 967}, - {0x1E1F, 0, 2, 969}, - {0x1E20, 0, 2, 971}, - {0x1E21, 0, 2, 973}, - {0x1E22, 0, 2, 975}, - {0x1E23, 0, 2, 977}, - {0x1E24, 0, 2, 979}, - {0x1E25, 0, 2, 981}, - {0x1E26, 0, 2, 983}, - {0x1E27, 0, 2, 985}, - {0x1E28, 0, 2, 987}, - {0x1E29, 0, 2, 989}, - {0x1E2A, 0, 2, 991}, - {0x1E2B, 0, 2, 993}, - {0x1E2C, 0, 2, 995}, - {0x1E2D, 0, 2, 997}, - {0x1E2E, 0, 2, 999}, - {0x1E2F, 0, 2, 1001}, - {0x1E30, 0, 2, 1003}, - {0x1E31, 0, 2, 1005}, - {0x1E32, 0, 2, 1007}, - {0x1E33, 0, 2, 1009}, - {0x1E34, 0, 2, 1011}, - {0x1E35, 0, 2, 1013}, - {0x1E36, 0, 2, 1015}, - {0x1E37, 0, 2, 1017}, - {0x1E38, 0, 2, 1019}, - {0x1E39, 0, 2, 1021}, - {0x1E3A, 0, 2, 1023}, - {0x1E3B, 0, 2, 1025}, - {0x1E3C, 0, 2, 1027}, - {0x1E3D, 0, 2, 1029}, - {0x1E3E, 0, 2, 1031}, - {0x1E3F, 0, 2, 1033}, - {0x1E40, 0, 2, 1035}, - {0x1E41, 0, 2, 1037}, - {0x1E42, 0, 2, 1039}, - {0x1E43, 0, 2, 1041}, - {0x1E44, 0, 2, 1043}, - {0x1E45, 0, 2, 1045}, - {0x1E46, 0, 2, 1047}, - {0x1E47, 0, 2, 1049}, - {0x1E48, 0, 2, 1051}, - {0x1E49, 0, 2, 1053}, - {0x1E4A, 0, 2, 1055}, - {0x1E4B, 0, 2, 1057}, - {0x1E4C, 0, 2, 1059}, - {0x1E4D, 0, 2, 1061}, - {0x1E4E, 0, 2, 1063}, - {0x1E4F, 0, 2, 1065}, - {0x1E50, 0, 2, 1067}, - {0x1E51, 0, 2, 1069}, - {0x1E52, 0, 2, 1071}, - {0x1E53, 0, 2, 1073}, - {0x1E54, 0, 2, 1075}, - {0x1E55, 0, 2, 1077}, - {0x1E56, 0, 2, 1079}, - {0x1E57, 0, 2, 1081}, - {0x1E58, 0, 2, 1083}, - {0x1E59, 0, 2, 1085}, - {0x1E5A, 0, 2, 1087}, - {0x1E5B, 0, 2, 1089}, - {0x1E5C, 0, 2, 1091}, - {0x1E5D, 0, 2, 1093}, - {0x1E5E, 0, 2, 1095}, - {0x1E5F, 0, 2, 1097}, - {0x1E60, 0, 2, 1099}, - {0x1E61, 0, 2, 1101}, - {0x1E62, 0, 2, 1103}, - {0x1E63, 0, 2, 1105}, - {0x1E64, 0, 2, 1107}, - {0x1E65, 0, 2, 1109}, - {0x1E66, 0, 2, 1111}, - {0x1E67, 0, 2, 1113}, - {0x1E68, 0, 2, 1115}, - {0x1E69, 0, 2, 1117}, - {0x1E6A, 0, 2, 1119}, - {0x1E6B, 0, 2, 1121}, - {0x1E6C, 0, 2, 1123}, - {0x1E6D, 0, 2, 1125}, - {0x1E6E, 0, 2, 1127}, - {0x1E6F, 0, 2, 1129}, - {0x1E70, 0, 2, 1131}, - {0x1E71, 0, 2, 1133}, - {0x1E72, 0, 2, 1135}, - {0x1E73, 0, 2, 1137}, - {0x1E74, 0, 2, 1139}, - {0x1E75, 0, 2, 1141}, - {0x1E76, 0, 2, 1143}, - {0x1E77, 0, 2, 1145}, - {0x1E78, 0, 2, 1147}, - {0x1E79, 0, 2, 1149}, - {0x1E7A, 0, 2, 1151}, - {0x1E7B, 0, 2, 1153}, - {0x1E7C, 0, 2, 1155}, - {0x1E7D, 0, 2, 1157}, - {0x1E7E, 0, 2, 1159}, - {0x1E7F, 0, 2, 1161}, - {0x1E80, 0, 2, 1163}, - {0x1E81, 0, 2, 1165}, - {0x1E82, 0, 2, 1167}, - {0x1E83, 0, 2, 1169}, - {0x1E84, 0, 2, 1171}, - {0x1E85, 0, 2, 1173}, - {0x1E86, 0, 2, 1175}, - {0x1E87, 0, 2, 1177}, - {0x1E88, 0, 2, 1179}, - {0x1E89, 0, 2, 1181}, - {0x1E8A, 0, 2, 1183}, - {0x1E8B, 0, 2, 1185}, - {0x1E8C, 0, 2, 1187}, - {0x1E8D, 0, 2, 1189}, - {0x1E8E, 0, 2, 1191}, - {0x1E8F, 0, 2, 1193}, - {0x1E90, 0, 2, 1195}, - {0x1E91, 0, 2, 1197}, - {0x1E92, 0, 2, 1199}, - {0x1E93, 0, 2, 1201}, - {0x1E94, 0, 2, 1203}, - {0x1E95, 0, 2, 1205}, - {0x1E96, 0, 2, 1207}, - {0x1E97, 0, 2, 1209}, - {0x1E98, 0, 2, 1211}, - {0x1E99, 0, 2, 1213}, - {0x1E9A, 0, 2 | DECOMP_COMPAT, 1215}, - {0x1E9B, 0, 2, 1217}, - {0x1EA0, 0, 2, 1219}, - {0x1EA1, 0, 2, 1221}, - {0x1EA2, 0, 2, 1223}, - {0x1EA3, 0, 2, 1225}, - {0x1EA4, 0, 2, 1227}, - {0x1EA5, 0, 2, 1229}, - {0x1EA6, 0, 2, 1231}, - {0x1EA7, 0, 2, 1233}, - {0x1EA8, 0, 2, 1235}, - {0x1EA9, 0, 2, 1237}, - {0x1EAA, 0, 2, 1239}, - {0x1EAB, 0, 2, 1241}, - {0x1EAC, 0, 2, 1243}, - {0x1EAD, 0, 2, 1245}, - {0x1EAE, 0, 2, 1247}, - {0x1EAF, 0, 2, 1249}, - {0x1EB0, 0, 2, 1251}, - {0x1EB1, 0, 2, 1253}, - {0x1EB2, 0, 2, 1255}, - {0x1EB3, 0, 2, 1257}, - {0x1EB4, 0, 2, 1259}, - {0x1EB5, 0, 2, 1261}, - {0x1EB6, 0, 2, 1263}, - {0x1EB7, 0, 2, 1265}, - {0x1EB8, 0, 2, 1267}, - {0x1EB9, 0, 2, 1269}, - {0x1EBA, 0, 2, 1271}, - {0x1EBB, 0, 2, 1273}, - {0x1EBC, 0, 2, 1275}, - {0x1EBD, 0, 2, 1277}, - {0x1EBE, 0, 2, 1279}, - {0x1EBF, 0, 2, 1281}, - {0x1EC0, 0, 2, 1283}, - {0x1EC1, 0, 2, 1285}, - {0x1EC2, 0, 2, 1287}, - {0x1EC3, 0, 2, 1289}, - {0x1EC4, 0, 2, 1291}, - {0x1EC5, 0, 2, 1293}, - {0x1EC6, 0, 2, 1295}, - {0x1EC7, 0, 2, 1297}, - {0x1EC8, 0, 2, 1299}, - {0x1EC9, 0, 2, 1301}, - {0x1ECA, 0, 2, 1303}, - {0x1ECB, 0, 2, 1305}, - {0x1ECC, 0, 2, 1307}, - {0x1ECD, 0, 2, 1309}, - {0x1ECE, 0, 2, 1311}, - {0x1ECF, 0, 2, 1313}, - {0x1ED0, 0, 2, 1315}, - {0x1ED1, 0, 2, 1317}, - {0x1ED2, 0, 2, 1319}, - {0x1ED3, 0, 2, 1321}, - {0x1ED4, 0, 2, 1323}, - {0x1ED5, 0, 2, 1325}, - {0x1ED6, 0, 2, 1327}, - {0x1ED7, 0, 2, 1329}, - {0x1ED8, 0, 2, 1331}, - {0x1ED9, 0, 2, 1333}, - {0x1EDA, 0, 2, 1335}, - {0x1EDB, 0, 2, 1337}, - {0x1EDC, 0, 2, 1339}, - {0x1EDD, 0, 2, 1341}, - {0x1EDE, 0, 2, 1343}, - {0x1EDF, 0, 2, 1345}, - {0x1EE0, 0, 2, 1347}, - {0x1EE1, 0, 2, 1349}, - {0x1EE2, 0, 2, 1351}, - {0x1EE3, 0, 2, 1353}, - {0x1EE4, 0, 2, 1355}, - {0x1EE5, 0, 2, 1357}, - {0x1EE6, 0, 2, 1359}, - {0x1EE7, 0, 2, 1361}, - {0x1EE8, 0, 2, 1363}, - {0x1EE9, 0, 2, 1365}, - {0x1EEA, 0, 2, 1367}, - {0x1EEB, 0, 2, 1369}, - {0x1EEC, 0, 2, 1371}, - {0x1EED, 0, 2, 1373}, - {0x1EEE, 0, 2, 1375}, - {0x1EEF, 0, 2, 1377}, - {0x1EF0, 0, 2, 1379}, - {0x1EF1, 0, 2, 1381}, - {0x1EF2, 0, 2, 1383}, - {0x1EF3, 0, 2, 1385}, - {0x1EF4, 0, 2, 1387}, - {0x1EF5, 0, 2, 1389}, - {0x1EF6, 0, 2, 1391}, - {0x1EF7, 0, 2, 1393}, - {0x1EF8, 0, 2, 1395}, - {0x1EF9, 0, 2, 1397}, - {0x1F00, 0, 2, 1399}, - {0x1F01, 0, 2, 1401}, - {0x1F02, 0, 2, 1403}, - {0x1F03, 0, 2, 1405}, - {0x1F04, 0, 2, 1407}, - {0x1F05, 0, 2, 1409}, - {0x1F06, 0, 2, 1411}, - {0x1F07, 0, 2, 1413}, - {0x1F08, 0, 2, 1415}, - {0x1F09, 0, 2, 1417}, - {0x1F0A, 0, 2, 1419}, - {0x1F0B, 0, 2, 1421}, - {0x1F0C, 0, 2, 1423}, - {0x1F0D, 0, 2, 1425}, - {0x1F0E, 0, 2, 1427}, - {0x1F0F, 0, 2, 1429}, - {0x1F10, 0, 2, 1431}, - {0x1F11, 0, 2, 1433}, - {0x1F12, 0, 2, 1435}, - {0x1F13, 0, 2, 1437}, - {0x1F14, 0, 2, 1439}, - {0x1F15, 0, 2, 1441}, - {0x1F18, 0, 2, 1443}, - {0x1F19, 0, 2, 1445}, - {0x1F1A, 0, 2, 1447}, - {0x1F1B, 0, 2, 1449}, - {0x1F1C, 0, 2, 1451}, - {0x1F1D, 0, 2, 1453}, - {0x1F20, 0, 2, 1455}, - {0x1F21, 0, 2, 1457}, - {0x1F22, 0, 2, 1459}, - {0x1F23, 0, 2, 1461}, - {0x1F24, 0, 2, 1463}, - {0x1F25, 0, 2, 1465}, - {0x1F26, 0, 2, 1467}, - {0x1F27, 0, 2, 1469}, - {0x1F28, 0, 2, 1471}, - {0x1F29, 0, 2, 1473}, - {0x1F2A, 0, 2, 1475}, - {0x1F2B, 0, 2, 1477}, - {0x1F2C, 0, 2, 1479}, - {0x1F2D, 0, 2, 1481}, - {0x1F2E, 0, 2, 1483}, - {0x1F2F, 0, 2, 1485}, - {0x1F30, 0, 2, 1487}, - {0x1F31, 0, 2, 1489}, - {0x1F32, 0, 2, 1491}, - {0x1F33, 0, 2, 1493}, - {0x1F34, 0, 2, 1495}, - {0x1F35, 0, 2, 1497}, - {0x1F36, 0, 2, 1499}, - {0x1F37, 0, 2, 1501}, - {0x1F38, 0, 2, 1503}, - {0x1F39, 0, 2, 1505}, - {0x1F3A, 0, 2, 1507}, - {0x1F3B, 0, 2, 1509}, - {0x1F3C, 0, 2, 1511}, - {0x1F3D, 0, 2, 1513}, - {0x1F3E, 0, 2, 1515}, - {0x1F3F, 0, 2, 1517}, - {0x1F40, 0, 2, 1519}, - {0x1F41, 0, 2, 1521}, - {0x1F42, 0, 2, 1523}, - {0x1F43, 0, 2, 1525}, - {0x1F44, 0, 2, 1527}, - {0x1F45, 0, 2, 1529}, - {0x1F48, 0, 2, 1531}, - {0x1F49, 0, 2, 1533}, - {0x1F4A, 0, 2, 1535}, - {0x1F4B, 0, 2, 1537}, - {0x1F4C, 0, 2, 1539}, - {0x1F4D, 0, 2, 1541}, - {0x1F50, 0, 2, 1543}, - {0x1F51, 0, 2, 1545}, - {0x1F52, 0, 2, 1547}, - {0x1F53, 0, 2, 1549}, - {0x1F54, 0, 2, 1551}, - {0x1F55, 0, 2, 1553}, - {0x1F56, 0, 2, 1555}, - {0x1F57, 0, 2, 1557}, - {0x1F59, 0, 2, 1559}, - {0x1F5B, 0, 2, 1561}, - {0x1F5D, 0, 2, 1563}, - {0x1F5F, 0, 2, 1565}, - {0x1F60, 0, 2, 1567}, - {0x1F61, 0, 2, 1569}, - {0x1F62, 0, 2, 1571}, - {0x1F63, 0, 2, 1573}, - {0x1F64, 0, 2, 1575}, - {0x1F65, 0, 2, 1577}, - {0x1F66, 0, 2, 1579}, - {0x1F67, 0, 2, 1581}, - {0x1F68, 0, 2, 1583}, - {0x1F69, 0, 2, 1585}, - {0x1F6A, 0, 2, 1587}, - {0x1F6B, 0, 2, 1589}, - {0x1F6C, 0, 2, 1591}, - {0x1F6D, 0, 2, 1593}, - {0x1F6E, 0, 2, 1595}, - {0x1F6F, 0, 2, 1597}, - {0x1F70, 0, 2, 1599}, - {0x1F71, 0, 1 | DECOMP_INLINE, 0x03AC}, - {0x1F72, 0, 2, 1601}, - {0x1F73, 0, 1 | DECOMP_INLINE, 0x03AD}, - {0x1F74, 0, 2, 1603}, - {0x1F75, 0, 1 | DECOMP_INLINE, 0x03AE}, - {0x1F76, 0, 2, 1605}, - {0x1F77, 0, 1 | DECOMP_INLINE, 0x03AF}, - {0x1F78, 0, 2, 1607}, - {0x1F79, 0, 1 | DECOMP_INLINE, 0x03CC}, - {0x1F7A, 0, 2, 1609}, - {0x1F7B, 0, 1 | DECOMP_INLINE, 0x03CD}, - {0x1F7C, 0, 2, 1611}, - {0x1F7D, 0, 1 | DECOMP_INLINE, 0x03CE}, - {0x1F80, 0, 2, 1613}, - {0x1F81, 0, 2, 1615}, - {0x1F82, 0, 2, 1617}, - {0x1F83, 0, 2, 1619}, - {0x1F84, 0, 2, 1621}, - {0x1F85, 0, 2, 1623}, - {0x1F86, 0, 2, 1625}, - {0x1F87, 0, 2, 1627}, - {0x1F88, 0, 2, 1629}, - {0x1F89, 0, 2, 1631}, - {0x1F8A, 0, 2, 1633}, - {0x1F8B, 0, 2, 1635}, - {0x1F8C, 0, 2, 1637}, - {0x1F8D, 0, 2, 1639}, - {0x1F8E, 0, 2, 1641}, - {0x1F8F, 0, 2, 1643}, - {0x1F90, 0, 2, 1645}, - {0x1F91, 0, 2, 1647}, - {0x1F92, 0, 2, 1649}, - {0x1F93, 0, 2, 1651}, - {0x1F94, 0, 2, 1653}, - {0x1F95, 0, 2, 1655}, - {0x1F96, 0, 2, 1657}, - {0x1F97, 0, 2, 1659}, - {0x1F98, 0, 2, 1661}, - {0x1F99, 0, 2, 1663}, - {0x1F9A, 0, 2, 1665}, - {0x1F9B, 0, 2, 1667}, - {0x1F9C, 0, 2, 1669}, - {0x1F9D, 0, 2, 1671}, - {0x1F9E, 0, 2, 1673}, - {0x1F9F, 0, 2, 1675}, - {0x1FA0, 0, 2, 1677}, - {0x1FA1, 0, 2, 1679}, - {0x1FA2, 0, 2, 1681}, - {0x1FA3, 0, 2, 1683}, - {0x1FA4, 0, 2, 1685}, - {0x1FA5, 0, 2, 1687}, - {0x1FA6, 0, 2, 1689}, - {0x1FA7, 0, 2, 1691}, - {0x1FA8, 0, 2, 1693}, - {0x1FA9, 0, 2, 1695}, - {0x1FAA, 0, 2, 1697}, - {0x1FAB, 0, 2, 1699}, - {0x1FAC, 0, 2, 1701}, - {0x1FAD, 0, 2, 1703}, - {0x1FAE, 0, 2, 1705}, - {0x1FAF, 0, 2, 1707}, - {0x1FB0, 0, 2, 1709}, - {0x1FB1, 0, 2, 1711}, - {0x1FB2, 0, 2, 1713}, - {0x1FB3, 0, 2, 1715}, - {0x1FB4, 0, 2, 1717}, - {0x1FB6, 0, 2, 1719}, - {0x1FB7, 0, 2, 1721}, - {0x1FB8, 0, 2, 1723}, - {0x1FB9, 0, 2, 1725}, - {0x1FBA, 0, 2, 1727}, - {0x1FBB, 0, 1 | DECOMP_INLINE, 0x0386}, - {0x1FBC, 0, 2, 1729}, - {0x1FBD, 0, 2 | DECOMP_COMPAT, 1731}, - {0x1FBE, 0, 1 | DECOMP_INLINE, 0x03B9}, - {0x1FBF, 0, 2 | DECOMP_COMPAT, 1733}, - {0x1FC0, 0, 2 | DECOMP_COMPAT, 1735}, - {0x1FC1, 0, 2, 1737}, - {0x1FC2, 0, 2, 1739}, - {0x1FC3, 0, 2, 1741}, - {0x1FC4, 0, 2, 1743}, - {0x1FC6, 0, 2, 1745}, - {0x1FC7, 0, 2, 1747}, - {0x1FC8, 0, 2, 1749}, - {0x1FC9, 0, 1 | DECOMP_INLINE, 0x0388}, - {0x1FCA, 0, 2, 1751}, - {0x1FCB, 0, 1 | DECOMP_INLINE, 0x0389}, - {0x1FCC, 0, 2, 1753}, - {0x1FCD, 0, 2, 1755}, - {0x1FCE, 0, 2, 1757}, - {0x1FCF, 0, 2, 1759}, - {0x1FD0, 0, 2, 1761}, - {0x1FD1, 0, 2, 1763}, - {0x1FD2, 0, 2, 1765}, - {0x1FD3, 0, 1 | DECOMP_INLINE, 0x0390}, - {0x1FD6, 0, 2, 1767}, - {0x1FD7, 0, 2, 1769}, - {0x1FD8, 0, 2, 1771}, - {0x1FD9, 0, 2, 1773}, - {0x1FDA, 0, 2, 1775}, - {0x1FDB, 0, 1 | DECOMP_INLINE, 0x038A}, - {0x1FDD, 0, 2, 1777}, - {0x1FDE, 0, 2, 1779}, - {0x1FDF, 0, 2, 1781}, - {0x1FE0, 0, 2, 1783}, - {0x1FE1, 0, 2, 1785}, - {0x1FE2, 0, 2, 1787}, - {0x1FE3, 0, 1 | DECOMP_INLINE, 0x03B0}, - {0x1FE4, 0, 2, 1789}, - {0x1FE5, 0, 2, 1791}, - {0x1FE6, 0, 2, 1793}, - {0x1FE7, 0, 2, 1795}, - {0x1FE8, 0, 2, 1797}, - {0x1FE9, 0, 2, 1799}, - {0x1FEA, 0, 2, 1801}, - {0x1FEB, 0, 1 | DECOMP_INLINE, 0x038E}, - {0x1FEC, 0, 2, 1803}, - {0x1FED, 0, 2, 1805}, - {0x1FEE, 0, 1 | DECOMP_INLINE, 0x0385}, - {0x1FEF, 0, 1 | DECOMP_INLINE, 0x0060}, - {0x1FF2, 0, 2, 1807}, - {0x1FF3, 0, 2, 1809}, - {0x1FF4, 0, 2, 1811}, - {0x1FF6, 0, 2, 1813}, - {0x1FF7, 0, 2, 1815}, - {0x1FF8, 0, 2, 1817}, - {0x1FF9, 0, 1 | DECOMP_INLINE, 0x038C}, - {0x1FFA, 0, 2, 1819}, - {0x1FFB, 0, 1 | DECOMP_INLINE, 0x038F}, - {0x1FFC, 0, 2, 1821}, - {0x1FFD, 0, 1 | DECOMP_INLINE, 0x00B4}, - {0x1FFE, 0, 2 | DECOMP_COMPAT, 1823}, - {0x2000, 0, 1 | DECOMP_INLINE, 0x2002}, - {0x2001, 0, 1 | DECOMP_INLINE, 0x2003}, - {0x2002, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2003, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2004, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2005, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2006, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2007, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2008, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2009, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x200A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2011, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2010}, - {0x2017, 0, 2 | DECOMP_COMPAT, 1825}, - {0x2024, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, - {0x2025, 0, 2 | DECOMP_COMPAT, 1827}, - {0x2026, 0, 3 | DECOMP_COMPAT, 1829}, - {0x202F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2033, 0, 2 | DECOMP_COMPAT, 1832}, - {0x2034, 0, 3 | DECOMP_COMPAT, 1834}, - {0x2036, 0, 2 | DECOMP_COMPAT, 1837}, - {0x2037, 0, 3 | DECOMP_COMPAT, 1839}, - {0x203C, 0, 2 | DECOMP_COMPAT, 1842}, - {0x203E, 0, 2 | DECOMP_COMPAT, 1844}, - {0x2047, 0, 2 | DECOMP_COMPAT, 1846}, - {0x2048, 0, 2 | DECOMP_COMPAT, 1848}, - {0x2049, 0, 2 | DECOMP_COMPAT, 1850}, - {0x2057, 0, 4 | DECOMP_COMPAT, 1852}, - {0x205F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x2070, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x2071, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x2074, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x2075, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x2076, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x2077, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x2078, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x2079, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x207A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, - {0x207B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2212}, - {0x207C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, - {0x207D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, - {0x207E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, - {0x207F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x2080, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x2081, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x2082, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x2083, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x2084, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x2085, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x2086, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x2087, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x2088, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x2089, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x208A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, - {0x208B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2212}, - {0x208C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, - {0x208D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, - {0x208E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, - {0x2090, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x2091, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x2092, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x2093, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x2094, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0259}, - {0x2095, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x2096, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x2097, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x2098, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x2099, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x209A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x209B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x209C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x20A8, 0, 2 | DECOMP_COMPAT, 1856}, - {0x20D0, 230, 0, 0}, - {0x20D1, 230, 0, 0}, - {0x20D2, 1, 0, 0}, - {0x20D3, 1, 0, 0}, - {0x20D4, 230, 0, 0}, - {0x20D5, 230, 0, 0}, - {0x20D6, 230, 0, 0}, - {0x20D7, 230, 0, 0}, - {0x20D8, 1, 0, 0}, - {0x20D9, 1, 0, 0}, - {0x20DA, 1, 0, 0}, - {0x20DB, 230, 0, 0}, - {0x20DC, 230, 0, 0}, - {0x20E1, 230, 0, 0}, - {0x20E5, 1, 0, 0}, - {0x20E6, 1, 0, 0}, - {0x20E7, 230, 0, 0}, - {0x20E8, 220, 0, 0}, - {0x20E9, 230, 0, 0}, - {0x20EA, 1, 0, 0}, - {0x20EB, 1, 0, 0}, - {0x20EC, 220, 0, 0}, - {0x20ED, 220, 0, 0}, - {0x20EE, 220, 0, 0}, - {0x20EF, 220, 0, 0}, - {0x20F0, 230, 0, 0}, - {0x2100, 0, 3 | DECOMP_COMPAT, 1858}, - {0x2101, 0, 3 | DECOMP_COMPAT, 1861}, - {0x2102, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x2103, 0, 2 | DECOMP_COMPAT, 1864}, - {0x2105, 0, 3 | DECOMP_COMPAT, 1866}, - {0x2106, 0, 3 | DECOMP_COMPAT, 1869}, - {0x2107, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0190}, - {0x2109, 0, 2 | DECOMP_COMPAT, 1872}, - {0x210A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x210B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x210C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x210D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x210E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x210F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0127}, - {0x2110, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x2111, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x2112, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x2113, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x2115, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x2116, 0, 2 | DECOMP_COMPAT, 1874}, - {0x2119, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x211A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x211B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x211C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x211D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x2120, 0, 2 | DECOMP_COMPAT, 1876}, - {0x2121, 0, 3 | DECOMP_COMPAT, 1878}, - {0x2122, 0, 2 | DECOMP_COMPAT, 1881}, - {0x2124, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x2126, 0, 1 | DECOMP_INLINE, 0x03A9}, - {0x2128, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x212A, 0, 1 | DECOMP_INLINE, 0x004B}, - {0x212B, 0, 1 | DECOMP_INLINE, 0x00C5}, - {0x212C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x212D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x212F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x2130, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x2131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x2133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x2134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x2135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D0}, - {0x2136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D1}, - {0x2137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D2}, - {0x2138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D3}, - {0x2139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x213B, 0, 3 | DECOMP_COMPAT, 1883}, - {0x213C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x213D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x213E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x213F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x2140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2211}, - {0x2145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x2146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x2147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x2148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x2149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x2150, 0, 3 | DECOMP_COMPAT, 1886}, - {0x2151, 0, 3 | DECOMP_COMPAT, 1889}, - {0x2152, 0, 4 | DECOMP_COMPAT, 1892}, - {0x2153, 0, 3 | DECOMP_COMPAT, 1896}, - {0x2154, 0, 3 | DECOMP_COMPAT, 1899}, - {0x2155, 0, 3 | DECOMP_COMPAT, 1902}, - {0x2156, 0, 3 | DECOMP_COMPAT, 1905}, - {0x2157, 0, 3 | DECOMP_COMPAT, 1908}, - {0x2158, 0, 3 | DECOMP_COMPAT, 1911}, - {0x2159, 0, 3 | DECOMP_COMPAT, 1914}, - {0x215A, 0, 3 | DECOMP_COMPAT, 1917}, - {0x215B, 0, 3 | DECOMP_COMPAT, 1920}, - {0x215C, 0, 3 | DECOMP_COMPAT, 1923}, - {0x215D, 0, 3 | DECOMP_COMPAT, 1926}, - {0x215E, 0, 3 | DECOMP_COMPAT, 1929}, - {0x215F, 0, 2 | DECOMP_COMPAT, 1932}, - {0x2160, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x2161, 0, 2 | DECOMP_COMPAT, 1934}, - {0x2162, 0, 3 | DECOMP_COMPAT, 1936}, - {0x2163, 0, 2 | DECOMP_COMPAT, 1939}, - {0x2164, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x2165, 0, 2 | DECOMP_COMPAT, 1941}, - {0x2166, 0, 3 | DECOMP_COMPAT, 1943}, - {0x2167, 0, 4 | DECOMP_COMPAT, 1946}, - {0x2168, 0, 2 | DECOMP_COMPAT, 1950}, - {0x2169, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x216A, 0, 2 | DECOMP_COMPAT, 1952}, - {0x216B, 0, 3 | DECOMP_COMPAT, 1954}, - {0x216C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x216D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x216E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x216F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x2170, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x2171, 0, 2 | DECOMP_COMPAT, 1957}, - {0x2172, 0, 3 | DECOMP_COMPAT, 1959}, - {0x2173, 0, 2 | DECOMP_COMPAT, 1962}, - {0x2174, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x2175, 0, 2 | DECOMP_COMPAT, 1964}, - {0x2176, 0, 3 | DECOMP_COMPAT, 1966}, - {0x2177, 0, 4 | DECOMP_COMPAT, 1969}, - {0x2178, 0, 2 | DECOMP_COMPAT, 1973}, - {0x2179, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x217A, 0, 2 | DECOMP_COMPAT, 1975}, - {0x217B, 0, 3 | DECOMP_COMPAT, 1977}, - {0x217C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x217D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x217E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x217F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x2189, 0, 3 | DECOMP_COMPAT, 1980}, - {0x219A, 0, 2, 1983}, - {0x219B, 0, 2, 1985}, - {0x21AE, 0, 2, 1987}, - {0x21CD, 0, 2, 1989}, - {0x21CE, 0, 2, 1991}, - {0x21CF, 0, 2, 1993}, - {0x2204, 0, 2, 1995}, - {0x2209, 0, 2, 1997}, - {0x220C, 0, 2, 1999}, - {0x2224, 0, 2, 2001}, - {0x2226, 0, 2, 2003}, - {0x222C, 0, 2 | DECOMP_COMPAT, 2005}, - {0x222D, 0, 3 | DECOMP_COMPAT, 2007}, - {0x222F, 0, 2 | DECOMP_COMPAT, 2010}, - {0x2230, 0, 3 | DECOMP_COMPAT, 2012}, - {0x2241, 0, 2, 2015}, - {0x2244, 0, 2, 2017}, - {0x2247, 0, 2, 2019}, - {0x2249, 0, 2, 2021}, - {0x2260, 0, 2, 2023}, - {0x2262, 0, 2, 2025}, - {0x226D, 0, 2, 2027}, - {0x226E, 0, 2, 2029}, - {0x226F, 0, 2, 2031}, - {0x2270, 0, 2, 2033}, - {0x2271, 0, 2, 2035}, - {0x2274, 0, 2, 2037}, - {0x2275, 0, 2, 2039}, - {0x2278, 0, 2, 2041}, - {0x2279, 0, 2, 2043}, - {0x2280, 0, 2, 2045}, - {0x2281, 0, 2, 2047}, - {0x2284, 0, 2, 2049}, - {0x2285, 0, 2, 2051}, - {0x2288, 0, 2, 2053}, - {0x2289, 0, 2, 2055}, - {0x22AC, 0, 2, 2057}, - {0x22AD, 0, 2, 2059}, - {0x22AE, 0, 2, 2061}, - {0x22AF, 0, 2, 2063}, - {0x22E0, 0, 2, 2065}, - {0x22E1, 0, 2, 2067}, - {0x22E2, 0, 2, 2069}, - {0x22E3, 0, 2, 2071}, - {0x22EA, 0, 2, 2073}, - {0x22EB, 0, 2, 2075}, - {0x22EC, 0, 2, 2077}, - {0x22ED, 0, 2, 2079}, - {0x2329, 0, 1 | DECOMP_INLINE, 0x3008}, - {0x232A, 0, 1 | DECOMP_INLINE, 0x3009}, - {0x2460, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x2461, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x2462, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x2463, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x2464, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x2465, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x2466, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x2467, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x2468, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x2469, 0, 2 | DECOMP_COMPAT, 2081}, - {0x246A, 0, 2 | DECOMP_COMPAT, 2083}, - {0x246B, 0, 2 | DECOMP_COMPAT, 2085}, - {0x246C, 0, 2 | DECOMP_COMPAT, 2087}, - {0x246D, 0, 2 | DECOMP_COMPAT, 2089}, - {0x246E, 0, 2 | DECOMP_COMPAT, 2091}, - {0x246F, 0, 2 | DECOMP_COMPAT, 2093}, - {0x2470, 0, 2 | DECOMP_COMPAT, 2095}, - {0x2471, 0, 2 | DECOMP_COMPAT, 2097}, - {0x2472, 0, 2 | DECOMP_COMPAT, 2099}, - {0x2473, 0, 2 | DECOMP_COMPAT, 2101}, - {0x2474, 0, 3 | DECOMP_COMPAT, 2103}, - {0x2475, 0, 3 | DECOMP_COMPAT, 2106}, - {0x2476, 0, 3 | DECOMP_COMPAT, 2109}, - {0x2477, 0, 3 | DECOMP_COMPAT, 2112}, - {0x2478, 0, 3 | DECOMP_COMPAT, 2115}, - {0x2479, 0, 3 | DECOMP_COMPAT, 2118}, - {0x247A, 0, 3 | DECOMP_COMPAT, 2121}, - {0x247B, 0, 3 | DECOMP_COMPAT, 2124}, - {0x247C, 0, 3 | DECOMP_COMPAT, 2127}, - {0x247D, 0, 4 | DECOMP_COMPAT, 2130}, - {0x247E, 0, 4 | DECOMP_COMPAT, 2134}, - {0x247F, 0, 4 | DECOMP_COMPAT, 2138}, - {0x2480, 0, 4 | DECOMP_COMPAT, 2142}, - {0x2481, 0, 4 | DECOMP_COMPAT, 2146}, - {0x2482, 0, 4 | DECOMP_COMPAT, 2150}, - {0x2483, 0, 4 | DECOMP_COMPAT, 2154}, - {0x2484, 0, 4 | DECOMP_COMPAT, 2158}, - {0x2485, 0, 4 | DECOMP_COMPAT, 2162}, - {0x2486, 0, 4 | DECOMP_COMPAT, 2166}, - {0x2487, 0, 4 | DECOMP_COMPAT, 2170}, - {0x2488, 0, 2 | DECOMP_COMPAT, 2174}, - {0x2489, 0, 2 | DECOMP_COMPAT, 2176}, - {0x248A, 0, 2 | DECOMP_COMPAT, 2178}, - {0x248B, 0, 2 | DECOMP_COMPAT, 2180}, - {0x248C, 0, 2 | DECOMP_COMPAT, 2182}, - {0x248D, 0, 2 | DECOMP_COMPAT, 2184}, - {0x248E, 0, 2 | DECOMP_COMPAT, 2186}, - {0x248F, 0, 2 | DECOMP_COMPAT, 2188}, - {0x2490, 0, 2 | DECOMP_COMPAT, 2190}, - {0x2491, 0, 3 | DECOMP_COMPAT, 2192}, - {0x2492, 0, 3 | DECOMP_COMPAT, 2195}, - {0x2493, 0, 3 | DECOMP_COMPAT, 2198}, - {0x2494, 0, 3 | DECOMP_COMPAT, 2201}, - {0x2495, 0, 3 | DECOMP_COMPAT, 2204}, - {0x2496, 0, 3 | DECOMP_COMPAT, 2207}, - {0x2497, 0, 3 | DECOMP_COMPAT, 2210}, - {0x2498, 0, 3 | DECOMP_COMPAT, 2213}, - {0x2499, 0, 3 | DECOMP_COMPAT, 2216}, - {0x249A, 0, 3 | DECOMP_COMPAT, 2219}, - {0x249B, 0, 3 | DECOMP_COMPAT, 2222}, - {0x249C, 0, 3 | DECOMP_COMPAT, 2225}, - {0x249D, 0, 3 | DECOMP_COMPAT, 2228}, - {0x249E, 0, 3 | DECOMP_COMPAT, 2231}, - {0x249F, 0, 3 | DECOMP_COMPAT, 2234}, - {0x24A0, 0, 3 | DECOMP_COMPAT, 2237}, - {0x24A1, 0, 3 | DECOMP_COMPAT, 2240}, - {0x24A2, 0, 3 | DECOMP_COMPAT, 2243}, - {0x24A3, 0, 3 | DECOMP_COMPAT, 2246}, - {0x24A4, 0, 3 | DECOMP_COMPAT, 2249}, - {0x24A5, 0, 3 | DECOMP_COMPAT, 2252}, - {0x24A6, 0, 3 | DECOMP_COMPAT, 2255}, - {0x24A7, 0, 3 | DECOMP_COMPAT, 2258}, - {0x24A8, 0, 3 | DECOMP_COMPAT, 2261}, - {0x24A9, 0, 3 | DECOMP_COMPAT, 2264}, - {0x24AA, 0, 3 | DECOMP_COMPAT, 2267}, - {0x24AB, 0, 3 | DECOMP_COMPAT, 2270}, - {0x24AC, 0, 3 | DECOMP_COMPAT, 2273}, - {0x24AD, 0, 3 | DECOMP_COMPAT, 2276}, - {0x24AE, 0, 3 | DECOMP_COMPAT, 2279}, - {0x24AF, 0, 3 | DECOMP_COMPAT, 2282}, - {0x24B0, 0, 3 | DECOMP_COMPAT, 2285}, - {0x24B1, 0, 3 | DECOMP_COMPAT, 2288}, - {0x24B2, 0, 3 | DECOMP_COMPAT, 2291}, - {0x24B3, 0, 3 | DECOMP_COMPAT, 2294}, - {0x24B4, 0, 3 | DECOMP_COMPAT, 2297}, - {0x24B5, 0, 3 | DECOMP_COMPAT, 2300}, - {0x24B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x24B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x24B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x24B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x24BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x24BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x24BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x24BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x24BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x24BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x24C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x24C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x24C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x24C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x24C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x24C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x24C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x24C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x24C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x24C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x24CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x24CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x24CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x24CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x24CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x24CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x24D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x24D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x24D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x24D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x24D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x24D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x24D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x24D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x24D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x24D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x24DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x24DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x24DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x24DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x24DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x24DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x24E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x24E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x24E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x24E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x24E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x24E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x24E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x24E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x24E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x24E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x24EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x2A0C, 0, 4 | DECOMP_COMPAT, 2303}, - {0x2A74, 0, 3 | DECOMP_COMPAT, 2307}, - {0x2A75, 0, 2 | DECOMP_COMPAT, 2310}, - {0x2A76, 0, 3 | DECOMP_COMPAT, 2312}, - {0x2ADC, 0, 2 | DECOMP_NO_COMPOSE, 2315}, /* in exclusion list */ - {0x2C7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x2C7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x2CEF, 230, 0, 0}, - {0x2CF0, 230, 0, 0}, - {0x2CF1, 230, 0, 0}, - {0x2D6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2D61}, - {0x2D7F, 9, 0, 0}, - {0x2DE0, 230, 0, 0}, - {0x2DE1, 230, 0, 0}, - {0x2DE2, 230, 0, 0}, - {0x2DE3, 230, 0, 0}, - {0x2DE4, 230, 0, 0}, - {0x2DE5, 230, 0, 0}, - {0x2DE6, 230, 0, 0}, - {0x2DE7, 230, 0, 0}, - {0x2DE8, 230, 0, 0}, - {0x2DE9, 230, 0, 0}, - {0x2DEA, 230, 0, 0}, - {0x2DEB, 230, 0, 0}, - {0x2DEC, 230, 0, 0}, - {0x2DED, 230, 0, 0}, - {0x2DEE, 230, 0, 0}, - {0x2DEF, 230, 0, 0}, - {0x2DF0, 230, 0, 0}, - {0x2DF1, 230, 0, 0}, - {0x2DF2, 230, 0, 0}, - {0x2DF3, 230, 0, 0}, - {0x2DF4, 230, 0, 0}, - {0x2DF5, 230, 0, 0}, - {0x2DF6, 230, 0, 0}, - {0x2DF7, 230, 0, 0}, - {0x2DF8, 230, 0, 0}, - {0x2DF9, 230, 0, 0}, - {0x2DFA, 230, 0, 0}, - {0x2DFB, 230, 0, 0}, - {0x2DFC, 230, 0, 0}, - {0x2DFD, 230, 0, 0}, - {0x2DFE, 230, 0, 0}, - {0x2DFF, 230, 0, 0}, - {0x2E9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BCD}, - {0x2EF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F9F}, - {0x2F00, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, - {0x2F01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E28}, - {0x2F02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E36}, - {0x2F03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E3F}, - {0x2F04, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E59}, - {0x2F05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E85}, - {0x2F06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, - {0x2F07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EA0}, - {0x2F08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EBA}, - {0x2F09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x513F}, - {0x2F0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5165}, - {0x2F0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516B}, - {0x2F0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5182}, - {0x2F0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5196}, - {0x2F0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51AB}, - {0x2F0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51E0}, - {0x2F10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x51F5}, - {0x2F11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5200}, - {0x2F12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x529B}, - {0x2F13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x52F9}, - {0x2F14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5315}, - {0x2F15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x531A}, - {0x2F16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5338}, - {0x2F17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, - {0x2F18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x535C}, - {0x2F19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5369}, - {0x2F1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5382}, - {0x2F1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53B6}, - {0x2F1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53C8}, - {0x2F1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53E3}, - {0x2F1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56D7}, - {0x2F1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x571F}, - {0x2F20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x58EB}, - {0x2F21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5902}, - {0x2F22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x590A}, - {0x2F23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5915}, - {0x2F24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5927}, - {0x2F25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5973}, - {0x2F26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B50}, - {0x2F27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B80}, - {0x2F28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5BF8}, - {0x2F29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C0F}, - {0x2F2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C22}, - {0x2F2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C38}, - {0x2F2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C6E}, - {0x2F2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5C71}, - {0x2F2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DDB}, - {0x2F2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE5}, - {0x2F30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DF1}, - {0x2F31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DFE}, - {0x2F32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E72}, - {0x2F33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7A}, - {0x2F34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7F}, - {0x2F35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5EF4}, - {0x2F36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5EFE}, - {0x2F37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F0B}, - {0x2F38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F13}, - {0x2F39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F50}, - {0x2F3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F61}, - {0x2F3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F73}, - {0x2F3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5FC3}, - {0x2F3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6208}, - {0x2F3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6236}, - {0x2F3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x624B}, - {0x2F40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x652F}, - {0x2F41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6534}, - {0x2F42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6587}, - {0x2F43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6597}, - {0x2F44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65A4}, - {0x2F45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65B9}, - {0x2F46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E0}, - {0x2F47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E5}, - {0x2F48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x66F0}, - {0x2F49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, - {0x2F4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6728}, - {0x2F4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B20}, - {0x2F4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B62}, - {0x2F4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B79}, - {0x2F4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BB3}, - {0x2F4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BCB}, - {0x2F50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BD4}, - {0x2F51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6BDB}, - {0x2F52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C0F}, - {0x2F53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C14}, - {0x2F54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C34}, - {0x2F55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x706B}, - {0x2F56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x722A}, - {0x2F57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7236}, - {0x2F58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x723B}, - {0x2F59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x723F}, - {0x2F5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7247}, - {0x2F5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7259}, - {0x2F5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x725B}, - {0x2F5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x72AC}, - {0x2F5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7384}, - {0x2F5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7389}, - {0x2F60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x74DC}, - {0x2F61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x74E6}, - {0x2F62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7518}, - {0x2F63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x751F}, - {0x2F64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7528}, - {0x2F65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7530}, - {0x2F66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x758B}, - {0x2F67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7592}, - {0x2F68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7676}, - {0x2F69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x767D}, - {0x2F6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76AE}, - {0x2F6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76BF}, - {0x2F6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76EE}, - {0x2F6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77DB}, - {0x2F6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77E2}, - {0x2F6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x77F3}, - {0x2F70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x793A}, - {0x2F71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79B8}, - {0x2F72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79BE}, - {0x2F73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7A74}, - {0x2F74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7ACB}, - {0x2F75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7AF9}, - {0x2F76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7C73}, - {0x2F77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7CF8}, - {0x2F78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F36}, - {0x2F79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F51}, - {0x2F7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7F8A}, - {0x2F7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7FBD}, - {0x2F7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8001}, - {0x2F7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x800C}, - {0x2F7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8012}, - {0x2F7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8033}, - {0x2F80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x807F}, - {0x2F81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8089}, - {0x2F82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81E3}, - {0x2F83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81EA}, - {0x2F84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81F3}, - {0x2F85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x81FC}, - {0x2F86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x820C}, - {0x2F87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x821B}, - {0x2F88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x821F}, - {0x2F89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x826E}, - {0x2F8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8272}, - {0x2F8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8278}, - {0x2F8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x864D}, - {0x2F8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x866B}, - {0x2F8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8840}, - {0x2F8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x884C}, - {0x2F90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8863}, - {0x2F91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x897E}, - {0x2F92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x898B}, - {0x2F93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x89D2}, - {0x2F94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8A00}, - {0x2F95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C37}, - {0x2F96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C46}, - {0x2F97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C55}, - {0x2F98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C78}, - {0x2F99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8C9D}, - {0x2F9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D64}, - {0x2F9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D70}, - {0x2F9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8DB3}, - {0x2F9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8EAB}, - {0x2F9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8ECA}, - {0x2F9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8F9B}, - {0x2FA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8FB0}, - {0x2FA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8FB5}, - {0x2FA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9091}, - {0x2FA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9149}, - {0x2FA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91C6}, - {0x2FA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91CC}, - {0x2FA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91D1}, - {0x2FA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9577}, - {0x2FA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9580}, - {0x2FA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x961C}, - {0x2FAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96B6}, - {0x2FAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96B9}, - {0x2FAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x96E8}, - {0x2FAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9751}, - {0x2FAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x975E}, - {0x2FAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9762}, - {0x2FB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9769}, - {0x2FB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97CB}, - {0x2FB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97ED}, - {0x2FB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x97F3}, - {0x2FB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9801}, - {0x2FB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98A8}, - {0x2FB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98DB}, - {0x2FB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x98DF}, - {0x2FB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9996}, - {0x2FB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9999}, - {0x2FBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x99AC}, - {0x2FBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9AA8}, - {0x2FBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9AD8}, - {0x2FBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ADF}, - {0x2FBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B25}, - {0x2FBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B2F}, - {0x2FC0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B32}, - {0x2FC1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B3C}, - {0x2FC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9B5A}, - {0x2FC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9CE5}, - {0x2FC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9E75}, - {0x2FC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9E7F}, - {0x2FC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EA5}, - {0x2FC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EBB}, - {0x2FC8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EC3}, - {0x2FC9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ECD}, - {0x2FCA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9ED1}, - {0x2FCB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EF9}, - {0x2FCC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9EFD}, - {0x2FCD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F0E}, - {0x2FCE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F13}, - {0x2FCF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F20}, - {0x2FD0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F3B}, - {0x2FD1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F4A}, - {0x2FD2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F52}, - {0x2FD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F8D}, - {0x2FD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9F9C}, - {0x2FD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9FA0}, - {0x3000, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0020}, - {0x302A, 218, 0, 0}, - {0x302B, 228, 0, 0}, - {0x302C, 232, 0, 0}, - {0x302D, 222, 0, 0}, - {0x302E, 224, 0, 0}, - {0x302F, 224, 0, 0}, - {0x3036, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3012}, - {0x3038, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, - {0x3039, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5344}, - {0x303A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5345}, - {0x304C, 0, 2, 2317}, - {0x304E, 0, 2, 2319}, - {0x3050, 0, 2, 2321}, - {0x3052, 0, 2, 2323}, - {0x3054, 0, 2, 2325}, - {0x3056, 0, 2, 2327}, - {0x3058, 0, 2, 2329}, - {0x305A, 0, 2, 2331}, - {0x305C, 0, 2, 2333}, - {0x305E, 0, 2, 2335}, - {0x3060, 0, 2, 2337}, - {0x3062, 0, 2, 2339}, - {0x3065, 0, 2, 2341}, - {0x3067, 0, 2, 2343}, - {0x3069, 0, 2, 2345}, - {0x3070, 0, 2, 2347}, - {0x3071, 0, 2, 2349}, - {0x3073, 0, 2, 2351}, - {0x3074, 0, 2, 2353}, - {0x3076, 0, 2, 2355}, - {0x3077, 0, 2, 2357}, - {0x3079, 0, 2, 2359}, - {0x307A, 0, 2, 2361}, - {0x307C, 0, 2, 2363}, - {0x307D, 0, 2, 2365}, - {0x3094, 0, 2, 2367}, - {0x3099, 8, 0, 0}, - {0x309A, 8, 0, 0}, - {0x309B, 0, 2 | DECOMP_COMPAT, 2369}, - {0x309C, 0, 2 | DECOMP_COMPAT, 2371}, - {0x309E, 0, 2, 2373}, - {0x309F, 0, 2 | DECOMP_COMPAT, 2375}, - {0x30AC, 0, 2, 2377}, - {0x30AE, 0, 2, 2379}, - {0x30B0, 0, 2, 2381}, - {0x30B2, 0, 2, 2383}, - {0x30B4, 0, 2, 2385}, - {0x30B6, 0, 2, 2387}, - {0x30B8, 0, 2, 2389}, - {0x30BA, 0, 2, 2391}, - {0x30BC, 0, 2, 2393}, - {0x30BE, 0, 2, 2395}, - {0x30C0, 0, 2, 2397}, - {0x30C2, 0, 2, 2399}, - {0x30C5, 0, 2, 2401}, - {0x30C7, 0, 2, 2403}, - {0x30C9, 0, 2, 2405}, - {0x30D0, 0, 2, 2407}, - {0x30D1, 0, 2, 2409}, - {0x30D3, 0, 2, 2411}, - {0x30D4, 0, 2, 2413}, - {0x30D6, 0, 2, 2415}, - {0x30D7, 0, 2, 2417}, - {0x30D9, 0, 2, 2419}, - {0x30DA, 0, 2, 2421}, - {0x30DC, 0, 2, 2423}, - {0x30DD, 0, 2, 2425}, - {0x30F4, 0, 2, 2427}, - {0x30F7, 0, 2, 2429}, - {0x30F8, 0, 2, 2431}, - {0x30F9, 0, 2, 2433}, - {0x30FA, 0, 2, 2435}, - {0x30FE, 0, 2, 2437}, - {0x30FF, 0, 2 | DECOMP_COMPAT, 2439}, - {0x3131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1100}, - {0x3132, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1101}, - {0x3133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AA}, - {0x3134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1102}, - {0x3135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AC}, - {0x3136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11AD}, - {0x3137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1103}, - {0x3138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1104}, - {0x3139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1105}, - {0x313A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B0}, - {0x313B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B1}, - {0x313C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B2}, - {0x313D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B3}, - {0x313E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B4}, - {0x313F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11B5}, - {0x3140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111A}, - {0x3141, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1106}, - {0x3142, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1107}, - {0x3143, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1108}, - {0x3144, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1121}, - {0x3145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1109}, - {0x3146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110A}, - {0x3147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110B}, - {0x3148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110C}, - {0x3149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110D}, - {0x314A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110E}, - {0x314B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110F}, - {0x314C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1110}, - {0x314D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1111}, - {0x314E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1112}, - {0x314F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1161}, - {0x3150, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1162}, - {0x3151, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1163}, - {0x3152, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1164}, - {0x3153, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1165}, - {0x3154, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1166}, - {0x3155, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1167}, - {0x3156, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1168}, - {0x3157, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1169}, - {0x3158, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116A}, - {0x3159, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116B}, - {0x315A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116C}, - {0x315B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116D}, - {0x315C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116E}, - {0x315D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x116F}, - {0x315E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1170}, - {0x315F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1171}, - {0x3160, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1172}, - {0x3161, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1173}, - {0x3162, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1174}, - {0x3163, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1175}, - {0x3164, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1160}, - {0x3165, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1114}, - {0x3166, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1115}, - {0x3167, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11C7}, - {0x3168, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11C8}, - {0x3169, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11CC}, - {0x316A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11CE}, - {0x316B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D3}, - {0x316C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D7}, - {0x316D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11D9}, - {0x316E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111C}, - {0x316F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11DD}, - {0x3170, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11DF}, - {0x3171, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111D}, - {0x3172, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x111E}, - {0x3173, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1120}, - {0x3174, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1122}, - {0x3175, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1123}, - {0x3176, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1127}, - {0x3177, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1129}, - {0x3178, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112B}, - {0x3179, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112C}, - {0x317A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112D}, - {0x317B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112E}, - {0x317C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x112F}, - {0x317D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1132}, - {0x317E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1136}, - {0x317F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1140}, - {0x3180, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1147}, - {0x3181, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x114C}, - {0x3182, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11F1}, - {0x3183, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11F2}, - {0x3184, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1157}, - {0x3185, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1158}, - {0x3186, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1159}, - {0x3187, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1184}, - {0x3188, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1185}, - {0x3189, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1188}, - {0x318A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1191}, - {0x318B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1192}, - {0x318C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1194}, - {0x318D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x119E}, - {0x318E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x11A1}, - {0x3192, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, - {0x3193, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, - {0x3194, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, - {0x3195, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56DB}, - {0x3196, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0A}, - {0x3197, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, - {0x3198, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0B}, - {0x3199, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7532}, - {0x319A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E59}, - {0x319B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E19}, - {0x319C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E01}, - {0x319D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5929}, - {0x319E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5730}, - {0x319F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EBA}, - {0x3200, 0, 3 | DECOMP_COMPAT, 2441}, - {0x3201, 0, 3 | DECOMP_COMPAT, 2444}, - {0x3202, 0, 3 | DECOMP_COMPAT, 2447}, - {0x3203, 0, 3 | DECOMP_COMPAT, 2450}, - {0x3204, 0, 3 | DECOMP_COMPAT, 2453}, - {0x3205, 0, 3 | DECOMP_COMPAT, 2456}, - {0x3206, 0, 3 | DECOMP_COMPAT, 2459}, - {0x3207, 0, 3 | DECOMP_COMPAT, 2462}, - {0x3208, 0, 3 | DECOMP_COMPAT, 2465}, - {0x3209, 0, 3 | DECOMP_COMPAT, 2468}, - {0x320A, 0, 3 | DECOMP_COMPAT, 2471}, - {0x320B, 0, 3 | DECOMP_COMPAT, 2474}, - {0x320C, 0, 3 | DECOMP_COMPAT, 2477}, - {0x320D, 0, 3 | DECOMP_COMPAT, 2480}, - {0x320E, 0, 4 | DECOMP_COMPAT, 2483}, - {0x320F, 0, 4 | DECOMP_COMPAT, 2487}, - {0x3210, 0, 4 | DECOMP_COMPAT, 2491}, - {0x3211, 0, 4 | DECOMP_COMPAT, 2495}, - {0x3212, 0, 4 | DECOMP_COMPAT, 2499}, - {0x3213, 0, 4 | DECOMP_COMPAT, 2503}, - {0x3214, 0, 4 | DECOMP_COMPAT, 2507}, - {0x3215, 0, 4 | DECOMP_COMPAT, 2511}, - {0x3216, 0, 4 | DECOMP_COMPAT, 2515}, - {0x3217, 0, 4 | DECOMP_COMPAT, 2519}, - {0x3218, 0, 4 | DECOMP_COMPAT, 2523}, - {0x3219, 0, 4 | DECOMP_COMPAT, 2527}, - {0x321A, 0, 4 | DECOMP_COMPAT, 2531}, - {0x321B, 0, 4 | DECOMP_COMPAT, 2535}, - {0x321C, 0, 4 | DECOMP_COMPAT, 2539}, - {0x321D, 0, 7 | DECOMP_COMPAT, 2543}, - {0x321E, 0, 6 | DECOMP_COMPAT, 2550}, - {0x3220, 0, 3 | DECOMP_COMPAT, 2556}, - {0x3221, 0, 3 | DECOMP_COMPAT, 2559}, - {0x3222, 0, 3 | DECOMP_COMPAT, 2562}, - {0x3223, 0, 3 | DECOMP_COMPAT, 2565}, - {0x3224, 0, 3 | DECOMP_COMPAT, 2568}, - {0x3225, 0, 3 | DECOMP_COMPAT, 2571}, - {0x3226, 0, 3 | DECOMP_COMPAT, 2574}, - {0x3227, 0, 3 | DECOMP_COMPAT, 2577}, - {0x3228, 0, 3 | DECOMP_COMPAT, 2580}, - {0x3229, 0, 3 | DECOMP_COMPAT, 2583}, - {0x322A, 0, 3 | DECOMP_COMPAT, 2586}, - {0x322B, 0, 3 | DECOMP_COMPAT, 2589}, - {0x322C, 0, 3 | DECOMP_COMPAT, 2592}, - {0x322D, 0, 3 | DECOMP_COMPAT, 2595}, - {0x322E, 0, 3 | DECOMP_COMPAT, 2598}, - {0x322F, 0, 3 | DECOMP_COMPAT, 2601}, - {0x3230, 0, 3 | DECOMP_COMPAT, 2604}, - {0x3231, 0, 3 | DECOMP_COMPAT, 2607}, - {0x3232, 0, 3 | DECOMP_COMPAT, 2610}, - {0x3233, 0, 3 | DECOMP_COMPAT, 2613}, - {0x3234, 0, 3 | DECOMP_COMPAT, 2616}, - {0x3235, 0, 3 | DECOMP_COMPAT, 2619}, - {0x3236, 0, 3 | DECOMP_COMPAT, 2622}, - {0x3237, 0, 3 | DECOMP_COMPAT, 2625}, - {0x3238, 0, 3 | DECOMP_COMPAT, 2628}, - {0x3239, 0, 3 | DECOMP_COMPAT, 2631}, - {0x323A, 0, 3 | DECOMP_COMPAT, 2634}, - {0x323B, 0, 3 | DECOMP_COMPAT, 2637}, - {0x323C, 0, 3 | DECOMP_COMPAT, 2640}, - {0x323D, 0, 3 | DECOMP_COMPAT, 2643}, - {0x323E, 0, 3 | DECOMP_COMPAT, 2646}, - {0x323F, 0, 3 | DECOMP_COMPAT, 2649}, - {0x3240, 0, 3 | DECOMP_COMPAT, 2652}, - {0x3241, 0, 3 | DECOMP_COMPAT, 2655}, - {0x3242, 0, 3 | DECOMP_COMPAT, 2658}, - {0x3243, 0, 3 | DECOMP_COMPAT, 2661}, - {0x3244, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x554F}, - {0x3245, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5E7C}, - {0x3246, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6587}, - {0x3247, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7B8F}, - {0x3250, 0, 3 | DECOMP_COMPAT, 2664}, - {0x3251, 0, 2 | DECOMP_COMPAT, 2667}, - {0x3252, 0, 2 | DECOMP_COMPAT, 2669}, - {0x3253, 0, 2 | DECOMP_COMPAT, 2671}, - {0x3254, 0, 2 | DECOMP_COMPAT, 2673}, - {0x3255, 0, 2 | DECOMP_COMPAT, 2675}, - {0x3256, 0, 2 | DECOMP_COMPAT, 2677}, - {0x3257, 0, 2 | DECOMP_COMPAT, 2679}, - {0x3258, 0, 2 | DECOMP_COMPAT, 2681}, - {0x3259, 0, 2 | DECOMP_COMPAT, 2683}, - {0x325A, 0, 2 | DECOMP_COMPAT, 2685}, - {0x325B, 0, 2 | DECOMP_COMPAT, 2687}, - {0x325C, 0, 2 | DECOMP_COMPAT, 2689}, - {0x325D, 0, 2 | DECOMP_COMPAT, 2691}, - {0x325E, 0, 2 | DECOMP_COMPAT, 2693}, - {0x325F, 0, 2 | DECOMP_COMPAT, 2695}, - {0x3260, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1100}, - {0x3261, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1102}, - {0x3262, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1103}, - {0x3263, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1105}, - {0x3264, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1106}, - {0x3265, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1107}, - {0x3266, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1109}, - {0x3267, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110B}, - {0x3268, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110C}, - {0x3269, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110E}, - {0x326A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x110F}, - {0x326B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1110}, - {0x326C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1111}, - {0x326D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1112}, - {0x326E, 0, 2 | DECOMP_COMPAT, 2697}, - {0x326F, 0, 2 | DECOMP_COMPAT, 2699}, - {0x3270, 0, 2 | DECOMP_COMPAT, 2701}, - {0x3271, 0, 2 | DECOMP_COMPAT, 2703}, - {0x3272, 0, 2 | DECOMP_COMPAT, 2705}, - {0x3273, 0, 2 | DECOMP_COMPAT, 2707}, - {0x3274, 0, 2 | DECOMP_COMPAT, 2709}, - {0x3275, 0, 2 | DECOMP_COMPAT, 2711}, - {0x3276, 0, 2 | DECOMP_COMPAT, 2713}, - {0x3277, 0, 2 | DECOMP_COMPAT, 2715}, - {0x3278, 0, 2 | DECOMP_COMPAT, 2717}, - {0x3279, 0, 2 | DECOMP_COMPAT, 2719}, - {0x327A, 0, 2 | DECOMP_COMPAT, 2721}, - {0x327B, 0, 2 | DECOMP_COMPAT, 2723}, - {0x327C, 0, 5 | DECOMP_COMPAT, 2725}, - {0x327D, 0, 4 | DECOMP_COMPAT, 2730}, - {0x327E, 0, 2 | DECOMP_COMPAT, 2734}, - {0x3280, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, - {0x3281, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, - {0x3282, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, - {0x3283, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x56DB}, - {0x3284, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E94}, - {0x3285, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516D}, - {0x3286, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E03}, - {0x3287, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x516B}, - {0x3288, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E5D}, - {0x3289, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5341}, - {0x328A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, - {0x328B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x706B}, - {0x328C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6C34}, - {0x328D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6728}, - {0x328E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x91D1}, - {0x328F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x571F}, - {0x3290, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65E5}, - {0x3291, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x682A}, - {0x3292, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6709}, - {0x3293, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x793E}, - {0x3294, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x540D}, - {0x3295, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7279}, - {0x3296, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CA1}, - {0x3297, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x795D}, - {0x3298, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x52B4}, - {0x3299, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x79D8}, - {0x329A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7537}, - {0x329B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5973}, - {0x329C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9069}, - {0x329D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x512A}, - {0x329E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5370}, - {0x329F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6CE8}, - {0x32A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x9805}, - {0x32A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4F11}, - {0x32A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5199}, - {0x32A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6B63}, - {0x32A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0A}, - {0x32A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, - {0x32A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E0B}, - {0x32A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE6}, - {0x32A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53F3}, - {0x32A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x533B}, - {0x32AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B97}, - {0x32AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B66}, - {0x32AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x76E3}, - {0x32AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4F01}, - {0x32AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CC7}, - {0x32AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5354}, - {0x32B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x591C}, - {0x32B1, 0, 2 | DECOMP_COMPAT, 2736}, - {0x32B2, 0, 2 | DECOMP_COMPAT, 2738}, - {0x32B3, 0, 2 | DECOMP_COMPAT, 2740}, - {0x32B4, 0, 2 | DECOMP_COMPAT, 2742}, - {0x32B5, 0, 2 | DECOMP_COMPAT, 2744}, - {0x32B6, 0, 2 | DECOMP_COMPAT, 2746}, - {0x32B7, 0, 2 | DECOMP_COMPAT, 2748}, - {0x32B8, 0, 2 | DECOMP_COMPAT, 2750}, - {0x32B9, 0, 2 | DECOMP_COMPAT, 2752}, - {0x32BA, 0, 2 | DECOMP_COMPAT, 2754}, - {0x32BB, 0, 2 | DECOMP_COMPAT, 2756}, - {0x32BC, 0, 2 | DECOMP_COMPAT, 2758}, - {0x32BD, 0, 2 | DECOMP_COMPAT, 2760}, - {0x32BE, 0, 2 | DECOMP_COMPAT, 2762}, - {0x32BF, 0, 2 | DECOMP_COMPAT, 2764}, - {0x32C0, 0, 2 | DECOMP_COMPAT, 2766}, - {0x32C1, 0, 2 | DECOMP_COMPAT, 2768}, - {0x32C2, 0, 2 | DECOMP_COMPAT, 2770}, - {0x32C3, 0, 2 | DECOMP_COMPAT, 2772}, - {0x32C4, 0, 2 | DECOMP_COMPAT, 2774}, - {0x32C5, 0, 2 | DECOMP_COMPAT, 2776}, - {0x32C6, 0, 2 | DECOMP_COMPAT, 2778}, - {0x32C7, 0, 2 | DECOMP_COMPAT, 2780}, - {0x32C8, 0, 2 | DECOMP_COMPAT, 2782}, - {0x32C9, 0, 3 | DECOMP_COMPAT, 2784}, - {0x32CA, 0, 3 | DECOMP_COMPAT, 2787}, - {0x32CB, 0, 3 | DECOMP_COMPAT, 2790}, - {0x32CC, 0, 2 | DECOMP_COMPAT, 2793}, - {0x32CD, 0, 3 | DECOMP_COMPAT, 2795}, - {0x32CE, 0, 2 | DECOMP_COMPAT, 2798}, - {0x32CF, 0, 3 | DECOMP_COMPAT, 2800}, - {0x32D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A2}, - {0x32D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A4}, - {0x32D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A6}, - {0x32D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A8}, - {0x32D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AA}, - {0x32D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AB}, - {0x32D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AD}, - {0x32D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AF}, - {0x32D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B1}, - {0x32D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B3}, - {0x32DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, - {0x32DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B7}, - {0x32DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B9}, - {0x32DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BB}, - {0x32DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BD}, - {0x32DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BF}, - {0x32E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C1}, - {0x32E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C4}, - {0x32E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C6}, - {0x32E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C8}, - {0x32E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CA}, - {0x32E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CB}, - {0x32E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CC}, - {0x32E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CD}, - {0x32E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CE}, - {0x32E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CF}, - {0x32EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D2}, - {0x32EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D5}, - {0x32EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D8}, - {0x32ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DB}, - {0x32EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DE}, - {0x32EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DF}, - {0x32F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E0}, - {0x32F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E1}, - {0x32F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E2}, - {0x32F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E4}, - {0x32F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E6}, - {0x32F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E8}, - {0x32F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E9}, - {0x32F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EA}, - {0x32F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EB}, - {0x32F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EC}, - {0x32FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30ED}, - {0x32FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EF}, - {0x32FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F0}, - {0x32FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F1}, - {0x32FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F2}, - {0x32FF, 0, 2 | DECOMP_COMPAT, 2803}, - {0x3300, 0, 4 | DECOMP_COMPAT, 2805}, - {0x3301, 0, 4 | DECOMP_COMPAT, 2809}, - {0x3302, 0, 4 | DECOMP_COMPAT, 2813}, - {0x3303, 0, 3 | DECOMP_COMPAT, 2817}, - {0x3304, 0, 4 | DECOMP_COMPAT, 2820}, - {0x3305, 0, 3 | DECOMP_COMPAT, 2824}, - {0x3306, 0, 3 | DECOMP_COMPAT, 2827}, - {0x3307, 0, 5 | DECOMP_COMPAT, 2830}, - {0x3308, 0, 4 | DECOMP_COMPAT, 2835}, - {0x3309, 0, 3 | DECOMP_COMPAT, 2839}, - {0x330A, 0, 3 | DECOMP_COMPAT, 2842}, - {0x330B, 0, 3 | DECOMP_COMPAT, 2845}, - {0x330C, 0, 4 | DECOMP_COMPAT, 2848}, - {0x330D, 0, 4 | DECOMP_COMPAT, 2852}, - {0x330E, 0, 3 | DECOMP_COMPAT, 2856}, - {0x330F, 0, 3 | DECOMP_COMPAT, 2859}, - {0x3310, 0, 2 | DECOMP_COMPAT, 2862}, - {0x3311, 0, 3 | DECOMP_COMPAT, 2864}, - {0x3312, 0, 4 | DECOMP_COMPAT, 2867}, - {0x3313, 0, 4 | DECOMP_COMPAT, 2871}, - {0x3314, 0, 2 | DECOMP_COMPAT, 2875}, - {0x3315, 0, 5 | DECOMP_COMPAT, 2877}, - {0x3316, 0, 6 | DECOMP_COMPAT, 2882}, - {0x3317, 0, 5 | DECOMP_COMPAT, 2888}, - {0x3318, 0, 3 | DECOMP_COMPAT, 2893}, - {0x3319, 0, 5 | DECOMP_COMPAT, 2896}, - {0x331A, 0, 5 | DECOMP_COMPAT, 2901}, - {0x331B, 0, 4 | DECOMP_COMPAT, 2906}, - {0x331C, 0, 3 | DECOMP_COMPAT, 2910}, - {0x331D, 0, 3 | DECOMP_COMPAT, 2913}, - {0x331E, 0, 3 | DECOMP_COMPAT, 2916}, - {0x331F, 0, 4 | DECOMP_COMPAT, 2919}, - {0x3320, 0, 5 | DECOMP_COMPAT, 2923}, - {0x3321, 0, 4 | DECOMP_COMPAT, 2928}, - {0x3322, 0, 3 | DECOMP_COMPAT, 2932}, - {0x3323, 0, 3 | DECOMP_COMPAT, 2935}, - {0x3324, 0, 3 | DECOMP_COMPAT, 2938}, - {0x3325, 0, 2 | DECOMP_COMPAT, 2941}, - {0x3326, 0, 2 | DECOMP_COMPAT, 2943}, - {0x3327, 0, 2 | DECOMP_COMPAT, 2945}, - {0x3328, 0, 2 | DECOMP_COMPAT, 2947}, - {0x3329, 0, 3 | DECOMP_COMPAT, 2949}, - {0x332A, 0, 3 | DECOMP_COMPAT, 2952}, - {0x332B, 0, 5 | DECOMP_COMPAT, 2955}, - {0x332C, 0, 3 | DECOMP_COMPAT, 2960}, - {0x332D, 0, 4 | DECOMP_COMPAT, 2963}, - {0x332E, 0, 5 | DECOMP_COMPAT, 2967}, - {0x332F, 0, 3 | DECOMP_COMPAT, 2972}, - {0x3330, 0, 2 | DECOMP_COMPAT, 2975}, - {0x3331, 0, 2 | DECOMP_COMPAT, 2977}, - {0x3332, 0, 5 | DECOMP_COMPAT, 2979}, - {0x3333, 0, 4 | DECOMP_COMPAT, 2984}, - {0x3334, 0, 5 | DECOMP_COMPAT, 2988}, - {0x3335, 0, 3 | DECOMP_COMPAT, 2993}, - {0x3336, 0, 5 | DECOMP_COMPAT, 2996}, - {0x3337, 0, 2 | DECOMP_COMPAT, 3001}, - {0x3338, 0, 3 | DECOMP_COMPAT, 3003}, - {0x3339, 0, 3 | DECOMP_COMPAT, 3006}, - {0x333A, 0, 3 | DECOMP_COMPAT, 3009}, - {0x333B, 0, 3 | DECOMP_COMPAT, 3012}, - {0x333C, 0, 3 | DECOMP_COMPAT, 3015}, - {0x333D, 0, 4 | DECOMP_COMPAT, 3018}, - {0x333E, 0, 3 | DECOMP_COMPAT, 3022}, - {0x333F, 0, 2 | DECOMP_COMPAT, 3025}, - {0x3340, 0, 3 | DECOMP_COMPAT, 3027}, - {0x3341, 0, 3 | DECOMP_COMPAT, 3030}, - {0x3342, 0, 3 | DECOMP_COMPAT, 3033}, - {0x3343, 0, 4 | DECOMP_COMPAT, 3036}, - {0x3344, 0, 3 | DECOMP_COMPAT, 3040}, - {0x3345, 0, 3 | DECOMP_COMPAT, 3043}, - {0x3346, 0, 3 | DECOMP_COMPAT, 3046}, - {0x3347, 0, 5 | DECOMP_COMPAT, 3049}, - {0x3348, 0, 4 | DECOMP_COMPAT, 3054}, - {0x3349, 0, 2 | DECOMP_COMPAT, 3058}, - {0x334A, 0, 5 | DECOMP_COMPAT, 3060}, - {0x334B, 0, 2 | DECOMP_COMPAT, 3065}, - {0x334C, 0, 4 | DECOMP_COMPAT, 3067}, - {0x334D, 0, 4 | DECOMP_COMPAT, 3071}, - {0x334E, 0, 3 | DECOMP_COMPAT, 3075}, - {0x334F, 0, 3 | DECOMP_COMPAT, 3078}, - {0x3350, 0, 3 | DECOMP_COMPAT, 3081}, - {0x3351, 0, 4 | DECOMP_COMPAT, 3084}, - {0x3352, 0, 2 | DECOMP_COMPAT, 3088}, - {0x3353, 0, 3 | DECOMP_COMPAT, 3090}, - {0x3354, 0, 4 | DECOMP_COMPAT, 3093}, - {0x3355, 0, 2 | DECOMP_COMPAT, 3097}, - {0x3356, 0, 5 | DECOMP_COMPAT, 3099}, - {0x3357, 0, 3 | DECOMP_COMPAT, 3104}, - {0x3358, 0, 2 | DECOMP_COMPAT, 3107}, - {0x3359, 0, 2 | DECOMP_COMPAT, 3109}, - {0x335A, 0, 2 | DECOMP_COMPAT, 3111}, - {0x335B, 0, 2 | DECOMP_COMPAT, 3113}, - {0x335C, 0, 2 | DECOMP_COMPAT, 3115}, - {0x335D, 0, 2 | DECOMP_COMPAT, 3117}, - {0x335E, 0, 2 | DECOMP_COMPAT, 3119}, - {0x335F, 0, 2 | DECOMP_COMPAT, 3121}, - {0x3360, 0, 2 | DECOMP_COMPAT, 3123}, - {0x3361, 0, 2 | DECOMP_COMPAT, 3125}, - {0x3362, 0, 3 | DECOMP_COMPAT, 3127}, - {0x3363, 0, 3 | DECOMP_COMPAT, 3130}, - {0x3364, 0, 3 | DECOMP_COMPAT, 3133}, - {0x3365, 0, 3 | DECOMP_COMPAT, 3136}, - {0x3366, 0, 3 | DECOMP_COMPAT, 3139}, - {0x3367, 0, 3 | DECOMP_COMPAT, 3142}, - {0x3368, 0, 3 | DECOMP_COMPAT, 3145}, - {0x3369, 0, 3 | DECOMP_COMPAT, 3148}, - {0x336A, 0, 3 | DECOMP_COMPAT, 3151}, - {0x336B, 0, 3 | DECOMP_COMPAT, 3154}, - {0x336C, 0, 3 | DECOMP_COMPAT, 3157}, - {0x336D, 0, 3 | DECOMP_COMPAT, 3160}, - {0x336E, 0, 3 | DECOMP_COMPAT, 3163}, - {0x336F, 0, 3 | DECOMP_COMPAT, 3166}, - {0x3370, 0, 3 | DECOMP_COMPAT, 3169}, - {0x3371, 0, 3 | DECOMP_COMPAT, 3172}, - {0x3372, 0, 2 | DECOMP_COMPAT, 3175}, - {0x3373, 0, 2 | DECOMP_COMPAT, 3177}, - {0x3374, 0, 3 | DECOMP_COMPAT, 3179}, - {0x3375, 0, 2 | DECOMP_COMPAT, 3182}, - {0x3376, 0, 2 | DECOMP_COMPAT, 3184}, - {0x3377, 0, 2 | DECOMP_COMPAT, 3186}, - {0x3378, 0, 3 | DECOMP_COMPAT, 3188}, - {0x3379, 0, 3 | DECOMP_COMPAT, 3191}, - {0x337A, 0, 2 | DECOMP_COMPAT, 3194}, - {0x337B, 0, 2 | DECOMP_COMPAT, 3196}, - {0x337C, 0, 2 | DECOMP_COMPAT, 3198}, - {0x337D, 0, 2 | DECOMP_COMPAT, 3200}, - {0x337E, 0, 2 | DECOMP_COMPAT, 3202}, - {0x337F, 0, 4 | DECOMP_COMPAT, 3204}, - {0x3380, 0, 2 | DECOMP_COMPAT, 3208}, - {0x3381, 0, 2 | DECOMP_COMPAT, 3210}, - {0x3382, 0, 2 | DECOMP_COMPAT, 3212}, - {0x3383, 0, 2 | DECOMP_COMPAT, 3214}, - {0x3384, 0, 2 | DECOMP_COMPAT, 3216}, - {0x3385, 0, 2 | DECOMP_COMPAT, 3218}, - {0x3386, 0, 2 | DECOMP_COMPAT, 3220}, - {0x3387, 0, 2 | DECOMP_COMPAT, 3222}, - {0x3388, 0, 3 | DECOMP_COMPAT, 3224}, - {0x3389, 0, 4 | DECOMP_COMPAT, 3227}, - {0x338A, 0, 2 | DECOMP_COMPAT, 3231}, - {0x338B, 0, 2 | DECOMP_COMPAT, 3233}, - {0x338C, 0, 2 | DECOMP_COMPAT, 3235}, - {0x338D, 0, 2 | DECOMP_COMPAT, 3237}, - {0x338E, 0, 2 | DECOMP_COMPAT, 3239}, - {0x338F, 0, 2 | DECOMP_COMPAT, 3241}, - {0x3390, 0, 2 | DECOMP_COMPAT, 3243}, - {0x3391, 0, 3 | DECOMP_COMPAT, 3245}, - {0x3392, 0, 3 | DECOMP_COMPAT, 3248}, - {0x3393, 0, 3 | DECOMP_COMPAT, 3251}, - {0x3394, 0, 3 | DECOMP_COMPAT, 3254}, - {0x3395, 0, 2 | DECOMP_COMPAT, 3257}, - {0x3396, 0, 2 | DECOMP_COMPAT, 3259}, - {0x3397, 0, 2 | DECOMP_COMPAT, 3261}, - {0x3398, 0, 2 | DECOMP_COMPAT, 3263}, - {0x3399, 0, 2 | DECOMP_COMPAT, 3265}, - {0x339A, 0, 2 | DECOMP_COMPAT, 3267}, - {0x339B, 0, 2 | DECOMP_COMPAT, 3269}, - {0x339C, 0, 2 | DECOMP_COMPAT, 3271}, - {0x339D, 0, 2 | DECOMP_COMPAT, 3273}, - {0x339E, 0, 2 | DECOMP_COMPAT, 3275}, - {0x339F, 0, 3 | DECOMP_COMPAT, 3277}, - {0x33A0, 0, 3 | DECOMP_COMPAT, 3280}, - {0x33A1, 0, 2 | DECOMP_COMPAT, 3283}, - {0x33A2, 0, 3 | DECOMP_COMPAT, 3285}, - {0x33A3, 0, 3 | DECOMP_COMPAT, 3288}, - {0x33A4, 0, 3 | DECOMP_COMPAT, 3291}, - {0x33A5, 0, 2 | DECOMP_COMPAT, 3294}, - {0x33A6, 0, 3 | DECOMP_COMPAT, 3296}, - {0x33A7, 0, 3 | DECOMP_COMPAT, 3299}, - {0x33A8, 0, 4 | DECOMP_COMPAT, 3302}, - {0x33A9, 0, 2 | DECOMP_COMPAT, 3306}, - {0x33AA, 0, 3 | DECOMP_COMPAT, 3308}, - {0x33AB, 0, 3 | DECOMP_COMPAT, 3311}, - {0x33AC, 0, 3 | DECOMP_COMPAT, 3314}, - {0x33AD, 0, 3 | DECOMP_COMPAT, 3317}, - {0x33AE, 0, 5 | DECOMP_COMPAT, 3320}, - {0x33AF, 0, 6 | DECOMP_COMPAT, 3325}, - {0x33B0, 0, 2 | DECOMP_COMPAT, 3331}, - {0x33B1, 0, 2 | DECOMP_COMPAT, 3333}, - {0x33B2, 0, 2 | DECOMP_COMPAT, 3335}, - {0x33B3, 0, 2 | DECOMP_COMPAT, 3337}, - {0x33B4, 0, 2 | DECOMP_COMPAT, 3339}, - {0x33B5, 0, 2 | DECOMP_COMPAT, 3341}, - {0x33B6, 0, 2 | DECOMP_COMPAT, 3343}, - {0x33B7, 0, 2 | DECOMP_COMPAT, 3345}, - {0x33B8, 0, 2 | DECOMP_COMPAT, 3347}, - {0x33B9, 0, 2 | DECOMP_COMPAT, 3349}, - {0x33BA, 0, 2 | DECOMP_COMPAT, 3351}, - {0x33BB, 0, 2 | DECOMP_COMPAT, 3353}, - {0x33BC, 0, 2 | DECOMP_COMPAT, 3355}, - {0x33BD, 0, 2 | DECOMP_COMPAT, 3357}, - {0x33BE, 0, 2 | DECOMP_COMPAT, 3359}, - {0x33BF, 0, 2 | DECOMP_COMPAT, 3361}, - {0x33C0, 0, 2 | DECOMP_COMPAT, 3363}, - {0x33C1, 0, 2 | DECOMP_COMPAT, 3365}, - {0x33C2, 0, 4 | DECOMP_COMPAT, 3367}, - {0x33C3, 0, 2 | DECOMP_COMPAT, 3371}, - {0x33C4, 0, 2 | DECOMP_COMPAT, 3373}, - {0x33C5, 0, 2 | DECOMP_COMPAT, 3375}, - {0x33C6, 0, 4 | DECOMP_COMPAT, 3377}, - {0x33C7, 0, 3 | DECOMP_COMPAT, 3381}, - {0x33C8, 0, 2 | DECOMP_COMPAT, 3384}, - {0x33C9, 0, 2 | DECOMP_COMPAT, 3386}, - {0x33CA, 0, 2 | DECOMP_COMPAT, 3388}, - {0x33CB, 0, 2 | DECOMP_COMPAT, 3390}, - {0x33CC, 0, 2 | DECOMP_COMPAT, 3392}, - {0x33CD, 0, 2 | DECOMP_COMPAT, 3394}, - {0x33CE, 0, 2 | DECOMP_COMPAT, 3396}, - {0x33CF, 0, 2 | DECOMP_COMPAT, 3398}, - {0x33D0, 0, 2 | DECOMP_COMPAT, 3400}, - {0x33D1, 0, 2 | DECOMP_COMPAT, 3402}, - {0x33D2, 0, 3 | DECOMP_COMPAT, 3404}, - {0x33D3, 0, 2 | DECOMP_COMPAT, 3407}, - {0x33D4, 0, 2 | DECOMP_COMPAT, 3409}, - {0x33D5, 0, 3 | DECOMP_COMPAT, 3411}, - {0x33D6, 0, 3 | DECOMP_COMPAT, 3414}, - {0x33D7, 0, 2 | DECOMP_COMPAT, 3417}, - {0x33D8, 0, 4 | DECOMP_COMPAT, 3419}, - {0x33D9, 0, 3 | DECOMP_COMPAT, 3423}, - {0x33DA, 0, 2 | DECOMP_COMPAT, 3426}, - {0x33DB, 0, 2 | DECOMP_COMPAT, 3428}, - {0x33DC, 0, 2 | DECOMP_COMPAT, 3430}, - {0x33DD, 0, 2 | DECOMP_COMPAT, 3432}, - {0x33DE, 0, 3 | DECOMP_COMPAT, 3434}, - {0x33DF, 0, 3 | DECOMP_COMPAT, 3437}, - {0x33E0, 0, 2 | DECOMP_COMPAT, 3440}, - {0x33E1, 0, 2 | DECOMP_COMPAT, 3442}, - {0x33E2, 0, 2 | DECOMP_COMPAT, 3444}, - {0x33E3, 0, 2 | DECOMP_COMPAT, 3446}, - {0x33E4, 0, 2 | DECOMP_COMPAT, 3448}, - {0x33E5, 0, 2 | DECOMP_COMPAT, 3450}, - {0x33E6, 0, 2 | DECOMP_COMPAT, 3452}, - {0x33E7, 0, 2 | DECOMP_COMPAT, 3454}, - {0x33E8, 0, 2 | DECOMP_COMPAT, 3456}, - {0x33E9, 0, 3 | DECOMP_COMPAT, 3458}, - {0x33EA, 0, 3 | DECOMP_COMPAT, 3461}, - {0x33EB, 0, 3 | DECOMP_COMPAT, 3464}, - {0x33EC, 0, 3 | DECOMP_COMPAT, 3467}, - {0x33ED, 0, 3 | DECOMP_COMPAT, 3470}, - {0x33EE, 0, 3 | DECOMP_COMPAT, 3473}, - {0x33EF, 0, 3 | DECOMP_COMPAT, 3476}, - {0x33F0, 0, 3 | DECOMP_COMPAT, 3479}, - {0x33F1, 0, 3 | DECOMP_COMPAT, 3482}, - {0x33F2, 0, 3 | DECOMP_COMPAT, 3485}, - {0x33F3, 0, 3 | DECOMP_COMPAT, 3488}, - {0x33F4, 0, 3 | DECOMP_COMPAT, 3491}, - {0x33F5, 0, 3 | DECOMP_COMPAT, 3494}, - {0x33F6, 0, 3 | DECOMP_COMPAT, 3497}, - {0x33F7, 0, 3 | DECOMP_COMPAT, 3500}, - {0x33F8, 0, 3 | DECOMP_COMPAT, 3503}, - {0x33F9, 0, 3 | DECOMP_COMPAT, 3506}, - {0x33FA, 0, 3 | DECOMP_COMPAT, 3509}, - {0x33FB, 0, 3 | DECOMP_COMPAT, 3512}, - {0x33FC, 0, 3 | DECOMP_COMPAT, 3515}, - {0x33FD, 0, 3 | DECOMP_COMPAT, 3518}, - {0x33FE, 0, 3 | DECOMP_COMPAT, 3521}, - {0x33FF, 0, 3 | DECOMP_COMPAT, 3524}, - {0xA66F, 230, 0, 0}, - {0xA674, 230, 0, 0}, - {0xA675, 230, 0, 0}, - {0xA676, 230, 0, 0}, - {0xA677, 230, 0, 0}, - {0xA678, 230, 0, 0}, - {0xA679, 230, 0, 0}, - {0xA67A, 230, 0, 0}, - {0xA67B, 230, 0, 0}, - {0xA67C, 230, 0, 0}, - {0xA67D, 230, 0, 0}, - {0xA69C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044A}, - {0xA69D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044C}, - {0xA69E, 230, 0, 0}, - {0xA69F, 230, 0, 0}, - {0xA6F0, 230, 0, 0}, - {0xA6F1, 230, 0, 0}, - {0xA770, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA76F}, - {0xA7F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0xA7F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0xA7F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0xA7F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0126}, - {0xA7F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0153}, - {0xA806, 9, 0, 0}, - {0xA82C, 9, 0, 0}, - {0xA8C4, 9, 0, 0}, - {0xA8E0, 230, 0, 0}, - {0xA8E1, 230, 0, 0}, - {0xA8E2, 230, 0, 0}, - {0xA8E3, 230, 0, 0}, - {0xA8E4, 230, 0, 0}, - {0xA8E5, 230, 0, 0}, - {0xA8E6, 230, 0, 0}, - {0xA8E7, 230, 0, 0}, - {0xA8E8, 230, 0, 0}, - {0xA8E9, 230, 0, 0}, - {0xA8EA, 230, 0, 0}, - {0xA8EB, 230, 0, 0}, - {0xA8EC, 230, 0, 0}, - {0xA8ED, 230, 0, 0}, - {0xA8EE, 230, 0, 0}, - {0xA8EF, 230, 0, 0}, - {0xA8F0, 230, 0, 0}, - {0xA8F1, 230, 0, 0}, - {0xA92B, 220, 0, 0}, - {0xA92C, 220, 0, 0}, - {0xA92D, 220, 0, 0}, - {0xA953, 9, 0, 0}, - {0xA9B3, 7, 0, 0}, - {0xA9C0, 9, 0, 0}, - {0xAAB0, 230, 0, 0}, - {0xAAB2, 230, 0, 0}, - {0xAAB3, 230, 0, 0}, - {0xAAB4, 220, 0, 0}, - {0xAAB7, 230, 0, 0}, - {0xAAB8, 230, 0, 0}, - {0xAABE, 230, 0, 0}, - {0xAABF, 230, 0, 0}, - {0xAAC1, 230, 0, 0}, - {0xAAF6, 9, 0, 0}, - {0xAB5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA727}, - {0xAB5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB37}, - {0xAB5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026B}, - {0xAB5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB52}, - {0xAB69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028D}, - {0xABED, 9, 0, 0}, - {0xF900, 0, 1 | DECOMP_INLINE, 0x8C48}, - {0xF901, 0, 1 | DECOMP_INLINE, 0x66F4}, - {0xF902, 0, 1 | DECOMP_INLINE, 0x8ECA}, - {0xF903, 0, 1 | DECOMP_INLINE, 0x8CC8}, - {0xF904, 0, 1 | DECOMP_INLINE, 0x6ED1}, - {0xF905, 0, 1 | DECOMP_INLINE, 0x4E32}, - {0xF906, 0, 1 | DECOMP_INLINE, 0x53E5}, - {0xF907, 0, 1 | DECOMP_INLINE, 0x9F9C}, - {0xF908, 0, 1 | DECOMP_INLINE, 0x9F9C}, - {0xF909, 0, 1 | DECOMP_INLINE, 0x5951}, - {0xF90A, 0, 1 | DECOMP_INLINE, 0x91D1}, - {0xF90B, 0, 1 | DECOMP_INLINE, 0x5587}, - {0xF90C, 0, 1 | DECOMP_INLINE, 0x5948}, - {0xF90D, 0, 1 | DECOMP_INLINE, 0x61F6}, - {0xF90E, 0, 1 | DECOMP_INLINE, 0x7669}, - {0xF90F, 0, 1 | DECOMP_INLINE, 0x7F85}, - {0xF910, 0, 1 | DECOMP_INLINE, 0x863F}, - {0xF911, 0, 1 | DECOMP_INLINE, 0x87BA}, - {0xF912, 0, 1 | DECOMP_INLINE, 0x88F8}, - {0xF913, 0, 1 | DECOMP_INLINE, 0x908F}, - {0xF914, 0, 1 | DECOMP_INLINE, 0x6A02}, - {0xF915, 0, 1 | DECOMP_INLINE, 0x6D1B}, - {0xF916, 0, 1 | DECOMP_INLINE, 0x70D9}, - {0xF917, 0, 1 | DECOMP_INLINE, 0x73DE}, - {0xF918, 0, 1 | DECOMP_INLINE, 0x843D}, - {0xF919, 0, 1 | DECOMP_INLINE, 0x916A}, - {0xF91A, 0, 1 | DECOMP_INLINE, 0x99F1}, - {0xF91B, 0, 1 | DECOMP_INLINE, 0x4E82}, - {0xF91C, 0, 1 | DECOMP_INLINE, 0x5375}, - {0xF91D, 0, 1 | DECOMP_INLINE, 0x6B04}, - {0xF91E, 0, 1 | DECOMP_INLINE, 0x721B}, - {0xF91F, 0, 1 | DECOMP_INLINE, 0x862D}, - {0xF920, 0, 1 | DECOMP_INLINE, 0x9E1E}, - {0xF921, 0, 1 | DECOMP_INLINE, 0x5D50}, - {0xF922, 0, 1 | DECOMP_INLINE, 0x6FEB}, - {0xF923, 0, 1 | DECOMP_INLINE, 0x85CD}, - {0xF924, 0, 1 | DECOMP_INLINE, 0x8964}, - {0xF925, 0, 1 | DECOMP_INLINE, 0x62C9}, - {0xF926, 0, 1 | DECOMP_INLINE, 0x81D8}, - {0xF927, 0, 1 | DECOMP_INLINE, 0x881F}, - {0xF928, 0, 1 | DECOMP_INLINE, 0x5ECA}, - {0xF929, 0, 1 | DECOMP_INLINE, 0x6717}, - {0xF92A, 0, 1 | DECOMP_INLINE, 0x6D6A}, - {0xF92B, 0, 1 | DECOMP_INLINE, 0x72FC}, - {0xF92C, 0, 1 | DECOMP_INLINE, 0x90CE}, - {0xF92D, 0, 1 | DECOMP_INLINE, 0x4F86}, - {0xF92E, 0, 1 | DECOMP_INLINE, 0x51B7}, - {0xF92F, 0, 1 | DECOMP_INLINE, 0x52DE}, - {0xF930, 0, 1 | DECOMP_INLINE, 0x64C4}, - {0xF931, 0, 1 | DECOMP_INLINE, 0x6AD3}, - {0xF932, 0, 1 | DECOMP_INLINE, 0x7210}, - {0xF933, 0, 1 | DECOMP_INLINE, 0x76E7}, - {0xF934, 0, 1 | DECOMP_INLINE, 0x8001}, - {0xF935, 0, 1 | DECOMP_INLINE, 0x8606}, - {0xF936, 0, 1 | DECOMP_INLINE, 0x865C}, - {0xF937, 0, 1 | DECOMP_INLINE, 0x8DEF}, - {0xF938, 0, 1 | DECOMP_INLINE, 0x9732}, - {0xF939, 0, 1 | DECOMP_INLINE, 0x9B6F}, - {0xF93A, 0, 1 | DECOMP_INLINE, 0x9DFA}, - {0xF93B, 0, 1 | DECOMP_INLINE, 0x788C}, - {0xF93C, 0, 1 | DECOMP_INLINE, 0x797F}, - {0xF93D, 0, 1 | DECOMP_INLINE, 0x7DA0}, - {0xF93E, 0, 1 | DECOMP_INLINE, 0x83C9}, - {0xF93F, 0, 1 | DECOMP_INLINE, 0x9304}, - {0xF940, 0, 1 | DECOMP_INLINE, 0x9E7F}, - {0xF941, 0, 1 | DECOMP_INLINE, 0x8AD6}, - {0xF942, 0, 1 | DECOMP_INLINE, 0x58DF}, - {0xF943, 0, 1 | DECOMP_INLINE, 0x5F04}, - {0xF944, 0, 1 | DECOMP_INLINE, 0x7C60}, - {0xF945, 0, 1 | DECOMP_INLINE, 0x807E}, - {0xF946, 0, 1 | DECOMP_INLINE, 0x7262}, - {0xF947, 0, 1 | DECOMP_INLINE, 0x78CA}, - {0xF948, 0, 1 | DECOMP_INLINE, 0x8CC2}, - {0xF949, 0, 1 | DECOMP_INLINE, 0x96F7}, - {0xF94A, 0, 1 | DECOMP_INLINE, 0x58D8}, - {0xF94B, 0, 1 | DECOMP_INLINE, 0x5C62}, - {0xF94C, 0, 1 | DECOMP_INLINE, 0x6A13}, - {0xF94D, 0, 1 | DECOMP_INLINE, 0x6DDA}, - {0xF94E, 0, 1 | DECOMP_INLINE, 0x6F0F}, - {0xF94F, 0, 1 | DECOMP_INLINE, 0x7D2F}, - {0xF950, 0, 1 | DECOMP_INLINE, 0x7E37}, - {0xF951, 0, 1 | DECOMP_INLINE, 0x964B}, - {0xF952, 0, 1 | DECOMP_INLINE, 0x52D2}, - {0xF953, 0, 1 | DECOMP_INLINE, 0x808B}, - {0xF954, 0, 1 | DECOMP_INLINE, 0x51DC}, - {0xF955, 0, 1 | DECOMP_INLINE, 0x51CC}, - {0xF956, 0, 1 | DECOMP_INLINE, 0x7A1C}, - {0xF957, 0, 1 | DECOMP_INLINE, 0x7DBE}, - {0xF958, 0, 1 | DECOMP_INLINE, 0x83F1}, - {0xF959, 0, 1 | DECOMP_INLINE, 0x9675}, - {0xF95A, 0, 1 | DECOMP_INLINE, 0x8B80}, - {0xF95B, 0, 1 | DECOMP_INLINE, 0x62CF}, - {0xF95C, 0, 1 | DECOMP_INLINE, 0x6A02}, - {0xF95D, 0, 1 | DECOMP_INLINE, 0x8AFE}, - {0xF95E, 0, 1 | DECOMP_INLINE, 0x4E39}, - {0xF95F, 0, 1 | DECOMP_INLINE, 0x5BE7}, - {0xF960, 0, 1 | DECOMP_INLINE, 0x6012}, - {0xF961, 0, 1 | DECOMP_INLINE, 0x7387}, - {0xF962, 0, 1 | DECOMP_INLINE, 0x7570}, - {0xF963, 0, 1 | DECOMP_INLINE, 0x5317}, - {0xF964, 0, 1 | DECOMP_INLINE, 0x78FB}, - {0xF965, 0, 1 | DECOMP_INLINE, 0x4FBF}, - {0xF966, 0, 1 | DECOMP_INLINE, 0x5FA9}, - {0xF967, 0, 1 | DECOMP_INLINE, 0x4E0D}, - {0xF968, 0, 1 | DECOMP_INLINE, 0x6CCC}, - {0xF969, 0, 1 | DECOMP_INLINE, 0x6578}, - {0xF96A, 0, 1 | DECOMP_INLINE, 0x7D22}, - {0xF96B, 0, 1 | DECOMP_INLINE, 0x53C3}, - {0xF96C, 0, 1 | DECOMP_INLINE, 0x585E}, - {0xF96D, 0, 1 | DECOMP_INLINE, 0x7701}, - {0xF96E, 0, 1 | DECOMP_INLINE, 0x8449}, - {0xF96F, 0, 1 | DECOMP_INLINE, 0x8AAA}, - {0xF970, 0, 1 | DECOMP_INLINE, 0x6BBA}, - {0xF971, 0, 1 | DECOMP_INLINE, 0x8FB0}, - {0xF972, 0, 1 | DECOMP_INLINE, 0x6C88}, - {0xF973, 0, 1 | DECOMP_INLINE, 0x62FE}, - {0xF974, 0, 1 | DECOMP_INLINE, 0x82E5}, - {0xF975, 0, 1 | DECOMP_INLINE, 0x63A0}, - {0xF976, 0, 1 | DECOMP_INLINE, 0x7565}, - {0xF977, 0, 1 | DECOMP_INLINE, 0x4EAE}, - {0xF978, 0, 1 | DECOMP_INLINE, 0x5169}, - {0xF979, 0, 1 | DECOMP_INLINE, 0x51C9}, - {0xF97A, 0, 1 | DECOMP_INLINE, 0x6881}, - {0xF97B, 0, 1 | DECOMP_INLINE, 0x7CE7}, - {0xF97C, 0, 1 | DECOMP_INLINE, 0x826F}, - {0xF97D, 0, 1 | DECOMP_INLINE, 0x8AD2}, - {0xF97E, 0, 1 | DECOMP_INLINE, 0x91CF}, - {0xF97F, 0, 1 | DECOMP_INLINE, 0x52F5}, - {0xF980, 0, 1 | DECOMP_INLINE, 0x5442}, - {0xF981, 0, 1 | DECOMP_INLINE, 0x5973}, - {0xF982, 0, 1 | DECOMP_INLINE, 0x5EEC}, - {0xF983, 0, 1 | DECOMP_INLINE, 0x65C5}, - {0xF984, 0, 1 | DECOMP_INLINE, 0x6FFE}, - {0xF985, 0, 1 | DECOMP_INLINE, 0x792A}, - {0xF986, 0, 1 | DECOMP_INLINE, 0x95AD}, - {0xF987, 0, 1 | DECOMP_INLINE, 0x9A6A}, - {0xF988, 0, 1 | DECOMP_INLINE, 0x9E97}, - {0xF989, 0, 1 | DECOMP_INLINE, 0x9ECE}, - {0xF98A, 0, 1 | DECOMP_INLINE, 0x529B}, - {0xF98B, 0, 1 | DECOMP_INLINE, 0x66C6}, - {0xF98C, 0, 1 | DECOMP_INLINE, 0x6B77}, - {0xF98D, 0, 1 | DECOMP_INLINE, 0x8F62}, - {0xF98E, 0, 1 | DECOMP_INLINE, 0x5E74}, - {0xF98F, 0, 1 | DECOMP_INLINE, 0x6190}, - {0xF990, 0, 1 | DECOMP_INLINE, 0x6200}, - {0xF991, 0, 1 | DECOMP_INLINE, 0x649A}, - {0xF992, 0, 1 | DECOMP_INLINE, 0x6F23}, - {0xF993, 0, 1 | DECOMP_INLINE, 0x7149}, - {0xF994, 0, 1 | DECOMP_INLINE, 0x7489}, - {0xF995, 0, 1 | DECOMP_INLINE, 0x79CA}, - {0xF996, 0, 1 | DECOMP_INLINE, 0x7DF4}, - {0xF997, 0, 1 | DECOMP_INLINE, 0x806F}, - {0xF998, 0, 1 | DECOMP_INLINE, 0x8F26}, - {0xF999, 0, 1 | DECOMP_INLINE, 0x84EE}, - {0xF99A, 0, 1 | DECOMP_INLINE, 0x9023}, - {0xF99B, 0, 1 | DECOMP_INLINE, 0x934A}, - {0xF99C, 0, 1 | DECOMP_INLINE, 0x5217}, - {0xF99D, 0, 1 | DECOMP_INLINE, 0x52A3}, - {0xF99E, 0, 1 | DECOMP_INLINE, 0x54BD}, - {0xF99F, 0, 1 | DECOMP_INLINE, 0x70C8}, - {0xF9A0, 0, 1 | DECOMP_INLINE, 0x88C2}, - {0xF9A1, 0, 1 | DECOMP_INLINE, 0x8AAA}, - {0xF9A2, 0, 1 | DECOMP_INLINE, 0x5EC9}, - {0xF9A3, 0, 1 | DECOMP_INLINE, 0x5FF5}, - {0xF9A4, 0, 1 | DECOMP_INLINE, 0x637B}, - {0xF9A5, 0, 1 | DECOMP_INLINE, 0x6BAE}, - {0xF9A6, 0, 1 | DECOMP_INLINE, 0x7C3E}, - {0xF9A7, 0, 1 | DECOMP_INLINE, 0x7375}, - {0xF9A8, 0, 1 | DECOMP_INLINE, 0x4EE4}, - {0xF9A9, 0, 1 | DECOMP_INLINE, 0x56F9}, - {0xF9AA, 0, 1 | DECOMP_INLINE, 0x5BE7}, - {0xF9AB, 0, 1 | DECOMP_INLINE, 0x5DBA}, - {0xF9AC, 0, 1 | DECOMP_INLINE, 0x601C}, - {0xF9AD, 0, 1 | DECOMP_INLINE, 0x73B2}, - {0xF9AE, 0, 1 | DECOMP_INLINE, 0x7469}, - {0xF9AF, 0, 1 | DECOMP_INLINE, 0x7F9A}, - {0xF9B0, 0, 1 | DECOMP_INLINE, 0x8046}, - {0xF9B1, 0, 1 | DECOMP_INLINE, 0x9234}, - {0xF9B2, 0, 1 | DECOMP_INLINE, 0x96F6}, - {0xF9B3, 0, 1 | DECOMP_INLINE, 0x9748}, - {0xF9B4, 0, 1 | DECOMP_INLINE, 0x9818}, - {0xF9B5, 0, 1 | DECOMP_INLINE, 0x4F8B}, - {0xF9B6, 0, 1 | DECOMP_INLINE, 0x79AE}, - {0xF9B7, 0, 1 | DECOMP_INLINE, 0x91B4}, - {0xF9B8, 0, 1 | DECOMP_INLINE, 0x96B8}, - {0xF9B9, 0, 1 | DECOMP_INLINE, 0x60E1}, - {0xF9BA, 0, 1 | DECOMP_INLINE, 0x4E86}, - {0xF9BB, 0, 1 | DECOMP_INLINE, 0x50DA}, - {0xF9BC, 0, 1 | DECOMP_INLINE, 0x5BEE}, - {0xF9BD, 0, 1 | DECOMP_INLINE, 0x5C3F}, - {0xF9BE, 0, 1 | DECOMP_INLINE, 0x6599}, - {0xF9BF, 0, 1 | DECOMP_INLINE, 0x6A02}, - {0xF9C0, 0, 1 | DECOMP_INLINE, 0x71CE}, - {0xF9C1, 0, 1 | DECOMP_INLINE, 0x7642}, - {0xF9C2, 0, 1 | DECOMP_INLINE, 0x84FC}, - {0xF9C3, 0, 1 | DECOMP_INLINE, 0x907C}, - {0xF9C4, 0, 1 | DECOMP_INLINE, 0x9F8D}, - {0xF9C5, 0, 1 | DECOMP_INLINE, 0x6688}, - {0xF9C6, 0, 1 | DECOMP_INLINE, 0x962E}, - {0xF9C7, 0, 1 | DECOMP_INLINE, 0x5289}, - {0xF9C8, 0, 1 | DECOMP_INLINE, 0x677B}, - {0xF9C9, 0, 1 | DECOMP_INLINE, 0x67F3}, - {0xF9CA, 0, 1 | DECOMP_INLINE, 0x6D41}, - {0xF9CB, 0, 1 | DECOMP_INLINE, 0x6E9C}, - {0xF9CC, 0, 1 | DECOMP_INLINE, 0x7409}, - {0xF9CD, 0, 1 | DECOMP_INLINE, 0x7559}, - {0xF9CE, 0, 1 | DECOMP_INLINE, 0x786B}, - {0xF9CF, 0, 1 | DECOMP_INLINE, 0x7D10}, - {0xF9D0, 0, 1 | DECOMP_INLINE, 0x985E}, - {0xF9D1, 0, 1 | DECOMP_INLINE, 0x516D}, - {0xF9D2, 0, 1 | DECOMP_INLINE, 0x622E}, - {0xF9D3, 0, 1 | DECOMP_INLINE, 0x9678}, - {0xF9D4, 0, 1 | DECOMP_INLINE, 0x502B}, - {0xF9D5, 0, 1 | DECOMP_INLINE, 0x5D19}, - {0xF9D6, 0, 1 | DECOMP_INLINE, 0x6DEA}, - {0xF9D7, 0, 1 | DECOMP_INLINE, 0x8F2A}, - {0xF9D8, 0, 1 | DECOMP_INLINE, 0x5F8B}, - {0xF9D9, 0, 1 | DECOMP_INLINE, 0x6144}, - {0xF9DA, 0, 1 | DECOMP_INLINE, 0x6817}, - {0xF9DB, 0, 1 | DECOMP_INLINE, 0x7387}, - {0xF9DC, 0, 1 | DECOMP_INLINE, 0x9686}, - {0xF9DD, 0, 1 | DECOMP_INLINE, 0x5229}, - {0xF9DE, 0, 1 | DECOMP_INLINE, 0x540F}, - {0xF9DF, 0, 1 | DECOMP_INLINE, 0x5C65}, - {0xF9E0, 0, 1 | DECOMP_INLINE, 0x6613}, - {0xF9E1, 0, 1 | DECOMP_INLINE, 0x674E}, - {0xF9E2, 0, 1 | DECOMP_INLINE, 0x68A8}, - {0xF9E3, 0, 1 | DECOMP_INLINE, 0x6CE5}, - {0xF9E4, 0, 1 | DECOMP_INLINE, 0x7406}, - {0xF9E5, 0, 1 | DECOMP_INLINE, 0x75E2}, - {0xF9E6, 0, 1 | DECOMP_INLINE, 0x7F79}, - {0xF9E7, 0, 1 | DECOMP_INLINE, 0x88CF}, - {0xF9E8, 0, 1 | DECOMP_INLINE, 0x88E1}, - {0xF9E9, 0, 1 | DECOMP_INLINE, 0x91CC}, - {0xF9EA, 0, 1 | DECOMP_INLINE, 0x96E2}, - {0xF9EB, 0, 1 | DECOMP_INLINE, 0x533F}, - {0xF9EC, 0, 1 | DECOMP_INLINE, 0x6EBA}, - {0xF9ED, 0, 1 | DECOMP_INLINE, 0x541D}, - {0xF9EE, 0, 1 | DECOMP_INLINE, 0x71D0}, - {0xF9EF, 0, 1 | DECOMP_INLINE, 0x7498}, - {0xF9F0, 0, 1 | DECOMP_INLINE, 0x85FA}, - {0xF9F1, 0, 1 | DECOMP_INLINE, 0x96A3}, - {0xF9F2, 0, 1 | DECOMP_INLINE, 0x9C57}, - {0xF9F3, 0, 1 | DECOMP_INLINE, 0x9E9F}, - {0xF9F4, 0, 1 | DECOMP_INLINE, 0x6797}, - {0xF9F5, 0, 1 | DECOMP_INLINE, 0x6DCB}, - {0xF9F6, 0, 1 | DECOMP_INLINE, 0x81E8}, - {0xF9F7, 0, 1 | DECOMP_INLINE, 0x7ACB}, - {0xF9F8, 0, 1 | DECOMP_INLINE, 0x7B20}, - {0xF9F9, 0, 1 | DECOMP_INLINE, 0x7C92}, - {0xF9FA, 0, 1 | DECOMP_INLINE, 0x72C0}, - {0xF9FB, 0, 1 | DECOMP_INLINE, 0x7099}, - {0xF9FC, 0, 1 | DECOMP_INLINE, 0x8B58}, - {0xF9FD, 0, 1 | DECOMP_INLINE, 0x4EC0}, - {0xF9FE, 0, 1 | DECOMP_INLINE, 0x8336}, - {0xF9FF, 0, 1 | DECOMP_INLINE, 0x523A}, - {0xFA00, 0, 1 | DECOMP_INLINE, 0x5207}, - {0xFA01, 0, 1 | DECOMP_INLINE, 0x5EA6}, - {0xFA02, 0, 1 | DECOMP_INLINE, 0x62D3}, - {0xFA03, 0, 1 | DECOMP_INLINE, 0x7CD6}, - {0xFA04, 0, 1 | DECOMP_INLINE, 0x5B85}, - {0xFA05, 0, 1 | DECOMP_INLINE, 0x6D1E}, - {0xFA06, 0, 1 | DECOMP_INLINE, 0x66B4}, - {0xFA07, 0, 1 | DECOMP_INLINE, 0x8F3B}, - {0xFA08, 0, 1 | DECOMP_INLINE, 0x884C}, - {0xFA09, 0, 1 | DECOMP_INLINE, 0x964D}, - {0xFA0A, 0, 1 | DECOMP_INLINE, 0x898B}, - {0xFA0B, 0, 1 | DECOMP_INLINE, 0x5ED3}, - {0xFA0C, 0, 1 | DECOMP_INLINE, 0x5140}, - {0xFA0D, 0, 1 | DECOMP_INLINE, 0x55C0}, - {0xFA10, 0, 1 | DECOMP_INLINE, 0x585A}, - {0xFA12, 0, 1 | DECOMP_INLINE, 0x6674}, - {0xFA15, 0, 1 | DECOMP_INLINE, 0x51DE}, - {0xFA16, 0, 1 | DECOMP_INLINE, 0x732A}, - {0xFA17, 0, 1 | DECOMP_INLINE, 0x76CA}, - {0xFA18, 0, 1 | DECOMP_INLINE, 0x793C}, - {0xFA19, 0, 1 | DECOMP_INLINE, 0x795E}, - {0xFA1A, 0, 1 | DECOMP_INLINE, 0x7965}, - {0xFA1B, 0, 1 | DECOMP_INLINE, 0x798F}, - {0xFA1C, 0, 1 | DECOMP_INLINE, 0x9756}, - {0xFA1D, 0, 1 | DECOMP_INLINE, 0x7CBE}, - {0xFA1E, 0, 1 | DECOMP_INLINE, 0x7FBD}, - {0xFA20, 0, 1 | DECOMP_INLINE, 0x8612}, - {0xFA22, 0, 1 | DECOMP_INLINE, 0x8AF8}, - {0xFA25, 0, 1 | DECOMP_INLINE, 0x9038}, - {0xFA26, 0, 1 | DECOMP_INLINE, 0x90FD}, - {0xFA2A, 0, 1 | DECOMP_INLINE, 0x98EF}, - {0xFA2B, 0, 1 | DECOMP_INLINE, 0x98FC}, - {0xFA2C, 0, 1 | DECOMP_INLINE, 0x9928}, - {0xFA2D, 0, 1 | DECOMP_INLINE, 0x9DB4}, - {0xFA2E, 0, 1 | DECOMP_INLINE, 0x90DE}, - {0xFA2F, 0, 1 | DECOMP_INLINE, 0x96B7}, - {0xFA30, 0, 1 | DECOMP_INLINE, 0x4FAE}, - {0xFA31, 0, 1 | DECOMP_INLINE, 0x50E7}, - {0xFA32, 0, 1 | DECOMP_INLINE, 0x514D}, - {0xFA33, 0, 1 | DECOMP_INLINE, 0x52C9}, - {0xFA34, 0, 1 | DECOMP_INLINE, 0x52E4}, - {0xFA35, 0, 1 | DECOMP_INLINE, 0x5351}, - {0xFA36, 0, 1 | DECOMP_INLINE, 0x559D}, - {0xFA37, 0, 1 | DECOMP_INLINE, 0x5606}, - {0xFA38, 0, 1 | DECOMP_INLINE, 0x5668}, - {0xFA39, 0, 1 | DECOMP_INLINE, 0x5840}, - {0xFA3A, 0, 1 | DECOMP_INLINE, 0x58A8}, - {0xFA3B, 0, 1 | DECOMP_INLINE, 0x5C64}, - {0xFA3C, 0, 1 | DECOMP_INLINE, 0x5C6E}, - {0xFA3D, 0, 1 | DECOMP_INLINE, 0x6094}, - {0xFA3E, 0, 1 | DECOMP_INLINE, 0x6168}, - {0xFA3F, 0, 1 | DECOMP_INLINE, 0x618E}, - {0xFA40, 0, 1 | DECOMP_INLINE, 0x61F2}, - {0xFA41, 0, 1 | DECOMP_INLINE, 0x654F}, - {0xFA42, 0, 1 | DECOMP_INLINE, 0x65E2}, - {0xFA43, 0, 1 | DECOMP_INLINE, 0x6691}, - {0xFA44, 0, 1 | DECOMP_INLINE, 0x6885}, - {0xFA45, 0, 1 | DECOMP_INLINE, 0x6D77}, - {0xFA46, 0, 1 | DECOMP_INLINE, 0x6E1A}, - {0xFA47, 0, 1 | DECOMP_INLINE, 0x6F22}, - {0xFA48, 0, 1 | DECOMP_INLINE, 0x716E}, - {0xFA49, 0, 1 | DECOMP_INLINE, 0x722B}, - {0xFA4A, 0, 1 | DECOMP_INLINE, 0x7422}, - {0xFA4B, 0, 1 | DECOMP_INLINE, 0x7891}, - {0xFA4C, 0, 1 | DECOMP_INLINE, 0x793E}, - {0xFA4D, 0, 1 | DECOMP_INLINE, 0x7949}, - {0xFA4E, 0, 1 | DECOMP_INLINE, 0x7948}, - {0xFA4F, 0, 1 | DECOMP_INLINE, 0x7950}, - {0xFA50, 0, 1 | DECOMP_INLINE, 0x7956}, - {0xFA51, 0, 1 | DECOMP_INLINE, 0x795D}, - {0xFA52, 0, 1 | DECOMP_INLINE, 0x798D}, - {0xFA53, 0, 1 | DECOMP_INLINE, 0x798E}, - {0xFA54, 0, 1 | DECOMP_INLINE, 0x7A40}, - {0xFA55, 0, 1 | DECOMP_INLINE, 0x7A81}, - {0xFA56, 0, 1 | DECOMP_INLINE, 0x7BC0}, - {0xFA57, 0, 1 | DECOMP_INLINE, 0x7DF4}, - {0xFA58, 0, 1 | DECOMP_INLINE, 0x7E09}, - {0xFA59, 0, 1 | DECOMP_INLINE, 0x7E41}, - {0xFA5A, 0, 1 | DECOMP_INLINE, 0x7F72}, - {0xFA5B, 0, 1 | DECOMP_INLINE, 0x8005}, - {0xFA5C, 0, 1 | DECOMP_INLINE, 0x81ED}, - {0xFA5D, 0, 1 | DECOMP_INLINE, 0x8279}, - {0xFA5E, 0, 1 | DECOMP_INLINE, 0x8279}, - {0xFA5F, 0, 1 | DECOMP_INLINE, 0x8457}, - {0xFA60, 0, 1 | DECOMP_INLINE, 0x8910}, - {0xFA61, 0, 1 | DECOMP_INLINE, 0x8996}, - {0xFA62, 0, 1 | DECOMP_INLINE, 0x8B01}, - {0xFA63, 0, 1 | DECOMP_INLINE, 0x8B39}, - {0xFA64, 0, 1 | DECOMP_INLINE, 0x8CD3}, - {0xFA65, 0, 1 | DECOMP_INLINE, 0x8D08}, - {0xFA66, 0, 1 | DECOMP_INLINE, 0x8FB6}, - {0xFA67, 0, 1 | DECOMP_INLINE, 0x9038}, - {0xFA68, 0, 1 | DECOMP_INLINE, 0x96E3}, - {0xFA69, 0, 1 | DECOMP_INLINE, 0x97FF}, - {0xFA6A, 0, 1 | DECOMP_INLINE, 0x983B}, - {0xFA6B, 0, 1 | DECOMP_INLINE, 0x6075}, - {0xFA6C, 0, 1, 3527}, - {0xFA6D, 0, 1 | DECOMP_INLINE, 0x8218}, - {0xFA70, 0, 1 | DECOMP_INLINE, 0x4E26}, - {0xFA71, 0, 1 | DECOMP_INLINE, 0x51B5}, - {0xFA72, 0, 1 | DECOMP_INLINE, 0x5168}, - {0xFA73, 0, 1 | DECOMP_INLINE, 0x4F80}, - {0xFA74, 0, 1 | DECOMP_INLINE, 0x5145}, - {0xFA75, 0, 1 | DECOMP_INLINE, 0x5180}, - {0xFA76, 0, 1 | DECOMP_INLINE, 0x52C7}, - {0xFA77, 0, 1 | DECOMP_INLINE, 0x52FA}, - {0xFA78, 0, 1 | DECOMP_INLINE, 0x559D}, - {0xFA79, 0, 1 | DECOMP_INLINE, 0x5555}, - {0xFA7A, 0, 1 | DECOMP_INLINE, 0x5599}, - {0xFA7B, 0, 1 | DECOMP_INLINE, 0x55E2}, - {0xFA7C, 0, 1 | DECOMP_INLINE, 0x585A}, - {0xFA7D, 0, 1 | DECOMP_INLINE, 0x58B3}, - {0xFA7E, 0, 1 | DECOMP_INLINE, 0x5944}, - {0xFA7F, 0, 1 | DECOMP_INLINE, 0x5954}, - {0xFA80, 0, 1 | DECOMP_INLINE, 0x5A62}, - {0xFA81, 0, 1 | DECOMP_INLINE, 0x5B28}, - {0xFA82, 0, 1 | DECOMP_INLINE, 0x5ED2}, - {0xFA83, 0, 1 | DECOMP_INLINE, 0x5ED9}, - {0xFA84, 0, 1 | DECOMP_INLINE, 0x5F69}, - {0xFA85, 0, 1 | DECOMP_INLINE, 0x5FAD}, - {0xFA86, 0, 1 | DECOMP_INLINE, 0x60D8}, - {0xFA87, 0, 1 | DECOMP_INLINE, 0x614E}, - {0xFA88, 0, 1 | DECOMP_INLINE, 0x6108}, - {0xFA89, 0, 1 | DECOMP_INLINE, 0x618E}, - {0xFA8A, 0, 1 | DECOMP_INLINE, 0x6160}, - {0xFA8B, 0, 1 | DECOMP_INLINE, 0x61F2}, - {0xFA8C, 0, 1 | DECOMP_INLINE, 0x6234}, - {0xFA8D, 0, 1 | DECOMP_INLINE, 0x63C4}, - {0xFA8E, 0, 1 | DECOMP_INLINE, 0x641C}, - {0xFA8F, 0, 1 | DECOMP_INLINE, 0x6452}, - {0xFA90, 0, 1 | DECOMP_INLINE, 0x6556}, - {0xFA91, 0, 1 | DECOMP_INLINE, 0x6674}, - {0xFA92, 0, 1 | DECOMP_INLINE, 0x6717}, - {0xFA93, 0, 1 | DECOMP_INLINE, 0x671B}, - {0xFA94, 0, 1 | DECOMP_INLINE, 0x6756}, - {0xFA95, 0, 1 | DECOMP_INLINE, 0x6B79}, - {0xFA96, 0, 1 | DECOMP_INLINE, 0x6BBA}, - {0xFA97, 0, 1 | DECOMP_INLINE, 0x6D41}, - {0xFA98, 0, 1 | DECOMP_INLINE, 0x6EDB}, - {0xFA99, 0, 1 | DECOMP_INLINE, 0x6ECB}, - {0xFA9A, 0, 1 | DECOMP_INLINE, 0x6F22}, - {0xFA9B, 0, 1 | DECOMP_INLINE, 0x701E}, - {0xFA9C, 0, 1 | DECOMP_INLINE, 0x716E}, - {0xFA9D, 0, 1 | DECOMP_INLINE, 0x77A7}, - {0xFA9E, 0, 1 | DECOMP_INLINE, 0x7235}, - {0xFA9F, 0, 1 | DECOMP_INLINE, 0x72AF}, - {0xFAA0, 0, 1 | DECOMP_INLINE, 0x732A}, - {0xFAA1, 0, 1 | DECOMP_INLINE, 0x7471}, - {0xFAA2, 0, 1 | DECOMP_INLINE, 0x7506}, - {0xFAA3, 0, 1 | DECOMP_INLINE, 0x753B}, - {0xFAA4, 0, 1 | DECOMP_INLINE, 0x761D}, - {0xFAA5, 0, 1 | DECOMP_INLINE, 0x761F}, - {0xFAA6, 0, 1 | DECOMP_INLINE, 0x76CA}, - {0xFAA7, 0, 1 | DECOMP_INLINE, 0x76DB}, - {0xFAA8, 0, 1 | DECOMP_INLINE, 0x76F4}, - {0xFAA9, 0, 1 | DECOMP_INLINE, 0x774A}, - {0xFAAA, 0, 1 | DECOMP_INLINE, 0x7740}, - {0xFAAB, 0, 1 | DECOMP_INLINE, 0x78CC}, - {0xFAAC, 0, 1 | DECOMP_INLINE, 0x7AB1}, - {0xFAAD, 0, 1 | DECOMP_INLINE, 0x7BC0}, - {0xFAAE, 0, 1 | DECOMP_INLINE, 0x7C7B}, - {0xFAAF, 0, 1 | DECOMP_INLINE, 0x7D5B}, - {0xFAB0, 0, 1 | DECOMP_INLINE, 0x7DF4}, - {0xFAB1, 0, 1 | DECOMP_INLINE, 0x7F3E}, - {0xFAB2, 0, 1 | DECOMP_INLINE, 0x8005}, - {0xFAB3, 0, 1 | DECOMP_INLINE, 0x8352}, - {0xFAB4, 0, 1 | DECOMP_INLINE, 0x83EF}, - {0xFAB5, 0, 1 | DECOMP_INLINE, 0x8779}, - {0xFAB6, 0, 1 | DECOMP_INLINE, 0x8941}, - {0xFAB7, 0, 1 | DECOMP_INLINE, 0x8986}, - {0xFAB8, 0, 1 | DECOMP_INLINE, 0x8996}, - {0xFAB9, 0, 1 | DECOMP_INLINE, 0x8ABF}, - {0xFABA, 0, 1 | DECOMP_INLINE, 0x8AF8}, - {0xFABB, 0, 1 | DECOMP_INLINE, 0x8ACB}, - {0xFABC, 0, 1 | DECOMP_INLINE, 0x8B01}, - {0xFABD, 0, 1 | DECOMP_INLINE, 0x8AFE}, - {0xFABE, 0, 1 | DECOMP_INLINE, 0x8AED}, - {0xFABF, 0, 1 | DECOMP_INLINE, 0x8B39}, - {0xFAC0, 0, 1 | DECOMP_INLINE, 0x8B8A}, - {0xFAC1, 0, 1 | DECOMP_INLINE, 0x8D08}, - {0xFAC2, 0, 1 | DECOMP_INLINE, 0x8F38}, - {0xFAC3, 0, 1 | DECOMP_INLINE, 0x9072}, - {0xFAC4, 0, 1 | DECOMP_INLINE, 0x9199}, - {0xFAC5, 0, 1 | DECOMP_INLINE, 0x9276}, - {0xFAC6, 0, 1 | DECOMP_INLINE, 0x967C}, - {0xFAC7, 0, 1 | DECOMP_INLINE, 0x96E3}, - {0xFAC8, 0, 1 | DECOMP_INLINE, 0x9756}, - {0xFAC9, 0, 1 | DECOMP_INLINE, 0x97DB}, - {0xFACA, 0, 1 | DECOMP_INLINE, 0x97FF}, - {0xFACB, 0, 1 | DECOMP_INLINE, 0x980B}, - {0xFACC, 0, 1 | DECOMP_INLINE, 0x983B}, - {0xFACD, 0, 1 | DECOMP_INLINE, 0x9B12}, - {0xFACE, 0, 1 | DECOMP_INLINE, 0x9F9C}, - {0xFACF, 0, 1, 3528}, - {0xFAD0, 0, 1, 3529}, - {0xFAD1, 0, 1, 3530}, - {0xFAD2, 0, 1 | DECOMP_INLINE, 0x3B9D}, - {0xFAD3, 0, 1 | DECOMP_INLINE, 0x4018}, - {0xFAD4, 0, 1 | DECOMP_INLINE, 0x4039}, - {0xFAD5, 0, 1, 3531}, - {0xFAD6, 0, 1, 3532}, - {0xFAD7, 0, 1, 3533}, - {0xFAD8, 0, 1 | DECOMP_INLINE, 0x9F43}, - {0xFAD9, 0, 1 | DECOMP_INLINE, 0x9F8E}, - {0xFB00, 0, 2 | DECOMP_COMPAT, 3534}, - {0xFB01, 0, 2 | DECOMP_COMPAT, 3536}, - {0xFB02, 0, 2 | DECOMP_COMPAT, 3538}, - {0xFB03, 0, 3 | DECOMP_COMPAT, 3540}, - {0xFB04, 0, 3 | DECOMP_COMPAT, 3543}, - {0xFB05, 0, 2 | DECOMP_COMPAT, 3546}, - {0xFB06, 0, 2 | DECOMP_COMPAT, 3548}, - {0xFB13, 0, 2 | DECOMP_COMPAT, 3550}, - {0xFB14, 0, 2 | DECOMP_COMPAT, 3552}, - {0xFB15, 0, 2 | DECOMP_COMPAT, 3554}, - {0xFB16, 0, 2 | DECOMP_COMPAT, 3556}, - {0xFB17, 0, 2 | DECOMP_COMPAT, 3558}, - {0xFB1D, 0, 2 | DECOMP_NO_COMPOSE, 3560}, /* in exclusion list */ - {0xFB1E, 26, 0, 0}, - {0xFB1F, 0, 2 | DECOMP_NO_COMPOSE, 3562}, /* in exclusion list */ - {0xFB20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05E2}, - {0xFB21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D0}, - {0xFB22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D3}, - {0xFB23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05D4}, - {0xFB24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DB}, - {0xFB25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DC}, - {0xFB26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05DD}, - {0xFB27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05E8}, - {0xFB28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x05EA}, - {0xFB29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, - {0xFB2A, 0, 2 | DECOMP_NO_COMPOSE, 3564}, /* in exclusion list */ - {0xFB2B, 0, 2 | DECOMP_NO_COMPOSE, 3566}, /* in exclusion list */ - {0xFB2C, 0, 2 | DECOMP_NO_COMPOSE, 3568}, /* in exclusion list */ - {0xFB2D, 0, 2 | DECOMP_NO_COMPOSE, 3570}, /* in exclusion list */ - {0xFB2E, 0, 2 | DECOMP_NO_COMPOSE, 3572}, /* in exclusion list */ - {0xFB2F, 0, 2 | DECOMP_NO_COMPOSE, 3574}, /* in exclusion list */ - {0xFB30, 0, 2 | DECOMP_NO_COMPOSE, 3576}, /* in exclusion list */ - {0xFB31, 0, 2 | DECOMP_NO_COMPOSE, 3578}, /* in exclusion list */ - {0xFB32, 0, 2 | DECOMP_NO_COMPOSE, 3580}, /* in exclusion list */ - {0xFB33, 0, 2 | DECOMP_NO_COMPOSE, 3582}, /* in exclusion list */ - {0xFB34, 0, 2 | DECOMP_NO_COMPOSE, 3584}, /* in exclusion list */ - {0xFB35, 0, 2 | DECOMP_NO_COMPOSE, 3586}, /* in exclusion list */ - {0xFB36, 0, 2 | DECOMP_NO_COMPOSE, 3588}, /* in exclusion list */ - {0xFB38, 0, 2 | DECOMP_NO_COMPOSE, 3590}, /* in exclusion list */ - {0xFB39, 0, 2 | DECOMP_NO_COMPOSE, 3592}, /* in exclusion list */ - {0xFB3A, 0, 2 | DECOMP_NO_COMPOSE, 3594}, /* in exclusion list */ - {0xFB3B, 0, 2 | DECOMP_NO_COMPOSE, 3596}, /* in exclusion list */ - {0xFB3C, 0, 2 | DECOMP_NO_COMPOSE, 3598}, /* in exclusion list */ - {0xFB3E, 0, 2 | DECOMP_NO_COMPOSE, 3600}, /* in exclusion list */ - {0xFB40, 0, 2 | DECOMP_NO_COMPOSE, 3602}, /* in exclusion list */ - {0xFB41, 0, 2 | DECOMP_NO_COMPOSE, 3604}, /* in exclusion list */ - {0xFB43, 0, 2 | DECOMP_NO_COMPOSE, 3606}, /* in exclusion list */ - {0xFB44, 0, 2 | DECOMP_NO_COMPOSE, 3608}, /* in exclusion list */ - {0xFB46, 0, 2 | DECOMP_NO_COMPOSE, 3610}, /* in exclusion list */ - {0xFB47, 0, 2 | DECOMP_NO_COMPOSE, 3612}, /* in exclusion list */ - {0xFB48, 0, 2 | DECOMP_NO_COMPOSE, 3614}, /* in exclusion list */ - {0xFB49, 0, 2 | DECOMP_NO_COMPOSE, 3616}, /* in exclusion list */ - {0xFB4A, 0, 2 | DECOMP_NO_COMPOSE, 3618}, /* in exclusion list */ - {0xFB4B, 0, 2 | DECOMP_NO_COMPOSE, 3620}, /* in exclusion list */ - {0xFB4C, 0, 2 | DECOMP_NO_COMPOSE, 3622}, /* in exclusion list */ - {0xFB4D, 0, 2 | DECOMP_NO_COMPOSE, 3624}, /* in exclusion list */ - {0xFB4E, 0, 2 | DECOMP_NO_COMPOSE, 3626}, /* in exclusion list */ - {0xFB4F, 0, 2 | DECOMP_COMPAT, 3628}, - {0xFB50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0671}, - {0xFB51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0671}, - {0xFB52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, - {0xFB53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, - {0xFB54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, - {0xFB55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067B}, - {0xFB56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, - {0xFB57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, - {0xFB58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, - {0xFB59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067E}, - {0xFB5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, - {0xFB5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, - {0xFB5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, - {0xFB5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0680}, - {0xFB5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, - {0xFB5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, - {0xFB60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, - {0xFB61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067A}, - {0xFB62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, - {0xFB63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, - {0xFB64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, - {0xFB65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x067F}, - {0xFB66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, - {0xFB67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, - {0xFB68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, - {0xFB69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0679}, - {0xFB6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, - {0xFB6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, - {0xFB6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, - {0xFB6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A4}, - {0xFB6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, - {0xFB6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, - {0xFB70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, - {0xFB71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A6}, - {0xFB72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, - {0xFB73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, - {0xFB74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, - {0xFB75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0684}, - {0xFB76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, - {0xFB77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, - {0xFB78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, - {0xFB79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0683}, - {0xFB7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, - {0xFB7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, - {0xFB7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, - {0xFB7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0686}, - {0xFB7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, - {0xFB7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, - {0xFB80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, - {0xFB81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0687}, - {0xFB82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068D}, - {0xFB83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068D}, - {0xFB84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068C}, - {0xFB85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068C}, - {0xFB86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068E}, - {0xFB87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x068E}, - {0xFB88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0688}, - {0xFB89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0688}, - {0xFB8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0698}, - {0xFB8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0698}, - {0xFB8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0691}, - {0xFB8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0691}, - {0xFB8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, - {0xFB8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, - {0xFB90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, - {0xFB91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A9}, - {0xFB92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, - {0xFB93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, - {0xFB94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, - {0xFB95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AF}, - {0xFB96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, - {0xFB97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, - {0xFB98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, - {0xFB99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B3}, - {0xFB9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, - {0xFB9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, - {0xFB9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, - {0xFB9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06B1}, - {0xFB9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, - {0xFB9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, - {0xFBA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, - {0xFBA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, - {0xFBA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, - {0xFBA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BB}, - {0xFBA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C0}, - {0xFBA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C0}, - {0xFBA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, - {0xFBA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, - {0xFBA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, - {0xFBA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C1}, - {0xFBAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, - {0xFBAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, - {0xFBAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, - {0xFBAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BE}, - {0xFBAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D2}, - {0xFBAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D2}, - {0xFBB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D3}, - {0xFBB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D3}, - {0xFBD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, - {0xFBD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, - {0xFBD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, - {0xFBD6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06AD}, - {0xFBD7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C7}, - {0xFBD8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C7}, - {0xFBD9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C6}, - {0xFBDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C6}, - {0xFBDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C8}, - {0xFBDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C8}, - {0xFBDD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0677}, - {0xFBDE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CB}, - {0xFBDF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CB}, - {0xFBE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C5}, - {0xFBE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C5}, - {0xFBE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C9}, - {0xFBE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06C9}, - {0xFBE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, - {0xFBE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, - {0xFBE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, - {0xFBE7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06D0}, - {0xFBE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, - {0xFBE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, - {0xFBEA, 0, 2 | DECOMP_COMPAT, 3630}, - {0xFBEB, 0, 2 | DECOMP_COMPAT, 3632}, - {0xFBEC, 0, 2 | DECOMP_COMPAT, 3634}, - {0xFBED, 0, 2 | DECOMP_COMPAT, 3636}, - {0xFBEE, 0, 2 | DECOMP_COMPAT, 3638}, - {0xFBEF, 0, 2 | DECOMP_COMPAT, 3640}, - {0xFBF0, 0, 2 | DECOMP_COMPAT, 3642}, - {0xFBF1, 0, 2 | DECOMP_COMPAT, 3644}, - {0xFBF2, 0, 2 | DECOMP_COMPAT, 3646}, - {0xFBF3, 0, 2 | DECOMP_COMPAT, 3648}, - {0xFBF4, 0, 2 | DECOMP_COMPAT, 3650}, - {0xFBF5, 0, 2 | DECOMP_COMPAT, 3652}, - {0xFBF6, 0, 2 | DECOMP_COMPAT, 3654}, - {0xFBF7, 0, 2 | DECOMP_COMPAT, 3656}, - {0xFBF8, 0, 2 | DECOMP_COMPAT, 3658}, - {0xFBF9, 0, 2 | DECOMP_COMPAT, 3660}, - {0xFBFA, 0, 2 | DECOMP_COMPAT, 3662}, - {0xFBFB, 0, 2 | DECOMP_COMPAT, 3664}, - {0xFBFC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, - {0xFBFD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, - {0xFBFE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, - {0xFBFF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06CC}, - {0xFC00, 0, 2 | DECOMP_COMPAT, 3666}, - {0xFC01, 0, 2 | DECOMP_COMPAT, 3668}, - {0xFC02, 0, 2 | DECOMP_COMPAT, 3670}, - {0xFC03, 0, 2 | DECOMP_COMPAT, 3672}, - {0xFC04, 0, 2 | DECOMP_COMPAT, 3674}, - {0xFC05, 0, 2 | DECOMP_COMPAT, 3676}, - {0xFC06, 0, 2 | DECOMP_COMPAT, 3678}, - {0xFC07, 0, 2 | DECOMP_COMPAT, 3680}, - {0xFC08, 0, 2 | DECOMP_COMPAT, 3682}, - {0xFC09, 0, 2 | DECOMP_COMPAT, 3684}, - {0xFC0A, 0, 2 | DECOMP_COMPAT, 3686}, - {0xFC0B, 0, 2 | DECOMP_COMPAT, 3688}, - {0xFC0C, 0, 2 | DECOMP_COMPAT, 3690}, - {0xFC0D, 0, 2 | DECOMP_COMPAT, 3692}, - {0xFC0E, 0, 2 | DECOMP_COMPAT, 3694}, - {0xFC0F, 0, 2 | DECOMP_COMPAT, 3696}, - {0xFC10, 0, 2 | DECOMP_COMPAT, 3698}, - {0xFC11, 0, 2 | DECOMP_COMPAT, 3700}, - {0xFC12, 0, 2 | DECOMP_COMPAT, 3702}, - {0xFC13, 0, 2 | DECOMP_COMPAT, 3704}, - {0xFC14, 0, 2 | DECOMP_COMPAT, 3706}, - {0xFC15, 0, 2 | DECOMP_COMPAT, 3708}, - {0xFC16, 0, 2 | DECOMP_COMPAT, 3710}, - {0xFC17, 0, 2 | DECOMP_COMPAT, 3712}, - {0xFC18, 0, 2 | DECOMP_COMPAT, 3714}, - {0xFC19, 0, 2 | DECOMP_COMPAT, 3716}, - {0xFC1A, 0, 2 | DECOMP_COMPAT, 3718}, - {0xFC1B, 0, 2 | DECOMP_COMPAT, 3720}, - {0xFC1C, 0, 2 | DECOMP_COMPAT, 3722}, - {0xFC1D, 0, 2 | DECOMP_COMPAT, 3724}, - {0xFC1E, 0, 2 | DECOMP_COMPAT, 3726}, - {0xFC1F, 0, 2 | DECOMP_COMPAT, 3728}, - {0xFC20, 0, 2 | DECOMP_COMPAT, 3730}, - {0xFC21, 0, 2 | DECOMP_COMPAT, 3732}, - {0xFC22, 0, 2 | DECOMP_COMPAT, 3734}, - {0xFC23, 0, 2 | DECOMP_COMPAT, 3736}, - {0xFC24, 0, 2 | DECOMP_COMPAT, 3738}, - {0xFC25, 0, 2 | DECOMP_COMPAT, 3740}, - {0xFC26, 0, 2 | DECOMP_COMPAT, 3742}, - {0xFC27, 0, 2 | DECOMP_COMPAT, 3744}, - {0xFC28, 0, 2 | DECOMP_COMPAT, 3746}, - {0xFC29, 0, 2 | DECOMP_COMPAT, 3748}, - {0xFC2A, 0, 2 | DECOMP_COMPAT, 3750}, - {0xFC2B, 0, 2 | DECOMP_COMPAT, 3752}, - {0xFC2C, 0, 2 | DECOMP_COMPAT, 3754}, - {0xFC2D, 0, 2 | DECOMP_COMPAT, 3756}, - {0xFC2E, 0, 2 | DECOMP_COMPAT, 3758}, - {0xFC2F, 0, 2 | DECOMP_COMPAT, 3760}, - {0xFC30, 0, 2 | DECOMP_COMPAT, 3762}, - {0xFC31, 0, 2 | DECOMP_COMPAT, 3764}, - {0xFC32, 0, 2 | DECOMP_COMPAT, 3766}, - {0xFC33, 0, 2 | DECOMP_COMPAT, 3768}, - {0xFC34, 0, 2 | DECOMP_COMPAT, 3770}, - {0xFC35, 0, 2 | DECOMP_COMPAT, 3772}, - {0xFC36, 0, 2 | DECOMP_COMPAT, 3774}, - {0xFC37, 0, 2 | DECOMP_COMPAT, 3776}, - {0xFC38, 0, 2 | DECOMP_COMPAT, 3778}, - {0xFC39, 0, 2 | DECOMP_COMPAT, 3780}, - {0xFC3A, 0, 2 | DECOMP_COMPAT, 3782}, - {0xFC3B, 0, 2 | DECOMP_COMPAT, 3784}, - {0xFC3C, 0, 2 | DECOMP_COMPAT, 3786}, - {0xFC3D, 0, 2 | DECOMP_COMPAT, 3788}, - {0xFC3E, 0, 2 | DECOMP_COMPAT, 3790}, - {0xFC3F, 0, 2 | DECOMP_COMPAT, 3792}, - {0xFC40, 0, 2 | DECOMP_COMPAT, 3794}, - {0xFC41, 0, 2 | DECOMP_COMPAT, 3796}, - {0xFC42, 0, 2 | DECOMP_COMPAT, 3798}, - {0xFC43, 0, 2 | DECOMP_COMPAT, 3800}, - {0xFC44, 0, 2 | DECOMP_COMPAT, 3802}, - {0xFC45, 0, 2 | DECOMP_COMPAT, 3804}, - {0xFC46, 0, 2 | DECOMP_COMPAT, 3806}, - {0xFC47, 0, 2 | DECOMP_COMPAT, 3808}, - {0xFC48, 0, 2 | DECOMP_COMPAT, 3810}, - {0xFC49, 0, 2 | DECOMP_COMPAT, 3812}, - {0xFC4A, 0, 2 | DECOMP_COMPAT, 3814}, - {0xFC4B, 0, 2 | DECOMP_COMPAT, 3816}, - {0xFC4C, 0, 2 | DECOMP_COMPAT, 3818}, - {0xFC4D, 0, 2 | DECOMP_COMPAT, 3820}, - {0xFC4E, 0, 2 | DECOMP_COMPAT, 3822}, - {0xFC4F, 0, 2 | DECOMP_COMPAT, 3824}, - {0xFC50, 0, 2 | DECOMP_COMPAT, 3826}, - {0xFC51, 0, 2 | DECOMP_COMPAT, 3828}, - {0xFC52, 0, 2 | DECOMP_COMPAT, 3830}, - {0xFC53, 0, 2 | DECOMP_COMPAT, 3832}, - {0xFC54, 0, 2 | DECOMP_COMPAT, 3834}, - {0xFC55, 0, 2 | DECOMP_COMPAT, 3836}, - {0xFC56, 0, 2 | DECOMP_COMPAT, 3838}, - {0xFC57, 0, 2 | DECOMP_COMPAT, 3840}, - {0xFC58, 0, 2 | DECOMP_COMPAT, 3842}, - {0xFC59, 0, 2 | DECOMP_COMPAT, 3844}, - {0xFC5A, 0, 2 | DECOMP_COMPAT, 3846}, - {0xFC5B, 0, 2 | DECOMP_COMPAT, 3848}, - {0xFC5C, 0, 2 | DECOMP_COMPAT, 3850}, - {0xFC5D, 0, 2 | DECOMP_COMPAT, 3852}, - {0xFC5E, 0, 3 | DECOMP_COMPAT, 3854}, - {0xFC5F, 0, 3 | DECOMP_COMPAT, 3857}, - {0xFC60, 0, 3 | DECOMP_COMPAT, 3860}, - {0xFC61, 0, 3 | DECOMP_COMPAT, 3863}, - {0xFC62, 0, 3 | DECOMP_COMPAT, 3866}, - {0xFC63, 0, 3 | DECOMP_COMPAT, 3869}, - {0xFC64, 0, 2 | DECOMP_COMPAT, 3872}, - {0xFC65, 0, 2 | DECOMP_COMPAT, 3874}, - {0xFC66, 0, 2 | DECOMP_COMPAT, 3876}, - {0xFC67, 0, 2 | DECOMP_COMPAT, 3878}, - {0xFC68, 0, 2 | DECOMP_COMPAT, 3880}, - {0xFC69, 0, 2 | DECOMP_COMPAT, 3882}, - {0xFC6A, 0, 2 | DECOMP_COMPAT, 3884}, - {0xFC6B, 0, 2 | DECOMP_COMPAT, 3886}, - {0xFC6C, 0, 2 | DECOMP_COMPAT, 3888}, - {0xFC6D, 0, 2 | DECOMP_COMPAT, 3890}, - {0xFC6E, 0, 2 | DECOMP_COMPAT, 3892}, - {0xFC6F, 0, 2 | DECOMP_COMPAT, 3894}, - {0xFC70, 0, 2 | DECOMP_COMPAT, 3896}, - {0xFC71, 0, 2 | DECOMP_COMPAT, 3898}, - {0xFC72, 0, 2 | DECOMP_COMPAT, 3900}, - {0xFC73, 0, 2 | DECOMP_COMPAT, 3902}, - {0xFC74, 0, 2 | DECOMP_COMPAT, 3904}, - {0xFC75, 0, 2 | DECOMP_COMPAT, 3906}, - {0xFC76, 0, 2 | DECOMP_COMPAT, 3908}, - {0xFC77, 0, 2 | DECOMP_COMPAT, 3910}, - {0xFC78, 0, 2 | DECOMP_COMPAT, 3912}, - {0xFC79, 0, 2 | DECOMP_COMPAT, 3914}, - {0xFC7A, 0, 2 | DECOMP_COMPAT, 3916}, - {0xFC7B, 0, 2 | DECOMP_COMPAT, 3918}, - {0xFC7C, 0, 2 | DECOMP_COMPAT, 3920}, - {0xFC7D, 0, 2 | DECOMP_COMPAT, 3922}, - {0xFC7E, 0, 2 | DECOMP_COMPAT, 3924}, - {0xFC7F, 0, 2 | DECOMP_COMPAT, 3926}, - {0xFC80, 0, 2 | DECOMP_COMPAT, 3928}, - {0xFC81, 0, 2 | DECOMP_COMPAT, 3930}, - {0xFC82, 0, 2 | DECOMP_COMPAT, 3932}, - {0xFC83, 0, 2 | DECOMP_COMPAT, 3934}, - {0xFC84, 0, 2 | DECOMP_COMPAT, 3936}, - {0xFC85, 0, 2 | DECOMP_COMPAT, 3938}, - {0xFC86, 0, 2 | DECOMP_COMPAT, 3940}, - {0xFC87, 0, 2 | DECOMP_COMPAT, 3942}, - {0xFC88, 0, 2 | DECOMP_COMPAT, 3944}, - {0xFC89, 0, 2 | DECOMP_COMPAT, 3946}, - {0xFC8A, 0, 2 | DECOMP_COMPAT, 3948}, - {0xFC8B, 0, 2 | DECOMP_COMPAT, 3950}, - {0xFC8C, 0, 2 | DECOMP_COMPAT, 3952}, - {0xFC8D, 0, 2 | DECOMP_COMPAT, 3954}, - {0xFC8E, 0, 2 | DECOMP_COMPAT, 3956}, - {0xFC8F, 0, 2 | DECOMP_COMPAT, 3958}, - {0xFC90, 0, 2 | DECOMP_COMPAT, 3960}, - {0xFC91, 0, 2 | DECOMP_COMPAT, 3962}, - {0xFC92, 0, 2 | DECOMP_COMPAT, 3964}, - {0xFC93, 0, 2 | DECOMP_COMPAT, 3966}, - {0xFC94, 0, 2 | DECOMP_COMPAT, 3968}, - {0xFC95, 0, 2 | DECOMP_COMPAT, 3970}, - {0xFC96, 0, 2 | DECOMP_COMPAT, 3972}, - {0xFC97, 0, 2 | DECOMP_COMPAT, 3974}, - {0xFC98, 0, 2 | DECOMP_COMPAT, 3976}, - {0xFC99, 0, 2 | DECOMP_COMPAT, 3978}, - {0xFC9A, 0, 2 | DECOMP_COMPAT, 3980}, - {0xFC9B, 0, 2 | DECOMP_COMPAT, 3982}, - {0xFC9C, 0, 2 | DECOMP_COMPAT, 3984}, - {0xFC9D, 0, 2 | DECOMP_COMPAT, 3986}, - {0xFC9E, 0, 2 | DECOMP_COMPAT, 3988}, - {0xFC9F, 0, 2 | DECOMP_COMPAT, 3990}, - {0xFCA0, 0, 2 | DECOMP_COMPAT, 3992}, - {0xFCA1, 0, 2 | DECOMP_COMPAT, 3994}, - {0xFCA2, 0, 2 | DECOMP_COMPAT, 3996}, - {0xFCA3, 0, 2 | DECOMP_COMPAT, 3998}, - {0xFCA4, 0, 2 | DECOMP_COMPAT, 4000}, - {0xFCA5, 0, 2 | DECOMP_COMPAT, 4002}, - {0xFCA6, 0, 2 | DECOMP_COMPAT, 4004}, - {0xFCA7, 0, 2 | DECOMP_COMPAT, 4006}, - {0xFCA8, 0, 2 | DECOMP_COMPAT, 4008}, - {0xFCA9, 0, 2 | DECOMP_COMPAT, 4010}, - {0xFCAA, 0, 2 | DECOMP_COMPAT, 4012}, - {0xFCAB, 0, 2 | DECOMP_COMPAT, 4014}, - {0xFCAC, 0, 2 | DECOMP_COMPAT, 4016}, - {0xFCAD, 0, 2 | DECOMP_COMPAT, 4018}, - {0xFCAE, 0, 2 | DECOMP_COMPAT, 4020}, - {0xFCAF, 0, 2 | DECOMP_COMPAT, 4022}, - {0xFCB0, 0, 2 | DECOMP_COMPAT, 4024}, - {0xFCB1, 0, 2 | DECOMP_COMPAT, 4026}, - {0xFCB2, 0, 2 | DECOMP_COMPAT, 4028}, - {0xFCB3, 0, 2 | DECOMP_COMPAT, 4030}, - {0xFCB4, 0, 2 | DECOMP_COMPAT, 4032}, - {0xFCB5, 0, 2 | DECOMP_COMPAT, 4034}, - {0xFCB6, 0, 2 | DECOMP_COMPAT, 4036}, - {0xFCB7, 0, 2 | DECOMP_COMPAT, 4038}, - {0xFCB8, 0, 2 | DECOMP_COMPAT, 4040}, - {0xFCB9, 0, 2 | DECOMP_COMPAT, 4042}, - {0xFCBA, 0, 2 | DECOMP_COMPAT, 4044}, - {0xFCBB, 0, 2 | DECOMP_COMPAT, 4046}, - {0xFCBC, 0, 2 | DECOMP_COMPAT, 4048}, - {0xFCBD, 0, 2 | DECOMP_COMPAT, 4050}, - {0xFCBE, 0, 2 | DECOMP_COMPAT, 4052}, - {0xFCBF, 0, 2 | DECOMP_COMPAT, 4054}, - {0xFCC0, 0, 2 | DECOMP_COMPAT, 4056}, - {0xFCC1, 0, 2 | DECOMP_COMPAT, 4058}, - {0xFCC2, 0, 2 | DECOMP_COMPAT, 4060}, - {0xFCC3, 0, 2 | DECOMP_COMPAT, 4062}, - {0xFCC4, 0, 2 | DECOMP_COMPAT, 4064}, - {0xFCC5, 0, 2 | DECOMP_COMPAT, 4066}, - {0xFCC6, 0, 2 | DECOMP_COMPAT, 4068}, - {0xFCC7, 0, 2 | DECOMP_COMPAT, 4070}, - {0xFCC8, 0, 2 | DECOMP_COMPAT, 4072}, - {0xFCC9, 0, 2 | DECOMP_COMPAT, 4074}, - {0xFCCA, 0, 2 | DECOMP_COMPAT, 4076}, - {0xFCCB, 0, 2 | DECOMP_COMPAT, 4078}, - {0xFCCC, 0, 2 | DECOMP_COMPAT, 4080}, - {0xFCCD, 0, 2 | DECOMP_COMPAT, 4082}, - {0xFCCE, 0, 2 | DECOMP_COMPAT, 4084}, - {0xFCCF, 0, 2 | DECOMP_COMPAT, 4086}, - {0xFCD0, 0, 2 | DECOMP_COMPAT, 4088}, - {0xFCD1, 0, 2 | DECOMP_COMPAT, 4090}, - {0xFCD2, 0, 2 | DECOMP_COMPAT, 4092}, - {0xFCD3, 0, 2 | DECOMP_COMPAT, 4094}, - {0xFCD4, 0, 2 | DECOMP_COMPAT, 4096}, - {0xFCD5, 0, 2 | DECOMP_COMPAT, 4098}, - {0xFCD6, 0, 2 | DECOMP_COMPAT, 4100}, - {0xFCD7, 0, 2 | DECOMP_COMPAT, 4102}, - {0xFCD8, 0, 2 | DECOMP_COMPAT, 4104}, - {0xFCD9, 0, 2 | DECOMP_COMPAT, 4106}, - {0xFCDA, 0, 2 | DECOMP_COMPAT, 4108}, - {0xFCDB, 0, 2 | DECOMP_COMPAT, 4110}, - {0xFCDC, 0, 2 | DECOMP_COMPAT, 4112}, - {0xFCDD, 0, 2 | DECOMP_COMPAT, 4114}, - {0xFCDE, 0, 2 | DECOMP_COMPAT, 4116}, - {0xFCDF, 0, 2 | DECOMP_COMPAT, 4118}, - {0xFCE0, 0, 2 | DECOMP_COMPAT, 4120}, - {0xFCE1, 0, 2 | DECOMP_COMPAT, 4122}, - {0xFCE2, 0, 2 | DECOMP_COMPAT, 4124}, - {0xFCE3, 0, 2 | DECOMP_COMPAT, 4126}, - {0xFCE4, 0, 2 | DECOMP_COMPAT, 4128}, - {0xFCE5, 0, 2 | DECOMP_COMPAT, 4130}, - {0xFCE6, 0, 2 | DECOMP_COMPAT, 4132}, - {0xFCE7, 0, 2 | DECOMP_COMPAT, 4134}, - {0xFCE8, 0, 2 | DECOMP_COMPAT, 4136}, - {0xFCE9, 0, 2 | DECOMP_COMPAT, 4138}, - {0xFCEA, 0, 2 | DECOMP_COMPAT, 4140}, - {0xFCEB, 0, 2 | DECOMP_COMPAT, 4142}, - {0xFCEC, 0, 2 | DECOMP_COMPAT, 4144}, - {0xFCED, 0, 2 | DECOMP_COMPAT, 4146}, - {0xFCEE, 0, 2 | DECOMP_COMPAT, 4148}, - {0xFCEF, 0, 2 | DECOMP_COMPAT, 4150}, - {0xFCF0, 0, 2 | DECOMP_COMPAT, 4152}, - {0xFCF1, 0, 2 | DECOMP_COMPAT, 4154}, - {0xFCF2, 0, 3 | DECOMP_COMPAT, 4156}, - {0xFCF3, 0, 3 | DECOMP_COMPAT, 4159}, - {0xFCF4, 0, 3 | DECOMP_COMPAT, 4162}, - {0xFCF5, 0, 2 | DECOMP_COMPAT, 4165}, - {0xFCF6, 0, 2 | DECOMP_COMPAT, 4167}, - {0xFCF7, 0, 2 | DECOMP_COMPAT, 4169}, - {0xFCF8, 0, 2 | DECOMP_COMPAT, 4171}, - {0xFCF9, 0, 2 | DECOMP_COMPAT, 4173}, - {0xFCFA, 0, 2 | DECOMP_COMPAT, 4175}, - {0xFCFB, 0, 2 | DECOMP_COMPAT, 4177}, - {0xFCFC, 0, 2 | DECOMP_COMPAT, 4179}, - {0xFCFD, 0, 2 | DECOMP_COMPAT, 4181}, - {0xFCFE, 0, 2 | DECOMP_COMPAT, 4183}, - {0xFCFF, 0, 2 | DECOMP_COMPAT, 4185}, - {0xFD00, 0, 2 | DECOMP_COMPAT, 4187}, - {0xFD01, 0, 2 | DECOMP_COMPAT, 4189}, - {0xFD02, 0, 2 | DECOMP_COMPAT, 4191}, - {0xFD03, 0, 2 | DECOMP_COMPAT, 4193}, - {0xFD04, 0, 2 | DECOMP_COMPAT, 4195}, - {0xFD05, 0, 2 | DECOMP_COMPAT, 4197}, - {0xFD06, 0, 2 | DECOMP_COMPAT, 4199}, - {0xFD07, 0, 2 | DECOMP_COMPAT, 4201}, - {0xFD08, 0, 2 | DECOMP_COMPAT, 4203}, - {0xFD09, 0, 2 | DECOMP_COMPAT, 4205}, - {0xFD0A, 0, 2 | DECOMP_COMPAT, 4207}, - {0xFD0B, 0, 2 | DECOMP_COMPAT, 4209}, - {0xFD0C, 0, 2 | DECOMP_COMPAT, 4211}, - {0xFD0D, 0, 2 | DECOMP_COMPAT, 4213}, - {0xFD0E, 0, 2 | DECOMP_COMPAT, 4215}, - {0xFD0F, 0, 2 | DECOMP_COMPAT, 4217}, - {0xFD10, 0, 2 | DECOMP_COMPAT, 4219}, - {0xFD11, 0, 2 | DECOMP_COMPAT, 4221}, - {0xFD12, 0, 2 | DECOMP_COMPAT, 4223}, - {0xFD13, 0, 2 | DECOMP_COMPAT, 4225}, - {0xFD14, 0, 2 | DECOMP_COMPAT, 4227}, - {0xFD15, 0, 2 | DECOMP_COMPAT, 4229}, - {0xFD16, 0, 2 | DECOMP_COMPAT, 4231}, - {0xFD17, 0, 2 | DECOMP_COMPAT, 4233}, - {0xFD18, 0, 2 | DECOMP_COMPAT, 4235}, - {0xFD19, 0, 2 | DECOMP_COMPAT, 4237}, - {0xFD1A, 0, 2 | DECOMP_COMPAT, 4239}, - {0xFD1B, 0, 2 | DECOMP_COMPAT, 4241}, - {0xFD1C, 0, 2 | DECOMP_COMPAT, 4243}, - {0xFD1D, 0, 2 | DECOMP_COMPAT, 4245}, - {0xFD1E, 0, 2 | DECOMP_COMPAT, 4247}, - {0xFD1F, 0, 2 | DECOMP_COMPAT, 4249}, - {0xFD20, 0, 2 | DECOMP_COMPAT, 4251}, - {0xFD21, 0, 2 | DECOMP_COMPAT, 4253}, - {0xFD22, 0, 2 | DECOMP_COMPAT, 4255}, - {0xFD23, 0, 2 | DECOMP_COMPAT, 4257}, - {0xFD24, 0, 2 | DECOMP_COMPAT, 4259}, - {0xFD25, 0, 2 | DECOMP_COMPAT, 4261}, - {0xFD26, 0, 2 | DECOMP_COMPAT, 4263}, - {0xFD27, 0, 2 | DECOMP_COMPAT, 4265}, - {0xFD28, 0, 2 | DECOMP_COMPAT, 4267}, - {0xFD29, 0, 2 | DECOMP_COMPAT, 4269}, - {0xFD2A, 0, 2 | DECOMP_COMPAT, 4271}, - {0xFD2B, 0, 2 | DECOMP_COMPAT, 4273}, - {0xFD2C, 0, 2 | DECOMP_COMPAT, 4275}, - {0xFD2D, 0, 2 | DECOMP_COMPAT, 4277}, - {0xFD2E, 0, 2 | DECOMP_COMPAT, 4279}, - {0xFD2F, 0, 2 | DECOMP_COMPAT, 4281}, - {0xFD30, 0, 2 | DECOMP_COMPAT, 4283}, - {0xFD31, 0, 2 | DECOMP_COMPAT, 4285}, - {0xFD32, 0, 2 | DECOMP_COMPAT, 4287}, - {0xFD33, 0, 2 | DECOMP_COMPAT, 4289}, - {0xFD34, 0, 2 | DECOMP_COMPAT, 4291}, - {0xFD35, 0, 2 | DECOMP_COMPAT, 4293}, - {0xFD36, 0, 2 | DECOMP_COMPAT, 4295}, - {0xFD37, 0, 2 | DECOMP_COMPAT, 4297}, - {0xFD38, 0, 2 | DECOMP_COMPAT, 4299}, - {0xFD39, 0, 2 | DECOMP_COMPAT, 4301}, - {0xFD3A, 0, 2 | DECOMP_COMPAT, 4303}, - {0xFD3B, 0, 2 | DECOMP_COMPAT, 4305}, - {0xFD3C, 0, 2 | DECOMP_COMPAT, 4307}, - {0xFD3D, 0, 2 | DECOMP_COMPAT, 4309}, - {0xFD50, 0, 3 | DECOMP_COMPAT, 4311}, - {0xFD51, 0, 3 | DECOMP_COMPAT, 4314}, - {0xFD52, 0, 3 | DECOMP_COMPAT, 4317}, - {0xFD53, 0, 3 | DECOMP_COMPAT, 4320}, - {0xFD54, 0, 3 | DECOMP_COMPAT, 4323}, - {0xFD55, 0, 3 | DECOMP_COMPAT, 4326}, - {0xFD56, 0, 3 | DECOMP_COMPAT, 4329}, - {0xFD57, 0, 3 | DECOMP_COMPAT, 4332}, - {0xFD58, 0, 3 | DECOMP_COMPAT, 4335}, - {0xFD59, 0, 3 | DECOMP_COMPAT, 4338}, - {0xFD5A, 0, 3 | DECOMP_COMPAT, 4341}, - {0xFD5B, 0, 3 | DECOMP_COMPAT, 4344}, - {0xFD5C, 0, 3 | DECOMP_COMPAT, 4347}, - {0xFD5D, 0, 3 | DECOMP_COMPAT, 4350}, - {0xFD5E, 0, 3 | DECOMP_COMPAT, 4353}, - {0xFD5F, 0, 3 | DECOMP_COMPAT, 4356}, - {0xFD60, 0, 3 | DECOMP_COMPAT, 4359}, - {0xFD61, 0, 3 | DECOMP_COMPAT, 4362}, - {0xFD62, 0, 3 | DECOMP_COMPAT, 4365}, - {0xFD63, 0, 3 | DECOMP_COMPAT, 4368}, - {0xFD64, 0, 3 | DECOMP_COMPAT, 4371}, - {0xFD65, 0, 3 | DECOMP_COMPAT, 4374}, - {0xFD66, 0, 3 | DECOMP_COMPAT, 4377}, - {0xFD67, 0, 3 | DECOMP_COMPAT, 4380}, - {0xFD68, 0, 3 | DECOMP_COMPAT, 4383}, - {0xFD69, 0, 3 | DECOMP_COMPAT, 4386}, - {0xFD6A, 0, 3 | DECOMP_COMPAT, 4389}, - {0xFD6B, 0, 3 | DECOMP_COMPAT, 4392}, - {0xFD6C, 0, 3 | DECOMP_COMPAT, 4395}, - {0xFD6D, 0, 3 | DECOMP_COMPAT, 4398}, - {0xFD6E, 0, 3 | DECOMP_COMPAT, 4401}, - {0xFD6F, 0, 3 | DECOMP_COMPAT, 4404}, - {0xFD70, 0, 3 | DECOMP_COMPAT, 4407}, - {0xFD71, 0, 3 | DECOMP_COMPAT, 4410}, - {0xFD72, 0, 3 | DECOMP_COMPAT, 4413}, - {0xFD73, 0, 3 | DECOMP_COMPAT, 4416}, - {0xFD74, 0, 3 | DECOMP_COMPAT, 4419}, - {0xFD75, 0, 3 | DECOMP_COMPAT, 4422}, - {0xFD76, 0, 3 | DECOMP_COMPAT, 4425}, - {0xFD77, 0, 3 | DECOMP_COMPAT, 4428}, - {0xFD78, 0, 3 | DECOMP_COMPAT, 4431}, - {0xFD79, 0, 3 | DECOMP_COMPAT, 4434}, - {0xFD7A, 0, 3 | DECOMP_COMPAT, 4437}, - {0xFD7B, 0, 3 | DECOMP_COMPAT, 4440}, - {0xFD7C, 0, 3 | DECOMP_COMPAT, 4443}, - {0xFD7D, 0, 3 | DECOMP_COMPAT, 4446}, - {0xFD7E, 0, 3 | DECOMP_COMPAT, 4449}, - {0xFD7F, 0, 3 | DECOMP_COMPAT, 4452}, - {0xFD80, 0, 3 | DECOMP_COMPAT, 4455}, - {0xFD81, 0, 3 | DECOMP_COMPAT, 4458}, - {0xFD82, 0, 3 | DECOMP_COMPAT, 4461}, - {0xFD83, 0, 3 | DECOMP_COMPAT, 4464}, - {0xFD84, 0, 3 | DECOMP_COMPAT, 4467}, - {0xFD85, 0, 3 | DECOMP_COMPAT, 4470}, - {0xFD86, 0, 3 | DECOMP_COMPAT, 4473}, - {0xFD87, 0, 3 | DECOMP_COMPAT, 4476}, - {0xFD88, 0, 3 | DECOMP_COMPAT, 4479}, - {0xFD89, 0, 3 | DECOMP_COMPAT, 4482}, - {0xFD8A, 0, 3 | DECOMP_COMPAT, 4485}, - {0xFD8B, 0, 3 | DECOMP_COMPAT, 4488}, - {0xFD8C, 0, 3 | DECOMP_COMPAT, 4491}, - {0xFD8D, 0, 3 | DECOMP_COMPAT, 4494}, - {0xFD8E, 0, 3 | DECOMP_COMPAT, 4497}, - {0xFD8F, 0, 3 | DECOMP_COMPAT, 4500}, - {0xFD92, 0, 3 | DECOMP_COMPAT, 4503}, - {0xFD93, 0, 3 | DECOMP_COMPAT, 4506}, - {0xFD94, 0, 3 | DECOMP_COMPAT, 4509}, - {0xFD95, 0, 3 | DECOMP_COMPAT, 4512}, - {0xFD96, 0, 3 | DECOMP_COMPAT, 4515}, - {0xFD97, 0, 3 | DECOMP_COMPAT, 4518}, - {0xFD98, 0, 3 | DECOMP_COMPAT, 4521}, - {0xFD99, 0, 3 | DECOMP_COMPAT, 4524}, - {0xFD9A, 0, 3 | DECOMP_COMPAT, 4527}, - {0xFD9B, 0, 3 | DECOMP_COMPAT, 4530}, - {0xFD9C, 0, 3 | DECOMP_COMPAT, 4533}, - {0xFD9D, 0, 3 | DECOMP_COMPAT, 4536}, - {0xFD9E, 0, 3 | DECOMP_COMPAT, 4539}, - {0xFD9F, 0, 3 | DECOMP_COMPAT, 4542}, - {0xFDA0, 0, 3 | DECOMP_COMPAT, 4545}, - {0xFDA1, 0, 3 | DECOMP_COMPAT, 4548}, - {0xFDA2, 0, 3 | DECOMP_COMPAT, 4551}, - {0xFDA3, 0, 3 | DECOMP_COMPAT, 4554}, - {0xFDA4, 0, 3 | DECOMP_COMPAT, 4557}, - {0xFDA5, 0, 3 | DECOMP_COMPAT, 4560}, - {0xFDA6, 0, 3 | DECOMP_COMPAT, 4563}, - {0xFDA7, 0, 3 | DECOMP_COMPAT, 4566}, - {0xFDA8, 0, 3 | DECOMP_COMPAT, 4569}, - {0xFDA9, 0, 3 | DECOMP_COMPAT, 4572}, - {0xFDAA, 0, 3 | DECOMP_COMPAT, 4575}, - {0xFDAB, 0, 3 | DECOMP_COMPAT, 4578}, - {0xFDAC, 0, 3 | DECOMP_COMPAT, 4581}, - {0xFDAD, 0, 3 | DECOMP_COMPAT, 4584}, - {0xFDAE, 0, 3 | DECOMP_COMPAT, 4587}, - {0xFDAF, 0, 3 | DECOMP_COMPAT, 4590}, - {0xFDB0, 0, 3 | DECOMP_COMPAT, 4593}, - {0xFDB1, 0, 3 | DECOMP_COMPAT, 4596}, - {0xFDB2, 0, 3 | DECOMP_COMPAT, 4599}, - {0xFDB3, 0, 3 | DECOMP_COMPAT, 4602}, - {0xFDB4, 0, 3 | DECOMP_COMPAT, 4605}, - {0xFDB5, 0, 3 | DECOMP_COMPAT, 4608}, - {0xFDB6, 0, 3 | DECOMP_COMPAT, 4611}, - {0xFDB7, 0, 3 | DECOMP_COMPAT, 4614}, - {0xFDB8, 0, 3 | DECOMP_COMPAT, 4617}, - {0xFDB9, 0, 3 | DECOMP_COMPAT, 4620}, - {0xFDBA, 0, 3 | DECOMP_COMPAT, 4623}, - {0xFDBB, 0, 3 | DECOMP_COMPAT, 4626}, - {0xFDBC, 0, 3 | DECOMP_COMPAT, 4629}, - {0xFDBD, 0, 3 | DECOMP_COMPAT, 4632}, - {0xFDBE, 0, 3 | DECOMP_COMPAT, 4635}, - {0xFDBF, 0, 3 | DECOMP_COMPAT, 4638}, - {0xFDC0, 0, 3 | DECOMP_COMPAT, 4641}, - {0xFDC1, 0, 3 | DECOMP_COMPAT, 4644}, - {0xFDC2, 0, 3 | DECOMP_COMPAT, 4647}, - {0xFDC3, 0, 3 | DECOMP_COMPAT, 4650}, - {0xFDC4, 0, 3 | DECOMP_COMPAT, 4653}, - {0xFDC5, 0, 3 | DECOMP_COMPAT, 4656}, - {0xFDC6, 0, 3 | DECOMP_COMPAT, 4659}, - {0xFDC7, 0, 3 | DECOMP_COMPAT, 4662}, - {0xFDF0, 0, 3 | DECOMP_COMPAT, 4665}, - {0xFDF1, 0, 3 | DECOMP_COMPAT, 4668}, - {0xFDF2, 0, 4 | DECOMP_COMPAT, 4671}, - {0xFDF3, 0, 4 | DECOMP_COMPAT, 4675}, - {0xFDF4, 0, 4 | DECOMP_COMPAT, 4679}, - {0xFDF5, 0, 4 | DECOMP_COMPAT, 4683}, - {0xFDF6, 0, 4 | DECOMP_COMPAT, 4687}, - {0xFDF7, 0, 4 | DECOMP_COMPAT, 4691}, - {0xFDF8, 0, 4 | DECOMP_COMPAT, 4695}, - {0xFDF9, 0, 3 | DECOMP_COMPAT, 4699}, - {0xFDFA, 0, 18 | DECOMP_COMPAT, 4702}, - {0xFDFB, 0, 8 | DECOMP_COMPAT, 4720}, - {0xFDFC, 0, 4 | DECOMP_COMPAT, 4728}, - {0xFE10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, - {0xFE11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, - {0xFE12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3002}, - {0xFE13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, - {0xFE14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, - {0xFE15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, - {0xFE16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, - {0xFE17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3016}, - {0xFE18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3017}, - {0xFE19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2026}, - {0xFE20, 230, 0, 0}, - {0xFE21, 230, 0, 0}, - {0xFE22, 230, 0, 0}, - {0xFE23, 230, 0, 0}, - {0xFE24, 230, 0, 0}, - {0xFE25, 230, 0, 0}, - {0xFE26, 230, 0, 0}, - {0xFE27, 220, 0, 0}, - {0xFE28, 220, 0, 0}, - {0xFE29, 220, 0, 0}, - {0xFE2A, 220, 0, 0}, - {0xFE2B, 220, 0, 0}, - {0xFE2C, 220, 0, 0}, - {0xFE2D, 220, 0, 0}, - {0xFE2E, 230, 0, 0}, - {0xFE2F, 230, 0, 0}, - {0xFE30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2025}, - {0xFE31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2014}, - {0xFE32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2013}, - {0xFE33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFE34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFE35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, - {0xFE36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, - {0xFE37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, - {0xFE38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, - {0xFE39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3014}, - {0xFE3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3015}, - {0xFE3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3010}, - {0xFE3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3011}, - {0xFE3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300A}, - {0xFE3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300B}, - {0xFE3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3008}, - {0xFE40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3009}, - {0xFE41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300C}, - {0xFE42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300D}, - {0xFE43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300E}, - {0xFE44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300F}, - {0xFE47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005B}, - {0xFE48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005D}, - {0xFE49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, - {0xFE4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, - {0xFE4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, - {0xFE4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x203E}, - {0xFE4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFE4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFE4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFE50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, - {0xFE51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, - {0xFE52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, - {0xFE54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, - {0xFE55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, - {0xFE56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, - {0xFE57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, - {0xFE58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2014}, - {0xFE59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, - {0xFE5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, - {0xFE5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, - {0xFE5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, - {0xFE5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3014}, - {0xFE5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3015}, - {0xFE5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0023}, - {0xFE60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0026}, - {0xFE61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002A}, - {0xFE62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, - {0xFE63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002D}, - {0xFE64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003C}, - {0xFE65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003E}, - {0xFE66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, - {0xFE68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005C}, - {0xFE69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0024}, - {0xFE6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0025}, - {0xFE6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0040}, - {0xFE70, 0, 2 | DECOMP_COMPAT, 4732}, - {0xFE71, 0, 2 | DECOMP_COMPAT, 4734}, - {0xFE72, 0, 2 | DECOMP_COMPAT, 4736}, - {0xFE74, 0, 2 | DECOMP_COMPAT, 4738}, - {0xFE76, 0, 2 | DECOMP_COMPAT, 4740}, - {0xFE77, 0, 2 | DECOMP_COMPAT, 4742}, - {0xFE78, 0, 2 | DECOMP_COMPAT, 4744}, - {0xFE79, 0, 2 | DECOMP_COMPAT, 4746}, - {0xFE7A, 0, 2 | DECOMP_COMPAT, 4748}, - {0xFE7B, 0, 2 | DECOMP_COMPAT, 4750}, - {0xFE7C, 0, 2 | DECOMP_COMPAT, 4752}, - {0xFE7D, 0, 2 | DECOMP_COMPAT, 4754}, - {0xFE7E, 0, 2 | DECOMP_COMPAT, 4756}, - {0xFE7F, 0, 2 | DECOMP_COMPAT, 4758}, - {0xFE80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0621}, - {0xFE81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0622}, - {0xFE82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0622}, - {0xFE83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0623}, - {0xFE84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0623}, - {0xFE85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0624}, - {0xFE86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0624}, - {0xFE87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0625}, - {0xFE88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0625}, - {0xFE89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, - {0xFE8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, - {0xFE8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, - {0xFE8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0626}, - {0xFE8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, - {0xFE8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, - {0xFE8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0xFE90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0xFE91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0xFE92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0xFE93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0629}, - {0xFE94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0629}, - {0xFE95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0xFE96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0xFE97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0xFE98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0xFE99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0xFE9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0xFE9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0xFE9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0xFE9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0xFE9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0xFE9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0xFEA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0xFEA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0xFEA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0xFEA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0xFEA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0xFEA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0xFEA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0xFEA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0xFEA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0xFEA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, - {0xFEAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, - {0xFEAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, - {0xFEAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, - {0xFEAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, - {0xFEAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, - {0xFEAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, - {0xFEB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, - {0xFEB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0xFEB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0xFEB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0xFEB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0xFEB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0xFEB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0xFEB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0xFEB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0xFEB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0xFEBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0xFEBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0xFEBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0xFEBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0xFEBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0xFEBF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0xFEC0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0xFEC1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0xFEC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0xFEC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0xFEC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0xFEC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0xFEC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0xFEC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0xFEC8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0xFEC9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0xFECA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0xFECB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0xFECC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0xFECD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0xFECE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0xFECF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0xFED0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0xFED1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0xFED2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0xFED3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0xFED4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0xFED5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0xFED6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0xFED7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0xFED8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0xFED9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0xFEDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0xFEDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0xFEDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0xFEDD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0xFEDE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0xFEDF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0xFEE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0xFEE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0xFEE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0xFEE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0xFEE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0xFEE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0xFEE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0xFEE7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0xFEE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0xFEE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0xFEEA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0xFEEB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0xFEEC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0xFEED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, - {0xFEEE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, - {0xFEEF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, - {0xFEF0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0649}, - {0xFEF1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0xFEF2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0xFEF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0xFEF4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0xFEF5, 0, 2 | DECOMP_COMPAT, 4760}, - {0xFEF6, 0, 2 | DECOMP_COMPAT, 4762}, - {0xFEF7, 0, 2 | DECOMP_COMPAT, 4764}, - {0xFEF8, 0, 2 | DECOMP_COMPAT, 4766}, - {0xFEF9, 0, 2 | DECOMP_COMPAT, 4768}, - {0xFEFA, 0, 2 | DECOMP_COMPAT, 4770}, - {0xFEFB, 0, 2 | DECOMP_COMPAT, 4772}, - {0xFEFC, 0, 2 | DECOMP_COMPAT, 4774}, - {0xFF01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0021}, - {0xFF02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0022}, - {0xFF03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0023}, - {0xFF04, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0024}, - {0xFF05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0025}, - {0xFF06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0026}, - {0xFF07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0027}, - {0xFF08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0028}, - {0xFF09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0029}, - {0xFF0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002A}, - {0xFF0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002B}, - {0xFF0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002C}, - {0xFF0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002D}, - {0xFF0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002E}, - {0xFF0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x002F}, - {0xFF10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0xFF11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0xFF12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0xFF13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0xFF14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0xFF15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0xFF16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0xFF17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0xFF18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0xFF19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0xFF1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003A}, - {0xFF1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003B}, - {0xFF1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003C}, - {0xFF1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003D}, - {0xFF1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003E}, - {0xFF1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x003F}, - {0xFF20, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0040}, - {0xFF21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0xFF22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0xFF23, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0xFF24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0xFF25, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0xFF26, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0xFF27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0xFF28, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0xFF29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0xFF2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0xFF2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0xFF2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0xFF2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0xFF2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0xFF2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0xFF30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0xFF31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0xFF32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0xFF33, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0xFF34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0xFF35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0xFF36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0xFF37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0xFF38, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0xFF39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0xFF3A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0xFF3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005B}, - {0xFF3C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005C}, - {0xFF3D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005D}, - {0xFF3E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005E}, - {0xFF3F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005F}, - {0xFF40, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0060}, - {0xFF41, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0xFF42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0xFF43, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0xFF44, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0xFF45, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0xFF46, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0xFF47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0xFF48, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0xFF49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0xFF4A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0xFF4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0xFF4C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0xFF4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0xFF4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0xFF4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0xFF50, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0xFF51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0xFF52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0xFF53, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0xFF54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0xFF55, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0xFF56, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0xFF57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0xFF58, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0xFF59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0xFF5A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0xFF5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007B}, - {0xFF5C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007C}, - {0xFF5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007D}, - {0xFF5E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007E}, - {0xFF5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2985}, - {0xFF60, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2986}, - {0xFF61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3002}, - {0xFF62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300C}, - {0xFF63, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x300D}, - {0xFF64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3001}, - {0xFF65, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30FB}, - {0xFF66, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F2}, - {0xFF67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A1}, - {0xFF68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A3}, - {0xFF69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A5}, - {0xFF6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A7}, - {0xFF6B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A9}, - {0xFF6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E3}, - {0xFF6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E5}, - {0xFF6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E7}, - {0xFF6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C3}, - {0xFF70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30FC}, - {0xFF71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A2}, - {0xFF72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A4}, - {0xFF73, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A6}, - {0xFF74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30A8}, - {0xFF75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AA}, - {0xFF76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AB}, - {0xFF77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AD}, - {0xFF78, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30AF}, - {0xFF79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B1}, - {0xFF7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B3}, - {0xFF7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, - {0xFF7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B7}, - {0xFF7D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B9}, - {0xFF7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BB}, - {0xFF7F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BD}, - {0xFF80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30BF}, - {0xFF81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C1}, - {0xFF82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C4}, - {0xFF83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C6}, - {0xFF84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C8}, - {0xFF85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CA}, - {0xFF86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CB}, - {0xFF87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CC}, - {0xFF88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CD}, - {0xFF89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CE}, - {0xFF8A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30CF}, - {0xFF8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D2}, - {0xFF8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D5}, - {0xFF8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30D8}, - {0xFF8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DB}, - {0xFF8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DE}, - {0xFF90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30DF}, - {0xFF91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E0}, - {0xFF92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E1}, - {0xFF93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E2}, - {0xFF94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E4}, - {0xFF95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E6}, - {0xFF96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E8}, - {0xFF97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30E9}, - {0xFF98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EA}, - {0xFF99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EB}, - {0xFF9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EC}, - {0xFF9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30ED}, - {0xFF9C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30EF}, - {0xFF9D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30F3}, - {0xFF9E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3099}, - {0xFF9F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x309A}, - {0xFFA0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3164}, - {0xFFA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3131}, - {0xFFA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3132}, - {0xFFA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3133}, - {0xFFA4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3134}, - {0xFFA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3135}, - {0xFFA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3136}, - {0xFFA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3137}, - {0xFFA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3138}, - {0xFFA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3139}, - {0xFFAA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313A}, - {0xFFAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313B}, - {0xFFAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313C}, - {0xFFAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313D}, - {0xFFAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313E}, - {0xFFAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x313F}, - {0xFFB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3140}, - {0xFFB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3141}, - {0xFFB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3142}, - {0xFFB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3143}, - {0xFFB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3144}, - {0xFFB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3145}, - {0xFFB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3146}, - {0xFFB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3147}, - {0xFFB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3148}, - {0xFFB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3149}, - {0xFFBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314A}, - {0xFFBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314B}, - {0xFFBC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314C}, - {0xFFBD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314D}, - {0xFFBE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314E}, - {0xFFC2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x314F}, - {0xFFC3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3150}, - {0xFFC4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3151}, - {0xFFC5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3152}, - {0xFFC6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3153}, - {0xFFC7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3154}, - {0xFFCA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3155}, - {0xFFCB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3156}, - {0xFFCC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3157}, - {0xFFCD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3158}, - {0xFFCE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3159}, - {0xFFCF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315A}, - {0xFFD2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315B}, - {0xFFD3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315C}, - {0xFFD4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315D}, - {0xFFD5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315E}, - {0xFFD6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x315F}, - {0xFFD7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3160}, - {0xFFDA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3161}, - {0xFFDB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3162}, - {0xFFDC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x3163}, - {0xFFE0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A2}, - {0xFFE1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A3}, - {0xFFE2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00AC}, - {0xFFE3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00AF}, - {0xFFE4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A6}, - {0xFFE5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00A5}, - {0xFFE6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x20A9}, - {0xFFE8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2502}, - {0xFFE9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2190}, - {0xFFEA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2191}, - {0xFFEB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2192}, - {0xFFEC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2193}, - {0xFFED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x25A0}, - {0xFFEE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x25CB}, - {0x101FD, 220, 0, 0}, - {0x102E0, 220, 0, 0}, - {0x10376, 230, 0, 0}, - {0x10377, 230, 0, 0}, - {0x10378, 230, 0, 0}, - {0x10379, 230, 0, 0}, - {0x1037A, 230, 0, 0}, - {0x10781, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02D0}, - {0x10782, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02D1}, - {0x10783, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00E6}, - {0x10784, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0299}, - {0x10785, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0253}, - {0x10787, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A3}, - {0x10788, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB66}, - {0x10789, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A5}, - {0x1078A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A4}, - {0x1078B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0256}, - {0x1078C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0257}, - {0x1078D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x1D91}, - {0x1078E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0258}, - {0x1078F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x025E}, - {0x10790, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A9}, - {0x10791, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0264}, - {0x10792, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0262}, - {0x10793, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0260}, - {0x10794, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029B}, - {0x10795, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0127}, - {0x10796, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x029C}, - {0x10797, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0267}, - {0x10798, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0284}, - {0x10799, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02AA}, - {0x1079A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02AB}, - {0x1079B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026C}, - {0x1079C, 0, 1 | DECOMP_COMPAT, 4776}, - {0x1079D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA78E}, - {0x1079E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x026E}, - {0x1079F, 0, 1 | DECOMP_COMPAT, 4777}, - {0x107A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028E}, - {0x107A1, 0, 1 | DECOMP_COMPAT, 4778}, - {0x107A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x00F8}, - {0x107A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0276}, - {0x107A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0277}, - {0x107A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x107A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027A}, - {0x107A7, 0, 1 | DECOMP_COMPAT, 4779}, - {0x107A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027D}, - {0x107A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x027E}, - {0x107AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0280}, - {0x107AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A8}, - {0x107AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A6}, - {0x107AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xAB67}, - {0x107AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A7}, - {0x107AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0288}, - {0x107B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2C71}, - {0x107B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x028F}, - {0x107B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A1}, - {0x107B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x02A2}, - {0x107B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0298}, - {0x107B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C0}, - {0x107B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C1}, - {0x107B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x01C2}, - {0x107B9, 0, 1 | DECOMP_COMPAT, 4780}, - {0x107BA, 0, 1 | DECOMP_COMPAT, 4781}, - {0x10A0D, 220, 0, 0}, - {0x10A0F, 230, 0, 0}, - {0x10A38, 230, 0, 0}, - {0x10A39, 1, 0, 0}, - {0x10A3A, 220, 0, 0}, - {0x10A3F, 9, 0, 0}, - {0x10AE5, 230, 0, 0}, - {0x10AE6, 220, 0, 0}, - {0x10D24, 230, 0, 0}, - {0x10D25, 230, 0, 0}, - {0x10D26, 230, 0, 0}, - {0x10D27, 230, 0, 0}, - {0x10EAB, 230, 0, 0}, - {0x10EAC, 230, 0, 0}, - {0x10EFD, 220, 0, 0}, - {0x10EFE, 220, 0, 0}, - {0x10EFF, 220, 0, 0}, - {0x10F46, 220, 0, 0}, - {0x10F47, 220, 0, 0}, - {0x10F48, 230, 0, 0}, - {0x10F49, 230, 0, 0}, - {0x10F4A, 230, 0, 0}, - {0x10F4B, 220, 0, 0}, - {0x10F4C, 230, 0, 0}, - {0x10F4D, 220, 0, 0}, - {0x10F4E, 220, 0, 0}, - {0x10F4F, 220, 0, 0}, - {0x10F50, 220, 0, 0}, - {0x10F82, 230, 0, 0}, - {0x10F83, 220, 0, 0}, - {0x10F84, 230, 0, 0}, - {0x10F85, 220, 0, 0}, - {0x11046, 9, 0, 0}, - {0x11070, 9, 0, 0}, - {0x1107F, 9, 0, 0}, - {0x1109A, 0, 2, 4782}, - {0x1109C, 0, 2, 4784}, - {0x110AB, 0, 2, 4786}, - {0x110B9, 9, 0, 0}, - {0x110BA, 7, 0, 0}, - {0x11100, 230, 0, 0}, - {0x11101, 230, 0, 0}, - {0x11102, 230, 0, 0}, - {0x1112E, 0, 2, 4788}, - {0x1112F, 0, 2, 4790}, - {0x11133, 9, 0, 0}, - {0x11134, 9, 0, 0}, - {0x11173, 7, 0, 0}, - {0x111C0, 9, 0, 0}, - {0x111CA, 7, 0, 0}, - {0x11235, 9, 0, 0}, - {0x11236, 7, 0, 0}, - {0x112E9, 7, 0, 0}, - {0x112EA, 9, 0, 0}, - {0x1133B, 7, 0, 0}, - {0x1133C, 7, 0, 0}, - {0x1134B, 0, 2, 4792}, - {0x1134C, 0, 2, 4794}, - {0x1134D, 9, 0, 0}, - {0x11366, 230, 0, 0}, - {0x11367, 230, 0, 0}, - {0x11368, 230, 0, 0}, - {0x11369, 230, 0, 0}, - {0x1136A, 230, 0, 0}, - {0x1136B, 230, 0, 0}, - {0x1136C, 230, 0, 0}, - {0x11370, 230, 0, 0}, - {0x11371, 230, 0, 0}, - {0x11372, 230, 0, 0}, - {0x11373, 230, 0, 0}, - {0x11374, 230, 0, 0}, - {0x11442, 9, 0, 0}, - {0x11446, 7, 0, 0}, - {0x1145E, 230, 0, 0}, - {0x114BB, 0, 2, 4796}, - {0x114BC, 0, 2, 4798}, - {0x114BE, 0, 2, 4800}, - {0x114C2, 9, 0, 0}, - {0x114C3, 7, 0, 0}, - {0x115BA, 0, 2, 4802}, - {0x115BB, 0, 2, 4804}, - {0x115BF, 9, 0, 0}, - {0x115C0, 7, 0, 0}, - {0x1163F, 9, 0, 0}, - {0x116B6, 9, 0, 0}, - {0x116B7, 7, 0, 0}, - {0x1172B, 9, 0, 0}, - {0x11839, 9, 0, 0}, - {0x1183A, 7, 0, 0}, - {0x11938, 0, 2, 4806}, - {0x1193D, 9, 0, 0}, - {0x1193E, 9, 0, 0}, - {0x11943, 7, 0, 0}, - {0x119E0, 9, 0, 0}, - {0x11A34, 9, 0, 0}, - {0x11A47, 9, 0, 0}, - {0x11A99, 9, 0, 0}, - {0x11C3F, 9, 0, 0}, - {0x11D42, 7, 0, 0}, - {0x11D44, 9, 0, 0}, - {0x11D45, 9, 0, 0}, - {0x11D97, 9, 0, 0}, - {0x11F41, 9, 0, 0}, - {0x11F42, 9, 0, 0}, - {0x16AF0, 1, 0, 0}, - {0x16AF1, 1, 0, 0}, - {0x16AF2, 1, 0, 0}, - {0x16AF3, 1, 0, 0}, - {0x16AF4, 1, 0, 0}, - {0x16B30, 230, 0, 0}, - {0x16B31, 230, 0, 0}, - {0x16B32, 230, 0, 0}, - {0x16B33, 230, 0, 0}, - {0x16B34, 230, 0, 0}, - {0x16B35, 230, 0, 0}, - {0x16B36, 230, 0, 0}, - {0x16FF0, 6, 0, 0}, - {0x16FF1, 6, 0, 0}, - {0x1BC9E, 1, 0, 0}, - {0x1D15E, 0, 2 | DECOMP_NO_COMPOSE, 4808}, /* in exclusion list */ - {0x1D15F, 0, 2 | DECOMP_NO_COMPOSE, 4810}, /* in exclusion list */ - {0x1D160, 0, 2 | DECOMP_NO_COMPOSE, 4812}, /* in exclusion list */ - {0x1D161, 0, 2 | DECOMP_NO_COMPOSE, 4814}, /* in exclusion list */ - {0x1D162, 0, 2 | DECOMP_NO_COMPOSE, 4816}, /* in exclusion list */ - {0x1D163, 0, 2 | DECOMP_NO_COMPOSE, 4818}, /* in exclusion list */ - {0x1D164, 0, 2 | DECOMP_NO_COMPOSE, 4820}, /* in exclusion list */ - {0x1D165, 216, 0, 0}, - {0x1D166, 216, 0, 0}, - {0x1D167, 1, 0, 0}, - {0x1D168, 1, 0, 0}, - {0x1D169, 1, 0, 0}, - {0x1D16D, 226, 0, 0}, - {0x1D16E, 216, 0, 0}, - {0x1D16F, 216, 0, 0}, - {0x1D170, 216, 0, 0}, - {0x1D171, 216, 0, 0}, - {0x1D172, 216, 0, 0}, - {0x1D17B, 220, 0, 0}, - {0x1D17C, 220, 0, 0}, - {0x1D17D, 220, 0, 0}, - {0x1D17E, 220, 0, 0}, - {0x1D17F, 220, 0, 0}, - {0x1D180, 220, 0, 0}, - {0x1D181, 220, 0, 0}, - {0x1D182, 220, 0, 0}, - {0x1D185, 230, 0, 0}, - {0x1D186, 230, 0, 0}, - {0x1D187, 230, 0, 0}, - {0x1D188, 230, 0, 0}, - {0x1D189, 230, 0, 0}, - {0x1D18A, 220, 0, 0}, - {0x1D18B, 220, 0, 0}, - {0x1D1AA, 230, 0, 0}, - {0x1D1AB, 230, 0, 0}, - {0x1D1AC, 230, 0, 0}, - {0x1D1AD, 230, 0, 0}, - {0x1D1BB, 0, 2 | DECOMP_NO_COMPOSE, 4822}, /* in exclusion list */ - {0x1D1BC, 0, 2 | DECOMP_NO_COMPOSE, 4824}, /* in exclusion list */ - {0x1D1BD, 0, 2 | DECOMP_NO_COMPOSE, 4826}, /* in exclusion list */ - {0x1D1BE, 0, 2 | DECOMP_NO_COMPOSE, 4828}, /* in exclusion list */ - {0x1D1BF, 0, 2 | DECOMP_NO_COMPOSE, 4830}, /* in exclusion list */ - {0x1D1C0, 0, 2 | DECOMP_NO_COMPOSE, 4832}, /* in exclusion list */ - {0x1D242, 230, 0, 0}, - {0x1D243, 230, 0, 0}, - {0x1D244, 230, 0, 0}, - {0x1D400, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D401, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D402, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D403, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D404, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D405, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D406, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D407, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D408, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D409, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D40A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D40B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D40C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D40D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D40E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D40F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D410, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D411, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D412, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D413, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D414, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D415, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D416, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D417, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D418, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D419, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D41A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D41B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D41C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D41D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D41E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D41F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D420, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D421, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D422, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D423, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D424, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D425, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D426, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D427, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D428, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D429, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D42A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D42B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D42C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D42D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D42E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D42F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D430, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D431, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D432, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D433, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D434, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D435, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D436, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D437, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D438, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D439, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D43A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D43B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D43C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D43D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D43E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D43F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D440, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D441, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D442, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D443, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D444, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D445, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D446, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D447, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D448, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D449, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D44A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D44B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D44C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D44D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D44E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D44F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D450, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D451, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D452, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D453, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D454, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D456, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D457, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D458, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D459, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D45A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D45B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D45C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D45D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D45E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D45F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D460, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D461, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D462, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D463, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D464, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D465, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D466, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D467, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D468, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D469, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D46A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D46B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D46C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D46D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D46E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D46F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D470, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D471, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D472, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D473, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D474, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D475, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D476, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D477, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D478, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D479, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D47A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D47B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D47C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D47D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D47E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D47F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D480, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D481, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D482, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D483, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D484, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D485, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D486, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D487, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D488, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D489, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D48A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D48B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D48C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D48D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D48E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D48F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D490, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D491, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D492, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D493, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D494, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D495, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D496, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D497, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D498, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D499, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D49A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D49B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D49C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D49E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D49F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D4A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D4A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D4A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D4A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D4AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D4AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D4AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D4AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D4AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D4B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D4B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D4B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D4B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D4B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D4B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D4B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D4B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D4B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D4B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D4BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D4BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D4BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D4BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D4C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D4C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D4C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D4C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D4C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D4C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D4C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D4C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D4C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D4CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D4CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D4CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D4CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D4CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D4CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D4D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D4D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D4D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D4D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D4D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D4D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D4D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D4D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D4D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D4D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D4DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D4DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D4DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D4DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D4DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D4DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D4E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D4E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D4E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D4E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D4E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D4E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D4E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D4E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D4E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D4E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D4EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D4EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D4EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D4ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D4EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D4EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D4F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D4F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D4F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D4F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D4F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D4F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D4F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D4F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D4F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D4F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D4FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D4FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D4FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D4FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D4FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D4FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D500, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D501, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D502, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D503, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D504, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D505, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D507, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D508, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D509, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D50A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D50D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D50E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D50F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D510, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D511, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D512, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D513, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D514, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D516, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D517, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D518, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D519, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D51A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D51B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D51C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D51E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D51F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D520, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D521, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D522, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D523, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D524, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D525, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D526, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D527, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D528, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D529, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D52A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D52B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D52C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D52D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D52E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D52F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D530, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D531, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D532, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D533, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D534, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D535, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D536, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D537, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D538, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D539, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D53B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D53C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D53D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D53E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D540, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D541, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D542, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D543, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D544, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D546, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D54A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D54B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D54C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D54D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D54E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D54F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D550, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D552, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D553, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D554, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D555, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D556, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D557, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D558, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D559, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D55A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D55B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D55C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D55D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D55E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D55F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D560, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D561, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D562, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D563, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D564, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D565, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D566, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D567, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D568, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D569, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D56A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D56B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D56C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D56D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D56E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D56F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D570, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D571, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D572, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D573, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D574, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D575, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D576, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D577, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D578, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D579, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D57A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D57B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D57C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D57D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D57E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D57F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D580, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D581, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D582, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D583, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D584, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D585, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D586, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D587, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D588, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D589, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D58A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D58B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D58C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D58D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D58E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D58F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D590, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D591, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D592, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D593, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D594, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D595, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D596, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D597, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D598, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D599, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D59A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D59B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D59C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D59D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D59E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D59F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D5A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D5A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D5A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D5A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D5A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D5A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D5A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D5A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D5A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D5A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D5AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D5AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D5AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D5AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D5AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D5AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D5B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D5B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D5B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D5B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D5B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D5B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D5B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D5B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D5B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D5B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D5BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D5BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D5BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D5BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D5BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D5BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D5C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D5C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D5C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D5C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D5C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D5C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D5C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D5C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D5C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D5C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D5CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D5CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D5CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D5CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D5CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D5CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D5D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D5D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D5D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D5D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D5D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D5D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D5D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D5D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D5D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D5D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D5DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D5DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D5DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D5DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D5DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D5DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D5E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D5E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D5E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D5E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D5E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D5E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D5E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D5E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D5E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D5E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D5EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D5EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D5EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D5ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D5EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D5EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D5F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D5F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D5F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D5F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D5F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D5F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D5F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D5F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D5F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D5F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D5FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D5FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D5FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D5FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D5FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D5FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D600, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D601, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D602, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D603, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D604, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D605, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D606, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D607, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D608, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D609, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D60A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D60B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D60C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D60D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D60E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D60F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D610, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D611, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D612, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D613, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D614, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D615, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D616, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D617, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D618, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D619, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D61A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D61B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D61C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D61D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D61E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D61F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D620, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D621, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D622, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D623, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D624, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D625, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D626, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D627, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D628, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D629, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D62A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D62B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D62C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D62D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D62E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D62F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D630, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D631, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D632, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D633, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D634, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D635, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D636, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D637, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D638, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D639, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D63A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D63B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D63C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D63D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D63E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D63F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D640, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D641, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D642, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D643, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D644, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D645, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D646, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D647, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D648, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D649, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D64A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D64B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D64C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D64D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D64E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D64F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D650, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D651, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D652, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D653, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D654, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D655, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D656, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D657, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D658, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D659, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D65A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D65B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D65C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D65D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D65E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D65F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D660, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D661, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D662, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D663, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D664, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D665, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D666, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D667, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D668, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D669, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D66A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D66B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D66C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D66D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D66E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D66F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D670, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1D671, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1D672, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1D673, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1D674, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1D675, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1D676, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1D677, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1D678, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1D679, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1D67A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1D67B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1D67C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1D67D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1D67E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1D67F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1D680, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1D681, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1D682, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1D683, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1D684, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1D685, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1D686, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1D687, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1D688, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1D689, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1D68A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0061}, - {0x1D68B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0062}, - {0x1D68C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0063}, - {0x1D68D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0064}, - {0x1D68E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0065}, - {0x1D68F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0066}, - {0x1D690, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0067}, - {0x1D691, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0068}, - {0x1D692, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0069}, - {0x1D693, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006A}, - {0x1D694, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006B}, - {0x1D695, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006C}, - {0x1D696, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006D}, - {0x1D697, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006E}, - {0x1D698, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x006F}, - {0x1D699, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0070}, - {0x1D69A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0071}, - {0x1D69B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0072}, - {0x1D69C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0073}, - {0x1D69D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0074}, - {0x1D69E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0075}, - {0x1D69F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0076}, - {0x1D6A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0077}, - {0x1D6A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0078}, - {0x1D6A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0079}, - {0x1D6A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x007A}, - {0x1D6A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0131}, - {0x1D6A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0237}, - {0x1D6A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, - {0x1D6A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, - {0x1D6AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x1D6AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, - {0x1D6AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, - {0x1D6AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, - {0x1D6AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, - {0x1D6AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x1D6B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, - {0x1D6B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, - {0x1D6B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, - {0x1D6B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, - {0x1D6B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, - {0x1D6B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, - {0x1D6B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, - {0x1D6B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x1D6B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, - {0x1D6B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, - {0x1D6BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x1D6BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, - {0x1D6BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x1D6BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, - {0x1D6BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, - {0x1D6BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, - {0x1D6C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, - {0x1D6C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, - {0x1D6C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, - {0x1D6C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D6C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D6C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D6C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x1D6C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, - {0x1D6C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, - {0x1D6C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1D6CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, - {0x1D6CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x1D6CC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, - {0x1D6CD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x1D6CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, - {0x1D6CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, - {0x1D6D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, - {0x1D6D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x1D6D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D6D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x1D6D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, - {0x1D6D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, - {0x1D6D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, - {0x1D6D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D6D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D6D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, - {0x1D6DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, - {0x1D6DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, - {0x1D6DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, - {0x1D6DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, - {0x1D6DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, - {0x1D6DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, - {0x1D6E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, - {0x1D6E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, - {0x1D6E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, - {0x1D6E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, - {0x1D6E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x1D6E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, - {0x1D6E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, - {0x1D6E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, - {0x1D6E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, - {0x1D6E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x1D6EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, - {0x1D6EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, - {0x1D6EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, - {0x1D6ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, - {0x1D6EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, - {0x1D6EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, - {0x1D6F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, - {0x1D6F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x1D6F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, - {0x1D6F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, - {0x1D6F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x1D6F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, - {0x1D6F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x1D6F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, - {0x1D6F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, - {0x1D6F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, - {0x1D6FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, - {0x1D6FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, - {0x1D6FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, - {0x1D6FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D6FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D6FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D700, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x1D701, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, - {0x1D702, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, - {0x1D703, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1D704, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, - {0x1D705, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x1D706, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, - {0x1D707, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x1D708, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, - {0x1D709, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, - {0x1D70A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, - {0x1D70B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x1D70C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D70D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x1D70E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, - {0x1D70F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, - {0x1D710, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, - {0x1D711, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D712, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D713, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, - {0x1D714, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, - {0x1D715, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, - {0x1D716, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, - {0x1D717, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, - {0x1D718, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, - {0x1D719, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, - {0x1D71A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, - {0x1D71B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, - {0x1D71C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, - {0x1D71D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, - {0x1D71E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x1D71F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, - {0x1D720, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, - {0x1D721, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, - {0x1D722, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, - {0x1D723, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x1D724, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, - {0x1D725, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, - {0x1D726, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, - {0x1D727, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, - {0x1D728, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, - {0x1D729, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, - {0x1D72A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, - {0x1D72B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x1D72C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, - {0x1D72D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, - {0x1D72E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x1D72F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, - {0x1D730, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x1D731, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, - {0x1D732, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, - {0x1D733, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, - {0x1D734, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, - {0x1D735, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, - {0x1D736, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, - {0x1D737, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D738, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D739, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D73A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x1D73B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, - {0x1D73C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, - {0x1D73D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1D73E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, - {0x1D73F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x1D740, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, - {0x1D741, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x1D742, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, - {0x1D743, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, - {0x1D744, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, - {0x1D745, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x1D746, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D747, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x1D748, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, - {0x1D749, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, - {0x1D74A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, - {0x1D74B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D74C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D74D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, - {0x1D74E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, - {0x1D74F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, - {0x1D750, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, - {0x1D751, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, - {0x1D752, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, - {0x1D753, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, - {0x1D754, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, - {0x1D755, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, - {0x1D756, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, - {0x1D757, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, - {0x1D758, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x1D759, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, - {0x1D75A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, - {0x1D75B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, - {0x1D75C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, - {0x1D75D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x1D75E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, - {0x1D75F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, - {0x1D760, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, - {0x1D761, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, - {0x1D762, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, - {0x1D763, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, - {0x1D764, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, - {0x1D765, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x1D766, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, - {0x1D767, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, - {0x1D768, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x1D769, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, - {0x1D76A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x1D76B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, - {0x1D76C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, - {0x1D76D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, - {0x1D76E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, - {0x1D76F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, - {0x1D770, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, - {0x1D771, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D772, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D773, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D774, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x1D775, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, - {0x1D776, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, - {0x1D777, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1D778, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, - {0x1D779, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x1D77A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, - {0x1D77B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x1D77C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, - {0x1D77D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, - {0x1D77E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, - {0x1D77F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x1D780, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D781, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x1D782, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, - {0x1D783, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, - {0x1D784, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, - {0x1D785, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D786, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D787, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, - {0x1D788, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, - {0x1D789, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, - {0x1D78A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, - {0x1D78B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, - {0x1D78C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, - {0x1D78D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, - {0x1D78E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, - {0x1D78F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, - {0x1D790, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0391}, - {0x1D791, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0392}, - {0x1D792, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0393}, - {0x1D793, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0394}, - {0x1D794, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0395}, - {0x1D795, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0396}, - {0x1D796, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0397}, - {0x1D797, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0398}, - {0x1D798, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0399}, - {0x1D799, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039A}, - {0x1D79A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039B}, - {0x1D79B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039C}, - {0x1D79C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039D}, - {0x1D79D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039E}, - {0x1D79E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x039F}, - {0x1D79F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A0}, - {0x1D7A0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A1}, - {0x1D7A1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F4}, - {0x1D7A2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A3}, - {0x1D7A3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A4}, - {0x1D7A4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A5}, - {0x1D7A5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A6}, - {0x1D7A6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A7}, - {0x1D7A7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A8}, - {0x1D7A8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03A9}, - {0x1D7A9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2207}, - {0x1D7AA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B1}, - {0x1D7AB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B2}, - {0x1D7AC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B3}, - {0x1D7AD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B4}, - {0x1D7AE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B5}, - {0x1D7AF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B6}, - {0x1D7B0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B7}, - {0x1D7B1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B8}, - {0x1D7B2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03B9}, - {0x1D7B3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BA}, - {0x1D7B4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BB}, - {0x1D7B5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BC}, - {0x1D7B6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BD}, - {0x1D7B7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BE}, - {0x1D7B8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03BF}, - {0x1D7B9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C0}, - {0x1D7BA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C1}, - {0x1D7BB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C2}, - {0x1D7BC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C3}, - {0x1D7BD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C4}, - {0x1D7BE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C5}, - {0x1D7BF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C6}, - {0x1D7C0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C7}, - {0x1D7C1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C8}, - {0x1D7C2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03C9}, - {0x1D7C3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x2202}, - {0x1D7C4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F5}, - {0x1D7C5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D1}, - {0x1D7C6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F0}, - {0x1D7C7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D5}, - {0x1D7C8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03F1}, - {0x1D7C9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03D6}, - {0x1D7CA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03DC}, - {0x1D7CB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x03DD}, - {0x1D7CE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1D7CF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1D7D0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1D7D1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1D7D2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1D7D3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1D7D4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1D7D5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1D7D6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1D7D7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x1D7D8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1D7D9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1D7DA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1D7DB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1D7DC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1D7DD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1D7DE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1D7DF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1D7E0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1D7E1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x1D7E2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1D7E3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1D7E4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1D7E5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1D7E6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1D7E7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1D7E8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1D7E9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1D7EA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1D7EB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x1D7EC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1D7ED, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1D7EE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1D7EF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1D7F0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1D7F1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1D7F2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1D7F3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1D7F4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1D7F5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x1D7F6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1D7F7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1D7F8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1D7F9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1D7FA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1D7FB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1D7FC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1D7FD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1D7FE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1D7FF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x1E000, 230, 0, 0}, - {0x1E001, 230, 0, 0}, - {0x1E002, 230, 0, 0}, - {0x1E003, 230, 0, 0}, - {0x1E004, 230, 0, 0}, - {0x1E005, 230, 0, 0}, - {0x1E006, 230, 0, 0}, - {0x1E008, 230, 0, 0}, - {0x1E009, 230, 0, 0}, - {0x1E00A, 230, 0, 0}, - {0x1E00B, 230, 0, 0}, - {0x1E00C, 230, 0, 0}, - {0x1E00D, 230, 0, 0}, - {0x1E00E, 230, 0, 0}, - {0x1E00F, 230, 0, 0}, - {0x1E010, 230, 0, 0}, - {0x1E011, 230, 0, 0}, - {0x1E012, 230, 0, 0}, - {0x1E013, 230, 0, 0}, - {0x1E014, 230, 0, 0}, - {0x1E015, 230, 0, 0}, - {0x1E016, 230, 0, 0}, - {0x1E017, 230, 0, 0}, - {0x1E018, 230, 0, 0}, - {0x1E01B, 230, 0, 0}, - {0x1E01C, 230, 0, 0}, - {0x1E01D, 230, 0, 0}, - {0x1E01E, 230, 0, 0}, - {0x1E01F, 230, 0, 0}, - {0x1E020, 230, 0, 0}, - {0x1E021, 230, 0, 0}, - {0x1E023, 230, 0, 0}, - {0x1E024, 230, 0, 0}, - {0x1E026, 230, 0, 0}, - {0x1E027, 230, 0, 0}, - {0x1E028, 230, 0, 0}, - {0x1E029, 230, 0, 0}, - {0x1E02A, 230, 0, 0}, - {0x1E030, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0430}, - {0x1E031, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0431}, - {0x1E032, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0432}, - {0x1E033, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0433}, - {0x1E034, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0434}, - {0x1E035, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0435}, - {0x1E036, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0436}, - {0x1E037, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0437}, - {0x1E038, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0438}, - {0x1E039, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043A}, - {0x1E03A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043B}, - {0x1E03B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043C}, - {0x1E03C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043E}, - {0x1E03D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043F}, - {0x1E03E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0440}, - {0x1E03F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0441}, - {0x1E040, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0442}, - {0x1E041, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0443}, - {0x1E042, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0444}, - {0x1E043, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0445}, - {0x1E044, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0446}, - {0x1E045, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0447}, - {0x1E046, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0448}, - {0x1E047, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044B}, - {0x1E048, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044D}, - {0x1E049, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044E}, - {0x1E04A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA689}, - {0x1E04B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04D9}, - {0x1E04C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0456}, - {0x1E04D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0458}, - {0x1E04E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04E9}, - {0x1E04F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04AF}, - {0x1E050, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04CF}, - {0x1E051, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0430}, - {0x1E052, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0431}, - {0x1E053, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0432}, - {0x1E054, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0433}, - {0x1E055, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0434}, - {0x1E056, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0435}, - {0x1E057, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0436}, - {0x1E058, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0437}, - {0x1E059, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0438}, - {0x1E05A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043A}, - {0x1E05B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043B}, - {0x1E05C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043E}, - {0x1E05D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x043F}, - {0x1E05E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0441}, - {0x1E05F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0443}, - {0x1E060, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0444}, - {0x1E061, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0445}, - {0x1E062, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0446}, - {0x1E063, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0447}, - {0x1E064, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0448}, - {0x1E065, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044A}, - {0x1E066, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x044B}, - {0x1E067, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0491}, - {0x1E068, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0456}, - {0x1E069, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0455}, - {0x1E06A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x045F}, - {0x1E06B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04AB}, - {0x1E06C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0xA651}, - {0x1E06D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x04B1}, - {0x1E08F, 230, 0, 0}, - {0x1E130, 230, 0, 0}, - {0x1E131, 230, 0, 0}, - {0x1E132, 230, 0, 0}, - {0x1E133, 230, 0, 0}, - {0x1E134, 230, 0, 0}, - {0x1E135, 230, 0, 0}, - {0x1E136, 230, 0, 0}, - {0x1E2AE, 230, 0, 0}, - {0x1E2EC, 230, 0, 0}, - {0x1E2ED, 230, 0, 0}, - {0x1E2EE, 230, 0, 0}, - {0x1E2EF, 230, 0, 0}, - {0x1E4EC, 232, 0, 0}, - {0x1E4ED, 232, 0, 0}, - {0x1E4EE, 220, 0, 0}, - {0x1E4EF, 230, 0, 0}, - {0x1E8D0, 220, 0, 0}, - {0x1E8D1, 220, 0, 0}, - {0x1E8D2, 220, 0, 0}, - {0x1E8D3, 220, 0, 0}, - {0x1E8D4, 220, 0, 0}, - {0x1E8D5, 220, 0, 0}, - {0x1E8D6, 220, 0, 0}, - {0x1E944, 230, 0, 0}, - {0x1E945, 230, 0, 0}, - {0x1E946, 230, 0, 0}, - {0x1E947, 230, 0, 0}, - {0x1E948, 230, 0, 0}, - {0x1E949, 230, 0, 0}, - {0x1E94A, 7, 0, 0}, - {0x1EE00, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, - {0x1EE01, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0x1EE02, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EE03, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, - {0x1EE05, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, - {0x1EE06, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, - {0x1EE07, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EE08, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0x1EE09, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EE0A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0x1EE0B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0x1EE0C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0x1EE0D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EE0E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EE0F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EE10, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0x1EE11, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EE12, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EE13, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, - {0x1EE14, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EE15, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0x1EE16, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0x1EE17, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EE18, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, - {0x1EE19, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EE1A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0x1EE1B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1EE1C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066E}, - {0x1EE1D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, - {0x1EE1E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A1}, - {0x1EE1F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066F}, - {0x1EE21, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0x1EE22, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EE24, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0x1EE27, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EE29, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EE2A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0x1EE2B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0x1EE2C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0x1EE2D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EE2E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EE2F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EE30, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0x1EE31, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EE32, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EE34, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EE35, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0x1EE36, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0x1EE37, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EE39, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EE3B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1EE42, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EE47, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EE49, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EE4B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0x1EE4D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EE4E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EE4F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EE51, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EE52, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EE54, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EE57, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EE59, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EE5B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1EE5D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06BA}, - {0x1EE5F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066F}, - {0x1EE61, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0x1EE62, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EE64, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0x1EE67, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EE68, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0x1EE69, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EE6A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0643}, - {0x1EE6C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0x1EE6D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EE6E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EE6F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EE70, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0x1EE71, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EE72, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EE74, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EE75, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0x1EE76, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0x1EE77, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EE79, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EE7A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0x1EE7B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1EE7C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x066E}, - {0x1EE7E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x06A1}, - {0x1EE80, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0627}, - {0x1EE81, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0x1EE82, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EE83, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, - {0x1EE84, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0647}, - {0x1EE85, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, - {0x1EE86, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, - {0x1EE87, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EE88, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0x1EE89, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EE8B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0x1EE8C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0x1EE8D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EE8E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EE8F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EE90, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0x1EE91, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EE92, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EE93, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, - {0x1EE94, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EE95, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0x1EE96, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0x1EE97, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EE98, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, - {0x1EE99, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EE9A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0x1EE9B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1EEA1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0628}, - {0x1EEA2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062C}, - {0x1EEA3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062F}, - {0x1EEA5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0648}, - {0x1EEA6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0632}, - {0x1EEA7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062D}, - {0x1EEA8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0637}, - {0x1EEA9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x064A}, - {0x1EEAB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0644}, - {0x1EEAC, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0645}, - {0x1EEAD, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0646}, - {0x1EEAE, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0633}, - {0x1EEAF, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0639}, - {0x1EEB0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0641}, - {0x1EEB1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0635}, - {0x1EEB2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0642}, - {0x1EEB3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0631}, - {0x1EEB4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0634}, - {0x1EEB5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062A}, - {0x1EEB6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062B}, - {0x1EEB7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x062E}, - {0x1EEB8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0630}, - {0x1EEB9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0636}, - {0x1EEBA, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0638}, - {0x1EEBB, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x063A}, - {0x1F100, 0, 2 | DECOMP_COMPAT, 4834}, - {0x1F101, 0, 2 | DECOMP_COMPAT, 4836}, - {0x1F102, 0, 2 | DECOMP_COMPAT, 4838}, - {0x1F103, 0, 2 | DECOMP_COMPAT, 4840}, - {0x1F104, 0, 2 | DECOMP_COMPAT, 4842}, - {0x1F105, 0, 2 | DECOMP_COMPAT, 4844}, - {0x1F106, 0, 2 | DECOMP_COMPAT, 4846}, - {0x1F107, 0, 2 | DECOMP_COMPAT, 4848}, - {0x1F108, 0, 2 | DECOMP_COMPAT, 4850}, - {0x1F109, 0, 2 | DECOMP_COMPAT, 4852}, - {0x1F10A, 0, 2 | DECOMP_COMPAT, 4854}, - {0x1F110, 0, 3 | DECOMP_COMPAT, 4856}, - {0x1F111, 0, 3 | DECOMP_COMPAT, 4859}, - {0x1F112, 0, 3 | DECOMP_COMPAT, 4862}, - {0x1F113, 0, 3 | DECOMP_COMPAT, 4865}, - {0x1F114, 0, 3 | DECOMP_COMPAT, 4868}, - {0x1F115, 0, 3 | DECOMP_COMPAT, 4871}, - {0x1F116, 0, 3 | DECOMP_COMPAT, 4874}, - {0x1F117, 0, 3 | DECOMP_COMPAT, 4877}, - {0x1F118, 0, 3 | DECOMP_COMPAT, 4880}, - {0x1F119, 0, 3 | DECOMP_COMPAT, 4883}, - {0x1F11A, 0, 3 | DECOMP_COMPAT, 4886}, - {0x1F11B, 0, 3 | DECOMP_COMPAT, 4889}, - {0x1F11C, 0, 3 | DECOMP_COMPAT, 4892}, - {0x1F11D, 0, 3 | DECOMP_COMPAT, 4895}, - {0x1F11E, 0, 3 | DECOMP_COMPAT, 4898}, - {0x1F11F, 0, 3 | DECOMP_COMPAT, 4901}, - {0x1F120, 0, 3 | DECOMP_COMPAT, 4904}, - {0x1F121, 0, 3 | DECOMP_COMPAT, 4907}, - {0x1F122, 0, 3 | DECOMP_COMPAT, 4910}, - {0x1F123, 0, 3 | DECOMP_COMPAT, 4913}, - {0x1F124, 0, 3 | DECOMP_COMPAT, 4916}, - {0x1F125, 0, 3 | DECOMP_COMPAT, 4919}, - {0x1F126, 0, 3 | DECOMP_COMPAT, 4922}, - {0x1F127, 0, 3 | DECOMP_COMPAT, 4925}, - {0x1F128, 0, 3 | DECOMP_COMPAT, 4928}, - {0x1F129, 0, 3 | DECOMP_COMPAT, 4931}, - {0x1F12A, 0, 3 | DECOMP_COMPAT, 4934}, - {0x1F12B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1F12C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1F12D, 0, 2 | DECOMP_COMPAT, 4937}, - {0x1F12E, 0, 2 | DECOMP_COMPAT, 4939}, - {0x1F130, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0041}, - {0x1F131, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0042}, - {0x1F132, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0043}, - {0x1F133, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0044}, - {0x1F134, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0045}, - {0x1F135, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0046}, - {0x1F136, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0047}, - {0x1F137, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0048}, - {0x1F138, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0049}, - {0x1F139, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004A}, - {0x1F13A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004B}, - {0x1F13B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004C}, - {0x1F13C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004D}, - {0x1F13D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004E}, - {0x1F13E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x004F}, - {0x1F13F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0050}, - {0x1F140, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0051}, - {0x1F141, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0052}, - {0x1F142, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0053}, - {0x1F143, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0054}, - {0x1F144, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0055}, - {0x1F145, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0056}, - {0x1F146, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0057}, - {0x1F147, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0058}, - {0x1F148, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0059}, - {0x1F149, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x005A}, - {0x1F14A, 0, 2 | DECOMP_COMPAT, 4941}, - {0x1F14B, 0, 2 | DECOMP_COMPAT, 4943}, - {0x1F14C, 0, 2 | DECOMP_COMPAT, 4945}, - {0x1F14D, 0, 2 | DECOMP_COMPAT, 4947}, - {0x1F14E, 0, 3 | DECOMP_COMPAT, 4949}, - {0x1F14F, 0, 2 | DECOMP_COMPAT, 4952}, - {0x1F16A, 0, 2 | DECOMP_COMPAT, 4954}, - {0x1F16B, 0, 2 | DECOMP_COMPAT, 4956}, - {0x1F16C, 0, 2 | DECOMP_COMPAT, 4958}, - {0x1F190, 0, 2 | DECOMP_COMPAT, 4960}, - {0x1F200, 0, 2 | DECOMP_COMPAT, 4962}, - {0x1F201, 0, 2 | DECOMP_COMPAT, 4964}, - {0x1F202, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30B5}, - {0x1F210, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x624B}, - {0x1F211, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5B57}, - {0x1F212, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53CC}, - {0x1F213, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x30C7}, - {0x1F214, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E8C}, - {0x1F215, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x591A}, - {0x1F216, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x89E3}, - {0x1F217, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5929}, - {0x1F218, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4EA4}, - {0x1F219, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6620}, - {0x1F21A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7121}, - {0x1F21B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6599}, - {0x1F21C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x524D}, - {0x1F21D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F8C}, - {0x1F21E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x518D}, - {0x1F21F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x65B0}, - {0x1F220, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x521D}, - {0x1F221, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7D42}, - {0x1F222, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x751F}, - {0x1F223, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8CA9}, - {0x1F224, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x58F0}, - {0x1F225, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5439}, - {0x1F226, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6F14}, - {0x1F227, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6295}, - {0x1F228, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6355}, - {0x1F229, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E00}, - {0x1F22A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E09}, - {0x1F22B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x904A}, - {0x1F22C, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5DE6}, - {0x1F22D, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x4E2D}, - {0x1F22E, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53F3}, - {0x1F22F, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6307}, - {0x1F230, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x8D70}, - {0x1F231, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6253}, - {0x1F232, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7981}, - {0x1F233, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7A7A}, - {0x1F234, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5408}, - {0x1F235, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6E80}, - {0x1F236, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6709}, - {0x1F237, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x6708}, - {0x1F238, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x7533}, - {0x1F239, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5272}, - {0x1F23A, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x55B6}, - {0x1F23B, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x914D}, - {0x1F240, 0, 3 | DECOMP_COMPAT, 4966}, - {0x1F241, 0, 3 | DECOMP_COMPAT, 4969}, - {0x1F242, 0, 3 | DECOMP_COMPAT, 4972}, - {0x1F243, 0, 3 | DECOMP_COMPAT, 4975}, - {0x1F244, 0, 3 | DECOMP_COMPAT, 4978}, - {0x1F245, 0, 3 | DECOMP_COMPAT, 4981}, - {0x1F246, 0, 3 | DECOMP_COMPAT, 4984}, - {0x1F247, 0, 3 | DECOMP_COMPAT, 4987}, - {0x1F248, 0, 3 | DECOMP_COMPAT, 4990}, - {0x1F250, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x5F97}, - {0x1F251, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x53EF}, - {0x1FBF0, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0030}, - {0x1FBF1, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0031}, - {0x1FBF2, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0032}, - {0x1FBF3, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0033}, - {0x1FBF4, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0034}, - {0x1FBF5, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0035}, - {0x1FBF6, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0036}, - {0x1FBF7, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0037}, - {0x1FBF8, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0038}, - {0x1FBF9, 0, 1 | DECOMP_COMPAT | DECOMP_INLINE, 0x0039}, - {0x2F800, 0, 1 | DECOMP_INLINE, 0x4E3D}, - {0x2F801, 0, 1 | DECOMP_INLINE, 0x4E38}, - {0x2F802, 0, 1 | DECOMP_INLINE, 0x4E41}, - {0x2F803, 0, 1, 4993}, - {0x2F804, 0, 1 | DECOMP_INLINE, 0x4F60}, - {0x2F805, 0, 1 | DECOMP_INLINE, 0x4FAE}, - {0x2F806, 0, 1 | DECOMP_INLINE, 0x4FBB}, - {0x2F807, 0, 1 | DECOMP_INLINE, 0x5002}, - {0x2F808, 0, 1 | DECOMP_INLINE, 0x507A}, - {0x2F809, 0, 1 | DECOMP_INLINE, 0x5099}, - {0x2F80A, 0, 1 | DECOMP_INLINE, 0x50E7}, - {0x2F80B, 0, 1 | DECOMP_INLINE, 0x50CF}, - {0x2F80C, 0, 1 | DECOMP_INLINE, 0x349E}, - {0x2F80D, 0, 1, 4994}, - {0x2F80E, 0, 1 | DECOMP_INLINE, 0x514D}, - {0x2F80F, 0, 1 | DECOMP_INLINE, 0x5154}, - {0x2F810, 0, 1 | DECOMP_INLINE, 0x5164}, - {0x2F811, 0, 1 | DECOMP_INLINE, 0x5177}, - {0x2F812, 0, 1, 4995}, - {0x2F813, 0, 1 | DECOMP_INLINE, 0x34B9}, - {0x2F814, 0, 1 | DECOMP_INLINE, 0x5167}, - {0x2F815, 0, 1 | DECOMP_INLINE, 0x518D}, - {0x2F816, 0, 1, 4996}, - {0x2F817, 0, 1 | DECOMP_INLINE, 0x5197}, - {0x2F818, 0, 1 | DECOMP_INLINE, 0x51A4}, - {0x2F819, 0, 1 | DECOMP_INLINE, 0x4ECC}, - {0x2F81A, 0, 1 | DECOMP_INLINE, 0x51AC}, - {0x2F81B, 0, 1 | DECOMP_INLINE, 0x51B5}, - {0x2F81C, 0, 1, 4997}, - {0x2F81D, 0, 1 | DECOMP_INLINE, 0x51F5}, - {0x2F81E, 0, 1 | DECOMP_INLINE, 0x5203}, - {0x2F81F, 0, 1 | DECOMP_INLINE, 0x34DF}, - {0x2F820, 0, 1 | DECOMP_INLINE, 0x523B}, - {0x2F821, 0, 1 | DECOMP_INLINE, 0x5246}, - {0x2F822, 0, 1 | DECOMP_INLINE, 0x5272}, - {0x2F823, 0, 1 | DECOMP_INLINE, 0x5277}, - {0x2F824, 0, 1 | DECOMP_INLINE, 0x3515}, - {0x2F825, 0, 1 | DECOMP_INLINE, 0x52C7}, - {0x2F826, 0, 1 | DECOMP_INLINE, 0x52C9}, - {0x2F827, 0, 1 | DECOMP_INLINE, 0x52E4}, - {0x2F828, 0, 1 | DECOMP_INLINE, 0x52FA}, - {0x2F829, 0, 1 | DECOMP_INLINE, 0x5305}, - {0x2F82A, 0, 1 | DECOMP_INLINE, 0x5306}, - {0x2F82B, 0, 1 | DECOMP_INLINE, 0x5317}, - {0x2F82C, 0, 1 | DECOMP_INLINE, 0x5349}, - {0x2F82D, 0, 1 | DECOMP_INLINE, 0x5351}, - {0x2F82E, 0, 1 | DECOMP_INLINE, 0x535A}, - {0x2F82F, 0, 1 | DECOMP_INLINE, 0x5373}, - {0x2F830, 0, 1 | DECOMP_INLINE, 0x537D}, - {0x2F831, 0, 1 | DECOMP_INLINE, 0x537F}, - {0x2F832, 0, 1 | DECOMP_INLINE, 0x537F}, - {0x2F833, 0, 1 | DECOMP_INLINE, 0x537F}, - {0x2F834, 0, 1, 4998}, - {0x2F835, 0, 1 | DECOMP_INLINE, 0x7070}, - {0x2F836, 0, 1 | DECOMP_INLINE, 0x53CA}, - {0x2F837, 0, 1 | DECOMP_INLINE, 0x53DF}, - {0x2F838, 0, 1, 4999}, - {0x2F839, 0, 1 | DECOMP_INLINE, 0x53EB}, - {0x2F83A, 0, 1 | DECOMP_INLINE, 0x53F1}, - {0x2F83B, 0, 1 | DECOMP_INLINE, 0x5406}, - {0x2F83C, 0, 1 | DECOMP_INLINE, 0x549E}, - {0x2F83D, 0, 1 | DECOMP_INLINE, 0x5438}, - {0x2F83E, 0, 1 | DECOMP_INLINE, 0x5448}, - {0x2F83F, 0, 1 | DECOMP_INLINE, 0x5468}, - {0x2F840, 0, 1 | DECOMP_INLINE, 0x54A2}, - {0x2F841, 0, 1 | DECOMP_INLINE, 0x54F6}, - {0x2F842, 0, 1 | DECOMP_INLINE, 0x5510}, - {0x2F843, 0, 1 | DECOMP_INLINE, 0x5553}, - {0x2F844, 0, 1 | DECOMP_INLINE, 0x5563}, - {0x2F845, 0, 1 | DECOMP_INLINE, 0x5584}, - {0x2F846, 0, 1 | DECOMP_INLINE, 0x5584}, - {0x2F847, 0, 1 | DECOMP_INLINE, 0x5599}, - {0x2F848, 0, 1 | DECOMP_INLINE, 0x55AB}, - {0x2F849, 0, 1 | DECOMP_INLINE, 0x55B3}, - {0x2F84A, 0, 1 | DECOMP_INLINE, 0x55C2}, - {0x2F84B, 0, 1 | DECOMP_INLINE, 0x5716}, - {0x2F84C, 0, 1 | DECOMP_INLINE, 0x5606}, - {0x2F84D, 0, 1 | DECOMP_INLINE, 0x5717}, - {0x2F84E, 0, 1 | DECOMP_INLINE, 0x5651}, - {0x2F84F, 0, 1 | DECOMP_INLINE, 0x5674}, - {0x2F850, 0, 1 | DECOMP_INLINE, 0x5207}, - {0x2F851, 0, 1 | DECOMP_INLINE, 0x58EE}, - {0x2F852, 0, 1 | DECOMP_INLINE, 0x57CE}, - {0x2F853, 0, 1 | DECOMP_INLINE, 0x57F4}, - {0x2F854, 0, 1 | DECOMP_INLINE, 0x580D}, - {0x2F855, 0, 1 | DECOMP_INLINE, 0x578B}, - {0x2F856, 0, 1 | DECOMP_INLINE, 0x5832}, - {0x2F857, 0, 1 | DECOMP_INLINE, 0x5831}, - {0x2F858, 0, 1 | DECOMP_INLINE, 0x58AC}, - {0x2F859, 0, 1, 5000}, - {0x2F85A, 0, 1 | DECOMP_INLINE, 0x58F2}, - {0x2F85B, 0, 1 | DECOMP_INLINE, 0x58F7}, - {0x2F85C, 0, 1 | DECOMP_INLINE, 0x5906}, - {0x2F85D, 0, 1 | DECOMP_INLINE, 0x591A}, - {0x2F85E, 0, 1 | DECOMP_INLINE, 0x5922}, - {0x2F85F, 0, 1 | DECOMP_INLINE, 0x5962}, - {0x2F860, 0, 1, 5001}, - {0x2F861, 0, 1, 5002}, - {0x2F862, 0, 1 | DECOMP_INLINE, 0x59EC}, - {0x2F863, 0, 1 | DECOMP_INLINE, 0x5A1B}, - {0x2F864, 0, 1 | DECOMP_INLINE, 0x5A27}, - {0x2F865, 0, 1 | DECOMP_INLINE, 0x59D8}, - {0x2F866, 0, 1 | DECOMP_INLINE, 0x5A66}, - {0x2F867, 0, 1 | DECOMP_INLINE, 0x36EE}, - {0x2F868, 0, 1 | DECOMP_INLINE, 0x36FC}, - {0x2F869, 0, 1 | DECOMP_INLINE, 0x5B08}, - {0x2F86A, 0, 1 | DECOMP_INLINE, 0x5B3E}, - {0x2F86B, 0, 1 | DECOMP_INLINE, 0x5B3E}, - {0x2F86C, 0, 1, 5003}, - {0x2F86D, 0, 1 | DECOMP_INLINE, 0x5BC3}, - {0x2F86E, 0, 1 | DECOMP_INLINE, 0x5BD8}, - {0x2F86F, 0, 1 | DECOMP_INLINE, 0x5BE7}, - {0x2F870, 0, 1 | DECOMP_INLINE, 0x5BF3}, - {0x2F871, 0, 1, 5004}, - {0x2F872, 0, 1 | DECOMP_INLINE, 0x5BFF}, - {0x2F873, 0, 1 | DECOMP_INLINE, 0x5C06}, - {0x2F874, 0, 1 | DECOMP_INLINE, 0x5F53}, - {0x2F875, 0, 1 | DECOMP_INLINE, 0x5C22}, - {0x2F876, 0, 1 | DECOMP_INLINE, 0x3781}, - {0x2F877, 0, 1 | DECOMP_INLINE, 0x5C60}, - {0x2F878, 0, 1 | DECOMP_INLINE, 0x5C6E}, - {0x2F879, 0, 1 | DECOMP_INLINE, 0x5CC0}, - {0x2F87A, 0, 1 | DECOMP_INLINE, 0x5C8D}, - {0x2F87B, 0, 1, 5005}, - {0x2F87C, 0, 1 | DECOMP_INLINE, 0x5D43}, - {0x2F87D, 0, 1, 5006}, - {0x2F87E, 0, 1 | DECOMP_INLINE, 0x5D6E}, - {0x2F87F, 0, 1 | DECOMP_INLINE, 0x5D6B}, - {0x2F880, 0, 1 | DECOMP_INLINE, 0x5D7C}, - {0x2F881, 0, 1 | DECOMP_INLINE, 0x5DE1}, - {0x2F882, 0, 1 | DECOMP_INLINE, 0x5DE2}, - {0x2F883, 0, 1 | DECOMP_INLINE, 0x382F}, - {0x2F884, 0, 1 | DECOMP_INLINE, 0x5DFD}, - {0x2F885, 0, 1 | DECOMP_INLINE, 0x5E28}, - {0x2F886, 0, 1 | DECOMP_INLINE, 0x5E3D}, - {0x2F887, 0, 1 | DECOMP_INLINE, 0x5E69}, - {0x2F888, 0, 1 | DECOMP_INLINE, 0x3862}, - {0x2F889, 0, 1, 5007}, - {0x2F88A, 0, 1 | DECOMP_INLINE, 0x387C}, - {0x2F88B, 0, 1 | DECOMP_INLINE, 0x5EB0}, - {0x2F88C, 0, 1 | DECOMP_INLINE, 0x5EB3}, - {0x2F88D, 0, 1 | DECOMP_INLINE, 0x5EB6}, - {0x2F88E, 0, 1 | DECOMP_INLINE, 0x5ECA}, - {0x2F88F, 0, 1, 5008}, - {0x2F890, 0, 1 | DECOMP_INLINE, 0x5EFE}, - {0x2F891, 0, 1, 5009}, - {0x2F892, 0, 1, 5010}, - {0x2F893, 0, 1 | DECOMP_INLINE, 0x8201}, - {0x2F894, 0, 1 | DECOMP_INLINE, 0x5F22}, - {0x2F895, 0, 1 | DECOMP_INLINE, 0x5F22}, - {0x2F896, 0, 1 | DECOMP_INLINE, 0x38C7}, - {0x2F897, 0, 1, 5011}, - {0x2F898, 0, 1, 5012}, - {0x2F899, 0, 1 | DECOMP_INLINE, 0x5F62}, - {0x2F89A, 0, 1 | DECOMP_INLINE, 0x5F6B}, - {0x2F89B, 0, 1 | DECOMP_INLINE, 0x38E3}, - {0x2F89C, 0, 1 | DECOMP_INLINE, 0x5F9A}, - {0x2F89D, 0, 1 | DECOMP_INLINE, 0x5FCD}, - {0x2F89E, 0, 1 | DECOMP_INLINE, 0x5FD7}, - {0x2F89F, 0, 1 | DECOMP_INLINE, 0x5FF9}, - {0x2F8A0, 0, 1 | DECOMP_INLINE, 0x6081}, - {0x2F8A1, 0, 1 | DECOMP_INLINE, 0x393A}, - {0x2F8A2, 0, 1 | DECOMP_INLINE, 0x391C}, - {0x2F8A3, 0, 1 | DECOMP_INLINE, 0x6094}, - {0x2F8A4, 0, 1, 5013}, - {0x2F8A5, 0, 1 | DECOMP_INLINE, 0x60C7}, - {0x2F8A6, 0, 1 | DECOMP_INLINE, 0x6148}, - {0x2F8A7, 0, 1 | DECOMP_INLINE, 0x614C}, - {0x2F8A8, 0, 1 | DECOMP_INLINE, 0x614E}, - {0x2F8A9, 0, 1 | DECOMP_INLINE, 0x614C}, - {0x2F8AA, 0, 1 | DECOMP_INLINE, 0x617A}, - {0x2F8AB, 0, 1 | DECOMP_INLINE, 0x618E}, - {0x2F8AC, 0, 1 | DECOMP_INLINE, 0x61B2}, - {0x2F8AD, 0, 1 | DECOMP_INLINE, 0x61A4}, - {0x2F8AE, 0, 1 | DECOMP_INLINE, 0x61AF}, - {0x2F8AF, 0, 1 | DECOMP_INLINE, 0x61DE}, - {0x2F8B0, 0, 1 | DECOMP_INLINE, 0x61F2}, - {0x2F8B1, 0, 1 | DECOMP_INLINE, 0x61F6}, - {0x2F8B2, 0, 1 | DECOMP_INLINE, 0x6210}, - {0x2F8B3, 0, 1 | DECOMP_INLINE, 0x621B}, - {0x2F8B4, 0, 1 | DECOMP_INLINE, 0x625D}, - {0x2F8B5, 0, 1 | DECOMP_INLINE, 0x62B1}, - {0x2F8B6, 0, 1 | DECOMP_INLINE, 0x62D4}, - {0x2F8B7, 0, 1 | DECOMP_INLINE, 0x6350}, - {0x2F8B8, 0, 1, 5014}, - {0x2F8B9, 0, 1 | DECOMP_INLINE, 0x633D}, - {0x2F8BA, 0, 1 | DECOMP_INLINE, 0x62FC}, - {0x2F8BB, 0, 1 | DECOMP_INLINE, 0x6368}, - {0x2F8BC, 0, 1 | DECOMP_INLINE, 0x6383}, - {0x2F8BD, 0, 1 | DECOMP_INLINE, 0x63E4}, - {0x2F8BE, 0, 1, 5015}, - {0x2F8BF, 0, 1 | DECOMP_INLINE, 0x6422}, - {0x2F8C0, 0, 1 | DECOMP_INLINE, 0x63C5}, - {0x2F8C1, 0, 1 | DECOMP_INLINE, 0x63A9}, - {0x2F8C2, 0, 1 | DECOMP_INLINE, 0x3A2E}, - {0x2F8C3, 0, 1 | DECOMP_INLINE, 0x6469}, - {0x2F8C4, 0, 1 | DECOMP_INLINE, 0x647E}, - {0x2F8C5, 0, 1 | DECOMP_INLINE, 0x649D}, - {0x2F8C6, 0, 1 | DECOMP_INLINE, 0x6477}, - {0x2F8C7, 0, 1 | DECOMP_INLINE, 0x3A6C}, - {0x2F8C8, 0, 1 | DECOMP_INLINE, 0x654F}, - {0x2F8C9, 0, 1 | DECOMP_INLINE, 0x656C}, - {0x2F8CA, 0, 1, 5016}, - {0x2F8CB, 0, 1 | DECOMP_INLINE, 0x65E3}, - {0x2F8CC, 0, 1 | DECOMP_INLINE, 0x66F8}, - {0x2F8CD, 0, 1 | DECOMP_INLINE, 0x6649}, - {0x2F8CE, 0, 1 | DECOMP_INLINE, 0x3B19}, - {0x2F8CF, 0, 1 | DECOMP_INLINE, 0x6691}, - {0x2F8D0, 0, 1 | DECOMP_INLINE, 0x3B08}, - {0x2F8D1, 0, 1 | DECOMP_INLINE, 0x3AE4}, - {0x2F8D2, 0, 1 | DECOMP_INLINE, 0x5192}, - {0x2F8D3, 0, 1 | DECOMP_INLINE, 0x5195}, - {0x2F8D4, 0, 1 | DECOMP_INLINE, 0x6700}, - {0x2F8D5, 0, 1 | DECOMP_INLINE, 0x669C}, - {0x2F8D6, 0, 1 | DECOMP_INLINE, 0x80AD}, - {0x2F8D7, 0, 1 | DECOMP_INLINE, 0x43D9}, - {0x2F8D8, 0, 1 | DECOMP_INLINE, 0x6717}, - {0x2F8D9, 0, 1 | DECOMP_INLINE, 0x671B}, - {0x2F8DA, 0, 1 | DECOMP_INLINE, 0x6721}, - {0x2F8DB, 0, 1 | DECOMP_INLINE, 0x675E}, - {0x2F8DC, 0, 1 | DECOMP_INLINE, 0x6753}, - {0x2F8DD, 0, 1, 5017}, - {0x2F8DE, 0, 1 | DECOMP_INLINE, 0x3B49}, - {0x2F8DF, 0, 1 | DECOMP_INLINE, 0x67FA}, - {0x2F8E0, 0, 1 | DECOMP_INLINE, 0x6785}, - {0x2F8E1, 0, 1 | DECOMP_INLINE, 0x6852}, - {0x2F8E2, 0, 1 | DECOMP_INLINE, 0x6885}, - {0x2F8E3, 0, 1, 5018}, - {0x2F8E4, 0, 1 | DECOMP_INLINE, 0x688E}, - {0x2F8E5, 0, 1 | DECOMP_INLINE, 0x681F}, - {0x2F8E6, 0, 1 | DECOMP_INLINE, 0x6914}, - {0x2F8E7, 0, 1 | DECOMP_INLINE, 0x3B9D}, - {0x2F8E8, 0, 1 | DECOMP_INLINE, 0x6942}, - {0x2F8E9, 0, 1 | DECOMP_INLINE, 0x69A3}, - {0x2F8EA, 0, 1 | DECOMP_INLINE, 0x69EA}, - {0x2F8EB, 0, 1 | DECOMP_INLINE, 0x6AA8}, - {0x2F8EC, 0, 1, 5019}, - {0x2F8ED, 0, 1 | DECOMP_INLINE, 0x6ADB}, - {0x2F8EE, 0, 1 | DECOMP_INLINE, 0x3C18}, - {0x2F8EF, 0, 1 | DECOMP_INLINE, 0x6B21}, - {0x2F8F0, 0, 1, 5020}, - {0x2F8F1, 0, 1 | DECOMP_INLINE, 0x6B54}, - {0x2F8F2, 0, 1 | DECOMP_INLINE, 0x3C4E}, - {0x2F8F3, 0, 1 | DECOMP_INLINE, 0x6B72}, - {0x2F8F4, 0, 1 | DECOMP_INLINE, 0x6B9F}, - {0x2F8F5, 0, 1 | DECOMP_INLINE, 0x6BBA}, - {0x2F8F6, 0, 1 | DECOMP_INLINE, 0x6BBB}, - {0x2F8F7, 0, 1, 5021}, - {0x2F8F8, 0, 1, 5022}, - {0x2F8F9, 0, 1, 5023}, - {0x2F8FA, 0, 1 | DECOMP_INLINE, 0x6C4E}, - {0x2F8FB, 0, 1, 5024}, - {0x2F8FC, 0, 1 | DECOMP_INLINE, 0x6CBF}, - {0x2F8FD, 0, 1 | DECOMP_INLINE, 0x6CCD}, - {0x2F8FE, 0, 1 | DECOMP_INLINE, 0x6C67}, - {0x2F8FF, 0, 1 | DECOMP_INLINE, 0x6D16}, - {0x2F900, 0, 1 | DECOMP_INLINE, 0x6D3E}, - {0x2F901, 0, 1 | DECOMP_INLINE, 0x6D77}, - {0x2F902, 0, 1 | DECOMP_INLINE, 0x6D41}, - {0x2F903, 0, 1 | DECOMP_INLINE, 0x6D69}, - {0x2F904, 0, 1 | DECOMP_INLINE, 0x6D78}, - {0x2F905, 0, 1 | DECOMP_INLINE, 0x6D85}, - {0x2F906, 0, 1, 5025}, - {0x2F907, 0, 1 | DECOMP_INLINE, 0x6D34}, - {0x2F908, 0, 1 | DECOMP_INLINE, 0x6E2F}, - {0x2F909, 0, 1 | DECOMP_INLINE, 0x6E6E}, - {0x2F90A, 0, 1 | DECOMP_INLINE, 0x3D33}, - {0x2F90B, 0, 1 | DECOMP_INLINE, 0x6ECB}, - {0x2F90C, 0, 1 | DECOMP_INLINE, 0x6EC7}, - {0x2F90D, 0, 1, 5026}, - {0x2F90E, 0, 1 | DECOMP_INLINE, 0x6DF9}, - {0x2F90F, 0, 1 | DECOMP_INLINE, 0x6F6E}, - {0x2F910, 0, 1, 5027}, - {0x2F911, 0, 1, 5028}, - {0x2F912, 0, 1 | DECOMP_INLINE, 0x6FC6}, - {0x2F913, 0, 1 | DECOMP_INLINE, 0x7039}, - {0x2F914, 0, 1 | DECOMP_INLINE, 0x701E}, - {0x2F915, 0, 1 | DECOMP_INLINE, 0x701B}, - {0x2F916, 0, 1 | DECOMP_INLINE, 0x3D96}, - {0x2F917, 0, 1 | DECOMP_INLINE, 0x704A}, - {0x2F918, 0, 1 | DECOMP_INLINE, 0x707D}, - {0x2F919, 0, 1 | DECOMP_INLINE, 0x7077}, - {0x2F91A, 0, 1 | DECOMP_INLINE, 0x70AD}, - {0x2F91B, 0, 1, 5029}, - {0x2F91C, 0, 1 | DECOMP_INLINE, 0x7145}, - {0x2F91D, 0, 1, 5030}, - {0x2F91E, 0, 1 | DECOMP_INLINE, 0x719C}, - {0x2F91F, 0, 1, 5031}, - {0x2F920, 0, 1 | DECOMP_INLINE, 0x7228}, - {0x2F921, 0, 1 | DECOMP_INLINE, 0x7235}, - {0x2F922, 0, 1 | DECOMP_INLINE, 0x7250}, - {0x2F923, 0, 1, 5032}, - {0x2F924, 0, 1 | DECOMP_INLINE, 0x7280}, - {0x2F925, 0, 1 | DECOMP_INLINE, 0x7295}, - {0x2F926, 0, 1, 5033}, - {0x2F927, 0, 1, 5034}, - {0x2F928, 0, 1 | DECOMP_INLINE, 0x737A}, - {0x2F929, 0, 1 | DECOMP_INLINE, 0x738B}, - {0x2F92A, 0, 1 | DECOMP_INLINE, 0x3EAC}, - {0x2F92B, 0, 1 | DECOMP_INLINE, 0x73A5}, - {0x2F92C, 0, 1 | DECOMP_INLINE, 0x3EB8}, - {0x2F92D, 0, 1 | DECOMP_INLINE, 0x3EB8}, - {0x2F92E, 0, 1 | DECOMP_INLINE, 0x7447}, - {0x2F92F, 0, 1 | DECOMP_INLINE, 0x745C}, - {0x2F930, 0, 1 | DECOMP_INLINE, 0x7471}, - {0x2F931, 0, 1 | DECOMP_INLINE, 0x7485}, - {0x2F932, 0, 1 | DECOMP_INLINE, 0x74CA}, - {0x2F933, 0, 1 | DECOMP_INLINE, 0x3F1B}, - {0x2F934, 0, 1 | DECOMP_INLINE, 0x7524}, - {0x2F935, 0, 1, 5035}, - {0x2F936, 0, 1 | DECOMP_INLINE, 0x753E}, - {0x2F937, 0, 1, 5036}, - {0x2F938, 0, 1 | DECOMP_INLINE, 0x7570}, - {0x2F939, 0, 1, 5037}, - {0x2F93A, 0, 1 | DECOMP_INLINE, 0x7610}, - {0x2F93B, 0, 1, 5038}, - {0x2F93C, 0, 1, 5039}, - {0x2F93D, 0, 1, 5040}, - {0x2F93E, 0, 1 | DECOMP_INLINE, 0x3FFC}, - {0x2F93F, 0, 1 | DECOMP_INLINE, 0x4008}, - {0x2F940, 0, 1 | DECOMP_INLINE, 0x76F4}, - {0x2F941, 0, 1, 5041}, - {0x2F942, 0, 1, 5042}, - {0x2F943, 0, 1, 5043}, - {0x2F944, 0, 1, 5044}, - {0x2F945, 0, 1 | DECOMP_INLINE, 0x771E}, - {0x2F946, 0, 1 | DECOMP_INLINE, 0x771F}, - {0x2F947, 0, 1 | DECOMP_INLINE, 0x771F}, - {0x2F948, 0, 1 | DECOMP_INLINE, 0x774A}, - {0x2F949, 0, 1 | DECOMP_INLINE, 0x4039}, - {0x2F94A, 0, 1 | DECOMP_INLINE, 0x778B}, - {0x2F94B, 0, 1 | DECOMP_INLINE, 0x4046}, - {0x2F94C, 0, 1 | DECOMP_INLINE, 0x4096}, - {0x2F94D, 0, 1, 5045}, - {0x2F94E, 0, 1 | DECOMP_INLINE, 0x784E}, - {0x2F94F, 0, 1 | DECOMP_INLINE, 0x788C}, - {0x2F950, 0, 1 | DECOMP_INLINE, 0x78CC}, - {0x2F951, 0, 1 | DECOMP_INLINE, 0x40E3}, - {0x2F952, 0, 1, 5046}, - {0x2F953, 0, 1 | DECOMP_INLINE, 0x7956}, - {0x2F954, 0, 1, 5047}, - {0x2F955, 0, 1, 5048}, - {0x2F956, 0, 1 | DECOMP_INLINE, 0x798F}, - {0x2F957, 0, 1 | DECOMP_INLINE, 0x79EB}, - {0x2F958, 0, 1 | DECOMP_INLINE, 0x412F}, - {0x2F959, 0, 1 | DECOMP_INLINE, 0x7A40}, - {0x2F95A, 0, 1 | DECOMP_INLINE, 0x7A4A}, - {0x2F95B, 0, 1 | DECOMP_INLINE, 0x7A4F}, - {0x2F95C, 0, 1, 5049}, - {0x2F95D, 0, 1, 5050}, - {0x2F95E, 0, 1, 5051}, - {0x2F95F, 0, 1 | DECOMP_INLINE, 0x7AEE}, - {0x2F960, 0, 1 | DECOMP_INLINE, 0x4202}, - {0x2F961, 0, 1, 5052}, - {0x2F962, 0, 1 | DECOMP_INLINE, 0x7BC6}, - {0x2F963, 0, 1 | DECOMP_INLINE, 0x7BC9}, - {0x2F964, 0, 1 | DECOMP_INLINE, 0x4227}, - {0x2F965, 0, 1, 5053}, - {0x2F966, 0, 1 | DECOMP_INLINE, 0x7CD2}, - {0x2F967, 0, 1 | DECOMP_INLINE, 0x42A0}, - {0x2F968, 0, 1 | DECOMP_INLINE, 0x7CE8}, - {0x2F969, 0, 1 | DECOMP_INLINE, 0x7CE3}, - {0x2F96A, 0, 1 | DECOMP_INLINE, 0x7D00}, - {0x2F96B, 0, 1, 5054}, - {0x2F96C, 0, 1 | DECOMP_INLINE, 0x7D63}, - {0x2F96D, 0, 1 | DECOMP_INLINE, 0x4301}, - {0x2F96E, 0, 1 | DECOMP_INLINE, 0x7DC7}, - {0x2F96F, 0, 1 | DECOMP_INLINE, 0x7E02}, - {0x2F970, 0, 1 | DECOMP_INLINE, 0x7E45}, - {0x2F971, 0, 1 | DECOMP_INLINE, 0x4334}, - {0x2F972, 0, 1, 5055}, - {0x2F973, 0, 1, 5056}, - {0x2F974, 0, 1 | DECOMP_INLINE, 0x4359}, - {0x2F975, 0, 1, 5057}, - {0x2F976, 0, 1 | DECOMP_INLINE, 0x7F7A}, - {0x2F977, 0, 1, 5058}, - {0x2F978, 0, 1 | DECOMP_INLINE, 0x7F95}, - {0x2F979, 0, 1 | DECOMP_INLINE, 0x7FFA}, - {0x2F97A, 0, 1 | DECOMP_INLINE, 0x8005}, - {0x2F97B, 0, 1, 5059}, - {0x2F97C, 0, 1, 5060}, - {0x2F97D, 0, 1 | DECOMP_INLINE, 0x8060}, - {0x2F97E, 0, 1, 5061}, - {0x2F97F, 0, 1 | DECOMP_INLINE, 0x8070}, - {0x2F980, 0, 1, 5062}, - {0x2F981, 0, 1 | DECOMP_INLINE, 0x43D5}, - {0x2F982, 0, 1 | DECOMP_INLINE, 0x80B2}, - {0x2F983, 0, 1 | DECOMP_INLINE, 0x8103}, - {0x2F984, 0, 1 | DECOMP_INLINE, 0x440B}, - {0x2F985, 0, 1 | DECOMP_INLINE, 0x813E}, - {0x2F986, 0, 1 | DECOMP_INLINE, 0x5AB5}, - {0x2F987, 0, 1, 5063}, - {0x2F988, 0, 1, 5064}, - {0x2F989, 0, 1, 5065}, - {0x2F98A, 0, 1, 5066}, - {0x2F98B, 0, 1 | DECOMP_INLINE, 0x8201}, - {0x2F98C, 0, 1 | DECOMP_INLINE, 0x8204}, - {0x2F98D, 0, 1 | DECOMP_INLINE, 0x8F9E}, - {0x2F98E, 0, 1 | DECOMP_INLINE, 0x446B}, - {0x2F98F, 0, 1 | DECOMP_INLINE, 0x8291}, - {0x2F990, 0, 1 | DECOMP_INLINE, 0x828B}, - {0x2F991, 0, 1 | DECOMP_INLINE, 0x829D}, - {0x2F992, 0, 1 | DECOMP_INLINE, 0x52B3}, - {0x2F993, 0, 1 | DECOMP_INLINE, 0x82B1}, - {0x2F994, 0, 1 | DECOMP_INLINE, 0x82B3}, - {0x2F995, 0, 1 | DECOMP_INLINE, 0x82BD}, - {0x2F996, 0, 1 | DECOMP_INLINE, 0x82E6}, - {0x2F997, 0, 1, 5067}, - {0x2F998, 0, 1 | DECOMP_INLINE, 0x82E5}, - {0x2F999, 0, 1 | DECOMP_INLINE, 0x831D}, - {0x2F99A, 0, 1 | DECOMP_INLINE, 0x8363}, - {0x2F99B, 0, 1 | DECOMP_INLINE, 0x83AD}, - {0x2F99C, 0, 1 | DECOMP_INLINE, 0x8323}, - {0x2F99D, 0, 1 | DECOMP_INLINE, 0x83BD}, - {0x2F99E, 0, 1 | DECOMP_INLINE, 0x83E7}, - {0x2F99F, 0, 1 | DECOMP_INLINE, 0x8457}, - {0x2F9A0, 0, 1 | DECOMP_INLINE, 0x8353}, - {0x2F9A1, 0, 1 | DECOMP_INLINE, 0x83CA}, - {0x2F9A2, 0, 1 | DECOMP_INLINE, 0x83CC}, - {0x2F9A3, 0, 1 | DECOMP_INLINE, 0x83DC}, - {0x2F9A4, 0, 1, 5068}, - {0x2F9A5, 0, 1, 5069}, - {0x2F9A6, 0, 1, 5070}, - {0x2F9A7, 0, 1 | DECOMP_INLINE, 0x452B}, - {0x2F9A8, 0, 1 | DECOMP_INLINE, 0x84F1}, - {0x2F9A9, 0, 1 | DECOMP_INLINE, 0x84F3}, - {0x2F9AA, 0, 1 | DECOMP_INLINE, 0x8516}, - {0x2F9AB, 0, 1, 5071}, - {0x2F9AC, 0, 1 | DECOMP_INLINE, 0x8564}, - {0x2F9AD, 0, 1, 5072}, - {0x2F9AE, 0, 1 | DECOMP_INLINE, 0x455D}, - {0x2F9AF, 0, 1 | DECOMP_INLINE, 0x4561}, - {0x2F9B0, 0, 1, 5073}, - {0x2F9B1, 0, 1, 5074}, - {0x2F9B2, 0, 1 | DECOMP_INLINE, 0x456B}, - {0x2F9B3, 0, 1 | DECOMP_INLINE, 0x8650}, - {0x2F9B4, 0, 1 | DECOMP_INLINE, 0x865C}, - {0x2F9B5, 0, 1 | DECOMP_INLINE, 0x8667}, - {0x2F9B6, 0, 1 | DECOMP_INLINE, 0x8669}, - {0x2F9B7, 0, 1 | DECOMP_INLINE, 0x86A9}, - {0x2F9B8, 0, 1 | DECOMP_INLINE, 0x8688}, - {0x2F9B9, 0, 1 | DECOMP_INLINE, 0x870E}, - {0x2F9BA, 0, 1 | DECOMP_INLINE, 0x86E2}, - {0x2F9BB, 0, 1 | DECOMP_INLINE, 0x8779}, - {0x2F9BC, 0, 1 | DECOMP_INLINE, 0x8728}, - {0x2F9BD, 0, 1 | DECOMP_INLINE, 0x876B}, - {0x2F9BE, 0, 1 | DECOMP_INLINE, 0x8786}, - {0x2F9BF, 0, 1 | DECOMP_INLINE, 0x45D7}, - {0x2F9C0, 0, 1 | DECOMP_INLINE, 0x87E1}, - {0x2F9C1, 0, 1 | DECOMP_INLINE, 0x8801}, - {0x2F9C2, 0, 1 | DECOMP_INLINE, 0x45F9}, - {0x2F9C3, 0, 1 | DECOMP_INLINE, 0x8860}, - {0x2F9C4, 0, 1 | DECOMP_INLINE, 0x8863}, - {0x2F9C5, 0, 1, 5075}, - {0x2F9C6, 0, 1 | DECOMP_INLINE, 0x88D7}, - {0x2F9C7, 0, 1 | DECOMP_INLINE, 0x88DE}, - {0x2F9C8, 0, 1 | DECOMP_INLINE, 0x4635}, - {0x2F9C9, 0, 1 | DECOMP_INLINE, 0x88FA}, - {0x2F9CA, 0, 1 | DECOMP_INLINE, 0x34BB}, - {0x2F9CB, 0, 1, 5076}, - {0x2F9CC, 0, 1, 5077}, - {0x2F9CD, 0, 1 | DECOMP_INLINE, 0x46BE}, - {0x2F9CE, 0, 1 | DECOMP_INLINE, 0x46C7}, - {0x2F9CF, 0, 1 | DECOMP_INLINE, 0x8AA0}, - {0x2F9D0, 0, 1 | DECOMP_INLINE, 0x8AED}, - {0x2F9D1, 0, 1 | DECOMP_INLINE, 0x8B8A}, - {0x2F9D2, 0, 1 | DECOMP_INLINE, 0x8C55}, - {0x2F9D3, 0, 1, 5078}, - {0x2F9D4, 0, 1 | DECOMP_INLINE, 0x8CAB}, - {0x2F9D5, 0, 1 | DECOMP_INLINE, 0x8CC1}, - {0x2F9D6, 0, 1 | DECOMP_INLINE, 0x8D1B}, - {0x2F9D7, 0, 1 | DECOMP_INLINE, 0x8D77}, - {0x2F9D8, 0, 1, 5079}, - {0x2F9D9, 0, 1, 5080}, - {0x2F9DA, 0, 1 | DECOMP_INLINE, 0x8DCB}, - {0x2F9DB, 0, 1 | DECOMP_INLINE, 0x8DBC}, - {0x2F9DC, 0, 1 | DECOMP_INLINE, 0x8DF0}, - {0x2F9DD, 0, 1, 5081}, - {0x2F9DE, 0, 1 | DECOMP_INLINE, 0x8ED4}, - {0x2F9DF, 0, 1 | DECOMP_INLINE, 0x8F38}, - {0x2F9E0, 0, 1, 5082}, - {0x2F9E1, 0, 1, 5083}, - {0x2F9E2, 0, 1 | DECOMP_INLINE, 0x9094}, - {0x2F9E3, 0, 1 | DECOMP_INLINE, 0x90F1}, - {0x2F9E4, 0, 1 | DECOMP_INLINE, 0x9111}, - {0x2F9E5, 0, 1, 5084}, - {0x2F9E6, 0, 1 | DECOMP_INLINE, 0x911B}, - {0x2F9E7, 0, 1 | DECOMP_INLINE, 0x9238}, - {0x2F9E8, 0, 1 | DECOMP_INLINE, 0x92D7}, - {0x2F9E9, 0, 1 | DECOMP_INLINE, 0x92D8}, - {0x2F9EA, 0, 1 | DECOMP_INLINE, 0x927C}, - {0x2F9EB, 0, 1 | DECOMP_INLINE, 0x93F9}, - {0x2F9EC, 0, 1 | DECOMP_INLINE, 0x9415}, - {0x2F9ED, 0, 1, 5085}, - {0x2F9EE, 0, 1 | DECOMP_INLINE, 0x958B}, - {0x2F9EF, 0, 1 | DECOMP_INLINE, 0x4995}, - {0x2F9F0, 0, 1 | DECOMP_INLINE, 0x95B7}, - {0x2F9F1, 0, 1, 5086}, - {0x2F9F2, 0, 1 | DECOMP_INLINE, 0x49E6}, - {0x2F9F3, 0, 1 | DECOMP_INLINE, 0x96C3}, - {0x2F9F4, 0, 1 | DECOMP_INLINE, 0x5DB2}, - {0x2F9F5, 0, 1 | DECOMP_INLINE, 0x9723}, - {0x2F9F6, 0, 1, 5087}, - {0x2F9F7, 0, 1, 5088}, - {0x2F9F8, 0, 1 | DECOMP_INLINE, 0x4A6E}, - {0x2F9F9, 0, 1 | DECOMP_INLINE, 0x4A76}, - {0x2F9FA, 0, 1 | DECOMP_INLINE, 0x97E0}, - {0x2F9FB, 0, 1, 5089}, - {0x2F9FC, 0, 1 | DECOMP_INLINE, 0x4AB2}, - {0x2F9FD, 0, 1, 5090}, - {0x2F9FE, 0, 1 | DECOMP_INLINE, 0x980B}, - {0x2F9FF, 0, 1 | DECOMP_INLINE, 0x980B}, - {0x2FA00, 0, 1 | DECOMP_INLINE, 0x9829}, - {0x2FA01, 0, 1, 5091}, - {0x2FA02, 0, 1 | DECOMP_INLINE, 0x98E2}, - {0x2FA03, 0, 1 | DECOMP_INLINE, 0x4B33}, - {0x2FA04, 0, 1 | DECOMP_INLINE, 0x9929}, - {0x2FA05, 0, 1 | DECOMP_INLINE, 0x99A7}, - {0x2FA06, 0, 1 | DECOMP_INLINE, 0x99C2}, - {0x2FA07, 0, 1 | DECOMP_INLINE, 0x99FE}, - {0x2FA08, 0, 1 | DECOMP_INLINE, 0x4BCE}, - {0x2FA09, 0, 1, 5092}, - {0x2FA0A, 0, 1 | DECOMP_INLINE, 0x9B12}, - {0x2FA0B, 0, 1 | DECOMP_INLINE, 0x9C40}, - {0x2FA0C, 0, 1 | DECOMP_INLINE, 0x9CFD}, - {0x2FA0D, 0, 1 | DECOMP_INLINE, 0x4CCE}, - {0x2FA0E, 0, 1 | DECOMP_INLINE, 0x4CED}, - {0x2FA0F, 0, 1 | DECOMP_INLINE, 0x9D67}, - {0x2FA10, 0, 1, 5093}, - {0x2FA11, 0, 1 | DECOMP_INLINE, 0x4CF8}, - {0x2FA12, 0, 1, 5094}, - {0x2FA13, 0, 1, 5095}, - {0x2FA14, 0, 1, 5096}, - {0x2FA15, 0, 1 | DECOMP_INLINE, 0x9EBB}, - {0x2FA16, 0, 1 | DECOMP_INLINE, 0x4D56}, - {0x2FA17, 0, 1 | DECOMP_INLINE, 0x9EF9}, - {0x2FA18, 0, 1 | DECOMP_INLINE, 0x9EFE}, - {0x2FA19, 0, 1 | DECOMP_INLINE, 0x9F05}, - {0x2FA1A, 0, 1 | DECOMP_INLINE, 0x9F0F}, - {0x2FA1B, 0, 1 | DECOMP_INLINE, 0x9F16}, - {0x2FA1C, 0, 1 | DECOMP_INLINE, 0x9F3B}, - {0x2FA1D, 0, 1, 5097} - -}; - -/* codepoints array */ -static const uint32 UnicodeDecomp_codepoints[5098] = -{ - /* 0 */ 0x0020, 0x0308, - /* 2 */ 0x0020, 0x0304, - /* 4 */ 0x0020, 0x0301, - /* 6 */ 0x0020, 0x0327, - /* 8 */ 0x0031, 0x2044, 0x0034, - /* 11 */ 0x0031, 0x2044, 0x0032, - /* 14 */ 0x0033, 0x2044, 0x0034, - /* 17 */ 0x0041, 0x0300, - /* 19 */ 0x0041, 0x0301, - /* 21 */ 0x0041, 0x0302, - /* 23 */ 0x0041, 0x0303, - /* 25 */ 0x0041, 0x0308, - /* 27 */ 0x0041, 0x030A, - /* 29 */ 0x0043, 0x0327, - /* 31 */ 0x0045, 0x0300, - /* 33 */ 0x0045, 0x0301, - /* 35 */ 0x0045, 0x0302, - /* 37 */ 0x0045, 0x0308, - /* 39 */ 0x0049, 0x0300, - /* 41 */ 0x0049, 0x0301, - /* 43 */ 0x0049, 0x0302, - /* 45 */ 0x0049, 0x0308, - /* 47 */ 0x004E, 0x0303, - /* 49 */ 0x004F, 0x0300, - /* 51 */ 0x004F, 0x0301, - /* 53 */ 0x004F, 0x0302, - /* 55 */ 0x004F, 0x0303, - /* 57 */ 0x004F, 0x0308, - /* 59 */ 0x0055, 0x0300, - /* 61 */ 0x0055, 0x0301, - /* 63 */ 0x0055, 0x0302, - /* 65 */ 0x0055, 0x0308, - /* 67 */ 0x0059, 0x0301, - /* 69 */ 0x0061, 0x0300, - /* 71 */ 0x0061, 0x0301, - /* 73 */ 0x0061, 0x0302, - /* 75 */ 0x0061, 0x0303, - /* 77 */ 0x0061, 0x0308, - /* 79 */ 0x0061, 0x030A, - /* 81 */ 0x0063, 0x0327, - /* 83 */ 0x0065, 0x0300, - /* 85 */ 0x0065, 0x0301, - /* 87 */ 0x0065, 0x0302, - /* 89 */ 0x0065, 0x0308, - /* 91 */ 0x0069, 0x0300, - /* 93 */ 0x0069, 0x0301, - /* 95 */ 0x0069, 0x0302, - /* 97 */ 0x0069, 0x0308, - /* 99 */ 0x006E, 0x0303, - /* 101 */ 0x006F, 0x0300, - /* 103 */ 0x006F, 0x0301, - /* 105 */ 0x006F, 0x0302, - /* 107 */ 0x006F, 0x0303, - /* 109 */ 0x006F, 0x0308, - /* 111 */ 0x0075, 0x0300, - /* 113 */ 0x0075, 0x0301, - /* 115 */ 0x0075, 0x0302, - /* 117 */ 0x0075, 0x0308, - /* 119 */ 0x0079, 0x0301, - /* 121 */ 0x0079, 0x0308, - /* 123 */ 0x0041, 0x0304, - /* 125 */ 0x0061, 0x0304, - /* 127 */ 0x0041, 0x0306, - /* 129 */ 0x0061, 0x0306, - /* 131 */ 0x0041, 0x0328, - /* 133 */ 0x0061, 0x0328, - /* 135 */ 0x0043, 0x0301, - /* 137 */ 0x0063, 0x0301, - /* 139 */ 0x0043, 0x0302, - /* 141 */ 0x0063, 0x0302, - /* 143 */ 0x0043, 0x0307, - /* 145 */ 0x0063, 0x0307, - /* 147 */ 0x0043, 0x030C, - /* 149 */ 0x0063, 0x030C, - /* 151 */ 0x0044, 0x030C, - /* 153 */ 0x0064, 0x030C, - /* 155 */ 0x0045, 0x0304, - /* 157 */ 0x0065, 0x0304, - /* 159 */ 0x0045, 0x0306, - /* 161 */ 0x0065, 0x0306, - /* 163 */ 0x0045, 0x0307, - /* 165 */ 0x0065, 0x0307, - /* 167 */ 0x0045, 0x0328, - /* 169 */ 0x0065, 0x0328, - /* 171 */ 0x0045, 0x030C, - /* 173 */ 0x0065, 0x030C, - /* 175 */ 0x0047, 0x0302, - /* 177 */ 0x0067, 0x0302, - /* 179 */ 0x0047, 0x0306, - /* 181 */ 0x0067, 0x0306, - /* 183 */ 0x0047, 0x0307, - /* 185 */ 0x0067, 0x0307, - /* 187 */ 0x0047, 0x0327, - /* 189 */ 0x0067, 0x0327, - /* 191 */ 0x0048, 0x0302, - /* 193 */ 0x0068, 0x0302, - /* 195 */ 0x0049, 0x0303, - /* 197 */ 0x0069, 0x0303, - /* 199 */ 0x0049, 0x0304, - /* 201 */ 0x0069, 0x0304, - /* 203 */ 0x0049, 0x0306, - /* 205 */ 0x0069, 0x0306, - /* 207 */ 0x0049, 0x0328, - /* 209 */ 0x0069, 0x0328, - /* 211 */ 0x0049, 0x0307, - /* 213 */ 0x0049, 0x004A, - /* 215 */ 0x0069, 0x006A, - /* 217 */ 0x004A, 0x0302, - /* 219 */ 0x006A, 0x0302, - /* 221 */ 0x004B, 0x0327, - /* 223 */ 0x006B, 0x0327, - /* 225 */ 0x004C, 0x0301, - /* 227 */ 0x006C, 0x0301, - /* 229 */ 0x004C, 0x0327, - /* 231 */ 0x006C, 0x0327, - /* 233 */ 0x004C, 0x030C, - /* 235 */ 0x006C, 0x030C, - /* 237 */ 0x004C, 0x00B7, - /* 239 */ 0x006C, 0x00B7, - /* 241 */ 0x004E, 0x0301, - /* 243 */ 0x006E, 0x0301, - /* 245 */ 0x004E, 0x0327, - /* 247 */ 0x006E, 0x0327, - /* 249 */ 0x004E, 0x030C, - /* 251 */ 0x006E, 0x030C, - /* 253 */ 0x02BC, 0x006E, - /* 255 */ 0x004F, 0x0304, - /* 257 */ 0x006F, 0x0304, - /* 259 */ 0x004F, 0x0306, - /* 261 */ 0x006F, 0x0306, - /* 263 */ 0x004F, 0x030B, - /* 265 */ 0x006F, 0x030B, - /* 267 */ 0x0052, 0x0301, - /* 269 */ 0x0072, 0x0301, - /* 271 */ 0x0052, 0x0327, - /* 273 */ 0x0072, 0x0327, - /* 275 */ 0x0052, 0x030C, - /* 277 */ 0x0072, 0x030C, - /* 279 */ 0x0053, 0x0301, - /* 281 */ 0x0073, 0x0301, - /* 283 */ 0x0053, 0x0302, - /* 285 */ 0x0073, 0x0302, - /* 287 */ 0x0053, 0x0327, - /* 289 */ 0x0073, 0x0327, - /* 291 */ 0x0053, 0x030C, - /* 293 */ 0x0073, 0x030C, - /* 295 */ 0x0054, 0x0327, - /* 297 */ 0x0074, 0x0327, - /* 299 */ 0x0054, 0x030C, - /* 301 */ 0x0074, 0x030C, - /* 303 */ 0x0055, 0x0303, - /* 305 */ 0x0075, 0x0303, - /* 307 */ 0x0055, 0x0304, - /* 309 */ 0x0075, 0x0304, - /* 311 */ 0x0055, 0x0306, - /* 313 */ 0x0075, 0x0306, - /* 315 */ 0x0055, 0x030A, - /* 317 */ 0x0075, 0x030A, - /* 319 */ 0x0055, 0x030B, - /* 321 */ 0x0075, 0x030B, - /* 323 */ 0x0055, 0x0328, - /* 325 */ 0x0075, 0x0328, - /* 327 */ 0x0057, 0x0302, - /* 329 */ 0x0077, 0x0302, - /* 331 */ 0x0059, 0x0302, - /* 333 */ 0x0079, 0x0302, - /* 335 */ 0x0059, 0x0308, - /* 337 */ 0x005A, 0x0301, - /* 339 */ 0x007A, 0x0301, - /* 341 */ 0x005A, 0x0307, - /* 343 */ 0x007A, 0x0307, - /* 345 */ 0x005A, 0x030C, - /* 347 */ 0x007A, 0x030C, - /* 349 */ 0x004F, 0x031B, - /* 351 */ 0x006F, 0x031B, - /* 353 */ 0x0055, 0x031B, - /* 355 */ 0x0075, 0x031B, - /* 357 */ 0x0044, 0x017D, - /* 359 */ 0x0044, 0x017E, - /* 361 */ 0x0064, 0x017E, - /* 363 */ 0x004C, 0x004A, - /* 365 */ 0x004C, 0x006A, - /* 367 */ 0x006C, 0x006A, - /* 369 */ 0x004E, 0x004A, - /* 371 */ 0x004E, 0x006A, - /* 373 */ 0x006E, 0x006A, - /* 375 */ 0x0041, 0x030C, - /* 377 */ 0x0061, 0x030C, - /* 379 */ 0x0049, 0x030C, - /* 381 */ 0x0069, 0x030C, - /* 383 */ 0x004F, 0x030C, - /* 385 */ 0x006F, 0x030C, - /* 387 */ 0x0055, 0x030C, - /* 389 */ 0x0075, 0x030C, - /* 391 */ 0x00DC, 0x0304, - /* 393 */ 0x00FC, 0x0304, - /* 395 */ 0x00DC, 0x0301, - /* 397 */ 0x00FC, 0x0301, - /* 399 */ 0x00DC, 0x030C, - /* 401 */ 0x00FC, 0x030C, - /* 403 */ 0x00DC, 0x0300, - /* 405 */ 0x00FC, 0x0300, - /* 407 */ 0x00C4, 0x0304, - /* 409 */ 0x00E4, 0x0304, - /* 411 */ 0x0226, 0x0304, - /* 413 */ 0x0227, 0x0304, - /* 415 */ 0x00C6, 0x0304, - /* 417 */ 0x00E6, 0x0304, - /* 419 */ 0x0047, 0x030C, - /* 421 */ 0x0067, 0x030C, - /* 423 */ 0x004B, 0x030C, - /* 425 */ 0x006B, 0x030C, - /* 427 */ 0x004F, 0x0328, - /* 429 */ 0x006F, 0x0328, - /* 431 */ 0x01EA, 0x0304, - /* 433 */ 0x01EB, 0x0304, - /* 435 */ 0x01B7, 0x030C, - /* 437 */ 0x0292, 0x030C, - /* 439 */ 0x006A, 0x030C, - /* 441 */ 0x0044, 0x005A, - /* 443 */ 0x0044, 0x007A, - /* 445 */ 0x0064, 0x007A, - /* 447 */ 0x0047, 0x0301, - /* 449 */ 0x0067, 0x0301, - /* 451 */ 0x004E, 0x0300, - /* 453 */ 0x006E, 0x0300, - /* 455 */ 0x00C5, 0x0301, - /* 457 */ 0x00E5, 0x0301, - /* 459 */ 0x00C6, 0x0301, - /* 461 */ 0x00E6, 0x0301, - /* 463 */ 0x00D8, 0x0301, - /* 465 */ 0x00F8, 0x0301, - /* 467 */ 0x0041, 0x030F, - /* 469 */ 0x0061, 0x030F, - /* 471 */ 0x0041, 0x0311, - /* 473 */ 0x0061, 0x0311, - /* 475 */ 0x0045, 0x030F, - /* 477 */ 0x0065, 0x030F, - /* 479 */ 0x0045, 0x0311, - /* 481 */ 0x0065, 0x0311, - /* 483 */ 0x0049, 0x030F, - /* 485 */ 0x0069, 0x030F, - /* 487 */ 0x0049, 0x0311, - /* 489 */ 0x0069, 0x0311, - /* 491 */ 0x004F, 0x030F, - /* 493 */ 0x006F, 0x030F, - /* 495 */ 0x004F, 0x0311, - /* 497 */ 0x006F, 0x0311, - /* 499 */ 0x0052, 0x030F, - /* 501 */ 0x0072, 0x030F, - /* 503 */ 0x0052, 0x0311, - /* 505 */ 0x0072, 0x0311, - /* 507 */ 0x0055, 0x030F, - /* 509 */ 0x0075, 0x030F, - /* 511 */ 0x0055, 0x0311, - /* 513 */ 0x0075, 0x0311, - /* 515 */ 0x0053, 0x0326, - /* 517 */ 0x0073, 0x0326, - /* 519 */ 0x0054, 0x0326, - /* 521 */ 0x0074, 0x0326, - /* 523 */ 0x0048, 0x030C, - /* 525 */ 0x0068, 0x030C, - /* 527 */ 0x0041, 0x0307, - /* 529 */ 0x0061, 0x0307, - /* 531 */ 0x0045, 0x0327, - /* 533 */ 0x0065, 0x0327, - /* 535 */ 0x00D6, 0x0304, - /* 537 */ 0x00F6, 0x0304, - /* 539 */ 0x00D5, 0x0304, - /* 541 */ 0x00F5, 0x0304, - /* 543 */ 0x004F, 0x0307, - /* 545 */ 0x006F, 0x0307, - /* 547 */ 0x022E, 0x0304, - /* 549 */ 0x022F, 0x0304, - /* 551 */ 0x0059, 0x0304, - /* 553 */ 0x0079, 0x0304, - /* 555 */ 0x0020, 0x0306, - /* 557 */ 0x0020, 0x0307, - /* 559 */ 0x0020, 0x030A, - /* 561 */ 0x0020, 0x0328, - /* 563 */ 0x0020, 0x0303, - /* 565 */ 0x0020, 0x030B, - /* 567 */ 0x0308, 0x0301, - /* 569 */ 0x0020, 0x0345, - /* 571 */ 0x0020, 0x0301, - /* 573 */ 0x00A8, 0x0301, - /* 575 */ 0x0391, 0x0301, - /* 577 */ 0x0395, 0x0301, - /* 579 */ 0x0397, 0x0301, - /* 581 */ 0x0399, 0x0301, - /* 583 */ 0x039F, 0x0301, - /* 585 */ 0x03A5, 0x0301, - /* 587 */ 0x03A9, 0x0301, - /* 589 */ 0x03CA, 0x0301, - /* 591 */ 0x0399, 0x0308, - /* 593 */ 0x03A5, 0x0308, - /* 595 */ 0x03B1, 0x0301, - /* 597 */ 0x03B5, 0x0301, - /* 599 */ 0x03B7, 0x0301, - /* 601 */ 0x03B9, 0x0301, - /* 603 */ 0x03CB, 0x0301, - /* 605 */ 0x03B9, 0x0308, - /* 607 */ 0x03C5, 0x0308, - /* 609 */ 0x03BF, 0x0301, - /* 611 */ 0x03C5, 0x0301, - /* 613 */ 0x03C9, 0x0301, - /* 615 */ 0x03D2, 0x0301, - /* 617 */ 0x03D2, 0x0308, - /* 619 */ 0x0415, 0x0300, - /* 621 */ 0x0415, 0x0308, - /* 623 */ 0x0413, 0x0301, - /* 625 */ 0x0406, 0x0308, - /* 627 */ 0x041A, 0x0301, - /* 629 */ 0x0418, 0x0300, - /* 631 */ 0x0423, 0x0306, - /* 633 */ 0x0418, 0x0306, - /* 635 */ 0x0438, 0x0306, - /* 637 */ 0x0435, 0x0300, - /* 639 */ 0x0435, 0x0308, - /* 641 */ 0x0433, 0x0301, - /* 643 */ 0x0456, 0x0308, - /* 645 */ 0x043A, 0x0301, - /* 647 */ 0x0438, 0x0300, - /* 649 */ 0x0443, 0x0306, - /* 651 */ 0x0474, 0x030F, - /* 653 */ 0x0475, 0x030F, - /* 655 */ 0x0416, 0x0306, - /* 657 */ 0x0436, 0x0306, - /* 659 */ 0x0410, 0x0306, - /* 661 */ 0x0430, 0x0306, - /* 663 */ 0x0410, 0x0308, - /* 665 */ 0x0430, 0x0308, - /* 667 */ 0x0415, 0x0306, - /* 669 */ 0x0435, 0x0306, - /* 671 */ 0x04D8, 0x0308, - /* 673 */ 0x04D9, 0x0308, - /* 675 */ 0x0416, 0x0308, - /* 677 */ 0x0436, 0x0308, - /* 679 */ 0x0417, 0x0308, - /* 681 */ 0x0437, 0x0308, - /* 683 */ 0x0418, 0x0304, - /* 685 */ 0x0438, 0x0304, - /* 687 */ 0x0418, 0x0308, - /* 689 */ 0x0438, 0x0308, - /* 691 */ 0x041E, 0x0308, - /* 693 */ 0x043E, 0x0308, - /* 695 */ 0x04E8, 0x0308, - /* 697 */ 0x04E9, 0x0308, - /* 699 */ 0x042D, 0x0308, - /* 701 */ 0x044D, 0x0308, - /* 703 */ 0x0423, 0x0304, - /* 705 */ 0x0443, 0x0304, - /* 707 */ 0x0423, 0x0308, - /* 709 */ 0x0443, 0x0308, - /* 711 */ 0x0423, 0x030B, - /* 713 */ 0x0443, 0x030B, - /* 715 */ 0x0427, 0x0308, - /* 717 */ 0x0447, 0x0308, - /* 719 */ 0x042B, 0x0308, - /* 721 */ 0x044B, 0x0308, - /* 723 */ 0x0565, 0x0582, - /* 725 */ 0x0627, 0x0653, - /* 727 */ 0x0627, 0x0654, - /* 729 */ 0x0648, 0x0654, - /* 731 */ 0x0627, 0x0655, - /* 733 */ 0x064A, 0x0654, - /* 735 */ 0x0627, 0x0674, - /* 737 */ 0x0648, 0x0674, - /* 739 */ 0x06C7, 0x0674, - /* 741 */ 0x064A, 0x0674, - /* 743 */ 0x06D5, 0x0654, - /* 745 */ 0x06C1, 0x0654, - /* 747 */ 0x06D2, 0x0654, - /* 749 */ 0x0928, 0x093C, - /* 751 */ 0x0930, 0x093C, - /* 753 */ 0x0933, 0x093C, - /* 755 */ 0x0915, 0x093C, - /* 757 */ 0x0916, 0x093C, - /* 759 */ 0x0917, 0x093C, - /* 761 */ 0x091C, 0x093C, - /* 763 */ 0x0921, 0x093C, - /* 765 */ 0x0922, 0x093C, - /* 767 */ 0x092B, 0x093C, - /* 769 */ 0x092F, 0x093C, - /* 771 */ 0x09C7, 0x09BE, - /* 773 */ 0x09C7, 0x09D7, - /* 775 */ 0x09A1, 0x09BC, - /* 777 */ 0x09A2, 0x09BC, - /* 779 */ 0x09AF, 0x09BC, - /* 781 */ 0x0A32, 0x0A3C, - /* 783 */ 0x0A38, 0x0A3C, - /* 785 */ 0x0A16, 0x0A3C, - /* 787 */ 0x0A17, 0x0A3C, - /* 789 */ 0x0A1C, 0x0A3C, - /* 791 */ 0x0A2B, 0x0A3C, - /* 793 */ 0x0B47, 0x0B56, - /* 795 */ 0x0B47, 0x0B3E, - /* 797 */ 0x0B47, 0x0B57, - /* 799 */ 0x0B21, 0x0B3C, - /* 801 */ 0x0B22, 0x0B3C, - /* 803 */ 0x0B92, 0x0BD7, - /* 805 */ 0x0BC6, 0x0BBE, - /* 807 */ 0x0BC7, 0x0BBE, - /* 809 */ 0x0BC6, 0x0BD7, - /* 811 */ 0x0C46, 0x0C56, - /* 813 */ 0x0CBF, 0x0CD5, - /* 815 */ 0x0CC6, 0x0CD5, - /* 817 */ 0x0CC6, 0x0CD6, - /* 819 */ 0x0CC6, 0x0CC2, - /* 821 */ 0x0CCA, 0x0CD5, - /* 823 */ 0x0D46, 0x0D3E, - /* 825 */ 0x0D47, 0x0D3E, - /* 827 */ 0x0D46, 0x0D57, - /* 829 */ 0x0DD9, 0x0DCA, - /* 831 */ 0x0DD9, 0x0DCF, - /* 833 */ 0x0DDC, 0x0DCA, - /* 835 */ 0x0DD9, 0x0DDF, - /* 837 */ 0x0E4D, 0x0E32, - /* 839 */ 0x0ECD, 0x0EB2, - /* 841 */ 0x0EAB, 0x0E99, - /* 843 */ 0x0EAB, 0x0EA1, - /* 845 */ 0x0F42, 0x0FB7, - /* 847 */ 0x0F4C, 0x0FB7, - /* 849 */ 0x0F51, 0x0FB7, - /* 851 */ 0x0F56, 0x0FB7, - /* 853 */ 0x0F5B, 0x0FB7, - /* 855 */ 0x0F40, 0x0FB5, - /* 857 */ 0x0F71, 0x0F72, - /* 859 */ 0x0F71, 0x0F74, - /* 861 */ 0x0FB2, 0x0F80, - /* 863 */ 0x0FB2, 0x0F81, - /* 865 */ 0x0FB3, 0x0F80, - /* 867 */ 0x0FB3, 0x0F81, - /* 869 */ 0x0F71, 0x0F80, - /* 871 */ 0x0F92, 0x0FB7, - /* 873 */ 0x0F9C, 0x0FB7, - /* 875 */ 0x0FA1, 0x0FB7, - /* 877 */ 0x0FA6, 0x0FB7, - /* 879 */ 0x0FAB, 0x0FB7, - /* 881 */ 0x0F90, 0x0FB5, - /* 883 */ 0x1025, 0x102E, - /* 885 */ 0x1B05, 0x1B35, - /* 887 */ 0x1B07, 0x1B35, - /* 889 */ 0x1B09, 0x1B35, - /* 891 */ 0x1B0B, 0x1B35, - /* 893 */ 0x1B0D, 0x1B35, - /* 895 */ 0x1B11, 0x1B35, - /* 897 */ 0x1B3A, 0x1B35, - /* 899 */ 0x1B3C, 0x1B35, - /* 901 */ 0x1B3E, 0x1B35, - /* 903 */ 0x1B3F, 0x1B35, - /* 905 */ 0x1B42, 0x1B35, - /* 907 */ 0x0041, 0x0325, - /* 909 */ 0x0061, 0x0325, - /* 911 */ 0x0042, 0x0307, - /* 913 */ 0x0062, 0x0307, - /* 915 */ 0x0042, 0x0323, - /* 917 */ 0x0062, 0x0323, - /* 919 */ 0x0042, 0x0331, - /* 921 */ 0x0062, 0x0331, - /* 923 */ 0x00C7, 0x0301, - /* 925 */ 0x00E7, 0x0301, - /* 927 */ 0x0044, 0x0307, - /* 929 */ 0x0064, 0x0307, - /* 931 */ 0x0044, 0x0323, - /* 933 */ 0x0064, 0x0323, - /* 935 */ 0x0044, 0x0331, - /* 937 */ 0x0064, 0x0331, - /* 939 */ 0x0044, 0x0327, - /* 941 */ 0x0064, 0x0327, - /* 943 */ 0x0044, 0x032D, - /* 945 */ 0x0064, 0x032D, - /* 947 */ 0x0112, 0x0300, - /* 949 */ 0x0113, 0x0300, - /* 951 */ 0x0112, 0x0301, - /* 953 */ 0x0113, 0x0301, - /* 955 */ 0x0045, 0x032D, - /* 957 */ 0x0065, 0x032D, - /* 959 */ 0x0045, 0x0330, - /* 961 */ 0x0065, 0x0330, - /* 963 */ 0x0228, 0x0306, - /* 965 */ 0x0229, 0x0306, - /* 967 */ 0x0046, 0x0307, - /* 969 */ 0x0066, 0x0307, - /* 971 */ 0x0047, 0x0304, - /* 973 */ 0x0067, 0x0304, - /* 975 */ 0x0048, 0x0307, - /* 977 */ 0x0068, 0x0307, - /* 979 */ 0x0048, 0x0323, - /* 981 */ 0x0068, 0x0323, - /* 983 */ 0x0048, 0x0308, - /* 985 */ 0x0068, 0x0308, - /* 987 */ 0x0048, 0x0327, - /* 989 */ 0x0068, 0x0327, - /* 991 */ 0x0048, 0x032E, - /* 993 */ 0x0068, 0x032E, - /* 995 */ 0x0049, 0x0330, - /* 997 */ 0x0069, 0x0330, - /* 999 */ 0x00CF, 0x0301, - /* 1001 */ 0x00EF, 0x0301, - /* 1003 */ 0x004B, 0x0301, - /* 1005 */ 0x006B, 0x0301, - /* 1007 */ 0x004B, 0x0323, - /* 1009 */ 0x006B, 0x0323, - /* 1011 */ 0x004B, 0x0331, - /* 1013 */ 0x006B, 0x0331, - /* 1015 */ 0x004C, 0x0323, - /* 1017 */ 0x006C, 0x0323, - /* 1019 */ 0x1E36, 0x0304, - /* 1021 */ 0x1E37, 0x0304, - /* 1023 */ 0x004C, 0x0331, - /* 1025 */ 0x006C, 0x0331, - /* 1027 */ 0x004C, 0x032D, - /* 1029 */ 0x006C, 0x032D, - /* 1031 */ 0x004D, 0x0301, - /* 1033 */ 0x006D, 0x0301, - /* 1035 */ 0x004D, 0x0307, - /* 1037 */ 0x006D, 0x0307, - /* 1039 */ 0x004D, 0x0323, - /* 1041 */ 0x006D, 0x0323, - /* 1043 */ 0x004E, 0x0307, - /* 1045 */ 0x006E, 0x0307, - /* 1047 */ 0x004E, 0x0323, - /* 1049 */ 0x006E, 0x0323, - /* 1051 */ 0x004E, 0x0331, - /* 1053 */ 0x006E, 0x0331, - /* 1055 */ 0x004E, 0x032D, - /* 1057 */ 0x006E, 0x032D, - /* 1059 */ 0x00D5, 0x0301, - /* 1061 */ 0x00F5, 0x0301, - /* 1063 */ 0x00D5, 0x0308, - /* 1065 */ 0x00F5, 0x0308, - /* 1067 */ 0x014C, 0x0300, - /* 1069 */ 0x014D, 0x0300, - /* 1071 */ 0x014C, 0x0301, - /* 1073 */ 0x014D, 0x0301, - /* 1075 */ 0x0050, 0x0301, - /* 1077 */ 0x0070, 0x0301, - /* 1079 */ 0x0050, 0x0307, - /* 1081 */ 0x0070, 0x0307, - /* 1083 */ 0x0052, 0x0307, - /* 1085 */ 0x0072, 0x0307, - /* 1087 */ 0x0052, 0x0323, - /* 1089 */ 0x0072, 0x0323, - /* 1091 */ 0x1E5A, 0x0304, - /* 1093 */ 0x1E5B, 0x0304, - /* 1095 */ 0x0052, 0x0331, - /* 1097 */ 0x0072, 0x0331, - /* 1099 */ 0x0053, 0x0307, - /* 1101 */ 0x0073, 0x0307, - /* 1103 */ 0x0053, 0x0323, - /* 1105 */ 0x0073, 0x0323, - /* 1107 */ 0x015A, 0x0307, - /* 1109 */ 0x015B, 0x0307, - /* 1111 */ 0x0160, 0x0307, - /* 1113 */ 0x0161, 0x0307, - /* 1115 */ 0x1E62, 0x0307, - /* 1117 */ 0x1E63, 0x0307, - /* 1119 */ 0x0054, 0x0307, - /* 1121 */ 0x0074, 0x0307, - /* 1123 */ 0x0054, 0x0323, - /* 1125 */ 0x0074, 0x0323, - /* 1127 */ 0x0054, 0x0331, - /* 1129 */ 0x0074, 0x0331, - /* 1131 */ 0x0054, 0x032D, - /* 1133 */ 0x0074, 0x032D, - /* 1135 */ 0x0055, 0x0324, - /* 1137 */ 0x0075, 0x0324, - /* 1139 */ 0x0055, 0x0330, - /* 1141 */ 0x0075, 0x0330, - /* 1143 */ 0x0055, 0x032D, - /* 1145 */ 0x0075, 0x032D, - /* 1147 */ 0x0168, 0x0301, - /* 1149 */ 0x0169, 0x0301, - /* 1151 */ 0x016A, 0x0308, - /* 1153 */ 0x016B, 0x0308, - /* 1155 */ 0x0056, 0x0303, - /* 1157 */ 0x0076, 0x0303, - /* 1159 */ 0x0056, 0x0323, - /* 1161 */ 0x0076, 0x0323, - /* 1163 */ 0x0057, 0x0300, - /* 1165 */ 0x0077, 0x0300, - /* 1167 */ 0x0057, 0x0301, - /* 1169 */ 0x0077, 0x0301, - /* 1171 */ 0x0057, 0x0308, - /* 1173 */ 0x0077, 0x0308, - /* 1175 */ 0x0057, 0x0307, - /* 1177 */ 0x0077, 0x0307, - /* 1179 */ 0x0057, 0x0323, - /* 1181 */ 0x0077, 0x0323, - /* 1183 */ 0x0058, 0x0307, - /* 1185 */ 0x0078, 0x0307, - /* 1187 */ 0x0058, 0x0308, - /* 1189 */ 0x0078, 0x0308, - /* 1191 */ 0x0059, 0x0307, - /* 1193 */ 0x0079, 0x0307, - /* 1195 */ 0x005A, 0x0302, - /* 1197 */ 0x007A, 0x0302, - /* 1199 */ 0x005A, 0x0323, - /* 1201 */ 0x007A, 0x0323, - /* 1203 */ 0x005A, 0x0331, - /* 1205 */ 0x007A, 0x0331, - /* 1207 */ 0x0068, 0x0331, - /* 1209 */ 0x0074, 0x0308, - /* 1211 */ 0x0077, 0x030A, - /* 1213 */ 0x0079, 0x030A, - /* 1215 */ 0x0061, 0x02BE, - /* 1217 */ 0x017F, 0x0307, - /* 1219 */ 0x0041, 0x0323, - /* 1221 */ 0x0061, 0x0323, - /* 1223 */ 0x0041, 0x0309, - /* 1225 */ 0x0061, 0x0309, - /* 1227 */ 0x00C2, 0x0301, - /* 1229 */ 0x00E2, 0x0301, - /* 1231 */ 0x00C2, 0x0300, - /* 1233 */ 0x00E2, 0x0300, - /* 1235 */ 0x00C2, 0x0309, - /* 1237 */ 0x00E2, 0x0309, - /* 1239 */ 0x00C2, 0x0303, - /* 1241 */ 0x00E2, 0x0303, - /* 1243 */ 0x1EA0, 0x0302, - /* 1245 */ 0x1EA1, 0x0302, - /* 1247 */ 0x0102, 0x0301, - /* 1249 */ 0x0103, 0x0301, - /* 1251 */ 0x0102, 0x0300, - /* 1253 */ 0x0103, 0x0300, - /* 1255 */ 0x0102, 0x0309, - /* 1257 */ 0x0103, 0x0309, - /* 1259 */ 0x0102, 0x0303, - /* 1261 */ 0x0103, 0x0303, - /* 1263 */ 0x1EA0, 0x0306, - /* 1265 */ 0x1EA1, 0x0306, - /* 1267 */ 0x0045, 0x0323, - /* 1269 */ 0x0065, 0x0323, - /* 1271 */ 0x0045, 0x0309, - /* 1273 */ 0x0065, 0x0309, - /* 1275 */ 0x0045, 0x0303, - /* 1277 */ 0x0065, 0x0303, - /* 1279 */ 0x00CA, 0x0301, - /* 1281 */ 0x00EA, 0x0301, - /* 1283 */ 0x00CA, 0x0300, - /* 1285 */ 0x00EA, 0x0300, - /* 1287 */ 0x00CA, 0x0309, - /* 1289 */ 0x00EA, 0x0309, - /* 1291 */ 0x00CA, 0x0303, - /* 1293 */ 0x00EA, 0x0303, - /* 1295 */ 0x1EB8, 0x0302, - /* 1297 */ 0x1EB9, 0x0302, - /* 1299 */ 0x0049, 0x0309, - /* 1301 */ 0x0069, 0x0309, - /* 1303 */ 0x0049, 0x0323, - /* 1305 */ 0x0069, 0x0323, - /* 1307 */ 0x004F, 0x0323, - /* 1309 */ 0x006F, 0x0323, - /* 1311 */ 0x004F, 0x0309, - /* 1313 */ 0x006F, 0x0309, - /* 1315 */ 0x00D4, 0x0301, - /* 1317 */ 0x00F4, 0x0301, - /* 1319 */ 0x00D4, 0x0300, - /* 1321 */ 0x00F4, 0x0300, - /* 1323 */ 0x00D4, 0x0309, - /* 1325 */ 0x00F4, 0x0309, - /* 1327 */ 0x00D4, 0x0303, - /* 1329 */ 0x00F4, 0x0303, - /* 1331 */ 0x1ECC, 0x0302, - /* 1333 */ 0x1ECD, 0x0302, - /* 1335 */ 0x01A0, 0x0301, - /* 1337 */ 0x01A1, 0x0301, - /* 1339 */ 0x01A0, 0x0300, - /* 1341 */ 0x01A1, 0x0300, - /* 1343 */ 0x01A0, 0x0309, - /* 1345 */ 0x01A1, 0x0309, - /* 1347 */ 0x01A0, 0x0303, - /* 1349 */ 0x01A1, 0x0303, - /* 1351 */ 0x01A0, 0x0323, - /* 1353 */ 0x01A1, 0x0323, - /* 1355 */ 0x0055, 0x0323, - /* 1357 */ 0x0075, 0x0323, - /* 1359 */ 0x0055, 0x0309, - /* 1361 */ 0x0075, 0x0309, - /* 1363 */ 0x01AF, 0x0301, - /* 1365 */ 0x01B0, 0x0301, - /* 1367 */ 0x01AF, 0x0300, - /* 1369 */ 0x01B0, 0x0300, - /* 1371 */ 0x01AF, 0x0309, - /* 1373 */ 0x01B0, 0x0309, - /* 1375 */ 0x01AF, 0x0303, - /* 1377 */ 0x01B0, 0x0303, - /* 1379 */ 0x01AF, 0x0323, - /* 1381 */ 0x01B0, 0x0323, - /* 1383 */ 0x0059, 0x0300, - /* 1385 */ 0x0079, 0x0300, - /* 1387 */ 0x0059, 0x0323, - /* 1389 */ 0x0079, 0x0323, - /* 1391 */ 0x0059, 0x0309, - /* 1393 */ 0x0079, 0x0309, - /* 1395 */ 0x0059, 0x0303, - /* 1397 */ 0x0079, 0x0303, - /* 1399 */ 0x03B1, 0x0313, - /* 1401 */ 0x03B1, 0x0314, - /* 1403 */ 0x1F00, 0x0300, - /* 1405 */ 0x1F01, 0x0300, - /* 1407 */ 0x1F00, 0x0301, - /* 1409 */ 0x1F01, 0x0301, - /* 1411 */ 0x1F00, 0x0342, - /* 1413 */ 0x1F01, 0x0342, - /* 1415 */ 0x0391, 0x0313, - /* 1417 */ 0x0391, 0x0314, - /* 1419 */ 0x1F08, 0x0300, - /* 1421 */ 0x1F09, 0x0300, - /* 1423 */ 0x1F08, 0x0301, - /* 1425 */ 0x1F09, 0x0301, - /* 1427 */ 0x1F08, 0x0342, - /* 1429 */ 0x1F09, 0x0342, - /* 1431 */ 0x03B5, 0x0313, - /* 1433 */ 0x03B5, 0x0314, - /* 1435 */ 0x1F10, 0x0300, - /* 1437 */ 0x1F11, 0x0300, - /* 1439 */ 0x1F10, 0x0301, - /* 1441 */ 0x1F11, 0x0301, - /* 1443 */ 0x0395, 0x0313, - /* 1445 */ 0x0395, 0x0314, - /* 1447 */ 0x1F18, 0x0300, - /* 1449 */ 0x1F19, 0x0300, - /* 1451 */ 0x1F18, 0x0301, - /* 1453 */ 0x1F19, 0x0301, - /* 1455 */ 0x03B7, 0x0313, - /* 1457 */ 0x03B7, 0x0314, - /* 1459 */ 0x1F20, 0x0300, - /* 1461 */ 0x1F21, 0x0300, - /* 1463 */ 0x1F20, 0x0301, - /* 1465 */ 0x1F21, 0x0301, - /* 1467 */ 0x1F20, 0x0342, - /* 1469 */ 0x1F21, 0x0342, - /* 1471 */ 0x0397, 0x0313, - /* 1473 */ 0x0397, 0x0314, - /* 1475 */ 0x1F28, 0x0300, - /* 1477 */ 0x1F29, 0x0300, - /* 1479 */ 0x1F28, 0x0301, - /* 1481 */ 0x1F29, 0x0301, - /* 1483 */ 0x1F28, 0x0342, - /* 1485 */ 0x1F29, 0x0342, - /* 1487 */ 0x03B9, 0x0313, - /* 1489 */ 0x03B9, 0x0314, - /* 1491 */ 0x1F30, 0x0300, - /* 1493 */ 0x1F31, 0x0300, - /* 1495 */ 0x1F30, 0x0301, - /* 1497 */ 0x1F31, 0x0301, - /* 1499 */ 0x1F30, 0x0342, - /* 1501 */ 0x1F31, 0x0342, - /* 1503 */ 0x0399, 0x0313, - /* 1505 */ 0x0399, 0x0314, - /* 1507 */ 0x1F38, 0x0300, - /* 1509 */ 0x1F39, 0x0300, - /* 1511 */ 0x1F38, 0x0301, - /* 1513 */ 0x1F39, 0x0301, - /* 1515 */ 0x1F38, 0x0342, - /* 1517 */ 0x1F39, 0x0342, - /* 1519 */ 0x03BF, 0x0313, - /* 1521 */ 0x03BF, 0x0314, - /* 1523 */ 0x1F40, 0x0300, - /* 1525 */ 0x1F41, 0x0300, - /* 1527 */ 0x1F40, 0x0301, - /* 1529 */ 0x1F41, 0x0301, - /* 1531 */ 0x039F, 0x0313, - /* 1533 */ 0x039F, 0x0314, - /* 1535 */ 0x1F48, 0x0300, - /* 1537 */ 0x1F49, 0x0300, - /* 1539 */ 0x1F48, 0x0301, - /* 1541 */ 0x1F49, 0x0301, - /* 1543 */ 0x03C5, 0x0313, - /* 1545 */ 0x03C5, 0x0314, - /* 1547 */ 0x1F50, 0x0300, - /* 1549 */ 0x1F51, 0x0300, - /* 1551 */ 0x1F50, 0x0301, - /* 1553 */ 0x1F51, 0x0301, - /* 1555 */ 0x1F50, 0x0342, - /* 1557 */ 0x1F51, 0x0342, - /* 1559 */ 0x03A5, 0x0314, - /* 1561 */ 0x1F59, 0x0300, - /* 1563 */ 0x1F59, 0x0301, - /* 1565 */ 0x1F59, 0x0342, - /* 1567 */ 0x03C9, 0x0313, - /* 1569 */ 0x03C9, 0x0314, - /* 1571 */ 0x1F60, 0x0300, - /* 1573 */ 0x1F61, 0x0300, - /* 1575 */ 0x1F60, 0x0301, - /* 1577 */ 0x1F61, 0x0301, - /* 1579 */ 0x1F60, 0x0342, - /* 1581 */ 0x1F61, 0x0342, - /* 1583 */ 0x03A9, 0x0313, - /* 1585 */ 0x03A9, 0x0314, - /* 1587 */ 0x1F68, 0x0300, - /* 1589 */ 0x1F69, 0x0300, - /* 1591 */ 0x1F68, 0x0301, - /* 1593 */ 0x1F69, 0x0301, - /* 1595 */ 0x1F68, 0x0342, - /* 1597 */ 0x1F69, 0x0342, - /* 1599 */ 0x03B1, 0x0300, - /* 1601 */ 0x03B5, 0x0300, - /* 1603 */ 0x03B7, 0x0300, - /* 1605 */ 0x03B9, 0x0300, - /* 1607 */ 0x03BF, 0x0300, - /* 1609 */ 0x03C5, 0x0300, - /* 1611 */ 0x03C9, 0x0300, - /* 1613 */ 0x1F00, 0x0345, - /* 1615 */ 0x1F01, 0x0345, - /* 1617 */ 0x1F02, 0x0345, - /* 1619 */ 0x1F03, 0x0345, - /* 1621 */ 0x1F04, 0x0345, - /* 1623 */ 0x1F05, 0x0345, - /* 1625 */ 0x1F06, 0x0345, - /* 1627 */ 0x1F07, 0x0345, - /* 1629 */ 0x1F08, 0x0345, - /* 1631 */ 0x1F09, 0x0345, - /* 1633 */ 0x1F0A, 0x0345, - /* 1635 */ 0x1F0B, 0x0345, - /* 1637 */ 0x1F0C, 0x0345, - /* 1639 */ 0x1F0D, 0x0345, - /* 1641 */ 0x1F0E, 0x0345, - /* 1643 */ 0x1F0F, 0x0345, - /* 1645 */ 0x1F20, 0x0345, - /* 1647 */ 0x1F21, 0x0345, - /* 1649 */ 0x1F22, 0x0345, - /* 1651 */ 0x1F23, 0x0345, - /* 1653 */ 0x1F24, 0x0345, - /* 1655 */ 0x1F25, 0x0345, - /* 1657 */ 0x1F26, 0x0345, - /* 1659 */ 0x1F27, 0x0345, - /* 1661 */ 0x1F28, 0x0345, - /* 1663 */ 0x1F29, 0x0345, - /* 1665 */ 0x1F2A, 0x0345, - /* 1667 */ 0x1F2B, 0x0345, - /* 1669 */ 0x1F2C, 0x0345, - /* 1671 */ 0x1F2D, 0x0345, - /* 1673 */ 0x1F2E, 0x0345, - /* 1675 */ 0x1F2F, 0x0345, - /* 1677 */ 0x1F60, 0x0345, - /* 1679 */ 0x1F61, 0x0345, - /* 1681 */ 0x1F62, 0x0345, - /* 1683 */ 0x1F63, 0x0345, - /* 1685 */ 0x1F64, 0x0345, - /* 1687 */ 0x1F65, 0x0345, - /* 1689 */ 0x1F66, 0x0345, - /* 1691 */ 0x1F67, 0x0345, - /* 1693 */ 0x1F68, 0x0345, - /* 1695 */ 0x1F69, 0x0345, - /* 1697 */ 0x1F6A, 0x0345, - /* 1699 */ 0x1F6B, 0x0345, - /* 1701 */ 0x1F6C, 0x0345, - /* 1703 */ 0x1F6D, 0x0345, - /* 1705 */ 0x1F6E, 0x0345, - /* 1707 */ 0x1F6F, 0x0345, - /* 1709 */ 0x03B1, 0x0306, - /* 1711 */ 0x03B1, 0x0304, - /* 1713 */ 0x1F70, 0x0345, - /* 1715 */ 0x03B1, 0x0345, - /* 1717 */ 0x03AC, 0x0345, - /* 1719 */ 0x03B1, 0x0342, - /* 1721 */ 0x1FB6, 0x0345, - /* 1723 */ 0x0391, 0x0306, - /* 1725 */ 0x0391, 0x0304, - /* 1727 */ 0x0391, 0x0300, - /* 1729 */ 0x0391, 0x0345, - /* 1731 */ 0x0020, 0x0313, - /* 1733 */ 0x0020, 0x0313, - /* 1735 */ 0x0020, 0x0342, - /* 1737 */ 0x00A8, 0x0342, - /* 1739 */ 0x1F74, 0x0345, - /* 1741 */ 0x03B7, 0x0345, - /* 1743 */ 0x03AE, 0x0345, - /* 1745 */ 0x03B7, 0x0342, - /* 1747 */ 0x1FC6, 0x0345, - /* 1749 */ 0x0395, 0x0300, - /* 1751 */ 0x0397, 0x0300, - /* 1753 */ 0x0397, 0x0345, - /* 1755 */ 0x1FBF, 0x0300, - /* 1757 */ 0x1FBF, 0x0301, - /* 1759 */ 0x1FBF, 0x0342, - /* 1761 */ 0x03B9, 0x0306, - /* 1763 */ 0x03B9, 0x0304, - /* 1765 */ 0x03CA, 0x0300, - /* 1767 */ 0x03B9, 0x0342, - /* 1769 */ 0x03CA, 0x0342, - /* 1771 */ 0x0399, 0x0306, - /* 1773 */ 0x0399, 0x0304, - /* 1775 */ 0x0399, 0x0300, - /* 1777 */ 0x1FFE, 0x0300, - /* 1779 */ 0x1FFE, 0x0301, - /* 1781 */ 0x1FFE, 0x0342, - /* 1783 */ 0x03C5, 0x0306, - /* 1785 */ 0x03C5, 0x0304, - /* 1787 */ 0x03CB, 0x0300, - /* 1789 */ 0x03C1, 0x0313, - /* 1791 */ 0x03C1, 0x0314, - /* 1793 */ 0x03C5, 0x0342, - /* 1795 */ 0x03CB, 0x0342, - /* 1797 */ 0x03A5, 0x0306, - /* 1799 */ 0x03A5, 0x0304, - /* 1801 */ 0x03A5, 0x0300, - /* 1803 */ 0x03A1, 0x0314, - /* 1805 */ 0x00A8, 0x0300, - /* 1807 */ 0x1F7C, 0x0345, - /* 1809 */ 0x03C9, 0x0345, - /* 1811 */ 0x03CE, 0x0345, - /* 1813 */ 0x03C9, 0x0342, - /* 1815 */ 0x1FF6, 0x0345, - /* 1817 */ 0x039F, 0x0300, - /* 1819 */ 0x03A9, 0x0300, - /* 1821 */ 0x03A9, 0x0345, - /* 1823 */ 0x0020, 0x0314, - /* 1825 */ 0x0020, 0x0333, - /* 1827 */ 0x002E, 0x002E, - /* 1829 */ 0x002E, 0x002E, 0x002E, - /* 1832 */ 0x2032, 0x2032, - /* 1834 */ 0x2032, 0x2032, 0x2032, - /* 1837 */ 0x2035, 0x2035, - /* 1839 */ 0x2035, 0x2035, 0x2035, - /* 1842 */ 0x0021, 0x0021, - /* 1844 */ 0x0020, 0x0305, - /* 1846 */ 0x003F, 0x003F, - /* 1848 */ 0x003F, 0x0021, - /* 1850 */ 0x0021, 0x003F, - /* 1852 */ 0x2032, 0x2032, 0x2032, 0x2032, - /* 1856 */ 0x0052, 0x0073, - /* 1858 */ 0x0061, 0x002F, 0x0063, - /* 1861 */ 0x0061, 0x002F, 0x0073, - /* 1864 */ 0x00B0, 0x0043, - /* 1866 */ 0x0063, 0x002F, 0x006F, - /* 1869 */ 0x0063, 0x002F, 0x0075, - /* 1872 */ 0x00B0, 0x0046, - /* 1874 */ 0x004E, 0x006F, - /* 1876 */ 0x0053, 0x004D, - /* 1878 */ 0x0054, 0x0045, 0x004C, - /* 1881 */ 0x0054, 0x004D, - /* 1883 */ 0x0046, 0x0041, 0x0058, - /* 1886 */ 0x0031, 0x2044, 0x0037, - /* 1889 */ 0x0031, 0x2044, 0x0039, - /* 1892 */ 0x0031, 0x2044, 0x0031, 0x0030, - /* 1896 */ 0x0031, 0x2044, 0x0033, - /* 1899 */ 0x0032, 0x2044, 0x0033, - /* 1902 */ 0x0031, 0x2044, 0x0035, - /* 1905 */ 0x0032, 0x2044, 0x0035, - /* 1908 */ 0x0033, 0x2044, 0x0035, - /* 1911 */ 0x0034, 0x2044, 0x0035, - /* 1914 */ 0x0031, 0x2044, 0x0036, - /* 1917 */ 0x0035, 0x2044, 0x0036, - /* 1920 */ 0x0031, 0x2044, 0x0038, - /* 1923 */ 0x0033, 0x2044, 0x0038, - /* 1926 */ 0x0035, 0x2044, 0x0038, - /* 1929 */ 0x0037, 0x2044, 0x0038, - /* 1932 */ 0x0031, 0x2044, - /* 1934 */ 0x0049, 0x0049, - /* 1936 */ 0x0049, 0x0049, 0x0049, - /* 1939 */ 0x0049, 0x0056, - /* 1941 */ 0x0056, 0x0049, - /* 1943 */ 0x0056, 0x0049, 0x0049, - /* 1946 */ 0x0056, 0x0049, 0x0049, 0x0049, - /* 1950 */ 0x0049, 0x0058, - /* 1952 */ 0x0058, 0x0049, - /* 1954 */ 0x0058, 0x0049, 0x0049, - /* 1957 */ 0x0069, 0x0069, - /* 1959 */ 0x0069, 0x0069, 0x0069, - /* 1962 */ 0x0069, 0x0076, - /* 1964 */ 0x0076, 0x0069, - /* 1966 */ 0x0076, 0x0069, 0x0069, - /* 1969 */ 0x0076, 0x0069, 0x0069, 0x0069, - /* 1973 */ 0x0069, 0x0078, - /* 1975 */ 0x0078, 0x0069, - /* 1977 */ 0x0078, 0x0069, 0x0069, - /* 1980 */ 0x0030, 0x2044, 0x0033, - /* 1983 */ 0x2190, 0x0338, - /* 1985 */ 0x2192, 0x0338, - /* 1987 */ 0x2194, 0x0338, - /* 1989 */ 0x21D0, 0x0338, - /* 1991 */ 0x21D4, 0x0338, - /* 1993 */ 0x21D2, 0x0338, - /* 1995 */ 0x2203, 0x0338, - /* 1997 */ 0x2208, 0x0338, - /* 1999 */ 0x220B, 0x0338, - /* 2001 */ 0x2223, 0x0338, - /* 2003 */ 0x2225, 0x0338, - /* 2005 */ 0x222B, 0x222B, - /* 2007 */ 0x222B, 0x222B, 0x222B, - /* 2010 */ 0x222E, 0x222E, - /* 2012 */ 0x222E, 0x222E, 0x222E, - /* 2015 */ 0x223C, 0x0338, - /* 2017 */ 0x2243, 0x0338, - /* 2019 */ 0x2245, 0x0338, - /* 2021 */ 0x2248, 0x0338, - /* 2023 */ 0x003D, 0x0338, - /* 2025 */ 0x2261, 0x0338, - /* 2027 */ 0x224D, 0x0338, - /* 2029 */ 0x003C, 0x0338, - /* 2031 */ 0x003E, 0x0338, - /* 2033 */ 0x2264, 0x0338, - /* 2035 */ 0x2265, 0x0338, - /* 2037 */ 0x2272, 0x0338, - /* 2039 */ 0x2273, 0x0338, - /* 2041 */ 0x2276, 0x0338, - /* 2043 */ 0x2277, 0x0338, - /* 2045 */ 0x227A, 0x0338, - /* 2047 */ 0x227B, 0x0338, - /* 2049 */ 0x2282, 0x0338, - /* 2051 */ 0x2283, 0x0338, - /* 2053 */ 0x2286, 0x0338, - /* 2055 */ 0x2287, 0x0338, - /* 2057 */ 0x22A2, 0x0338, - /* 2059 */ 0x22A8, 0x0338, - /* 2061 */ 0x22A9, 0x0338, - /* 2063 */ 0x22AB, 0x0338, - /* 2065 */ 0x227C, 0x0338, - /* 2067 */ 0x227D, 0x0338, - /* 2069 */ 0x2291, 0x0338, - /* 2071 */ 0x2292, 0x0338, - /* 2073 */ 0x22B2, 0x0338, - /* 2075 */ 0x22B3, 0x0338, - /* 2077 */ 0x22B4, 0x0338, - /* 2079 */ 0x22B5, 0x0338, - /* 2081 */ 0x0031, 0x0030, - /* 2083 */ 0x0031, 0x0031, - /* 2085 */ 0x0031, 0x0032, - /* 2087 */ 0x0031, 0x0033, - /* 2089 */ 0x0031, 0x0034, - /* 2091 */ 0x0031, 0x0035, - /* 2093 */ 0x0031, 0x0036, - /* 2095 */ 0x0031, 0x0037, - /* 2097 */ 0x0031, 0x0038, - /* 2099 */ 0x0031, 0x0039, - /* 2101 */ 0x0032, 0x0030, - /* 2103 */ 0x0028, 0x0031, 0x0029, - /* 2106 */ 0x0028, 0x0032, 0x0029, - /* 2109 */ 0x0028, 0x0033, 0x0029, - /* 2112 */ 0x0028, 0x0034, 0x0029, - /* 2115 */ 0x0028, 0x0035, 0x0029, - /* 2118 */ 0x0028, 0x0036, 0x0029, - /* 2121 */ 0x0028, 0x0037, 0x0029, - /* 2124 */ 0x0028, 0x0038, 0x0029, - /* 2127 */ 0x0028, 0x0039, 0x0029, - /* 2130 */ 0x0028, 0x0031, 0x0030, 0x0029, - /* 2134 */ 0x0028, 0x0031, 0x0031, 0x0029, - /* 2138 */ 0x0028, 0x0031, 0x0032, 0x0029, - /* 2142 */ 0x0028, 0x0031, 0x0033, 0x0029, - /* 2146 */ 0x0028, 0x0031, 0x0034, 0x0029, - /* 2150 */ 0x0028, 0x0031, 0x0035, 0x0029, - /* 2154 */ 0x0028, 0x0031, 0x0036, 0x0029, - /* 2158 */ 0x0028, 0x0031, 0x0037, 0x0029, - /* 2162 */ 0x0028, 0x0031, 0x0038, 0x0029, - /* 2166 */ 0x0028, 0x0031, 0x0039, 0x0029, - /* 2170 */ 0x0028, 0x0032, 0x0030, 0x0029, - /* 2174 */ 0x0031, 0x002E, - /* 2176 */ 0x0032, 0x002E, - /* 2178 */ 0x0033, 0x002E, - /* 2180 */ 0x0034, 0x002E, - /* 2182 */ 0x0035, 0x002E, - /* 2184 */ 0x0036, 0x002E, - /* 2186 */ 0x0037, 0x002E, - /* 2188 */ 0x0038, 0x002E, - /* 2190 */ 0x0039, 0x002E, - /* 2192 */ 0x0031, 0x0030, 0x002E, - /* 2195 */ 0x0031, 0x0031, 0x002E, - /* 2198 */ 0x0031, 0x0032, 0x002E, - /* 2201 */ 0x0031, 0x0033, 0x002E, - /* 2204 */ 0x0031, 0x0034, 0x002E, - /* 2207 */ 0x0031, 0x0035, 0x002E, - /* 2210 */ 0x0031, 0x0036, 0x002E, - /* 2213 */ 0x0031, 0x0037, 0x002E, - /* 2216 */ 0x0031, 0x0038, 0x002E, - /* 2219 */ 0x0031, 0x0039, 0x002E, - /* 2222 */ 0x0032, 0x0030, 0x002E, - /* 2225 */ 0x0028, 0x0061, 0x0029, - /* 2228 */ 0x0028, 0x0062, 0x0029, - /* 2231 */ 0x0028, 0x0063, 0x0029, - /* 2234 */ 0x0028, 0x0064, 0x0029, - /* 2237 */ 0x0028, 0x0065, 0x0029, - /* 2240 */ 0x0028, 0x0066, 0x0029, - /* 2243 */ 0x0028, 0x0067, 0x0029, - /* 2246 */ 0x0028, 0x0068, 0x0029, - /* 2249 */ 0x0028, 0x0069, 0x0029, - /* 2252 */ 0x0028, 0x006A, 0x0029, - /* 2255 */ 0x0028, 0x006B, 0x0029, - /* 2258 */ 0x0028, 0x006C, 0x0029, - /* 2261 */ 0x0028, 0x006D, 0x0029, - /* 2264 */ 0x0028, 0x006E, 0x0029, - /* 2267 */ 0x0028, 0x006F, 0x0029, - /* 2270 */ 0x0028, 0x0070, 0x0029, - /* 2273 */ 0x0028, 0x0071, 0x0029, - /* 2276 */ 0x0028, 0x0072, 0x0029, - /* 2279 */ 0x0028, 0x0073, 0x0029, - /* 2282 */ 0x0028, 0x0074, 0x0029, - /* 2285 */ 0x0028, 0x0075, 0x0029, - /* 2288 */ 0x0028, 0x0076, 0x0029, - /* 2291 */ 0x0028, 0x0077, 0x0029, - /* 2294 */ 0x0028, 0x0078, 0x0029, - /* 2297 */ 0x0028, 0x0079, 0x0029, - /* 2300 */ 0x0028, 0x007A, 0x0029, - /* 2303 */ 0x222B, 0x222B, 0x222B, 0x222B, - /* 2307 */ 0x003A, 0x003A, 0x003D, - /* 2310 */ 0x003D, 0x003D, - /* 2312 */ 0x003D, 0x003D, 0x003D, - /* 2315 */ 0x2ADD, 0x0338, - /* 2317 */ 0x304B, 0x3099, - /* 2319 */ 0x304D, 0x3099, - /* 2321 */ 0x304F, 0x3099, - /* 2323 */ 0x3051, 0x3099, - /* 2325 */ 0x3053, 0x3099, - /* 2327 */ 0x3055, 0x3099, - /* 2329 */ 0x3057, 0x3099, - /* 2331 */ 0x3059, 0x3099, - /* 2333 */ 0x305B, 0x3099, - /* 2335 */ 0x305D, 0x3099, - /* 2337 */ 0x305F, 0x3099, - /* 2339 */ 0x3061, 0x3099, - /* 2341 */ 0x3064, 0x3099, - /* 2343 */ 0x3066, 0x3099, - /* 2345 */ 0x3068, 0x3099, - /* 2347 */ 0x306F, 0x3099, - /* 2349 */ 0x306F, 0x309A, - /* 2351 */ 0x3072, 0x3099, - /* 2353 */ 0x3072, 0x309A, - /* 2355 */ 0x3075, 0x3099, - /* 2357 */ 0x3075, 0x309A, - /* 2359 */ 0x3078, 0x3099, - /* 2361 */ 0x3078, 0x309A, - /* 2363 */ 0x307B, 0x3099, - /* 2365 */ 0x307B, 0x309A, - /* 2367 */ 0x3046, 0x3099, - /* 2369 */ 0x0020, 0x3099, - /* 2371 */ 0x0020, 0x309A, - /* 2373 */ 0x309D, 0x3099, - /* 2375 */ 0x3088, 0x308A, - /* 2377 */ 0x30AB, 0x3099, - /* 2379 */ 0x30AD, 0x3099, - /* 2381 */ 0x30AF, 0x3099, - /* 2383 */ 0x30B1, 0x3099, - /* 2385 */ 0x30B3, 0x3099, - /* 2387 */ 0x30B5, 0x3099, - /* 2389 */ 0x30B7, 0x3099, - /* 2391 */ 0x30B9, 0x3099, - /* 2393 */ 0x30BB, 0x3099, - /* 2395 */ 0x30BD, 0x3099, - /* 2397 */ 0x30BF, 0x3099, - /* 2399 */ 0x30C1, 0x3099, - /* 2401 */ 0x30C4, 0x3099, - /* 2403 */ 0x30C6, 0x3099, - /* 2405 */ 0x30C8, 0x3099, - /* 2407 */ 0x30CF, 0x3099, - /* 2409 */ 0x30CF, 0x309A, - /* 2411 */ 0x30D2, 0x3099, - /* 2413 */ 0x30D2, 0x309A, - /* 2415 */ 0x30D5, 0x3099, - /* 2417 */ 0x30D5, 0x309A, - /* 2419 */ 0x30D8, 0x3099, - /* 2421 */ 0x30D8, 0x309A, - /* 2423 */ 0x30DB, 0x3099, - /* 2425 */ 0x30DB, 0x309A, - /* 2427 */ 0x30A6, 0x3099, - /* 2429 */ 0x30EF, 0x3099, - /* 2431 */ 0x30F0, 0x3099, - /* 2433 */ 0x30F1, 0x3099, - /* 2435 */ 0x30F2, 0x3099, - /* 2437 */ 0x30FD, 0x3099, - /* 2439 */ 0x30B3, 0x30C8, - /* 2441 */ 0x0028, 0x1100, 0x0029, - /* 2444 */ 0x0028, 0x1102, 0x0029, - /* 2447 */ 0x0028, 0x1103, 0x0029, - /* 2450 */ 0x0028, 0x1105, 0x0029, - /* 2453 */ 0x0028, 0x1106, 0x0029, - /* 2456 */ 0x0028, 0x1107, 0x0029, - /* 2459 */ 0x0028, 0x1109, 0x0029, - /* 2462 */ 0x0028, 0x110B, 0x0029, - /* 2465 */ 0x0028, 0x110C, 0x0029, - /* 2468 */ 0x0028, 0x110E, 0x0029, - /* 2471 */ 0x0028, 0x110F, 0x0029, - /* 2474 */ 0x0028, 0x1110, 0x0029, - /* 2477 */ 0x0028, 0x1111, 0x0029, - /* 2480 */ 0x0028, 0x1112, 0x0029, - /* 2483 */ 0x0028, 0x1100, 0x1161, 0x0029, - /* 2487 */ 0x0028, 0x1102, 0x1161, 0x0029, - /* 2491 */ 0x0028, 0x1103, 0x1161, 0x0029, - /* 2495 */ 0x0028, 0x1105, 0x1161, 0x0029, - /* 2499 */ 0x0028, 0x1106, 0x1161, 0x0029, - /* 2503 */ 0x0028, 0x1107, 0x1161, 0x0029, - /* 2507 */ 0x0028, 0x1109, 0x1161, 0x0029, - /* 2511 */ 0x0028, 0x110B, 0x1161, 0x0029, - /* 2515 */ 0x0028, 0x110C, 0x1161, 0x0029, - /* 2519 */ 0x0028, 0x110E, 0x1161, 0x0029, - /* 2523 */ 0x0028, 0x110F, 0x1161, 0x0029, - /* 2527 */ 0x0028, 0x1110, 0x1161, 0x0029, - /* 2531 */ 0x0028, 0x1111, 0x1161, 0x0029, - /* 2535 */ 0x0028, 0x1112, 0x1161, 0x0029, - /* 2539 */ 0x0028, 0x110C, 0x116E, 0x0029, - /* 2543 */ 0x0028, 0x110B, 0x1169, 0x110C, 0x1165, 0x11AB, 0x0029, - /* 2550 */ 0x0028, 0x110B, 0x1169, 0x1112, 0x116E, 0x0029, - /* 2556 */ 0x0028, 0x4E00, 0x0029, - /* 2559 */ 0x0028, 0x4E8C, 0x0029, - /* 2562 */ 0x0028, 0x4E09, 0x0029, - /* 2565 */ 0x0028, 0x56DB, 0x0029, - /* 2568 */ 0x0028, 0x4E94, 0x0029, - /* 2571 */ 0x0028, 0x516D, 0x0029, - /* 2574 */ 0x0028, 0x4E03, 0x0029, - /* 2577 */ 0x0028, 0x516B, 0x0029, - /* 2580 */ 0x0028, 0x4E5D, 0x0029, - /* 2583 */ 0x0028, 0x5341, 0x0029, - /* 2586 */ 0x0028, 0x6708, 0x0029, - /* 2589 */ 0x0028, 0x706B, 0x0029, - /* 2592 */ 0x0028, 0x6C34, 0x0029, - /* 2595 */ 0x0028, 0x6728, 0x0029, - /* 2598 */ 0x0028, 0x91D1, 0x0029, - /* 2601 */ 0x0028, 0x571F, 0x0029, - /* 2604 */ 0x0028, 0x65E5, 0x0029, - /* 2607 */ 0x0028, 0x682A, 0x0029, - /* 2610 */ 0x0028, 0x6709, 0x0029, - /* 2613 */ 0x0028, 0x793E, 0x0029, - /* 2616 */ 0x0028, 0x540D, 0x0029, - /* 2619 */ 0x0028, 0x7279, 0x0029, - /* 2622 */ 0x0028, 0x8CA1, 0x0029, - /* 2625 */ 0x0028, 0x795D, 0x0029, - /* 2628 */ 0x0028, 0x52B4, 0x0029, - /* 2631 */ 0x0028, 0x4EE3, 0x0029, - /* 2634 */ 0x0028, 0x547C, 0x0029, - /* 2637 */ 0x0028, 0x5B66, 0x0029, - /* 2640 */ 0x0028, 0x76E3, 0x0029, - /* 2643 */ 0x0028, 0x4F01, 0x0029, - /* 2646 */ 0x0028, 0x8CC7, 0x0029, - /* 2649 */ 0x0028, 0x5354, 0x0029, - /* 2652 */ 0x0028, 0x796D, 0x0029, - /* 2655 */ 0x0028, 0x4F11, 0x0029, - /* 2658 */ 0x0028, 0x81EA, 0x0029, - /* 2661 */ 0x0028, 0x81F3, 0x0029, - /* 2664 */ 0x0050, 0x0054, 0x0045, - /* 2667 */ 0x0032, 0x0031, - /* 2669 */ 0x0032, 0x0032, - /* 2671 */ 0x0032, 0x0033, - /* 2673 */ 0x0032, 0x0034, - /* 2675 */ 0x0032, 0x0035, - /* 2677 */ 0x0032, 0x0036, - /* 2679 */ 0x0032, 0x0037, - /* 2681 */ 0x0032, 0x0038, - /* 2683 */ 0x0032, 0x0039, - /* 2685 */ 0x0033, 0x0030, - /* 2687 */ 0x0033, 0x0031, - /* 2689 */ 0x0033, 0x0032, - /* 2691 */ 0x0033, 0x0033, - /* 2693 */ 0x0033, 0x0034, - /* 2695 */ 0x0033, 0x0035, - /* 2697 */ 0x1100, 0x1161, - /* 2699 */ 0x1102, 0x1161, - /* 2701 */ 0x1103, 0x1161, - /* 2703 */ 0x1105, 0x1161, - /* 2705 */ 0x1106, 0x1161, - /* 2707 */ 0x1107, 0x1161, - /* 2709 */ 0x1109, 0x1161, - /* 2711 */ 0x110B, 0x1161, - /* 2713 */ 0x110C, 0x1161, - /* 2715 */ 0x110E, 0x1161, - /* 2717 */ 0x110F, 0x1161, - /* 2719 */ 0x1110, 0x1161, - /* 2721 */ 0x1111, 0x1161, - /* 2723 */ 0x1112, 0x1161, - /* 2725 */ 0x110E, 0x1161, 0x11B7, 0x1100, 0x1169, - /* 2730 */ 0x110C, 0x116E, 0x110B, 0x1174, - /* 2734 */ 0x110B, 0x116E, - /* 2736 */ 0x0033, 0x0036, - /* 2738 */ 0x0033, 0x0037, - /* 2740 */ 0x0033, 0x0038, - /* 2742 */ 0x0033, 0x0039, - /* 2744 */ 0x0034, 0x0030, - /* 2746 */ 0x0034, 0x0031, - /* 2748 */ 0x0034, 0x0032, - /* 2750 */ 0x0034, 0x0033, - /* 2752 */ 0x0034, 0x0034, - /* 2754 */ 0x0034, 0x0035, - /* 2756 */ 0x0034, 0x0036, - /* 2758 */ 0x0034, 0x0037, - /* 2760 */ 0x0034, 0x0038, - /* 2762 */ 0x0034, 0x0039, - /* 2764 */ 0x0035, 0x0030, - /* 2766 */ 0x0031, 0x6708, - /* 2768 */ 0x0032, 0x6708, - /* 2770 */ 0x0033, 0x6708, - /* 2772 */ 0x0034, 0x6708, - /* 2774 */ 0x0035, 0x6708, - /* 2776 */ 0x0036, 0x6708, - /* 2778 */ 0x0037, 0x6708, - /* 2780 */ 0x0038, 0x6708, - /* 2782 */ 0x0039, 0x6708, - /* 2784 */ 0x0031, 0x0030, 0x6708, - /* 2787 */ 0x0031, 0x0031, 0x6708, - /* 2790 */ 0x0031, 0x0032, 0x6708, - /* 2793 */ 0x0048, 0x0067, - /* 2795 */ 0x0065, 0x0072, 0x0067, - /* 2798 */ 0x0065, 0x0056, - /* 2800 */ 0x004C, 0x0054, 0x0044, - /* 2803 */ 0x4EE4, 0x548C, - /* 2805 */ 0x30A2, 0x30D1, 0x30FC, 0x30C8, - /* 2809 */ 0x30A2, 0x30EB, 0x30D5, 0x30A1, - /* 2813 */ 0x30A2, 0x30F3, 0x30DA, 0x30A2, - /* 2817 */ 0x30A2, 0x30FC, 0x30EB, - /* 2820 */ 0x30A4, 0x30CB, 0x30F3, 0x30B0, - /* 2824 */ 0x30A4, 0x30F3, 0x30C1, - /* 2827 */ 0x30A6, 0x30A9, 0x30F3, - /* 2830 */ 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, - /* 2835 */ 0x30A8, 0x30FC, 0x30AB, 0x30FC, - /* 2839 */ 0x30AA, 0x30F3, 0x30B9, - /* 2842 */ 0x30AA, 0x30FC, 0x30E0, - /* 2845 */ 0x30AB, 0x30A4, 0x30EA, - /* 2848 */ 0x30AB, 0x30E9, 0x30C3, 0x30C8, - /* 2852 */ 0x30AB, 0x30ED, 0x30EA, 0x30FC, - /* 2856 */ 0x30AC, 0x30ED, 0x30F3, - /* 2859 */ 0x30AC, 0x30F3, 0x30DE, - /* 2862 */ 0x30AE, 0x30AC, - /* 2864 */ 0x30AE, 0x30CB, 0x30FC, - /* 2867 */ 0x30AD, 0x30E5, 0x30EA, 0x30FC, - /* 2871 */ 0x30AE, 0x30EB, 0x30C0, 0x30FC, - /* 2875 */ 0x30AD, 0x30ED, - /* 2877 */ 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, - /* 2882 */ 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, - /* 2888 */ 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, - /* 2893 */ 0x30B0, 0x30E9, 0x30E0, - /* 2896 */ 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, - /* 2901 */ 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, - /* 2906 */ 0x30AF, 0x30ED, 0x30FC, 0x30CD, - /* 2910 */ 0x30B1, 0x30FC, 0x30B9, - /* 2913 */ 0x30B3, 0x30EB, 0x30CA, - /* 2916 */ 0x30B3, 0x30FC, 0x30DD, - /* 2919 */ 0x30B5, 0x30A4, 0x30AF, 0x30EB, - /* 2923 */ 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, - /* 2928 */ 0x30B7, 0x30EA, 0x30F3, 0x30B0, - /* 2932 */ 0x30BB, 0x30F3, 0x30C1, - /* 2935 */ 0x30BB, 0x30F3, 0x30C8, - /* 2938 */ 0x30C0, 0x30FC, 0x30B9, - /* 2941 */ 0x30C7, 0x30B7, - /* 2943 */ 0x30C9, 0x30EB, - /* 2945 */ 0x30C8, 0x30F3, - /* 2947 */ 0x30CA, 0x30CE, - /* 2949 */ 0x30CE, 0x30C3, 0x30C8, - /* 2952 */ 0x30CF, 0x30A4, 0x30C4, - /* 2955 */ 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, - /* 2960 */ 0x30D1, 0x30FC, 0x30C4, - /* 2963 */ 0x30D0, 0x30FC, 0x30EC, 0x30EB, - /* 2967 */ 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, - /* 2972 */ 0x30D4, 0x30AF, 0x30EB, - /* 2975 */ 0x30D4, 0x30B3, - /* 2977 */ 0x30D3, 0x30EB, - /* 2979 */ 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, - /* 2984 */ 0x30D5, 0x30A3, 0x30FC, 0x30C8, - /* 2988 */ 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, - /* 2993 */ 0x30D5, 0x30E9, 0x30F3, - /* 2996 */ 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, - /* 3001 */ 0x30DA, 0x30BD, - /* 3003 */ 0x30DA, 0x30CB, 0x30D2, - /* 3006 */ 0x30D8, 0x30EB, 0x30C4, - /* 3009 */ 0x30DA, 0x30F3, 0x30B9, - /* 3012 */ 0x30DA, 0x30FC, 0x30B8, - /* 3015 */ 0x30D9, 0x30FC, 0x30BF, - /* 3018 */ 0x30DD, 0x30A4, 0x30F3, 0x30C8, - /* 3022 */ 0x30DC, 0x30EB, 0x30C8, - /* 3025 */ 0x30DB, 0x30F3, - /* 3027 */ 0x30DD, 0x30F3, 0x30C9, - /* 3030 */ 0x30DB, 0x30FC, 0x30EB, - /* 3033 */ 0x30DB, 0x30FC, 0x30F3, - /* 3036 */ 0x30DE, 0x30A4, 0x30AF, 0x30ED, - /* 3040 */ 0x30DE, 0x30A4, 0x30EB, - /* 3043 */ 0x30DE, 0x30C3, 0x30CF, - /* 3046 */ 0x30DE, 0x30EB, 0x30AF, - /* 3049 */ 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, - /* 3054 */ 0x30DF, 0x30AF, 0x30ED, 0x30F3, - /* 3058 */ 0x30DF, 0x30EA, - /* 3060 */ 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, - /* 3065 */ 0x30E1, 0x30AC, - /* 3067 */ 0x30E1, 0x30AC, 0x30C8, 0x30F3, - /* 3071 */ 0x30E1, 0x30FC, 0x30C8, 0x30EB, - /* 3075 */ 0x30E4, 0x30FC, 0x30C9, - /* 3078 */ 0x30E4, 0x30FC, 0x30EB, - /* 3081 */ 0x30E6, 0x30A2, 0x30F3, - /* 3084 */ 0x30EA, 0x30C3, 0x30C8, 0x30EB, - /* 3088 */ 0x30EA, 0x30E9, - /* 3090 */ 0x30EB, 0x30D4, 0x30FC, - /* 3093 */ 0x30EB, 0x30FC, 0x30D6, 0x30EB, - /* 3097 */ 0x30EC, 0x30E0, - /* 3099 */ 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, - /* 3104 */ 0x30EF, 0x30C3, 0x30C8, - /* 3107 */ 0x0030, 0x70B9, - /* 3109 */ 0x0031, 0x70B9, - /* 3111 */ 0x0032, 0x70B9, - /* 3113 */ 0x0033, 0x70B9, - /* 3115 */ 0x0034, 0x70B9, - /* 3117 */ 0x0035, 0x70B9, - /* 3119 */ 0x0036, 0x70B9, - /* 3121 */ 0x0037, 0x70B9, - /* 3123 */ 0x0038, 0x70B9, - /* 3125 */ 0x0039, 0x70B9, - /* 3127 */ 0x0031, 0x0030, 0x70B9, - /* 3130 */ 0x0031, 0x0031, 0x70B9, - /* 3133 */ 0x0031, 0x0032, 0x70B9, - /* 3136 */ 0x0031, 0x0033, 0x70B9, - /* 3139 */ 0x0031, 0x0034, 0x70B9, - /* 3142 */ 0x0031, 0x0035, 0x70B9, - /* 3145 */ 0x0031, 0x0036, 0x70B9, - /* 3148 */ 0x0031, 0x0037, 0x70B9, - /* 3151 */ 0x0031, 0x0038, 0x70B9, - /* 3154 */ 0x0031, 0x0039, 0x70B9, - /* 3157 */ 0x0032, 0x0030, 0x70B9, - /* 3160 */ 0x0032, 0x0031, 0x70B9, - /* 3163 */ 0x0032, 0x0032, 0x70B9, - /* 3166 */ 0x0032, 0x0033, 0x70B9, - /* 3169 */ 0x0032, 0x0034, 0x70B9, - /* 3172 */ 0x0068, 0x0050, 0x0061, - /* 3175 */ 0x0064, 0x0061, - /* 3177 */ 0x0041, 0x0055, - /* 3179 */ 0x0062, 0x0061, 0x0072, - /* 3182 */ 0x006F, 0x0056, - /* 3184 */ 0x0070, 0x0063, - /* 3186 */ 0x0064, 0x006D, - /* 3188 */ 0x0064, 0x006D, 0x00B2, - /* 3191 */ 0x0064, 0x006D, 0x00B3, - /* 3194 */ 0x0049, 0x0055, - /* 3196 */ 0x5E73, 0x6210, - /* 3198 */ 0x662D, 0x548C, - /* 3200 */ 0x5927, 0x6B63, - /* 3202 */ 0x660E, 0x6CBB, - /* 3204 */ 0x682A, 0x5F0F, 0x4F1A, 0x793E, - /* 3208 */ 0x0070, 0x0041, - /* 3210 */ 0x006E, 0x0041, - /* 3212 */ 0x03BC, 0x0041, - /* 3214 */ 0x006D, 0x0041, - /* 3216 */ 0x006B, 0x0041, - /* 3218 */ 0x004B, 0x0042, - /* 3220 */ 0x004D, 0x0042, - /* 3222 */ 0x0047, 0x0042, - /* 3224 */ 0x0063, 0x0061, 0x006C, - /* 3227 */ 0x006B, 0x0063, 0x0061, 0x006C, - /* 3231 */ 0x0070, 0x0046, - /* 3233 */ 0x006E, 0x0046, - /* 3235 */ 0x03BC, 0x0046, - /* 3237 */ 0x03BC, 0x0067, - /* 3239 */ 0x006D, 0x0067, - /* 3241 */ 0x006B, 0x0067, - /* 3243 */ 0x0048, 0x007A, - /* 3245 */ 0x006B, 0x0048, 0x007A, - /* 3248 */ 0x004D, 0x0048, 0x007A, - /* 3251 */ 0x0047, 0x0048, 0x007A, - /* 3254 */ 0x0054, 0x0048, 0x007A, - /* 3257 */ 0x03BC, 0x2113, - /* 3259 */ 0x006D, 0x2113, - /* 3261 */ 0x0064, 0x2113, - /* 3263 */ 0x006B, 0x2113, - /* 3265 */ 0x0066, 0x006D, - /* 3267 */ 0x006E, 0x006D, - /* 3269 */ 0x03BC, 0x006D, - /* 3271 */ 0x006D, 0x006D, - /* 3273 */ 0x0063, 0x006D, - /* 3275 */ 0x006B, 0x006D, - /* 3277 */ 0x006D, 0x006D, 0x00B2, - /* 3280 */ 0x0063, 0x006D, 0x00B2, - /* 3283 */ 0x006D, 0x00B2, - /* 3285 */ 0x006B, 0x006D, 0x00B2, - /* 3288 */ 0x006D, 0x006D, 0x00B3, - /* 3291 */ 0x0063, 0x006D, 0x00B3, - /* 3294 */ 0x006D, 0x00B3, - /* 3296 */ 0x006B, 0x006D, 0x00B3, - /* 3299 */ 0x006D, 0x2215, 0x0073, - /* 3302 */ 0x006D, 0x2215, 0x0073, 0x00B2, - /* 3306 */ 0x0050, 0x0061, - /* 3308 */ 0x006B, 0x0050, 0x0061, - /* 3311 */ 0x004D, 0x0050, 0x0061, - /* 3314 */ 0x0047, 0x0050, 0x0061, - /* 3317 */ 0x0072, 0x0061, 0x0064, - /* 3320 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, - /* 3325 */ 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, - /* 3331 */ 0x0070, 0x0073, - /* 3333 */ 0x006E, 0x0073, - /* 3335 */ 0x03BC, 0x0073, - /* 3337 */ 0x006D, 0x0073, - /* 3339 */ 0x0070, 0x0056, - /* 3341 */ 0x006E, 0x0056, - /* 3343 */ 0x03BC, 0x0056, - /* 3345 */ 0x006D, 0x0056, - /* 3347 */ 0x006B, 0x0056, - /* 3349 */ 0x004D, 0x0056, - /* 3351 */ 0x0070, 0x0057, - /* 3353 */ 0x006E, 0x0057, - /* 3355 */ 0x03BC, 0x0057, - /* 3357 */ 0x006D, 0x0057, - /* 3359 */ 0x006B, 0x0057, - /* 3361 */ 0x004D, 0x0057, - /* 3363 */ 0x006B, 0x03A9, - /* 3365 */ 0x004D, 0x03A9, - /* 3367 */ 0x0061, 0x002E, 0x006D, 0x002E, - /* 3371 */ 0x0042, 0x0071, - /* 3373 */ 0x0063, 0x0063, - /* 3375 */ 0x0063, 0x0064, - /* 3377 */ 0x0043, 0x2215, 0x006B, 0x0067, - /* 3381 */ 0x0043, 0x006F, 0x002E, - /* 3384 */ 0x0064, 0x0042, - /* 3386 */ 0x0047, 0x0079, - /* 3388 */ 0x0068, 0x0061, - /* 3390 */ 0x0048, 0x0050, - /* 3392 */ 0x0069, 0x006E, - /* 3394 */ 0x004B, 0x004B, - /* 3396 */ 0x004B, 0x004D, - /* 3398 */ 0x006B, 0x0074, - /* 3400 */ 0x006C, 0x006D, - /* 3402 */ 0x006C, 0x006E, - /* 3404 */ 0x006C, 0x006F, 0x0067, - /* 3407 */ 0x006C, 0x0078, - /* 3409 */ 0x006D, 0x0062, - /* 3411 */ 0x006D, 0x0069, 0x006C, - /* 3414 */ 0x006D, 0x006F, 0x006C, - /* 3417 */ 0x0050, 0x0048, - /* 3419 */ 0x0070, 0x002E, 0x006D, 0x002E, - /* 3423 */ 0x0050, 0x0050, 0x004D, - /* 3426 */ 0x0050, 0x0052, - /* 3428 */ 0x0073, 0x0072, - /* 3430 */ 0x0053, 0x0076, - /* 3432 */ 0x0057, 0x0062, - /* 3434 */ 0x0056, 0x2215, 0x006D, - /* 3437 */ 0x0041, 0x2215, 0x006D, - /* 3440 */ 0x0031, 0x65E5, - /* 3442 */ 0x0032, 0x65E5, - /* 3444 */ 0x0033, 0x65E5, - /* 3446 */ 0x0034, 0x65E5, - /* 3448 */ 0x0035, 0x65E5, - /* 3450 */ 0x0036, 0x65E5, - /* 3452 */ 0x0037, 0x65E5, - /* 3454 */ 0x0038, 0x65E5, - /* 3456 */ 0x0039, 0x65E5, - /* 3458 */ 0x0031, 0x0030, 0x65E5, - /* 3461 */ 0x0031, 0x0031, 0x65E5, - /* 3464 */ 0x0031, 0x0032, 0x65E5, - /* 3467 */ 0x0031, 0x0033, 0x65E5, - /* 3470 */ 0x0031, 0x0034, 0x65E5, - /* 3473 */ 0x0031, 0x0035, 0x65E5, - /* 3476 */ 0x0031, 0x0036, 0x65E5, - /* 3479 */ 0x0031, 0x0037, 0x65E5, - /* 3482 */ 0x0031, 0x0038, 0x65E5, - /* 3485 */ 0x0031, 0x0039, 0x65E5, - /* 3488 */ 0x0032, 0x0030, 0x65E5, - /* 3491 */ 0x0032, 0x0031, 0x65E5, - /* 3494 */ 0x0032, 0x0032, 0x65E5, - /* 3497 */ 0x0032, 0x0033, 0x65E5, - /* 3500 */ 0x0032, 0x0034, 0x65E5, - /* 3503 */ 0x0032, 0x0035, 0x65E5, - /* 3506 */ 0x0032, 0x0036, 0x65E5, - /* 3509 */ 0x0032, 0x0037, 0x65E5, - /* 3512 */ 0x0032, 0x0038, 0x65E5, - /* 3515 */ 0x0032, 0x0039, 0x65E5, - /* 3518 */ 0x0033, 0x0030, 0x65E5, - /* 3521 */ 0x0033, 0x0031, 0x65E5, - /* 3524 */ 0x0067, 0x0061, 0x006C, - /* 3527 */ 0x242EE, - /* 3528 */ 0x2284A, - /* 3529 */ 0x22844, - /* 3530 */ 0x233D5, - /* 3531 */ 0x25249, - /* 3532 */ 0x25CD0, - /* 3533 */ 0x27ED3, - /* 3534 */ 0x0066, 0x0066, - /* 3536 */ 0x0066, 0x0069, - /* 3538 */ 0x0066, 0x006C, - /* 3540 */ 0x0066, 0x0066, 0x0069, - /* 3543 */ 0x0066, 0x0066, 0x006C, - /* 3546 */ 0x017F, 0x0074, - /* 3548 */ 0x0073, 0x0074, - /* 3550 */ 0x0574, 0x0576, - /* 3552 */ 0x0574, 0x0565, - /* 3554 */ 0x0574, 0x056B, - /* 3556 */ 0x057E, 0x0576, - /* 3558 */ 0x0574, 0x056D, - /* 3560 */ 0x05D9, 0x05B4, - /* 3562 */ 0x05F2, 0x05B7, - /* 3564 */ 0x05E9, 0x05C1, - /* 3566 */ 0x05E9, 0x05C2, - /* 3568 */ 0xFB49, 0x05C1, - /* 3570 */ 0xFB49, 0x05C2, - /* 3572 */ 0x05D0, 0x05B7, - /* 3574 */ 0x05D0, 0x05B8, - /* 3576 */ 0x05D0, 0x05BC, - /* 3578 */ 0x05D1, 0x05BC, - /* 3580 */ 0x05D2, 0x05BC, - /* 3582 */ 0x05D3, 0x05BC, - /* 3584 */ 0x05D4, 0x05BC, - /* 3586 */ 0x05D5, 0x05BC, - /* 3588 */ 0x05D6, 0x05BC, - /* 3590 */ 0x05D8, 0x05BC, - /* 3592 */ 0x05D9, 0x05BC, - /* 3594 */ 0x05DA, 0x05BC, - /* 3596 */ 0x05DB, 0x05BC, - /* 3598 */ 0x05DC, 0x05BC, - /* 3600 */ 0x05DE, 0x05BC, - /* 3602 */ 0x05E0, 0x05BC, - /* 3604 */ 0x05E1, 0x05BC, - /* 3606 */ 0x05E3, 0x05BC, - /* 3608 */ 0x05E4, 0x05BC, - /* 3610 */ 0x05E6, 0x05BC, - /* 3612 */ 0x05E7, 0x05BC, - /* 3614 */ 0x05E8, 0x05BC, - /* 3616 */ 0x05E9, 0x05BC, - /* 3618 */ 0x05EA, 0x05BC, - /* 3620 */ 0x05D5, 0x05B9, - /* 3622 */ 0x05D1, 0x05BF, - /* 3624 */ 0x05DB, 0x05BF, - /* 3626 */ 0x05E4, 0x05BF, - /* 3628 */ 0x05D0, 0x05DC, - /* 3630 */ 0x0626, 0x0627, - /* 3632 */ 0x0626, 0x0627, - /* 3634 */ 0x0626, 0x06D5, - /* 3636 */ 0x0626, 0x06D5, - /* 3638 */ 0x0626, 0x0648, - /* 3640 */ 0x0626, 0x0648, - /* 3642 */ 0x0626, 0x06C7, - /* 3644 */ 0x0626, 0x06C7, - /* 3646 */ 0x0626, 0x06C6, - /* 3648 */ 0x0626, 0x06C6, - /* 3650 */ 0x0626, 0x06C8, - /* 3652 */ 0x0626, 0x06C8, - /* 3654 */ 0x0626, 0x06D0, - /* 3656 */ 0x0626, 0x06D0, - /* 3658 */ 0x0626, 0x06D0, - /* 3660 */ 0x0626, 0x0649, - /* 3662 */ 0x0626, 0x0649, - /* 3664 */ 0x0626, 0x0649, - /* 3666 */ 0x0626, 0x062C, - /* 3668 */ 0x0626, 0x062D, - /* 3670 */ 0x0626, 0x0645, - /* 3672 */ 0x0626, 0x0649, - /* 3674 */ 0x0626, 0x064A, - /* 3676 */ 0x0628, 0x062C, - /* 3678 */ 0x0628, 0x062D, - /* 3680 */ 0x0628, 0x062E, - /* 3682 */ 0x0628, 0x0645, - /* 3684 */ 0x0628, 0x0649, - /* 3686 */ 0x0628, 0x064A, - /* 3688 */ 0x062A, 0x062C, - /* 3690 */ 0x062A, 0x062D, - /* 3692 */ 0x062A, 0x062E, - /* 3694 */ 0x062A, 0x0645, - /* 3696 */ 0x062A, 0x0649, - /* 3698 */ 0x062A, 0x064A, - /* 3700 */ 0x062B, 0x062C, - /* 3702 */ 0x062B, 0x0645, - /* 3704 */ 0x062B, 0x0649, - /* 3706 */ 0x062B, 0x064A, - /* 3708 */ 0x062C, 0x062D, - /* 3710 */ 0x062C, 0x0645, - /* 3712 */ 0x062D, 0x062C, - /* 3714 */ 0x062D, 0x0645, - /* 3716 */ 0x062E, 0x062C, - /* 3718 */ 0x062E, 0x062D, - /* 3720 */ 0x062E, 0x0645, - /* 3722 */ 0x0633, 0x062C, - /* 3724 */ 0x0633, 0x062D, - /* 3726 */ 0x0633, 0x062E, - /* 3728 */ 0x0633, 0x0645, - /* 3730 */ 0x0635, 0x062D, - /* 3732 */ 0x0635, 0x0645, - /* 3734 */ 0x0636, 0x062C, - /* 3736 */ 0x0636, 0x062D, - /* 3738 */ 0x0636, 0x062E, - /* 3740 */ 0x0636, 0x0645, - /* 3742 */ 0x0637, 0x062D, - /* 3744 */ 0x0637, 0x0645, - /* 3746 */ 0x0638, 0x0645, - /* 3748 */ 0x0639, 0x062C, - /* 3750 */ 0x0639, 0x0645, - /* 3752 */ 0x063A, 0x062C, - /* 3754 */ 0x063A, 0x0645, - /* 3756 */ 0x0641, 0x062C, - /* 3758 */ 0x0641, 0x062D, - /* 3760 */ 0x0641, 0x062E, - /* 3762 */ 0x0641, 0x0645, - /* 3764 */ 0x0641, 0x0649, - /* 3766 */ 0x0641, 0x064A, - /* 3768 */ 0x0642, 0x062D, - /* 3770 */ 0x0642, 0x0645, - /* 3772 */ 0x0642, 0x0649, - /* 3774 */ 0x0642, 0x064A, - /* 3776 */ 0x0643, 0x0627, - /* 3778 */ 0x0643, 0x062C, - /* 3780 */ 0x0643, 0x062D, - /* 3782 */ 0x0643, 0x062E, - /* 3784 */ 0x0643, 0x0644, - /* 3786 */ 0x0643, 0x0645, - /* 3788 */ 0x0643, 0x0649, - /* 3790 */ 0x0643, 0x064A, - /* 3792 */ 0x0644, 0x062C, - /* 3794 */ 0x0644, 0x062D, - /* 3796 */ 0x0644, 0x062E, - /* 3798 */ 0x0644, 0x0645, - /* 3800 */ 0x0644, 0x0649, - /* 3802 */ 0x0644, 0x064A, - /* 3804 */ 0x0645, 0x062C, - /* 3806 */ 0x0645, 0x062D, - /* 3808 */ 0x0645, 0x062E, - /* 3810 */ 0x0645, 0x0645, - /* 3812 */ 0x0645, 0x0649, - /* 3814 */ 0x0645, 0x064A, - /* 3816 */ 0x0646, 0x062C, - /* 3818 */ 0x0646, 0x062D, - /* 3820 */ 0x0646, 0x062E, - /* 3822 */ 0x0646, 0x0645, - /* 3824 */ 0x0646, 0x0649, - /* 3826 */ 0x0646, 0x064A, - /* 3828 */ 0x0647, 0x062C, - /* 3830 */ 0x0647, 0x0645, - /* 3832 */ 0x0647, 0x0649, - /* 3834 */ 0x0647, 0x064A, - /* 3836 */ 0x064A, 0x062C, - /* 3838 */ 0x064A, 0x062D, - /* 3840 */ 0x064A, 0x062E, - /* 3842 */ 0x064A, 0x0645, - /* 3844 */ 0x064A, 0x0649, - /* 3846 */ 0x064A, 0x064A, - /* 3848 */ 0x0630, 0x0670, - /* 3850 */ 0x0631, 0x0670, - /* 3852 */ 0x0649, 0x0670, - /* 3854 */ 0x0020, 0x064C, 0x0651, - /* 3857 */ 0x0020, 0x064D, 0x0651, - /* 3860 */ 0x0020, 0x064E, 0x0651, - /* 3863 */ 0x0020, 0x064F, 0x0651, - /* 3866 */ 0x0020, 0x0650, 0x0651, - /* 3869 */ 0x0020, 0x0651, 0x0670, - /* 3872 */ 0x0626, 0x0631, - /* 3874 */ 0x0626, 0x0632, - /* 3876 */ 0x0626, 0x0645, - /* 3878 */ 0x0626, 0x0646, - /* 3880 */ 0x0626, 0x0649, - /* 3882 */ 0x0626, 0x064A, - /* 3884 */ 0x0628, 0x0631, - /* 3886 */ 0x0628, 0x0632, - /* 3888 */ 0x0628, 0x0645, - /* 3890 */ 0x0628, 0x0646, - /* 3892 */ 0x0628, 0x0649, - /* 3894 */ 0x0628, 0x064A, - /* 3896 */ 0x062A, 0x0631, - /* 3898 */ 0x062A, 0x0632, - /* 3900 */ 0x062A, 0x0645, - /* 3902 */ 0x062A, 0x0646, - /* 3904 */ 0x062A, 0x0649, - /* 3906 */ 0x062A, 0x064A, - /* 3908 */ 0x062B, 0x0631, - /* 3910 */ 0x062B, 0x0632, - /* 3912 */ 0x062B, 0x0645, - /* 3914 */ 0x062B, 0x0646, - /* 3916 */ 0x062B, 0x0649, - /* 3918 */ 0x062B, 0x064A, - /* 3920 */ 0x0641, 0x0649, - /* 3922 */ 0x0641, 0x064A, - /* 3924 */ 0x0642, 0x0649, - /* 3926 */ 0x0642, 0x064A, - /* 3928 */ 0x0643, 0x0627, - /* 3930 */ 0x0643, 0x0644, - /* 3932 */ 0x0643, 0x0645, - /* 3934 */ 0x0643, 0x0649, - /* 3936 */ 0x0643, 0x064A, - /* 3938 */ 0x0644, 0x0645, - /* 3940 */ 0x0644, 0x0649, - /* 3942 */ 0x0644, 0x064A, - /* 3944 */ 0x0645, 0x0627, - /* 3946 */ 0x0645, 0x0645, - /* 3948 */ 0x0646, 0x0631, - /* 3950 */ 0x0646, 0x0632, - /* 3952 */ 0x0646, 0x0645, - /* 3954 */ 0x0646, 0x0646, - /* 3956 */ 0x0646, 0x0649, - /* 3958 */ 0x0646, 0x064A, - /* 3960 */ 0x0649, 0x0670, - /* 3962 */ 0x064A, 0x0631, - /* 3964 */ 0x064A, 0x0632, - /* 3966 */ 0x064A, 0x0645, - /* 3968 */ 0x064A, 0x0646, - /* 3970 */ 0x064A, 0x0649, - /* 3972 */ 0x064A, 0x064A, - /* 3974 */ 0x0626, 0x062C, - /* 3976 */ 0x0626, 0x062D, - /* 3978 */ 0x0626, 0x062E, - /* 3980 */ 0x0626, 0x0645, - /* 3982 */ 0x0626, 0x0647, - /* 3984 */ 0x0628, 0x062C, - /* 3986 */ 0x0628, 0x062D, - /* 3988 */ 0x0628, 0x062E, - /* 3990 */ 0x0628, 0x0645, - /* 3992 */ 0x0628, 0x0647, - /* 3994 */ 0x062A, 0x062C, - /* 3996 */ 0x062A, 0x062D, - /* 3998 */ 0x062A, 0x062E, - /* 4000 */ 0x062A, 0x0645, - /* 4002 */ 0x062A, 0x0647, - /* 4004 */ 0x062B, 0x0645, - /* 4006 */ 0x062C, 0x062D, - /* 4008 */ 0x062C, 0x0645, - /* 4010 */ 0x062D, 0x062C, - /* 4012 */ 0x062D, 0x0645, - /* 4014 */ 0x062E, 0x062C, - /* 4016 */ 0x062E, 0x0645, - /* 4018 */ 0x0633, 0x062C, - /* 4020 */ 0x0633, 0x062D, - /* 4022 */ 0x0633, 0x062E, - /* 4024 */ 0x0633, 0x0645, - /* 4026 */ 0x0635, 0x062D, - /* 4028 */ 0x0635, 0x062E, - /* 4030 */ 0x0635, 0x0645, - /* 4032 */ 0x0636, 0x062C, - /* 4034 */ 0x0636, 0x062D, - /* 4036 */ 0x0636, 0x062E, - /* 4038 */ 0x0636, 0x0645, - /* 4040 */ 0x0637, 0x062D, - /* 4042 */ 0x0638, 0x0645, - /* 4044 */ 0x0639, 0x062C, - /* 4046 */ 0x0639, 0x0645, - /* 4048 */ 0x063A, 0x062C, - /* 4050 */ 0x063A, 0x0645, - /* 4052 */ 0x0641, 0x062C, - /* 4054 */ 0x0641, 0x062D, - /* 4056 */ 0x0641, 0x062E, - /* 4058 */ 0x0641, 0x0645, - /* 4060 */ 0x0642, 0x062D, - /* 4062 */ 0x0642, 0x0645, - /* 4064 */ 0x0643, 0x062C, - /* 4066 */ 0x0643, 0x062D, - /* 4068 */ 0x0643, 0x062E, - /* 4070 */ 0x0643, 0x0644, - /* 4072 */ 0x0643, 0x0645, - /* 4074 */ 0x0644, 0x062C, - /* 4076 */ 0x0644, 0x062D, - /* 4078 */ 0x0644, 0x062E, - /* 4080 */ 0x0644, 0x0645, - /* 4082 */ 0x0644, 0x0647, - /* 4084 */ 0x0645, 0x062C, - /* 4086 */ 0x0645, 0x062D, - /* 4088 */ 0x0645, 0x062E, - /* 4090 */ 0x0645, 0x0645, - /* 4092 */ 0x0646, 0x062C, - /* 4094 */ 0x0646, 0x062D, - /* 4096 */ 0x0646, 0x062E, - /* 4098 */ 0x0646, 0x0645, - /* 4100 */ 0x0646, 0x0647, - /* 4102 */ 0x0647, 0x062C, - /* 4104 */ 0x0647, 0x0645, - /* 4106 */ 0x0647, 0x0670, - /* 4108 */ 0x064A, 0x062C, - /* 4110 */ 0x064A, 0x062D, - /* 4112 */ 0x064A, 0x062E, - /* 4114 */ 0x064A, 0x0645, - /* 4116 */ 0x064A, 0x0647, - /* 4118 */ 0x0626, 0x0645, - /* 4120 */ 0x0626, 0x0647, - /* 4122 */ 0x0628, 0x0645, - /* 4124 */ 0x0628, 0x0647, - /* 4126 */ 0x062A, 0x0645, - /* 4128 */ 0x062A, 0x0647, - /* 4130 */ 0x062B, 0x0645, - /* 4132 */ 0x062B, 0x0647, - /* 4134 */ 0x0633, 0x0645, - /* 4136 */ 0x0633, 0x0647, - /* 4138 */ 0x0634, 0x0645, - /* 4140 */ 0x0634, 0x0647, - /* 4142 */ 0x0643, 0x0644, - /* 4144 */ 0x0643, 0x0645, - /* 4146 */ 0x0644, 0x0645, - /* 4148 */ 0x0646, 0x0645, - /* 4150 */ 0x0646, 0x0647, - /* 4152 */ 0x064A, 0x0645, - /* 4154 */ 0x064A, 0x0647, - /* 4156 */ 0x0640, 0x064E, 0x0651, - /* 4159 */ 0x0640, 0x064F, 0x0651, - /* 4162 */ 0x0640, 0x0650, 0x0651, - /* 4165 */ 0x0637, 0x0649, - /* 4167 */ 0x0637, 0x064A, - /* 4169 */ 0x0639, 0x0649, - /* 4171 */ 0x0639, 0x064A, - /* 4173 */ 0x063A, 0x0649, - /* 4175 */ 0x063A, 0x064A, - /* 4177 */ 0x0633, 0x0649, - /* 4179 */ 0x0633, 0x064A, - /* 4181 */ 0x0634, 0x0649, - /* 4183 */ 0x0634, 0x064A, - /* 4185 */ 0x062D, 0x0649, - /* 4187 */ 0x062D, 0x064A, - /* 4189 */ 0x062C, 0x0649, - /* 4191 */ 0x062C, 0x064A, - /* 4193 */ 0x062E, 0x0649, - /* 4195 */ 0x062E, 0x064A, - /* 4197 */ 0x0635, 0x0649, - /* 4199 */ 0x0635, 0x064A, - /* 4201 */ 0x0636, 0x0649, - /* 4203 */ 0x0636, 0x064A, - /* 4205 */ 0x0634, 0x062C, - /* 4207 */ 0x0634, 0x062D, - /* 4209 */ 0x0634, 0x062E, - /* 4211 */ 0x0634, 0x0645, - /* 4213 */ 0x0634, 0x0631, - /* 4215 */ 0x0633, 0x0631, - /* 4217 */ 0x0635, 0x0631, - /* 4219 */ 0x0636, 0x0631, - /* 4221 */ 0x0637, 0x0649, - /* 4223 */ 0x0637, 0x064A, - /* 4225 */ 0x0639, 0x0649, - /* 4227 */ 0x0639, 0x064A, - /* 4229 */ 0x063A, 0x0649, - /* 4231 */ 0x063A, 0x064A, - /* 4233 */ 0x0633, 0x0649, - /* 4235 */ 0x0633, 0x064A, - /* 4237 */ 0x0634, 0x0649, - /* 4239 */ 0x0634, 0x064A, - /* 4241 */ 0x062D, 0x0649, - /* 4243 */ 0x062D, 0x064A, - /* 4245 */ 0x062C, 0x0649, - /* 4247 */ 0x062C, 0x064A, - /* 4249 */ 0x062E, 0x0649, - /* 4251 */ 0x062E, 0x064A, - /* 4253 */ 0x0635, 0x0649, - /* 4255 */ 0x0635, 0x064A, - /* 4257 */ 0x0636, 0x0649, - /* 4259 */ 0x0636, 0x064A, - /* 4261 */ 0x0634, 0x062C, - /* 4263 */ 0x0634, 0x062D, - /* 4265 */ 0x0634, 0x062E, - /* 4267 */ 0x0634, 0x0645, - /* 4269 */ 0x0634, 0x0631, - /* 4271 */ 0x0633, 0x0631, - /* 4273 */ 0x0635, 0x0631, - /* 4275 */ 0x0636, 0x0631, - /* 4277 */ 0x0634, 0x062C, - /* 4279 */ 0x0634, 0x062D, - /* 4281 */ 0x0634, 0x062E, - /* 4283 */ 0x0634, 0x0645, - /* 4285 */ 0x0633, 0x0647, - /* 4287 */ 0x0634, 0x0647, - /* 4289 */ 0x0637, 0x0645, - /* 4291 */ 0x0633, 0x062C, - /* 4293 */ 0x0633, 0x062D, - /* 4295 */ 0x0633, 0x062E, - /* 4297 */ 0x0634, 0x062C, - /* 4299 */ 0x0634, 0x062D, - /* 4301 */ 0x0634, 0x062E, - /* 4303 */ 0x0637, 0x0645, - /* 4305 */ 0x0638, 0x0645, - /* 4307 */ 0x0627, 0x064B, - /* 4309 */ 0x0627, 0x064B, - /* 4311 */ 0x062A, 0x062C, 0x0645, - /* 4314 */ 0x062A, 0x062D, 0x062C, - /* 4317 */ 0x062A, 0x062D, 0x062C, - /* 4320 */ 0x062A, 0x062D, 0x0645, - /* 4323 */ 0x062A, 0x062E, 0x0645, - /* 4326 */ 0x062A, 0x0645, 0x062C, - /* 4329 */ 0x062A, 0x0645, 0x062D, - /* 4332 */ 0x062A, 0x0645, 0x062E, - /* 4335 */ 0x062C, 0x0645, 0x062D, - /* 4338 */ 0x062C, 0x0645, 0x062D, - /* 4341 */ 0x062D, 0x0645, 0x064A, - /* 4344 */ 0x062D, 0x0645, 0x0649, - /* 4347 */ 0x0633, 0x062D, 0x062C, - /* 4350 */ 0x0633, 0x062C, 0x062D, - /* 4353 */ 0x0633, 0x062C, 0x0649, - /* 4356 */ 0x0633, 0x0645, 0x062D, - /* 4359 */ 0x0633, 0x0645, 0x062D, - /* 4362 */ 0x0633, 0x0645, 0x062C, - /* 4365 */ 0x0633, 0x0645, 0x0645, - /* 4368 */ 0x0633, 0x0645, 0x0645, - /* 4371 */ 0x0635, 0x062D, 0x062D, - /* 4374 */ 0x0635, 0x062D, 0x062D, - /* 4377 */ 0x0635, 0x0645, 0x0645, - /* 4380 */ 0x0634, 0x062D, 0x0645, - /* 4383 */ 0x0634, 0x062D, 0x0645, - /* 4386 */ 0x0634, 0x062C, 0x064A, - /* 4389 */ 0x0634, 0x0645, 0x062E, - /* 4392 */ 0x0634, 0x0645, 0x062E, - /* 4395 */ 0x0634, 0x0645, 0x0645, - /* 4398 */ 0x0634, 0x0645, 0x0645, - /* 4401 */ 0x0636, 0x062D, 0x0649, - /* 4404 */ 0x0636, 0x062E, 0x0645, - /* 4407 */ 0x0636, 0x062E, 0x0645, - /* 4410 */ 0x0637, 0x0645, 0x062D, - /* 4413 */ 0x0637, 0x0645, 0x062D, - /* 4416 */ 0x0637, 0x0645, 0x0645, - /* 4419 */ 0x0637, 0x0645, 0x064A, - /* 4422 */ 0x0639, 0x062C, 0x0645, - /* 4425 */ 0x0639, 0x0645, 0x0645, - /* 4428 */ 0x0639, 0x0645, 0x0645, - /* 4431 */ 0x0639, 0x0645, 0x0649, - /* 4434 */ 0x063A, 0x0645, 0x0645, - /* 4437 */ 0x063A, 0x0645, 0x064A, - /* 4440 */ 0x063A, 0x0645, 0x0649, - /* 4443 */ 0x0641, 0x062E, 0x0645, - /* 4446 */ 0x0641, 0x062E, 0x0645, - /* 4449 */ 0x0642, 0x0645, 0x062D, - /* 4452 */ 0x0642, 0x0645, 0x0645, - /* 4455 */ 0x0644, 0x062D, 0x0645, - /* 4458 */ 0x0644, 0x062D, 0x064A, - /* 4461 */ 0x0644, 0x062D, 0x0649, - /* 4464 */ 0x0644, 0x062C, 0x062C, - /* 4467 */ 0x0644, 0x062C, 0x062C, - /* 4470 */ 0x0644, 0x062E, 0x0645, - /* 4473 */ 0x0644, 0x062E, 0x0645, - /* 4476 */ 0x0644, 0x0645, 0x062D, - /* 4479 */ 0x0644, 0x0645, 0x062D, - /* 4482 */ 0x0645, 0x062D, 0x062C, - /* 4485 */ 0x0645, 0x062D, 0x0645, - /* 4488 */ 0x0645, 0x062D, 0x064A, - /* 4491 */ 0x0645, 0x062C, 0x062D, - /* 4494 */ 0x0645, 0x062C, 0x0645, - /* 4497 */ 0x0645, 0x062E, 0x062C, - /* 4500 */ 0x0645, 0x062E, 0x0645, - /* 4503 */ 0x0645, 0x062C, 0x062E, - /* 4506 */ 0x0647, 0x0645, 0x062C, - /* 4509 */ 0x0647, 0x0645, 0x0645, - /* 4512 */ 0x0646, 0x062D, 0x0645, - /* 4515 */ 0x0646, 0x062D, 0x0649, - /* 4518 */ 0x0646, 0x062C, 0x0645, - /* 4521 */ 0x0646, 0x062C, 0x0645, - /* 4524 */ 0x0646, 0x062C, 0x0649, - /* 4527 */ 0x0646, 0x0645, 0x064A, - /* 4530 */ 0x0646, 0x0645, 0x0649, - /* 4533 */ 0x064A, 0x0645, 0x0645, - /* 4536 */ 0x064A, 0x0645, 0x0645, - /* 4539 */ 0x0628, 0x062E, 0x064A, - /* 4542 */ 0x062A, 0x062C, 0x064A, - /* 4545 */ 0x062A, 0x062C, 0x0649, - /* 4548 */ 0x062A, 0x062E, 0x064A, - /* 4551 */ 0x062A, 0x062E, 0x0649, - /* 4554 */ 0x062A, 0x0645, 0x064A, - /* 4557 */ 0x062A, 0x0645, 0x0649, - /* 4560 */ 0x062C, 0x0645, 0x064A, - /* 4563 */ 0x062C, 0x062D, 0x0649, - /* 4566 */ 0x062C, 0x0645, 0x0649, - /* 4569 */ 0x0633, 0x062E, 0x0649, - /* 4572 */ 0x0635, 0x062D, 0x064A, - /* 4575 */ 0x0634, 0x062D, 0x064A, - /* 4578 */ 0x0636, 0x062D, 0x064A, - /* 4581 */ 0x0644, 0x062C, 0x064A, - /* 4584 */ 0x0644, 0x0645, 0x064A, - /* 4587 */ 0x064A, 0x062D, 0x064A, - /* 4590 */ 0x064A, 0x062C, 0x064A, - /* 4593 */ 0x064A, 0x0645, 0x064A, - /* 4596 */ 0x0645, 0x0645, 0x064A, - /* 4599 */ 0x0642, 0x0645, 0x064A, - /* 4602 */ 0x0646, 0x062D, 0x064A, - /* 4605 */ 0x0642, 0x0645, 0x062D, - /* 4608 */ 0x0644, 0x062D, 0x0645, - /* 4611 */ 0x0639, 0x0645, 0x064A, - /* 4614 */ 0x0643, 0x0645, 0x064A, - /* 4617 */ 0x0646, 0x062C, 0x062D, - /* 4620 */ 0x0645, 0x062E, 0x064A, - /* 4623 */ 0x0644, 0x062C, 0x0645, - /* 4626 */ 0x0643, 0x0645, 0x0645, - /* 4629 */ 0x0644, 0x062C, 0x0645, - /* 4632 */ 0x0646, 0x062C, 0x062D, - /* 4635 */ 0x062C, 0x062D, 0x064A, - /* 4638 */ 0x062D, 0x062C, 0x064A, - /* 4641 */ 0x0645, 0x062C, 0x064A, - /* 4644 */ 0x0641, 0x0645, 0x064A, - /* 4647 */ 0x0628, 0x062D, 0x064A, - /* 4650 */ 0x0643, 0x0645, 0x0645, - /* 4653 */ 0x0639, 0x062C, 0x0645, - /* 4656 */ 0x0635, 0x0645, 0x0645, - /* 4659 */ 0x0633, 0x062E, 0x064A, - /* 4662 */ 0x0646, 0x062C, 0x064A, - /* 4665 */ 0x0635, 0x0644, 0x06D2, - /* 4668 */ 0x0642, 0x0644, 0x06D2, - /* 4671 */ 0x0627, 0x0644, 0x0644, 0x0647, - /* 4675 */ 0x0627, 0x0643, 0x0628, 0x0631, - /* 4679 */ 0x0645, 0x062D, 0x0645, 0x062F, - /* 4683 */ 0x0635, 0x0644, 0x0639, 0x0645, - /* 4687 */ 0x0631, 0x0633, 0x0648, 0x0644, - /* 4691 */ 0x0639, 0x0644, 0x064A, 0x0647, - /* 4695 */ 0x0648, 0x0633, 0x0644, 0x0645, - /* 4699 */ 0x0635, 0x0644, 0x0649, - /* 4702 */ 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, - /* 4720 */ 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, - /* 4728 */ 0x0631, 0x06CC, 0x0627, 0x0644, - /* 4732 */ 0x0020, 0x064B, - /* 4734 */ 0x0640, 0x064B, - /* 4736 */ 0x0020, 0x064C, - /* 4738 */ 0x0020, 0x064D, - /* 4740 */ 0x0020, 0x064E, - /* 4742 */ 0x0640, 0x064E, - /* 4744 */ 0x0020, 0x064F, - /* 4746 */ 0x0640, 0x064F, - /* 4748 */ 0x0020, 0x0650, - /* 4750 */ 0x0640, 0x0650, - /* 4752 */ 0x0020, 0x0651, - /* 4754 */ 0x0640, 0x0651, - /* 4756 */ 0x0020, 0x0652, - /* 4758 */ 0x0640, 0x0652, - /* 4760 */ 0x0644, 0x0622, - /* 4762 */ 0x0644, 0x0622, - /* 4764 */ 0x0644, 0x0623, - /* 4766 */ 0x0644, 0x0623, - /* 4768 */ 0x0644, 0x0625, - /* 4770 */ 0x0644, 0x0625, - /* 4772 */ 0x0644, 0x0627, - /* 4774 */ 0x0644, 0x0627, - /* 4776 */ 0x1DF04, - /* 4777 */ 0x1DF05, - /* 4778 */ 0x1DF06, - /* 4779 */ 0x1DF08, - /* 4780 */ 0x1DF0A, - /* 4781 */ 0x1DF1E, - /* 4782 */ 0x11099, 0x110BA, - /* 4784 */ 0x1109B, 0x110BA, - /* 4786 */ 0x110A5, 0x110BA, - /* 4788 */ 0x11131, 0x11127, - /* 4790 */ 0x11132, 0x11127, - /* 4792 */ 0x11347, 0x1133E, - /* 4794 */ 0x11347, 0x11357, - /* 4796 */ 0x114B9, 0x114BA, - /* 4798 */ 0x114B9, 0x114B0, - /* 4800 */ 0x114B9, 0x114BD, - /* 4802 */ 0x115B8, 0x115AF, - /* 4804 */ 0x115B9, 0x115AF, - /* 4806 */ 0x11935, 0x11930, - /* 4808 */ 0x1D157, 0x1D165, - /* 4810 */ 0x1D158, 0x1D165, - /* 4812 */ 0x1D15F, 0x1D16E, - /* 4814 */ 0x1D15F, 0x1D16F, - /* 4816 */ 0x1D15F, 0x1D170, - /* 4818 */ 0x1D15F, 0x1D171, - /* 4820 */ 0x1D15F, 0x1D172, - /* 4822 */ 0x1D1B9, 0x1D165, - /* 4824 */ 0x1D1BA, 0x1D165, - /* 4826 */ 0x1D1BB, 0x1D16E, - /* 4828 */ 0x1D1BC, 0x1D16E, - /* 4830 */ 0x1D1BB, 0x1D16F, - /* 4832 */ 0x1D1BC, 0x1D16F, - /* 4834 */ 0x0030, 0x002E, - /* 4836 */ 0x0030, 0x002C, - /* 4838 */ 0x0031, 0x002C, - /* 4840 */ 0x0032, 0x002C, - /* 4842 */ 0x0033, 0x002C, - /* 4844 */ 0x0034, 0x002C, - /* 4846 */ 0x0035, 0x002C, - /* 4848 */ 0x0036, 0x002C, - /* 4850 */ 0x0037, 0x002C, - /* 4852 */ 0x0038, 0x002C, - /* 4854 */ 0x0039, 0x002C, - /* 4856 */ 0x0028, 0x0041, 0x0029, - /* 4859 */ 0x0028, 0x0042, 0x0029, - /* 4862 */ 0x0028, 0x0043, 0x0029, - /* 4865 */ 0x0028, 0x0044, 0x0029, - /* 4868 */ 0x0028, 0x0045, 0x0029, - /* 4871 */ 0x0028, 0x0046, 0x0029, - /* 4874 */ 0x0028, 0x0047, 0x0029, - /* 4877 */ 0x0028, 0x0048, 0x0029, - /* 4880 */ 0x0028, 0x0049, 0x0029, - /* 4883 */ 0x0028, 0x004A, 0x0029, - /* 4886 */ 0x0028, 0x004B, 0x0029, - /* 4889 */ 0x0028, 0x004C, 0x0029, - /* 4892 */ 0x0028, 0x004D, 0x0029, - /* 4895 */ 0x0028, 0x004E, 0x0029, - /* 4898 */ 0x0028, 0x004F, 0x0029, - /* 4901 */ 0x0028, 0x0050, 0x0029, - /* 4904 */ 0x0028, 0x0051, 0x0029, - /* 4907 */ 0x0028, 0x0052, 0x0029, - /* 4910 */ 0x0028, 0x0053, 0x0029, - /* 4913 */ 0x0028, 0x0054, 0x0029, - /* 4916 */ 0x0028, 0x0055, 0x0029, - /* 4919 */ 0x0028, 0x0056, 0x0029, - /* 4922 */ 0x0028, 0x0057, 0x0029, - /* 4925 */ 0x0028, 0x0058, 0x0029, - /* 4928 */ 0x0028, 0x0059, 0x0029, - /* 4931 */ 0x0028, 0x005A, 0x0029, - /* 4934 */ 0x3014, 0x0053, 0x3015, - /* 4937 */ 0x0043, 0x0044, - /* 4939 */ 0x0057, 0x005A, - /* 4941 */ 0x0048, 0x0056, - /* 4943 */ 0x004D, 0x0056, - /* 4945 */ 0x0053, 0x0044, - /* 4947 */ 0x0053, 0x0053, - /* 4949 */ 0x0050, 0x0050, 0x0056, - /* 4952 */ 0x0057, 0x0043, - /* 4954 */ 0x004D, 0x0043, - /* 4956 */ 0x004D, 0x0044, - /* 4958 */ 0x004D, 0x0052, - /* 4960 */ 0x0044, 0x004A, - /* 4962 */ 0x307B, 0x304B, - /* 4964 */ 0x30B3, 0x30B3, - /* 4966 */ 0x3014, 0x672C, 0x3015, - /* 4969 */ 0x3014, 0x4E09, 0x3015, - /* 4972 */ 0x3014, 0x4E8C, 0x3015, - /* 4975 */ 0x3014, 0x5B89, 0x3015, - /* 4978 */ 0x3014, 0x70B9, 0x3015, - /* 4981 */ 0x3014, 0x6253, 0x3015, - /* 4984 */ 0x3014, 0x76D7, 0x3015, - /* 4987 */ 0x3014, 0x52DD, 0x3015, - /* 4990 */ 0x3014, 0x6557, 0x3015, - /* 4993 */ 0x20122, - /* 4994 */ 0x2063A, - /* 4995 */ 0x2051C, - /* 4996 */ 0x2054B, - /* 4997 */ 0x291DF, - /* 4998 */ 0x20A2C, - /* 4999 */ 0x20B63, - /* 5000 */ 0x214E4, - /* 5001 */ 0x216A8, - /* 5002 */ 0x216EA, - /* 5003 */ 0x219C8, - /* 5004 */ 0x21B18, - /* 5005 */ 0x21DE4, - /* 5006 */ 0x21DE6, - /* 5007 */ 0x22183, - /* 5008 */ 0x2A392, - /* 5009 */ 0x22331, - /* 5010 */ 0x22331, - /* 5011 */ 0x232B8, - /* 5012 */ 0x261DA, - /* 5013 */ 0x226D4, - /* 5014 */ 0x22B0C, - /* 5015 */ 0x22BF1, - /* 5016 */ 0x2300A, - /* 5017 */ 0x233C3, - /* 5018 */ 0x2346D, - /* 5019 */ 0x236A3, - /* 5020 */ 0x238A7, - /* 5021 */ 0x23A8D, - /* 5022 */ 0x21D0B, - /* 5023 */ 0x23AFA, - /* 5024 */ 0x23CBC, - /* 5025 */ 0x23D1E, - /* 5026 */ 0x23ED1, - /* 5027 */ 0x23F5E, - /* 5028 */ 0x23F8E, - /* 5029 */ 0x20525, - /* 5030 */ 0x24263, - /* 5031 */ 0x243AB, - /* 5032 */ 0x24608, - /* 5033 */ 0x24735, - /* 5034 */ 0x24814, - /* 5035 */ 0x24C36, - /* 5036 */ 0x24C92, - /* 5037 */ 0x2219F, - /* 5038 */ 0x24FA1, - /* 5039 */ 0x24FB8, - /* 5040 */ 0x25044, - /* 5041 */ 0x250F3, - /* 5042 */ 0x250F2, - /* 5043 */ 0x25119, - /* 5044 */ 0x25133, - /* 5045 */ 0x2541D, - /* 5046 */ 0x25626, - /* 5047 */ 0x2569A, - /* 5048 */ 0x256C5, - /* 5049 */ 0x2597C, - /* 5050 */ 0x25AA7, - /* 5051 */ 0x25AA7, - /* 5052 */ 0x25BAB, - /* 5053 */ 0x25C80, - /* 5054 */ 0x25F86, - /* 5055 */ 0x26228, - /* 5056 */ 0x26247, - /* 5057 */ 0x262D9, - /* 5058 */ 0x2633E, - /* 5059 */ 0x264DA, - /* 5060 */ 0x26523, - /* 5061 */ 0x265A8, - /* 5062 */ 0x2335F, - /* 5063 */ 0x267A7, - /* 5064 */ 0x267B5, - /* 5065 */ 0x23393, - /* 5066 */ 0x2339C, - /* 5067 */ 0x26B3C, - /* 5068 */ 0x26C36, - /* 5069 */ 0x26D6B, - /* 5070 */ 0x26CD5, - /* 5071 */ 0x273CA, - /* 5072 */ 0x26F2C, - /* 5073 */ 0x26FB1, - /* 5074 */ 0x270D2, - /* 5075 */ 0x27667, - /* 5076 */ 0x278AE, - /* 5077 */ 0x27966, - /* 5078 */ 0x27CA8, - /* 5079 */ 0x27F2F, - /* 5080 */ 0x20804, - /* 5081 */ 0x208DE, - /* 5082 */ 0x285D2, - /* 5083 */ 0x285ED, - /* 5084 */ 0x2872E, - /* 5085 */ 0x28BFA, - /* 5086 */ 0x28D77, - /* 5087 */ 0x29145, - /* 5088 */ 0x2921A, - /* 5089 */ 0x2940A, - /* 5090 */ 0x29496, - /* 5091 */ 0x295B6, - /* 5092 */ 0x29B30, - /* 5093 */ 0x2A0CE, - /* 5094 */ 0x2A105, - /* 5095 */ 0x2A20E, - /* 5096 */ 0x2A291, - /* 5097 */ 0x2A600 -}; diff --git a/contrib/libs/libpq/src/include/common/username.h b/contrib/libs/libpq/src/include/common/username.h deleted file mode 100644 index fd07df64c1..0000000000 --- a/contrib/libs/libpq/src/include/common/username.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * username.h - * lookup effective username - * - * Copyright (c) 2003-2023, PostgreSQL Global Development Group - * - * src/include/common/username.h - */ -#ifndef USERNAME_H -#define USERNAME_H - -extern const char *get_user_name(char **errstr); -extern const char *get_user_name_or_exit(const char *progname); - -#endif /* USERNAME_H */ diff --git a/contrib/libs/libpq/src/include/datatype/timestamp.h b/contrib/libs/libpq/src/include/datatype/timestamp.h deleted file mode 100644 index ab8ccf89ca..0000000000 --- a/contrib/libs/libpq/src/include/datatype/timestamp.h +++ /dev/null @@ -1,243 +0,0 @@ -/*------------------------------------------------------------------------- - * - * timestamp.h - * Timestamp and Interval typedefs and related macros. - * - * Note: this file must be includable in both frontend and backend contexts. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/datatype/timestamp.h - * - *------------------------------------------------------------------------- - */ -#ifndef DATATYPE_TIMESTAMP_H -#define DATATYPE_TIMESTAMP_H - -/* - * Timestamp represents absolute time. - * - * Interval represents delta time. Keep track of months (and years), days, - * and hours/minutes/seconds separately since the elapsed time spanned is - * unknown until instantiated relative to an absolute time. - * - * Note that Postgres uses "time interval" to mean a bounded interval, - * consisting of a beginning and ending time, not a time span - thomas 97/03/20 - * - * Timestamps, as well as the h/m/s fields of intervals, are stored as - * int64 values with units of microseconds. (Once upon a time they were - * double values with units of seconds.) - * - * TimeOffset and fsec_t are convenience typedefs for temporary variables. - * Do not use fsec_t in values stored on-disk. - * Also, fsec_t is only meant for *fractional* seconds; beware of overflow - * if the value you need to store could be many seconds. - */ - -typedef int64 Timestamp; -typedef int64 TimestampTz; -typedef int64 TimeOffset; -typedef int32 fsec_t; /* fractional seconds (in microseconds) */ - - -/* - * Storage format for type interval. - */ -typedef struct -{ - TimeOffset time; /* all time units other than days, months and - * years */ - int32 day; /* days, after time for alignment */ - int32 month; /* months and years, after time for alignment */ -} Interval; - -/* - * Data structure representing a broken-down interval. - * - * For historical reasons, this is modeled on struct pg_tm for timestamps. - * Unlike the situation for timestamps, there's no magic interpretation - * needed for months or years: they're just zero or not. Note that fields - * can be negative; however, because of the divisions done while converting - * from struct Interval, only tm_mday could be INT_MIN. This is important - * because we may need to negate the values in some code paths. - */ -struct pg_itm -{ - int tm_usec; - int tm_sec; - int tm_min; - int64 tm_hour; /* needs to be wide */ - int tm_mday; - int tm_mon; - int tm_year; -}; - -/* - * Data structure for decoding intervals. We could just use struct pg_itm, - * but then the requirement for tm_usec to be 64 bits would propagate to - * places where it's not really needed. Also, omitting the fields that - * aren't used during decoding seems like a good error-prevention measure. - */ -struct pg_itm_in -{ - int64 tm_usec; /* needs to be wide */ - int tm_mday; - int tm_mon; - int tm_year; -}; - - -/* Limits on the "precision" option (typmod) for these data types */ -#define MAX_TIMESTAMP_PRECISION 6 -#define MAX_INTERVAL_PRECISION 6 - -/* - * Round off to MAX_TIMESTAMP_PRECISION decimal places. - * Note: this is also used for rounding off intervals. - */ -#define TS_PREC_INV 1000000.0 -#define TSROUND(j) (rint(((double) (j)) * TS_PREC_INV) / TS_PREC_INV) - - -/* - * Assorted constants for datetime-related calculations - */ - -#define DAYS_PER_YEAR 365.25 /* assumes leap year every four years */ -#define MONTHS_PER_YEAR 12 -/* - * DAYS_PER_MONTH is very imprecise. The more accurate value is - * 365.2425/12 = 30.436875, or '30 days 10:29:06'. Right now we only - * return an integral number of days, but someday perhaps we should - * also return a 'time' value to be used as well. ISO 8601 suggests - * 30 days. - */ -#define DAYS_PER_MONTH 30 /* assumes exactly 30 days per month */ -#define HOURS_PER_DAY 24 /* assume no daylight savings time changes */ - -/* - * This doesn't adjust for uneven daylight savings time intervals or leap - * seconds, and it crudely estimates leap years. A more accurate value - * for days per years is 365.2422. - */ -#define SECS_PER_YEAR (36525 * 864) /* avoid floating-point computation */ -#define SECS_PER_DAY 86400 -#define SECS_PER_HOUR 3600 -#define SECS_PER_MINUTE 60 -#define MINS_PER_HOUR 60 - -#define USECS_PER_DAY INT64CONST(86400000000) -#define USECS_PER_HOUR INT64CONST(3600000000) -#define USECS_PER_MINUTE INT64CONST(60000000) -#define USECS_PER_SEC INT64CONST(1000000) - -/* - * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. - * Currently, the record holders for wackiest offsets in actual use are zones - * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 - * until 1867. If we were to reject such values we would fail to dump and - * restore old timestamptz values with these zone settings. - */ -#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ -#define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) - -/* - * We reserve the minimum and maximum integer values to represent - * timestamp (or timestamptz) -infinity and +infinity. - */ -#define TIMESTAMP_MINUS_INFINITY PG_INT64_MIN -#define TIMESTAMP_INFINITY PG_INT64_MAX - -/* - * Historically these alias for infinity have been used. - */ -#define DT_NOBEGIN TIMESTAMP_MINUS_INFINITY -#define DT_NOEND TIMESTAMP_INFINITY - -#define TIMESTAMP_NOBEGIN(j) \ - do {(j) = DT_NOBEGIN;} while (0) - -#define TIMESTAMP_IS_NOBEGIN(j) ((j) == DT_NOBEGIN) - -#define TIMESTAMP_NOEND(j) \ - do {(j) = DT_NOEND;} while (0) - -#define TIMESTAMP_IS_NOEND(j) ((j) == DT_NOEND) - -#define TIMESTAMP_NOT_FINITE(j) (TIMESTAMP_IS_NOBEGIN(j) || TIMESTAMP_IS_NOEND(j)) - - -/* - * Julian date support. - * - * date2j() and j2date() nominally handle the Julian date range 0..INT_MAX, - * or 4714-11-24 BC to 5874898-06-03 AD. In practice, date2j() will work and - * give correct negative Julian dates for dates before 4714-11-24 BC as well. - * We rely on it to do so back to 4714-11-01 BC. Allowing at least one day's - * slop is necessary so that timestamp rotation doesn't produce dates that - * would be rejected on input. For example, '4714-11-24 00:00 GMT BC' is a - * legal timestamptz value, but in zones east of Greenwich it would print as - * sometime in the afternoon of 4714-11-23 BC; if we couldn't process such a - * date we'd have a dump/reload failure. So the idea is for IS_VALID_JULIAN - * to accept a slightly wider range of dates than we really support, and - * then we apply the exact checks in IS_VALID_DATE or IS_VALID_TIMESTAMP, - * after timezone rotation if any. To save a few cycles, we can make - * IS_VALID_JULIAN check only to the month boundary, since its exact cutoffs - * are not very critical in this scheme. - * - * It is correct that JULIAN_MINYEAR is -4713, not -4714; it is defined to - * allow easy comparison to tm_year values, in which we follow the convention - * that tm_year <= 0 represents abs(tm_year)+1 BC. - */ - -#define JULIAN_MINYEAR (-4713) -#define JULIAN_MINMONTH (11) -#define JULIAN_MINDAY (24) -#define JULIAN_MAXYEAR (5874898) -#define JULIAN_MAXMONTH (6) -#define JULIAN_MAXDAY (3) - -#define IS_VALID_JULIAN(y,m,d) \ - (((y) > JULIAN_MINYEAR || \ - ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \ - ((y) < JULIAN_MAXYEAR || \ - ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH)))) - -/* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */ -#define UNIX_EPOCH_JDATE 2440588 /* == date2j(1970, 1, 1) */ -#define POSTGRES_EPOCH_JDATE 2451545 /* == date2j(2000, 1, 1) */ - -/* - * Range limits for dates and timestamps. - * - * We have traditionally allowed Julian day zero as a valid datetime value, - * so that is the lower bound for both dates and timestamps. - * - * The upper limit for dates is 5874897-12-31, which is a bit less than what - * the Julian-date code can allow. For timestamps, the upper limit is - * 294276-12-31. The int64 overflow limit would be a few days later; again, - * leaving some slop avoids worries about corner-case overflow, and provides - * a simpler user-visible definition. - */ - -/* First allowed date, and first disallowed date, in Julian-date form */ -#define DATETIME_MIN_JULIAN (0) -#define DATE_END_JULIAN (2147483494) /* == date2j(JULIAN_MAXYEAR, 1, 1) */ -#define TIMESTAMP_END_JULIAN (109203528) /* == date2j(294277, 1, 1) */ - -/* Timestamp limits */ -#define MIN_TIMESTAMP INT64CONST(-211813488000000000) -/* == (DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ -#define END_TIMESTAMP INT64CONST(9223371331200000000) -/* == (TIMESTAMP_END_JULIAN - POSTGRES_EPOCH_JDATE) * USECS_PER_DAY */ - -/* Range-check a date (given in Postgres, not Julian, numbering) */ -#define IS_VALID_DATE(d) \ - ((DATETIME_MIN_JULIAN - POSTGRES_EPOCH_JDATE) <= (d) && \ - (d) < (DATE_END_JULIAN - POSTGRES_EPOCH_JDATE)) - -/* Range-check a timestamp */ -#define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP) - -#endif /* DATATYPE_TIMESTAMP_H */ diff --git a/contrib/libs/libpq/src/include/lib/sort_template.h b/contrib/libs/libpq/src/include/lib/sort_template.h deleted file mode 100644 index 1edd05c7d3..0000000000 --- a/contrib/libs/libpq/src/include/lib/sort_template.h +++ /dev/null @@ -1,432 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sort_template.h - * - * A template for a sort algorithm that supports varying degrees of - * specialization. - * - * Copyright (c) 2021-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1992-1994, Regents of the University of California - * - * Usage notes: - * - * To generate functions specialized for a type, the following parameter - * macros should be #define'd before this file is included. - * - * - ST_SORT - the name of a sort function to be generated - * - ST_ELEMENT_TYPE - type of the referenced elements - * - ST_DECLARE - if defined the functions and types are declared - * - ST_DEFINE - if defined the functions and types are defined - * - ST_SCOPE - scope (e.g. extern, static inline) for functions - * - ST_CHECK_FOR_INTERRUPTS - if defined the sort is interruptible - * - * Instead of ST_ELEMENT_TYPE, ST_ELEMENT_TYPE_VOID can be defined. Then - * the generated functions will automatically gain an "element_size" - * parameter. This allows us to generate a traditional qsort function. - * - * One of the following macros must be defined, to show how to compare - * elements. The first two options are arbitrary expressions depending - * on whether an extra pass-through argument is desired, and the third - * option should be defined if the sort function should receive a - * function pointer at runtime. - * - * - ST_COMPARE(a, b) - a simple comparison expression - * - ST_COMPARE(a, b, arg) - variant that takes an extra argument - * - ST_COMPARE_RUNTIME_POINTER - sort function takes a function pointer - * - * To say that the comparator and therefore also sort function should - * receive an extra pass-through argument, specify the type of the - * argument. - * - * - ST_COMPARE_ARG_TYPE - type of extra argument - * - * The prototype of the generated sort function is: - * - * void ST_SORT(ST_ELEMENT_TYPE *data, size_t n, - * [size_t element_size,] - * [ST_SORT_compare_function compare,] - * [ST_COMPARE_ARG_TYPE *arg]); - * - * ST_SORT_compare_function is a function pointer of the following type: - * - * int (*)(const ST_ELEMENT_TYPE *a, const ST_ELEMENT_TYPE *b, - * [ST_COMPARE_ARG_TYPE *arg]) - * - * HISTORY - * - * Modifications from vanilla NetBSD source: - * - Add do ... while() macro fix - * - Remove __inline, _DIAGASSERTs, __P - * - Remove ill-considered "swap_cnt" switch to insertion sort, in favor - * of a simple check for presorted input. - * - Take care to recurse on the smaller partition, to bound stack usage - * - Convert into a header that can generate specialized functions - * - * IDENTIFICATION - * src/include/lib/sort_template.h - * - *------------------------------------------------------------------------- - */ - -/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Qsort routine based on J. L. Bentley and M. D. McIlroy, - * "Engineering a sort function", - * Software--Practice and Experience 23 (1993) 1249-1265. - * - * We have modified their original by adding a check for already-sorted - * input, which seems to be a win per discussions on pgsql-hackers around - * 2006-03-21. - * - * Also, we recurse on the smaller partition and iterate on the larger one, - * which ensures we cannot recurse more than log(N) levels (since the - * partition recursed to is surely no more than half of the input). Bentley - * and McIlroy explicitly rejected doing this on the grounds that it's "not - * worth the effort", but we have seen crashes in the field due to stack - * overrun, so that judgment seems wrong. - */ - -#define ST_MAKE_PREFIX(a) CppConcat(a,_) -#define ST_MAKE_NAME(a,b) ST_MAKE_NAME_(ST_MAKE_PREFIX(a),b) -#define ST_MAKE_NAME_(a,b) CppConcat(a,b) - -/* - * If the element type is void, we'll also need an element_size argument - * because we don't know the size. - */ -#ifdef ST_ELEMENT_TYPE_VOID -#define ST_ELEMENT_TYPE void -#define ST_SORT_PROTO_ELEMENT_SIZE , size_t element_size -#define ST_SORT_INVOKE_ELEMENT_SIZE , element_size -#else -#define ST_SORT_PROTO_ELEMENT_SIZE -#define ST_SORT_INVOKE_ELEMENT_SIZE -#endif - -/* - * If the user wants to be able to pass in compare functions at runtime, - * we'll need to make that an argument of the sort and med3 functions. - */ -#ifdef ST_COMPARE_RUNTIME_POINTER -/* - * The type of the comparator function pointer that ST_SORT will take, unless - * you've already declared a type name manually and want to use that instead of - * having a new one defined. - */ -#ifndef ST_COMPARATOR_TYPE_NAME -#define ST_COMPARATOR_TYPE_NAME ST_MAKE_NAME(ST_SORT, compare_function) -#endif -#define ST_COMPARE compare -#ifndef ST_COMPARE_ARG_TYPE -#define ST_SORT_PROTO_COMPARE , ST_COMPARATOR_TYPE_NAME compare -#define ST_SORT_INVOKE_COMPARE , compare -#else -#define ST_SORT_PROTO_COMPARE , ST_COMPARATOR_TYPE_NAME compare -#define ST_SORT_INVOKE_COMPARE , compare -#endif -#else -#define ST_SORT_PROTO_COMPARE -#define ST_SORT_INVOKE_COMPARE -#endif - -/* - * If the user wants to use a compare function or expression that takes an - * extra argument, we'll need to make that an argument of the sort, compare and - * med3 functions. - */ -#ifdef ST_COMPARE_ARG_TYPE -#define ST_SORT_PROTO_ARG , ST_COMPARE_ARG_TYPE *arg -#define ST_SORT_INVOKE_ARG , arg -#else -#define ST_SORT_PROTO_ARG -#define ST_SORT_INVOKE_ARG -#endif - -#ifdef ST_DECLARE - -#ifdef ST_COMPARE_RUNTIME_POINTER -typedef int (*ST_COMPARATOR_TYPE_NAME) (const ST_ELEMENT_TYPE *, - const ST_ELEMENT_TYPE * ST_SORT_PROTO_ARG); -#endif - -/* Declare the sort function. Note optional arguments at end. */ -ST_SCOPE void ST_SORT(ST_ELEMENT_TYPE * first, size_t n - ST_SORT_PROTO_ELEMENT_SIZE - ST_SORT_PROTO_COMPARE - ST_SORT_PROTO_ARG); - -#endif - -#ifdef ST_DEFINE - -/* sort private helper functions */ -#define ST_MED3 ST_MAKE_NAME(ST_SORT, med3) -#define ST_SWAP ST_MAKE_NAME(ST_SORT, swap) -#define ST_SWAPN ST_MAKE_NAME(ST_SORT, swapn) - -/* Users expecting to run very large sorts may need them to be interruptible. */ -#ifdef ST_CHECK_FOR_INTERRUPTS -#define DO_CHECK_FOR_INTERRUPTS() CHECK_FOR_INTERRUPTS() -#else -#define DO_CHECK_FOR_INTERRUPTS() -#endif - -/* - * Create wrapper macros that know how to invoke compare, med3 and sort with - * the right arguments. - */ -#ifdef ST_COMPARE_RUNTIME_POINTER -#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_) ST_SORT_INVOKE_ARG) -#elif defined(ST_COMPARE_ARG_TYPE) -#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_), arg) -#else -#define DO_COMPARE(a_, b_) ST_COMPARE((a_), (b_)) -#endif -#define DO_MED3(a_, b_, c_) \ - ST_MED3((a_), (b_), (c_) \ - ST_SORT_INVOKE_COMPARE \ - ST_SORT_INVOKE_ARG) -#define DO_SORT(a_, n_) \ - ST_SORT((a_), (n_) \ - ST_SORT_INVOKE_ELEMENT_SIZE \ - ST_SORT_INVOKE_COMPARE \ - ST_SORT_INVOKE_ARG) - -/* - * If we're working with void pointers, we'll use pointer arithmetic based on - * uint8, and use the runtime element_size to step through the array and swap - * elements. Otherwise we'll work with ST_ELEMENT_TYPE. - */ -#ifndef ST_ELEMENT_TYPE_VOID -#define ST_POINTER_TYPE ST_ELEMENT_TYPE -#define ST_POINTER_STEP 1 -#define DO_SWAPN(a_, b_, n_) ST_SWAPN((a_), (b_), (n_)) -#define DO_SWAP(a_, b_) ST_SWAP((a_), (b_)) -#else -#define ST_POINTER_TYPE uint8 -#define ST_POINTER_STEP element_size -#define DO_SWAPN(a_, b_, n_) ST_SWAPN((a_), (b_), (n_)) -#define DO_SWAP(a_, b_) DO_SWAPN((a_), (b_), element_size) -#endif - -/* - * Find the median of three values. Currently, performance seems to be best - * if the comparator is inlined here, but the med3 function is not inlined - * in the qsort function. - */ -static pg_noinline ST_ELEMENT_TYPE * -ST_MED3(ST_ELEMENT_TYPE * a, - ST_ELEMENT_TYPE * b, - ST_ELEMENT_TYPE * c - ST_SORT_PROTO_COMPARE - ST_SORT_PROTO_ARG) -{ - return DO_COMPARE(a, b) < 0 ? - (DO_COMPARE(b, c) < 0 ? b : (DO_COMPARE(a, c) < 0 ? c : a)) - : (DO_COMPARE(b, c) > 0 ? b : (DO_COMPARE(a, c) < 0 ? a : c)); -} - -static inline void -ST_SWAP(ST_POINTER_TYPE * a, ST_POINTER_TYPE * b) -{ - ST_POINTER_TYPE tmp = *a; - - *a = *b; - *b = tmp; -} - -static inline void -ST_SWAPN(ST_POINTER_TYPE * a, ST_POINTER_TYPE * b, size_t n) -{ - for (size_t i = 0; i < n; ++i) - ST_SWAP(&a[i], &b[i]); -} - -/* - * Sort an array. - */ -ST_SCOPE void -ST_SORT(ST_ELEMENT_TYPE * data, size_t n - ST_SORT_PROTO_ELEMENT_SIZE - ST_SORT_PROTO_COMPARE - ST_SORT_PROTO_ARG) -{ - ST_POINTER_TYPE *a = (ST_POINTER_TYPE *) data, - *pa, - *pb, - *pc, - *pd, - *pl, - *pm, - *pn; - size_t d1, - d2; - int r, - presorted; - -loop: - DO_CHECK_FOR_INTERRUPTS(); - if (n < 7) - { - for (pm = a + ST_POINTER_STEP; pm < a + n * ST_POINTER_STEP; - pm += ST_POINTER_STEP) - for (pl = pm; pl > a && DO_COMPARE(pl - ST_POINTER_STEP, pl) > 0; - pl -= ST_POINTER_STEP) - DO_SWAP(pl, pl - ST_POINTER_STEP); - return; - } - presorted = 1; - for (pm = a + ST_POINTER_STEP; pm < a + n * ST_POINTER_STEP; - pm += ST_POINTER_STEP) - { - DO_CHECK_FOR_INTERRUPTS(); - if (DO_COMPARE(pm - ST_POINTER_STEP, pm) > 0) - { - presorted = 0; - break; - } - } - if (presorted) - return; - pm = a + (n / 2) * ST_POINTER_STEP; - if (n > 7) - { - pl = a; - pn = a + (n - 1) * ST_POINTER_STEP; - if (n > 40) - { - size_t d = (n / 8) * ST_POINTER_STEP; - - pl = DO_MED3(pl, pl + d, pl + 2 * d); - pm = DO_MED3(pm - d, pm, pm + d); - pn = DO_MED3(pn - 2 * d, pn - d, pn); - } - pm = DO_MED3(pl, pm, pn); - } - DO_SWAP(a, pm); - pa = pb = a + ST_POINTER_STEP; - pc = pd = a + (n - 1) * ST_POINTER_STEP; - for (;;) - { - while (pb <= pc && (r = DO_COMPARE(pb, a)) <= 0) - { - if (r == 0) - { - DO_SWAP(pa, pb); - pa += ST_POINTER_STEP; - } - pb += ST_POINTER_STEP; - DO_CHECK_FOR_INTERRUPTS(); - } - while (pb <= pc && (r = DO_COMPARE(pc, a)) >= 0) - { - if (r == 0) - { - DO_SWAP(pc, pd); - pd -= ST_POINTER_STEP; - } - pc -= ST_POINTER_STEP; - DO_CHECK_FOR_INTERRUPTS(); - } - if (pb > pc) - break; - DO_SWAP(pb, pc); - pb += ST_POINTER_STEP; - pc -= ST_POINTER_STEP; - } - pn = a + n * ST_POINTER_STEP; - d1 = Min(pa - a, pb - pa); - DO_SWAPN(a, pb - d1, d1); - d1 = Min(pd - pc, pn - pd - ST_POINTER_STEP); - DO_SWAPN(pb, pn - d1, d1); - d1 = pb - pa; - d2 = pd - pc; - if (d1 <= d2) - { - /* Recurse on left partition, then iterate on right partition */ - if (d1 > ST_POINTER_STEP) - DO_SORT(a, d1 / ST_POINTER_STEP); - if (d2 > ST_POINTER_STEP) - { - /* Iterate rather than recurse to save stack space */ - /* DO_SORT(pn - d2, d2 / ST_POINTER_STEP) */ - a = pn - d2; - n = d2 / ST_POINTER_STEP; - goto loop; - } - } - else - { - /* Recurse on right partition, then iterate on left partition */ - if (d2 > ST_POINTER_STEP) - DO_SORT(pn - d2, d2 / ST_POINTER_STEP); - if (d1 > ST_POINTER_STEP) - { - /* Iterate rather than recurse to save stack space */ - /* DO_SORT(a, d1 / ST_POINTER_STEP) */ - n = d1 / ST_POINTER_STEP; - goto loop; - } - } -} -#endif - -#undef DO_CHECK_FOR_INTERRUPTS -#undef DO_COMPARE -#undef DO_MED3 -#undef DO_SORT -#undef DO_SWAP -#undef DO_SWAPN -#undef ST_CHECK_FOR_INTERRUPTS -#undef ST_COMPARATOR_TYPE_NAME -#undef ST_COMPARE -#undef ST_COMPARE_ARG_TYPE -#undef ST_COMPARE_RUNTIME_POINTER -#undef ST_ELEMENT_TYPE -#undef ST_ELEMENT_TYPE_VOID -#undef ST_MAKE_NAME -#undef ST_MAKE_NAME_ -#undef ST_MAKE_PREFIX -#undef ST_MED3 -#undef ST_POINTER_STEP -#undef ST_POINTER_TYPE -#undef ST_SCOPE -#undef ST_SORT -#undef ST_SORT_INVOKE_ARG -#undef ST_SORT_INVOKE_COMPARE -#undef ST_SORT_INVOKE_ELEMENT_SIZE -#undef ST_SORT_PROTO_ARG -#undef ST_SORT_PROTO_COMPARE -#undef ST_SORT_PROTO_ELEMENT_SIZE -#undef ST_SWAP -#undef ST_SWAPN diff --git a/contrib/libs/libpq/src/include/lib/stringinfo.h b/contrib/libs/libpq/src/include/lib/stringinfo.h deleted file mode 100644 index 36a416f8e0..0000000000 --- a/contrib/libs/libpq/src/include/lib/stringinfo.h +++ /dev/null @@ -1,161 +0,0 @@ -/*------------------------------------------------------------------------- - * - * stringinfo.h - * Declarations/definitions for "StringInfo" functions. - * - * StringInfo provides an extensible string data type (currently limited to a - * length of 1GB). It can be used to buffer either ordinary C strings - * (null-terminated text) or arbitrary binary data. All storage is allocated - * with palloc() (falling back to malloc in frontend code). - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/lib/stringinfo.h - * - *------------------------------------------------------------------------- - */ -#ifndef STRINGINFO_H -#define STRINGINFO_H - -/*------------------------- - * StringInfoData holds information about an extensible string. - * data is the current buffer for the string (allocated with palloc). - * len is the current string length. There is guaranteed to be - * a terminating '\0' at data[len], although this is not very - * useful when the string holds binary data rather than text. - * maxlen is the allocated size in bytes of 'data', i.e. the maximum - * string size (including the terminating '\0' char) that we can - * currently store in 'data' without having to reallocate - * more space. We must always have maxlen > len. - * cursor is initialized to zero by makeStringInfo or initStringInfo, - * but is not otherwise touched by the stringinfo.c routines. - * Some routines use it to scan through a StringInfo. - *------------------------- - */ -typedef struct StringInfoData -{ - char *data; - int len; - int maxlen; - int cursor; -} StringInfoData; - -typedef StringInfoData *StringInfo; - - -/*------------------------ - * There are two ways to create a StringInfo object initially: - * - * StringInfo stringptr = makeStringInfo(); - * Both the StringInfoData and the data buffer are palloc'd. - * - * StringInfoData string; - * initStringInfo(&string); - * The data buffer is palloc'd but the StringInfoData is just local. - * This is the easiest approach for a StringInfo object that will - * only live as long as the current routine. - * - * To destroy a StringInfo, pfree() the data buffer, and then pfree() the - * StringInfoData if it was palloc'd. There's no special support for this. - * - * NOTE: some routines build up a string using StringInfo, and then - * release the StringInfoData but return the data string itself to their - * caller. At that point the data string looks like a plain palloc'd - * string. - *------------------------- - */ - -/*------------------------ - * makeStringInfo - * Create an empty 'StringInfoData' & return a pointer to it. - */ -extern StringInfo makeStringInfo(void); - -/*------------------------ - * initStringInfo - * Initialize a StringInfoData struct (with previously undefined contents) - * to describe an empty string. - */ -extern void initStringInfo(StringInfo str); - -/*------------------------ - * resetStringInfo - * Clears the current content of the StringInfo, if any. The - * StringInfo remains valid. - */ -extern void resetStringInfo(StringInfo str); - -/*------------------------ - * appendStringInfo - * Format text data under the control of fmt (an sprintf-style format string) - * and append it to whatever is already in str. More space is allocated - * to str if necessary. This is sort of like a combination of sprintf and - * strcat. - */ -extern void appendStringInfo(StringInfo str, const char *fmt,...) pg_attribute_printf(2, 3); - -/*------------------------ - * appendStringInfoVA - * Attempt to format text data under the control of fmt (an sprintf-style - * format string) and append it to whatever is already in str. If successful - * return zero; if not (because there's not enough space), return an estimate - * of the space needed, without modifying str. Typically the caller should - * pass the return value to enlargeStringInfo() before trying again; see - * appendStringInfo for standard usage pattern. - */ -extern int appendStringInfoVA(StringInfo str, const char *fmt, va_list args) pg_attribute_printf(2, 0); - -/*------------------------ - * appendStringInfoString - * Append a null-terminated string to str. - * Like appendStringInfo(str, "%s", s) but faster. - */ -extern void appendStringInfoString(StringInfo str, const char *s); - -/*------------------------ - * appendStringInfoChar - * Append a single byte to str. - * Like appendStringInfo(str, "%c", ch) but much faster. - */ -extern void appendStringInfoChar(StringInfo str, char ch); - -/*------------------------ - * appendStringInfoCharMacro - * As above, but a macro for even more speed where it matters. - * Caution: str argument will be evaluated multiple times. - */ -#define appendStringInfoCharMacro(str,ch) \ - (((str)->len + 1 >= (str)->maxlen) ? \ - appendStringInfoChar(str, ch) : \ - (void)((str)->data[(str)->len] = (ch), (str)->data[++(str)->len] = '\0')) - -/*------------------------ - * appendStringInfoSpaces - * Append a given number of spaces to str. - */ -extern void appendStringInfoSpaces(StringInfo str, int count); - -/*------------------------ - * appendBinaryStringInfo - * Append arbitrary binary data to a StringInfo, allocating more space - * if necessary. - */ -extern void appendBinaryStringInfo(StringInfo str, - const void *data, int datalen); - -/*------------------------ - * appendBinaryStringInfoNT - * Append arbitrary binary data to a StringInfo, allocating more space - * if necessary. Does not ensure a trailing null-byte exists. - */ -extern void appendBinaryStringInfoNT(StringInfo str, - const void *data, int datalen); - -/*------------------------ - * enlargeStringInfo - * Make sure a StringInfo's buffer can hold at least 'needed' more bytes. - */ -extern void enlargeStringInfo(StringInfo str, int needed); - -#endif /* STRINGINFO_H */ diff --git a/contrib/libs/libpq/src/include/libpq/libpq-fs.h b/contrib/libs/libpq/src/include/libpq/libpq-fs.h deleted file mode 100644 index f89e0f9e3f..0000000000 --- a/contrib/libs/libpq/src/include/libpq/libpq-fs.h +++ /dev/null @@ -1,24 +0,0 @@ -/*------------------------------------------------------------------------- - * - * libpq-fs.h - * definitions for using Inversion file system routines (ie, large objects) - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/libpq/libpq-fs.h - * - *------------------------------------------------------------------------- - */ -#ifndef LIBPQ_FS_H -#define LIBPQ_FS_H - -/* - * Read/write mode flags for inversion (large object) calls - */ - -#define INV_WRITE 0x00020000 -#define INV_READ 0x00040000 - -#endif /* LIBPQ_FS_H */ diff --git a/contrib/libs/libpq/src/include/libpq/pqcomm.h b/contrib/libs/libpq/src/include/libpq/pqcomm.h deleted file mode 100644 index c85090259d..0000000000 --- a/contrib/libs/libpq/src/include/libpq/pqcomm.h +++ /dev/null @@ -1,163 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pqcomm.h - * Definitions common to frontends and backends. - * - * NOTE: for historical reasons, this does not correspond to pqcomm.c. - * pqcomm.c's routines are declared in libpq.h. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/libpq/pqcomm.h - * - *------------------------------------------------------------------------- - */ -#ifndef PQCOMM_H -#define PQCOMM_H - -#include <sys/socket.h> -#include <sys/un.h> -#include <netdb.h> -#include <netinet/in.h> - -typedef struct -{ - struct sockaddr_storage addr; - socklen_t salen; -} SockAddr; - -typedef struct -{ - int family; - SockAddr addr; -} AddrInfo; - -/* Configure the UNIX socket location for the well known port. */ - -#define UNIXSOCK_PATH(path, port, sockdir) \ - (AssertMacro(sockdir), \ - AssertMacro(*(sockdir) != '\0'), \ - snprintf(path, sizeof(path), "%s/.s.PGSQL.%d", \ - (sockdir), (port))) - -/* - * The maximum workable length of a socket path is what will fit into - * struct sockaddr_un. This is usually only 100 or so bytes :-(. - * - * For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(), - * then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes. - * (Because the standard API for getaddrinfo doesn't allow it to complain in - * a useful way when the socket pathname is too long, we have to test for - * this explicitly, instead of just letting the subroutine return an error.) - */ -#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path) - -/* - * A host that looks either like an absolute path or starts with @ is - * interpreted as a Unix-domain socket address. - */ -static inline bool -is_unixsock_path(const char *path) -{ - return is_absolute_path(path) || path[0] == '@'; -} - -/* - * These manipulate the frontend/backend protocol version number. - * - * The major number should be incremented for incompatible changes. The minor - * number should be incremented for compatible changes (eg. additional - * functionality). - * - * If a backend supports version m.n of the protocol it must actually support - * versions m.[0..n]. Backend support for version m-1 can be dropped after a - * `reasonable' length of time. - * - * A frontend isn't required to support anything other than the current - * version. - */ - -#define PG_PROTOCOL_MAJOR(v) ((v) >> 16) -#define PG_PROTOCOL_MINOR(v) ((v) & 0x0000ffff) -#define PG_PROTOCOL(m,n) (((m) << 16) | (n)) - -/* - * The earliest and latest frontend/backend protocol version supported. - * (Only protocol version 3 is currently supported) - */ - -#define PG_PROTOCOL_EARLIEST PG_PROTOCOL(3,0) -#define PG_PROTOCOL_LATEST PG_PROTOCOL(3,0) - -typedef uint32 ProtocolVersion; /* FE/BE protocol version number */ - -typedef ProtocolVersion MsgType; - - -/* - * Packet lengths are 4 bytes in network byte order. - * - * The initial length is omitted from the packet layouts appearing below. - */ - -typedef uint32 PacketLen; - -extern PGDLLIMPORT bool Db_user_namespace; - -/* - * In protocol 3.0 and later, the startup packet length is not fixed, but - * we set an arbitrary limit on it anyway. This is just to prevent simple - * denial-of-service attacks via sending enough data to run the server - * out of memory. - */ -#define MAX_STARTUP_PACKET_LENGTH 10000 - - -/* These are the authentication request codes sent by the backend. */ - -#define AUTH_REQ_OK 0 /* User is authenticated */ -#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ -#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ -#define AUTH_REQ_PASSWORD 3 /* Password */ -#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ -#define AUTH_REQ_MD5 5 /* md5 password */ -/* 6 is available. It was used for SCM creds, not supported any more. */ -#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ -#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ -#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ -#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ -#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ -#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ -#define AUTH_REQ_MAX AUTH_REQ_SASL_FIN /* maximum AUTH_REQ_* value */ - -typedef uint32 AuthRequest; - - -/* - * A client can also send a cancel-current-operation request to the postmaster. - * This is uglier than sending it directly to the client's backend, but it - * avoids depending on out-of-band communication facilities. - * - * The cancel request code must not match any protocol version number - * we're ever likely to use. This random choice should do. - */ -#define CANCEL_REQUEST_CODE PG_PROTOCOL(1234,5678) - -typedef struct CancelRequestPacket -{ - /* Note that each field is stored in network byte order! */ - MsgType cancelRequestCode; /* code to identify a cancel request */ - uint32 backendPID; /* PID of client's backend */ - uint32 cancelAuthCode; /* secret key to authorize cancel */ -} CancelRequestPacket; - - -/* - * A client can also start by sending a SSL or GSSAPI negotiation request to - * get a secure channel. - */ -#define NEGOTIATE_SSL_CODE PG_PROTOCOL(1234,5679) -#define NEGOTIATE_GSS_CODE PG_PROTOCOL(1234,5680) - -#endif /* PQCOMM_H */ diff --git a/contrib/libs/libpq/src/include/mb/pg_wchar.h b/contrib/libs/libpq/src/include/mb/pg_wchar.h deleted file mode 100644 index 06a56a41bb..0000000000 --- a/contrib/libs/libpq/src/include/mb/pg_wchar.h +++ /dev/null @@ -1,703 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_wchar.h - * multibyte-character support - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/mb/pg_wchar.h - * - * NOTES - * This is used both by the backend and by frontends, but should not be - * included by libpq client programs. In particular, a libpq client - * should not assume that the encoding IDs used by the version of libpq - * it's linked to match up with the IDs declared here. - * - *------------------------------------------------------------------------- - */ -#ifndef PG_WCHAR_H -#define PG_WCHAR_H - -/* - * The pg_wchar type - */ -typedef unsigned int pg_wchar; - -/* - * Maximum byte length of multibyte characters in any backend encoding - */ -#define MAX_MULTIBYTE_CHAR_LEN 4 - -/* - * various definitions for EUC - */ -#define SS2 0x8e /* single shift 2 (JIS0201) */ -#define SS3 0x8f /* single shift 3 (JIS0212) */ - -/* - * SJIS validation macros - */ -#define ISSJISHEAD(c) (((c) >= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) -#define ISSJISTAIL(c) (((c) >= 0x40 && (c) <= 0x7e) || ((c) >= 0x80 && (c) <= 0xfc)) - -/*---------------------------------------------------- - * MULE Internal Encoding (MIC) - * - * This encoding follows the design used within XEmacs; it is meant to - * subsume many externally-defined character sets. Each character includes - * identification of the character set it belongs to, so the encoding is - * general but somewhat bulky. - * - * Currently PostgreSQL supports 5 types of MULE character sets: - * - * 1) 1-byte ASCII characters. Each byte is below 0x80. - * - * 2) "Official" single byte charsets such as ISO-8859-1 (Latin1). - * Each MULE character consists of 2 bytes: LC1 + C1, where LC1 is - * an identifier for the charset (in the range 0x81 to 0x8d) and C1 - * is the character code (in the range 0xa0 to 0xff). - * - * 3) "Private" single byte charsets such as SISHENG. Each MULE - * character consists of 3 bytes: LCPRV1 + LC12 + C1, where LCPRV1 - * is a private-charset flag, LC12 is an identifier for the charset, - * and C1 is the character code (in the range 0xa0 to 0xff). - * LCPRV1 is either 0x9a (if LC12 is in the range 0xa0 to 0xdf) - * or 0x9b (if LC12 is in the range 0xe0 to 0xef). - * - * 4) "Official" multibyte charsets such as JIS X0208. Each MULE - * character consists of 3 bytes: LC2 + C1 + C2, where LC2 is - * an identifier for the charset (in the range 0x90 to 0x99) and C1 - * and C2 form the character code (each in the range 0xa0 to 0xff). - * - * 5) "Private" multibyte charsets such as CNS 11643-1992 Plane 3. - * Each MULE character consists of 4 bytes: LCPRV2 + LC22 + C1 + C2, - * where LCPRV2 is a private-charset flag, LC22 is an identifier for - * the charset, and C1 and C2 form the character code (each in the range - * 0xa0 to 0xff). LCPRV2 is either 0x9c (if LC22 is in the range 0xf0 - * to 0xf4) or 0x9d (if LC22 is in the range 0xf5 to 0xfe). - * - * "Official" encodings are those that have been assigned code numbers by - * the XEmacs project; "private" encodings have Postgres-specific charset - * identifiers. - * - * See the "XEmacs Internals Manual", available at http://www.xemacs.org, - * for more details. Note that for historical reasons, Postgres' - * private-charset flag values do not match what XEmacs says they should be, - * so this isn't really exactly MULE (not that private charsets would be - * interoperable anyway). - * - * Note that XEmacs's implementation is different from what emacs does. - * We follow emacs's implementation, rather than XEmacs's. - *---------------------------------------------------- - */ - -/* - * Charset identifiers (also called "leading bytes" in the MULE documentation) - */ - -/* - * Charset IDs for official single byte encodings (0x81-0x8e) - */ -#define LC_ISO8859_1 0x81 /* ISO8859 Latin 1 */ -#define LC_ISO8859_2 0x82 /* ISO8859 Latin 2 */ -#define LC_ISO8859_3 0x83 /* ISO8859 Latin 3 */ -#define LC_ISO8859_4 0x84 /* ISO8859 Latin 4 */ -#define LC_TIS620 0x85 /* Thai (not supported yet) */ -#define LC_ISO8859_7 0x86 /* Greek (not supported yet) */ -#define LC_ISO8859_6 0x87 /* Arabic (not supported yet) */ -#define LC_ISO8859_8 0x88 /* Hebrew (not supported yet) */ -#define LC_JISX0201K 0x89 /* Japanese 1 byte kana */ -#define LC_JISX0201R 0x8a /* Japanese 1 byte Roman */ -/* Note that 0x8b seems to be unused as of Emacs 20.7. - * However, there might be a chance that 0x8b could be used - * in later versions of Emacs. - */ -#define LC_KOI8_R 0x8b /* Cyrillic KOI8-R */ -#define LC_ISO8859_5 0x8c /* ISO8859 Cyrillic */ -#define LC_ISO8859_9 0x8d /* ISO8859 Latin 5 (not supported yet) */ -#define LC_ISO8859_15 0x8e /* ISO8859 Latin 15 (not supported yet) */ -/* #define CONTROL_1 0x8f control characters (unused) */ - -/* Is a leading byte for "official" single byte encodings? */ -#define IS_LC1(c) ((unsigned char)(c) >= 0x81 && (unsigned char)(c) <= 0x8d) - -/* - * Charset IDs for official multibyte encodings (0x90-0x99) - * 0x9a-0x9d are free. 0x9e and 0x9f are reserved. - */ -#define LC_JISX0208_1978 0x90 /* Japanese Kanji, old JIS (not supported) */ -#define LC_GB2312_80 0x91 /* Chinese */ -#define LC_JISX0208 0x92 /* Japanese Kanji (JIS X 0208) */ -#define LC_KS5601 0x93 /* Korean */ -#define LC_JISX0212 0x94 /* Japanese Kanji (JIS X 0212) */ -#define LC_CNS11643_1 0x95 /* CNS 11643-1992 Plane 1 */ -#define LC_CNS11643_2 0x96 /* CNS 11643-1992 Plane 2 */ -#define LC_JISX0213_1 0x97 /* Japanese Kanji (JIS X 0213 Plane 1) - * (not supported) */ -#define LC_BIG5_1 0x98 /* Plane 1 Chinese traditional (not - * supported) */ -#define LC_BIG5_2 0x99 /* Plane 1 Chinese traditional (not - * supported) */ - -/* Is a leading byte for "official" multibyte encodings? */ -#define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) - -/* - * Postgres-specific prefix bytes for "private" single byte encodings - * (According to the MULE docs, we should be using 0x9e for this) - */ -#define LCPRV1_A 0x9a -#define LCPRV1_B 0x9b -#define IS_LCPRV1(c) ((unsigned char)(c) == LCPRV1_A || (unsigned char)(c) == LCPRV1_B) -#define IS_LCPRV1_A_RANGE(c) \ - ((unsigned char)(c) >= 0xa0 && (unsigned char)(c) <= 0xdf) -#define IS_LCPRV1_B_RANGE(c) \ - ((unsigned char)(c) >= 0xe0 && (unsigned char)(c) <= 0xef) - -/* - * Postgres-specific prefix bytes for "private" multibyte encodings - * (According to the MULE docs, we should be using 0x9f for this) - */ -#define LCPRV2_A 0x9c -#define LCPRV2_B 0x9d -#define IS_LCPRV2(c) ((unsigned char)(c) == LCPRV2_A || (unsigned char)(c) == LCPRV2_B) -#define IS_LCPRV2_A_RANGE(c) \ - ((unsigned char)(c) >= 0xf0 && (unsigned char)(c) <= 0xf4) -#define IS_LCPRV2_B_RANGE(c) \ - ((unsigned char)(c) >= 0xf5 && (unsigned char)(c) <= 0xfe) - -/* - * Charset IDs for private single byte encodings (0xa0-0xef) - */ -#define LC_SISHENG 0xa0 /* Chinese SiSheng characters for - * PinYin/ZhuYin (not supported) */ -#define LC_IPA 0xa1 /* IPA (International Phonetic - * Association) (not supported) */ -#define LC_VISCII_LOWER 0xa2 /* Vietnamese VISCII1.1 lower-case (not - * supported) */ -#define LC_VISCII_UPPER 0xa3 /* Vietnamese VISCII1.1 upper-case (not - * supported) */ -#define LC_ARABIC_DIGIT 0xa4 /* Arabic digit (not supported) */ -#define LC_ARABIC_1_COLUMN 0xa5 /* Arabic 1-column (not supported) */ -#define LC_ASCII_RIGHT_TO_LEFT 0xa6 /* ASCII (left half of ISO8859-1) with - * right-to-left direction (not - * supported) */ -#define LC_LAO 0xa7 /* Lao characters (ISO10646 0E80..0EDF) - * (not supported) */ -#define LC_ARABIC_2_COLUMN 0xa8 /* Arabic 1-column (not supported) */ - -/* - * Charset IDs for private multibyte encodings (0xf0-0xff) - */ -#define LC_INDIAN_1_COLUMN 0xf0 /* Indian charset for 1-column width - * glyphs (not supported) */ -#define LC_TIBETAN_1_COLUMN 0xf1 /* Tibetan 1-column width glyphs (not - * supported) */ -#define LC_UNICODE_SUBSET_2 0xf2 /* Unicode characters of the range - * U+2500..U+33FF. (not supported) */ -#define LC_UNICODE_SUBSET_3 0xf3 /* Unicode characters of the range - * U+E000..U+FFFF. (not supported) */ -#define LC_UNICODE_SUBSET 0xf4 /* Unicode characters of the range - * U+0100..U+24FF. (not supported) */ -#define LC_ETHIOPIC 0xf5 /* Ethiopic characters (not supported) */ -#define LC_CNS11643_3 0xf6 /* CNS 11643-1992 Plane 3 */ -#define LC_CNS11643_4 0xf7 /* CNS 11643-1992 Plane 4 */ -#define LC_CNS11643_5 0xf8 /* CNS 11643-1992 Plane 5 */ -#define LC_CNS11643_6 0xf9 /* CNS 11643-1992 Plane 6 */ -#define LC_CNS11643_7 0xfa /* CNS 11643-1992 Plane 7 */ -#define LC_INDIAN_2_COLUMN 0xfb /* Indian charset for 2-column width - * glyphs (not supported) */ -#define LC_TIBETAN 0xfc /* Tibetan (not supported) */ -/* #define FREE 0xfd free (unused) */ -/* #define FREE 0xfe free (unused) */ -/* #define FREE 0xff free (unused) */ - -/*---------------------------------------------------- - * end of MULE stuff - *---------------------------------------------------- - */ - -/* - * PostgreSQL encoding identifiers - * - * WARNING: the order of this enum must be same as order of entries - * in the pg_enc2name_tbl[] array (in src/common/encnames.c), and - * in the pg_wchar_table[] array (in src/common/wchar.c)! - * - * If you add some encoding don't forget to check - * PG_ENCODING_BE_LAST macro. - * - * PG_SQL_ASCII is default encoding and must be = 0. - * - * XXX We must avoid renumbering any backend encoding until libpq's major - * version number is increased beyond 5; it turns out that the backend - * encoding IDs are effectively part of libpq's ABI as far as 8.2 initdb and - * psql are concerned. - */ -typedef enum pg_enc -{ - PG_SQL_ASCII = 0, /* SQL/ASCII */ - PG_EUC_JP, /* EUC for Japanese */ - PG_EUC_CN, /* EUC for Chinese */ - PG_EUC_KR, /* EUC for Korean */ - PG_EUC_TW, /* EUC for Taiwan */ - PG_EUC_JIS_2004, /* EUC-JIS-2004 */ - PG_UTF8, /* Unicode UTF8 */ - PG_MULE_INTERNAL, /* Mule internal code */ - PG_LATIN1, /* ISO-8859-1 Latin 1 */ - PG_LATIN2, /* ISO-8859-2 Latin 2 */ - PG_LATIN3, /* ISO-8859-3 Latin 3 */ - PG_LATIN4, /* ISO-8859-4 Latin 4 */ - PG_LATIN5, /* ISO-8859-9 Latin 5 */ - PG_LATIN6, /* ISO-8859-10 Latin6 */ - PG_LATIN7, /* ISO-8859-13 Latin7 */ - PG_LATIN8, /* ISO-8859-14 Latin8 */ - PG_LATIN9, /* ISO-8859-15 Latin9 */ - PG_LATIN10, /* ISO-8859-16 Latin10 */ - PG_WIN1256, /* windows-1256 */ - PG_WIN1258, /* Windows-1258 */ - PG_WIN866, /* (MS-DOS CP866) */ - PG_WIN874, /* windows-874 */ - PG_KOI8R, /* KOI8-R */ - PG_WIN1251, /* windows-1251 */ - PG_WIN1252, /* windows-1252 */ - PG_ISO_8859_5, /* ISO-8859-5 */ - PG_ISO_8859_6, /* ISO-8859-6 */ - PG_ISO_8859_7, /* ISO-8859-7 */ - PG_ISO_8859_8, /* ISO-8859-8 */ - PG_WIN1250, /* windows-1250 */ - PG_WIN1253, /* windows-1253 */ - PG_WIN1254, /* windows-1254 */ - PG_WIN1255, /* windows-1255 */ - PG_WIN1257, /* windows-1257 */ - PG_KOI8U, /* KOI8-U */ - /* PG_ENCODING_BE_LAST points to the above entry */ - - /* followings are for client encoding only */ - PG_SJIS, /* Shift JIS (Windows-932) */ - PG_BIG5, /* Big5 (Windows-950) */ - PG_GBK, /* GBK (Windows-936) */ - PG_UHC, /* UHC (Windows-949) */ - PG_GB18030, /* GB18030 */ - PG_JOHAB, /* EUC for Korean JOHAB */ - PG_SHIFT_JIS_2004, /* Shift-JIS-2004 */ - _PG_LAST_ENCODING_ /* mark only */ - -} pg_enc; - -#define PG_ENCODING_BE_LAST PG_KOI8U - -/* - * Please use these tests before access to pg_enc2name_tbl[] - * or to other places... - */ -#define PG_VALID_BE_ENCODING(_enc) \ - ((_enc) >= 0 && (_enc) <= PG_ENCODING_BE_LAST) - -#define PG_ENCODING_IS_CLIENT_ONLY(_enc) \ - ((_enc) > PG_ENCODING_BE_LAST && (_enc) < _PG_LAST_ENCODING_) - -#define PG_VALID_ENCODING(_enc) \ - ((_enc) >= 0 && (_enc) < _PG_LAST_ENCODING_) - -/* On FE are possible all encodings */ -#define PG_VALID_FE_ENCODING(_enc) PG_VALID_ENCODING(_enc) - -/* - * When converting strings between different encodings, we assume that space - * for converted result is 4-to-1 growth in the worst case. The rate for - * currently supported encoding pairs are within 3 (SJIS JIS X0201 half width - * kana -> UTF8 is the worst case). So "4" should be enough for the moment. - * - * Note that this is not the same as the maximum character width in any - * particular encoding. - */ -#define MAX_CONVERSION_GROWTH 4 - -/* - * Maximum byte length of a string that's required in any encoding to convert - * at least one character to any other encoding. In other words, if you feed - * MAX_CONVERSION_INPUT_LENGTH bytes to any encoding conversion function, it - * is guaranteed to be able to convert something without needing more input - * (assuming the input is valid). - * - * Currently, the maximum case is the conversion UTF8 -> SJIS JIS X0201 half - * width kana, where a pair of UTF-8 characters is converted into a single - * SHIFT_JIS_2004 character (the reverse of the worst case for - * MAX_CONVERSION_GROWTH). It needs 6 bytes of input. In theory, a - * user-defined conversion function might have more complicated cases, although - * for the reverse mapping you would probably also need to bump up - * MAX_CONVERSION_GROWTH. But there is no need to be stingy here, so make it - * generous. - */ -#define MAX_CONVERSION_INPUT_LENGTH 16 - -/* - * Maximum byte length of the string equivalent to any one Unicode code point, - * in any backend encoding. The current value assumes that a 4-byte UTF-8 - * character might expand by MAX_CONVERSION_GROWTH, which is a huge - * overestimate. But in current usage we don't allocate large multiples of - * this, so there's little point in being stingy. - */ -#define MAX_UNICODE_EQUIVALENT_STRING 16 - -/* - * Table for mapping an encoding number to official encoding name and - * possibly other subsidiary data. Be careful to check encoding number - * before accessing a table entry! - * - * if (PG_VALID_ENCODING(encoding)) - * pg_enc2name_tbl[ encoding ]; - */ -typedef struct pg_enc2name -{ - const char *name; - pg_enc encoding; -#ifdef WIN32 - unsigned codepage; /* codepage for WIN32 */ -#endif -} pg_enc2name; - -extern PGDLLIMPORT const pg_enc2name pg_enc2name_tbl[]; - -/* - * Encoding names for gettext - */ -typedef struct pg_enc2gettext -{ - pg_enc encoding; - const char *name; -} pg_enc2gettext; - -extern PGDLLIMPORT const pg_enc2gettext pg_enc2gettext_tbl[]; - -/* - * pg_wchar stuff - */ -typedef int (*mb2wchar_with_len_converter) (const unsigned char *from, - pg_wchar *to, - int len); - -typedef int (*wchar2mb_with_len_converter) (const pg_wchar *from, - unsigned char *to, - int len); - -typedef int (*mblen_converter) (const unsigned char *mbstr); - -typedef int (*mbdisplaylen_converter) (const unsigned char *mbstr); - -typedef bool (*mbcharacter_incrementer) (unsigned char *mbstr, int len); - -typedef int (*mbchar_verifier) (const unsigned char *mbstr, int len); - -typedef int (*mbstr_verifier) (const unsigned char *mbstr, int len); - -typedef struct -{ - mb2wchar_with_len_converter mb2wchar_with_len; /* convert a multibyte - * string to a wchar */ - wchar2mb_with_len_converter wchar2mb_with_len; /* convert a wchar string - * to a multibyte */ - mblen_converter mblen; /* get byte length of a char */ - mbdisplaylen_converter dsplen; /* get display width of a char */ - mbchar_verifier mbverifychar; /* verify multibyte character */ - mbstr_verifier mbverifystr; /* verify multibyte string */ - int maxmblen; /* max bytes for a char in this encoding */ -} pg_wchar_tbl; - -extern PGDLLIMPORT const pg_wchar_tbl pg_wchar_table[]; - -/* - * Data structures for conversions between UTF-8 and other encodings - * (UtfToLocal() and LocalToUtf()). In these data structures, characters of - * either encoding are represented by uint32 words; hence we can only support - * characters up to 4 bytes long. For example, the byte sequence 0xC2 0x89 - * would be represented by 0x0000C289, and 0xE8 0xA2 0xB4 by 0x00E8A2B4. - * - * There are three possible ways a character can be mapped: - * - * 1. Using a radix tree, from source to destination code. - * 2. Using a sorted array of source -> destination code pairs. This - * method is used for "combining" characters. There are so few of - * them that building a radix tree would be wasteful. - * 3. Using a conversion function. - */ - -/* - * Radix tree for character conversion. - * - * Logically, this is actually four different radix trees, for 1-byte, - * 2-byte, 3-byte and 4-byte inputs. The 1-byte tree is a simple lookup - * table from source to target code. The 2-byte tree consists of two levels: - * one lookup table for the first byte, where the value in the lookup table - * points to a lookup table for the second byte. And so on. - * - * Physically, all the trees are stored in one big array, in 'chars16' or - * 'chars32', depending on the maximum value that needs to be represented. For - * each level in each tree, we also store lower and upper bound of allowed - * values - values outside those bounds are considered invalid, and are left - * out of the tables. - * - * In the intermediate levels of the trees, the values stored are offsets - * into the chars[16|32] array. - * - * In the beginning of the chars[16|32] array, there is always a number of - * zeros, so that you safely follow an index from an intermediate table - * without explicitly checking for a zero. Following a zero any number of - * times will always bring you to the dummy, all-zeros table in the - * beginning. This helps to shave some cycles when looking up values. - */ -typedef struct -{ - /* - * Array containing all the values. Only one of chars16 or chars32 is - * used, depending on how wide the values we need to represent are. - */ - const uint16 *chars16; - const uint32 *chars32; - - /* Radix tree for 1-byte inputs */ - uint32 b1root; /* offset of table in the chars[16|32] array */ - uint8 b1_lower; /* min allowed value for a single byte input */ - uint8 b1_upper; /* max allowed value for a single byte input */ - - /* Radix tree for 2-byte inputs */ - uint32 b2root; /* offset of 1st byte's table */ - uint8 b2_1_lower; /* min/max allowed value for 1st input byte */ - uint8 b2_1_upper; - uint8 b2_2_lower; /* min/max allowed value for 2nd input byte */ - uint8 b2_2_upper; - - /* Radix tree for 3-byte inputs */ - uint32 b3root; /* offset of 1st byte's table */ - uint8 b3_1_lower; /* min/max allowed value for 1st input byte */ - uint8 b3_1_upper; - uint8 b3_2_lower; /* min/max allowed value for 2nd input byte */ - uint8 b3_2_upper; - uint8 b3_3_lower; /* min/max allowed value for 3rd input byte */ - uint8 b3_3_upper; - - /* Radix tree for 4-byte inputs */ - uint32 b4root; /* offset of 1st byte's table */ - uint8 b4_1_lower; /* min/max allowed value for 1st input byte */ - uint8 b4_1_upper; - uint8 b4_2_lower; /* min/max allowed value for 2nd input byte */ - uint8 b4_2_upper; - uint8 b4_3_lower; /* min/max allowed value for 3rd input byte */ - uint8 b4_3_upper; - uint8 b4_4_lower; /* min/max allowed value for 4th input byte */ - uint8 b4_4_upper; - -} pg_mb_radix_tree; - -/* - * UTF-8 to local code conversion map (for combined characters) - */ -typedef struct -{ - uint32 utf1; /* UTF-8 code 1 */ - uint32 utf2; /* UTF-8 code 2 */ - uint32 code; /* local code */ -} pg_utf_to_local_combined; - -/* - * local code to UTF-8 conversion map (for combined characters) - */ -typedef struct -{ - uint32 code; /* local code */ - uint32 utf1; /* UTF-8 code 1 */ - uint32 utf2; /* UTF-8 code 2 */ -} pg_local_to_utf_combined; - -/* - * callback function for algorithmic encoding conversions (in either direction) - * - * if function returns zero, it does not know how to convert the code - */ -typedef uint32 (*utf_local_conversion_func) (uint32 code); - -/* - * Support macro for encoding conversion functions to validate their - * arguments. (This could be made more compact if we included fmgr.h - * here, but we don't want to do that because this header file is also - * used by frontends.) - */ -#define CHECK_ENCODING_CONVERSION_ARGS(srcencoding,destencoding) \ - check_encoding_conversion_args(PG_GETARG_INT32(0), \ - PG_GETARG_INT32(1), \ - PG_GETARG_INT32(4), \ - (srcencoding), \ - (destencoding)) - - -/* - * Some handy functions for Unicode-specific tests. - */ -static inline bool -is_valid_unicode_codepoint(pg_wchar c) -{ - return (c > 0 && c <= 0x10FFFF); -} - -static inline bool -is_utf16_surrogate_first(pg_wchar c) -{ - return (c >= 0xD800 && c <= 0xDBFF); -} - -static inline bool -is_utf16_surrogate_second(pg_wchar c) -{ - return (c >= 0xDC00 && c <= 0xDFFF); -} - -static inline pg_wchar -surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) -{ - return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF); -} - - -/* - * These functions are considered part of libpq's exported API and - * are also declared in libpq-fe.h. - */ -extern int pg_char_to_encoding(const char *name); -extern const char *pg_encoding_to_char(int encoding); -extern int pg_valid_server_encoding_id(int encoding); - -/* - * These functions are available to frontend code that links with libpgcommon - * (in addition to the ones just above). The constant tables declared - * earlier in this file are also available from libpgcommon. - */ -extern int pg_encoding_mblen(int encoding, const char *mbstr); -extern int pg_encoding_mblen_bounded(int encoding, const char *mbstr); -extern int pg_encoding_dsplen(int encoding, const char *mbstr); -extern int pg_encoding_verifymbchar(int encoding, const char *mbstr, int len); -extern int pg_encoding_verifymbstr(int encoding, const char *mbstr, int len); -extern int pg_encoding_max_length(int encoding); -extern int pg_valid_client_encoding(const char *name); -extern int pg_valid_server_encoding(const char *name); -extern bool is_encoding_supported_by_icu(int encoding); -extern const char *get_encoding_name_for_icu(int encoding); - -extern unsigned char *unicode_to_utf8(pg_wchar c, unsigned char *utf8string); -extern pg_wchar utf8_to_unicode(const unsigned char *c); -extern bool pg_utf8_islegal(const unsigned char *source, int length); -extern int pg_utf_mblen(const unsigned char *s); -extern int pg_mule_mblen(const unsigned char *s); - -/* - * The remaining functions are backend-only. - */ -extern int pg_mb2wchar(const char *from, pg_wchar *to); -extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len); -extern int pg_encoding_mb2wchar_with_len(int encoding, - const char *from, pg_wchar *to, int len); -extern int pg_wchar2mb(const pg_wchar *from, char *to); -extern int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len); -extern int pg_encoding_wchar2mb_with_len(int encoding, - const pg_wchar *from, char *to, int len); -extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2); -extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n); -extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n); -extern size_t pg_wchar_strlen(const pg_wchar *str); -extern int pg_mblen(const char *mbstr); -extern int pg_dsplen(const char *mbstr); -extern int pg_mbstrlen(const char *mbstr); -extern int pg_mbstrlen_with_len(const char *mbstr, int limit); -extern int pg_mbcliplen(const char *mbstr, int len, int limit); -extern int pg_encoding_mbcliplen(int encoding, const char *mbstr, - int len, int limit); -extern int pg_mbcharcliplen(const char *mbstr, int len, int limit); -extern int pg_database_encoding_max_length(void); -extern mbcharacter_incrementer pg_database_encoding_character_incrementer(void); - -extern int PrepareClientEncoding(int encoding); -extern int SetClientEncoding(int encoding); -extern void InitializeClientEncoding(void); -extern int pg_get_client_encoding(void); -extern const char *pg_get_client_encoding_name(void); - -extern void SetDatabaseEncoding(int encoding); -extern int GetDatabaseEncoding(void); -extern const char *GetDatabaseEncodingName(void); -extern void SetMessageEncoding(int encoding); -extern int GetMessageEncoding(void); - -#ifdef ENABLE_NLS -extern int pg_bind_textdomain_codeset(const char *domainname); -#endif - -extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len, - int src_encoding, - int dest_encoding); -extern int pg_do_encoding_conversion_buf(Oid proc, - int src_encoding, - int dest_encoding, - unsigned char *src, int srclen, - unsigned char *dest, int destlen, - bool noError); - -extern char *pg_client_to_server(const char *s, int len); -extern char *pg_server_to_client(const char *s, int len); -extern char *pg_any_to_server(const char *s, int len, int encoding); -extern char *pg_server_to_any(const char *s, int len, int encoding); - -extern void pg_unicode_to_server(pg_wchar c, unsigned char *s); -extern bool pg_unicode_to_server_noerror(pg_wchar c, unsigned char *s); - -extern unsigned short BIG5toCNS(unsigned short big5, unsigned char *lc); -extern unsigned short CNStoBIG5(unsigned short cns, unsigned char lc); - -extern int UtfToLocal(const unsigned char *utf, int len, - unsigned char *iso, - const pg_mb_radix_tree *map, - const pg_utf_to_local_combined *cmap, int cmapsize, - utf_local_conversion_func conv_func, - int encoding, bool noError); -extern int LocalToUtf(const unsigned char *iso, int len, - unsigned char *utf, - const pg_mb_radix_tree *map, - const pg_local_to_utf_combined *cmap, int cmapsize, - utf_local_conversion_func conv_func, - int encoding, bool noError); - -extern bool pg_verifymbstr(const char *mbstr, int len, bool noError); -extern bool pg_verify_mbstr(int encoding, const char *mbstr, int len, - bool noError); -extern int pg_verify_mbstr_len(int encoding, const char *mbstr, int len, - bool noError); - -extern void check_encoding_conversion_args(int src_encoding, - int dest_encoding, - int len, - int expected_src_encoding, - int expected_dest_encoding); - -extern void report_invalid_encoding(int encoding, const char *mbstr, int len) pg_attribute_noreturn(); -extern void report_untranslatable_char(int src_encoding, int dest_encoding, - const char *mbstr, int len) pg_attribute_noreturn(); - -extern int local2local(const unsigned char *l, unsigned char *p, int len, - int src_encoding, int dest_encoding, - const unsigned char *tab, bool noError); -extern int latin2mic(const unsigned char *l, unsigned char *p, int len, - int lc, int encoding, bool noError); -extern int mic2latin(const unsigned char *mic, unsigned char *p, int len, - int lc, int encoding, bool noError); -extern int latin2mic_with_table(const unsigned char *l, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab, bool noError); -extern int mic2latin_with_table(const unsigned char *mic, unsigned char *p, - int len, int lc, int encoding, - const unsigned char *tab, bool noError); - -#ifdef WIN32 -extern WCHAR *pgwin32_message_to_UTF16(const char *str, int len, int *utf16len); -#endif - -#endif /* PG_WCHAR_H */ diff --git a/contrib/libs/libpq/src/include/parser/kwlist.h b/contrib/libs/libpq/src/include/parser/kwlist.h deleted file mode 100644 index f5b2e61ca5..0000000000 --- a/contrib/libs/libpq/src/include/parser/kwlist.h +++ /dev/null @@ -1,498 +0,0 @@ -/*------------------------------------------------------------------------- - * - * kwlist.h - * - * The keyword lists are kept in their own source files for use by - * automatic tools. The exact representation of a keyword is determined - * by the PG_KEYWORD macro, which is not defined in this file; it can - * be defined by the caller for special purposes. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/include/parser/kwlist.h - * - *------------------------------------------------------------------------- - */ - -/* there is deliberately not an #ifndef KWLIST_H here */ - -/* - * List of keyword (name, token-value, category, bare-label-status) entries. - * - * Note: gen_keywordlist.pl requires the entries to appear in ASCII order. - */ - -/* name, value, category, is-bare-label */ -PG_KEYWORD("abort", ABORT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("absent", ABSENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("absolute", ABSOLUTE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("access", ACCESS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("action", ACTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("add", ADD_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("admin", ADMIN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("after", AFTER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("aggregate", AGGREGATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("all", ALL, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("also", ALSO, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("alter", ALTER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("always", ALWAYS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("analyse", ANALYSE, RESERVED_KEYWORD, BARE_LABEL) /* British spelling */ -PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("and", AND, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("any", ANY, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("as", AS, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("asc", ASC, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("asensitive", ASENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("assertion", ASSERTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("assignment", ASSIGNMENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("asymmetric", ASYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("at", AT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("atomic", ATOMIC, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("attach", ATTACH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("attribute", ATTRIBUTE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("authorization", AUTHORIZATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("backward", BACKWARD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("before", BEFORE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("begin", BEGIN_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("between", BETWEEN, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("bigint", BIGINT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("binary", BINARY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("bit", BIT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("boolean", BOOLEAN_P, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("both", BOTH, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("breadth", BREADTH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("by", BY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cache", CACHE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("call", CALL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("called", CALLED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cascade", CASCADE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cascaded", CASCADED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("case", CASE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cast", CAST, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("catalog", CATALOG_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("chain", CHAIN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("char", CHAR_P, COL_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("character", CHARACTER, COL_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("characteristics", CHARACTERISTICS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("check", CHECK, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("checkpoint", CHECKPOINT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("class", CLASS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("close", CLOSE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cluster", CLUSTER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("coalesce", COALESCE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("collate", COLLATE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("collation", COLLATION, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("column", COLUMN, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("columns", COLUMNS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("comment", COMMENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("comments", COMMENTS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("commit", COMMIT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("committed", COMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("compression", COMPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("concurrently", CONCURRENTLY, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("configuration", CONFIGURATION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("conflict", CONFLICT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("connection", CONNECTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("constraint", CONSTRAINT, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("constraints", CONSTRAINTS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("content", CONTENT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("continue", CONTINUE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("conversion", CONVERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("copy", COPY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cost", COST, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("create", CREATE, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("cross", CROSS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("csv", CSV, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cube", CUBE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current", CURRENT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_catalog", CURRENT_CATALOG, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_date", CURRENT_DATE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_role", CURRENT_ROLE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_schema", CURRENT_SCHEMA, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_time", CURRENT_TIME, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_timestamp", CURRENT_TIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("current_user", CURRENT_USER, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cursor", CURSOR, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("cycle", CYCLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("data", DATA_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("database", DATABASE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("day", DAY_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("deallocate", DEALLOCATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("dec", DEC, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("decimal", DECIMAL_P, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("declare", DECLARE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("default", DEFAULT, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("defaults", DEFAULTS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("deferrable", DEFERRABLE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("deferred", DEFERRED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("definer", DEFINER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("delete", DELETE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("delimiter", DELIMITER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("delimiters", DELIMITERS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("depends", DEPENDS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("depth", DEPTH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("desc", DESC, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("detach", DETACH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("dictionary", DICTIONARY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("disable", DISABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("discard", DISCARD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("distinct", DISTINCT, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("do", DO, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("document", DOCUMENT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("domain", DOMAIN_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("double", DOUBLE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("drop", DROP, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("each", EACH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("else", ELSE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("enable", ENABLE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("encoding", ENCODING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("encrypted", ENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("end", END_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("enum", ENUM_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("escape", ESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("event", EVENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("except", EXCEPT, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("exclude", EXCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("excluding", EXCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("exclusive", EXCLUSIVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("execute", EXECUTE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("exists", EXISTS, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("explain", EXPLAIN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("expression", EXPRESSION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("extension", EXTENSION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("external", EXTERNAL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("extract", EXTRACT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("false", FALSE_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("family", FAMILY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("fetch", FETCH, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("filter", FILTER, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("finalize", FINALIZE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("first", FIRST_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("float", FLOAT_P, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("following", FOLLOWING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("for", FOR, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("force", FORCE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("foreign", FOREIGN, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("format", FORMAT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("forward", FORWARD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("freeze", FREEZE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("from", FROM, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("full", FULL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("function", FUNCTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("functions", FUNCTIONS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("generated", GENERATED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("global", GLOBAL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("grant", GRANT, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("granted", GRANTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("greatest", GREATEST, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("group", GROUP_P, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("grouping", GROUPING, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("groups", GROUPS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("handler", HANDLER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("having", HAVING, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("header", HEADER_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("hold", HOLD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("hour", HOUR_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("identity", IDENTITY_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("if", IF_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("ilike", ILIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("immediate", IMMEDIATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("immutable", IMMUTABLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("implicit", IMPLICIT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("import", IMPORT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("in", IN_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("include", INCLUDE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("including", INCLUDING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("increment", INCREMENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("indent", INDENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("index", INDEX, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("indexes", INDEXES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("inherit", INHERIT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("inherits", INHERITS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("initially", INITIALLY, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("inline", INLINE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("inner", INNER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("inout", INOUT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("input", INPUT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("insensitive", INSENSITIVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("insert", INSERT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("instead", INSTEAD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("int", INT_P, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("integer", INTEGER, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("intersect", INTERSECT, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("interval", INTERVAL, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("into", INTO, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("invoker", INVOKER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("is", IS, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("isnull", ISNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("isolation", ISOLATION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("join", JOIN, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("json", JSON, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("json_array", JSON_ARRAY, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("json_arrayagg", JSON_ARRAYAGG, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("json_object", JSON_OBJECT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("json_objectagg", JSON_OBJECTAGG, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("key", KEY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("keys", KEYS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("label", LABEL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("language", LANGUAGE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("large", LARGE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("last", LAST_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("lateral", LATERAL_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("leading", LEADING, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("leakproof", LEAKPROOF, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("least", LEAST, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("left", LEFT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("level", LEVEL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("like", LIKE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("limit", LIMIT, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("listen", LISTEN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("load", LOAD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("local", LOCAL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("localtime", LOCALTIME, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("localtimestamp", LOCALTIMESTAMP, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("location", LOCATION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("lock", LOCK_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("locked", LOCKED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("logged", LOGGED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("mapping", MAPPING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("match", MATCH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("matched", MATCHED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("materialized", MATERIALIZED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("maxvalue", MAXVALUE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("merge", MERGE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("method", METHOD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("minute", MINUTE_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("minvalue", MINVALUE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("mode", MODE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("month", MONTH_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("move", MOVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("name", NAME_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("names", NAMES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("national", NATIONAL, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("natural", NATURAL, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("nchar", NCHAR, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("new", NEW, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("next", NEXT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nfc", NFC, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nfd", NFD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nfkc", NFKC, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nfkd", NFKD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("no", NO, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("none", NONE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("normalize", NORMALIZE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("normalized", NORMALIZED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("not", NOT, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nothing", NOTHING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("notify", NOTIFY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("notnull", NOTNULL, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("nowait", NOWAIT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("null", NULL_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("nullif", NULLIF, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("nulls", NULLS_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("numeric", NUMERIC, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("object", OBJECT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("of", OF, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("off", OFF, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("offset", OFFSET, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("oids", OIDS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("old", OLD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("on", ON, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("only", ONLY, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("operator", OPERATOR, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("option", OPTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("options", OPTIONS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("or", OR, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("order", ORDER, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("ordinality", ORDINALITY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("others", OTHERS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("out", OUT_P, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("outer", OUTER_P, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("over", OVER, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("overlaps", OVERLAPS, TYPE_FUNC_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("overlay", OVERLAY, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("overriding", OVERRIDING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("owned", OWNED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("owner", OWNER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("parallel", PARALLEL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD, AS_LABEL) -PG_KEYWORD("prepare", PREPARE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("prepared", PREPARED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("preserve", PRESERVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("primary", PRIMARY, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("prior", PRIOR, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("privileges", PRIVILEGES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("procedural", PROCEDURAL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("procedure", PROCEDURE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("procedures", PROCEDURES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("program", PROGRAM, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("publication", PUBLICATION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("quote", QUOTE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("range", RANGE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("read", READ, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("real", REAL, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("reassign", REASSIGN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("recheck", RECHECK, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("recursive", RECURSIVE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("ref", REF_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("references", REFERENCES, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("referencing", REFERENCING, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("refresh", REFRESH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("reindex", REINDEX, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("relative", RELATIVE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("release", RELEASE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("rename", RENAME, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("repeatable", REPEATABLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("replace", REPLACE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("replica", REPLICA, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("reset", RESET, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("restart", RESTART, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("restrict", RESTRICT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("return", RETURN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("returning", RETURNING, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("returns", RETURNS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("revoke", REVOKE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("right", RIGHT, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("role", ROLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("rollback", ROLLBACK, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("rollup", ROLLUP, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("routine", ROUTINE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("routines", ROUTINES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("row", ROW, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("rows", ROWS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("rule", RULE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("savepoint", SAVEPOINT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("scalar", SCALAR, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("schema", SCHEMA, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("schemas", SCHEMAS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("scroll", SCROLL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("search", SEARCH, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("second", SECOND_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("security", SECURITY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("select", SELECT, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("sequence", SEQUENCE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("sequences", SEQUENCES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("serializable", SERIALIZABLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("server", SERVER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("session", SESSION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("session_user", SESSION_USER, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("set", SET, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("setof", SETOF, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("sets", SETS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("share", SHARE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("show", SHOW, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("similar", SIMILAR, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("simple", SIMPLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("skip", SKIP, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("start", START, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("statement", STATEMENT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("statistics", STATISTICS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("stdin", STDIN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("stdout", STDOUT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("storage", STORAGE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("stored", STORED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("strict", STRICT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("strip", STRIP_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("subscription", SUBSCRIPTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("substring", SUBSTRING, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("support", SUPPORT, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("symmetric", SYMMETRIC, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("sysid", SYSID, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("system", SYSTEM_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("system_user", SYSTEM_USER, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("table", TABLE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("tables", TABLES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("tablesample", TABLESAMPLE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("tablespace", TABLESPACE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("temp", TEMP, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("template", TEMPLATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("temporary", TEMPORARY, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("text", TEXT_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("then", THEN, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("ties", TIES, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("time", TIME, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("timestamp", TIMESTAMP, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("to", TO, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("trailing", TRAILING, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("transaction", TRANSACTION, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("transform", TRANSFORM, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("treat", TREAT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("trigger", TRIGGER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("trim", TRIM, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("true", TRUE_P, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("truncate", TRUNCATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("trusted", TRUSTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("type", TYPE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("types", TYPES_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("uescape", UESCAPE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("unbounded", UNBOUNDED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("uncommitted", UNCOMMITTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("unencrypted", UNENCRYPTED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("union", UNION, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("unique", UNIQUE, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("unknown", UNKNOWN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("user", USER, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("using", USING, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("valid", VALID, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("validate", VALIDATE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("validator", VALIDATOR, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("value", VALUE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("values", VALUES, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("varchar", VARCHAR, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("variadic", VARIADIC, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("varying", VARYING, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("verbose", VERBOSE, TYPE_FUNC_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("version", VERSION_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("view", VIEW, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("views", VIEWS, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("volatile", VOLATILE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("when", WHEN, RESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("where", WHERE, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("whitespace", WHITESPACE_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("window", WINDOW, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("with", WITH, RESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("within", WITHIN, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("without", WITHOUT, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("work", WORK, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("wrapper", WRAPPER, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("write", WRITE, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("xml", XML_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlattributes", XMLATTRIBUTES, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlconcat", XMLCONCAT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlelement", XMLELEMENT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlexists", XMLEXISTS, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlforest", XMLFOREST, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlnamespaces", XMLNAMESPACES, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlparse", XMLPARSE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlpi", XMLPI, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlroot", XMLROOT, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmlserialize", XMLSERIALIZE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("xmltable", XMLTABLE, COL_NAME_KEYWORD, BARE_LABEL) -PG_KEYWORD("year", YEAR_P, UNRESERVED_KEYWORD, AS_LABEL) -PG_KEYWORD("yes", YES_P, UNRESERVED_KEYWORD, BARE_LABEL) -PG_KEYWORD("zone", ZONE, UNRESERVED_KEYWORD, BARE_LABEL) diff --git a/contrib/libs/libpq/src/include/pg_config-linux-aarch64.h b/contrib/libs/libpq/src/include/pg_config-linux-aarch64.h deleted file mode 100644 index f27c40f1d7..0000000000 --- a/contrib/libs/libpq/src/include/pg_config-linux-aarch64.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "pg_config-linux.h" - -/* Define to 1 if you have __get_cpuid. */ -#undef HAVE__GET_CPUID diff --git a/contrib/libs/libpq/src/include/pg_config-linux.h b/contrib/libs/libpq/src/include/pg_config-linux.h deleted file mode 100644 index b4592fa70a..0000000000 --- a/contrib/libs/libpq/src/include/pg_config-linux.h +++ /dev/null @@ -1,825 +0,0 @@ -/* src/include/pg_config.h. Generated from pg_config.h.in by configure. */ -/* src/include/pg_config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* The normal alignment of `double', in bytes. */ -#define ALIGNOF_DOUBLE 8 - -/* The normal alignment of `int', in bytes. */ -#define ALIGNOF_INT 4 - -/* The normal alignment of `long', in bytes. */ -#define ALIGNOF_LONG 8 - -/* The normal alignment of `long long int', in bytes. */ -/* #undef ALIGNOF_LONG_LONG_INT */ - -/* The normal alignment of `PG_INT128_TYPE', in bytes. */ -#define ALIGNOF_PG_INT128_TYPE 16 - -/* The normal alignment of `short', in bytes. */ -#define ALIGNOF_SHORT 2 - -/* Size of a disk block --- this also limits the size of a tuple. You can set - it bigger if you need bigger tuples (although TOAST should reduce the need - to have large tuples, since fields can be spread across multiple tuples). - BLCKSZ must be a power of 2. The maximum possible value of BLCKSZ is - currently 2^15 (32768). This is determined by the 15-bit widths of the - lp_off and lp_len fields in ItemIdData (see include/storage/itemid.h). - Changing BLCKSZ requires an initdb. */ -#define BLCKSZ 8192 - -/* Saved arguments from configure */ -#define CONFIGURE_ARGS " '--prefix=/var/empty/postgresql-16.2' '--with-openssl' '--with-libxml' '--with-icu' '--sysconfdir=/etc' '--libdir=$(lib)/lib' '--with-system-tzdata=/var/empty/tzdata-2022f/share/zoneinfo' '--enable-debug' '--with-systemd' '--with-ossp-uuid' '--with-lz4' '--with-gssapi' '--without-gssapi' 'CC=cc' 'CXX=g++' 'PKG_CONFIG=pkg-config' 'PKG_CONFIG_PATH=/var/empty/libxcrypt-4.4.30/lib/pkgconfig:/var/empty/zlib-1.2.13-dev/lib/pkgconfig:/var/empty/ncurses-6.3-p20220507-dev/lib/pkgconfig:/var/empty/openssl-3.0.7-dev/lib/pkgconfig:/var/empty/libxml2-2.10.3-dev/lib/pkgconfig:/var/empty/icu4c-72.1-dev/lib/pkgconfig:/var/empty/lz4-1.9.4-dev/lib/pkgconfig:/var/empty/systemd-251.7-dev/lib/pkgconfig:/var/empty/systemd-251.7-dev/share/pkgconfig:/var/empty/libkrb5-1.20-dev/lib/pkgconfig:/var/empty/libossp-uuid-1.6.2/lib/pkgconfig'" - -/* Define to the default TCP port number on which the server listens and to - which clients will try to connect. This can be overridden at run-time, but - it's convenient if your clients have the right default compiled in. - (--with-pgport=PORTNUM) */ -#define DEF_PGPORT 5432 - -/* Define to the default TCP port number as a string constant. */ -#define DEF_PGPORT_STR "5432" - -/* Define to the file name extension of dynamically-loadable modules. */ -#define DLSUFFIX ".so" - -/* Define to build with GSSAPI support. (--with-gssapi) */ -/* #undef ENABLE_GSS */ - -/* Define to 1 if you want National Language Support. (--enable-nls) */ -/* #undef ENABLE_NLS */ - -/* Define to 1 to build client libraries as thread-safe code. - (--enable-thread-safety) */ -#define ENABLE_THREAD_SAFETY 1 - -/* Define to 1 if you have the `append_history' function. */ -#define HAVE_APPEND_HISTORY 1 - -/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ -#define HAVE_ASN1_STRING_GET0_DATA 1 - -/* Define to 1 if you want to use atomics if available. */ -#define HAVE_ATOMICS 1 - -/* Define to 1 if you have the <atomic.h> header file. */ -/* #undef HAVE_ATOMIC_H */ - -/* Define to 1 if you have the `backtrace_symbols' function. */ -#define HAVE_BACKTRACE_SYMBOLS 1 - -/* Define to 1 if you have the `BIO_meth_new' function. */ -#define HAVE_BIO_METH_NEW 1 - -/* Define to 1 if your compiler handles computed gotos. */ -#define HAVE_COMPUTED_GOTO 1 - -/* Define to 1 if you have the `copyfile' function. */ -/* #undef HAVE_COPYFILE */ - -/* Define to 1 if you have the <copyfile.h> header file. */ -/* #undef HAVE_COPYFILE_H */ - -/* Define to 1 if you have the <crtdefs.h> header file. */ -/* #undef HAVE_CRTDEFS_H */ - -/* Define to 1 if you have the `CRYPTO_lock' function. */ -/* #undef HAVE_CRYPTO_LOCK */ - -/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you - don't. */ -#define HAVE_DECL_FDATASYNC 1 - -/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you - don't. */ -#define HAVE_DECL_F_FULLFSYNC 0 - -/* Define to 1 if you have the declaration of - `LLVMCreateGDBRegistrationListener', and to 0 if you don't. */ -/* #undef HAVE_DECL_LLVMCREATEGDBREGISTRATIONLISTENER */ - -/* Define to 1 if you have the declaration of - `LLVMCreatePerfJITEventListener', and to 0 if you don't. */ -/* #undef HAVE_DECL_LLVMCREATEPERFJITEVENTLISTENER */ - -/* Define to 1 if you have the declaration of `LLVMGetHostCPUFeatures', and to - 0 if you don't. */ -/* #undef HAVE_DECL_LLVMGETHOSTCPUFEATURES */ - -/* Define to 1 if you have the declaration of `LLVMGetHostCPUName', and to 0 - if you don't. */ -/* #undef HAVE_DECL_LLVMGETHOSTCPUNAME */ - -/* Define to 1 if you have the declaration of `LLVMOrcGetSymbolAddressIn', and - to 0 if you don't. */ -/* #undef HAVE_DECL_LLVMORCGETSYMBOLADDRESSIN */ - -/* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you - don't. */ -#define HAVE_DECL_POSIX_FADVISE 1 - -/* Define to 1 if you have the declaration of `preadv', and to 0 if you don't. - */ -#define HAVE_DECL_PREADV 1 - -/* Define to 1 if you have the declaration of `pwritev', and to 0 if you - don't. */ -#define HAVE_DECL_PWRITEV 1 - -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you - don't. */ -#define HAVE_DECL_STRLCAT 0 - -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you - don't. */ -#define HAVE_DECL_STRLCPY 0 - -/* Define to 1 if you have the declaration of `strnlen', and to 0 if you - don't. */ -#define HAVE_DECL_STRNLEN 1 - -/* Define to 1 if you have the <editline/history.h> header file. */ -/* #undef HAVE_EDITLINE_HISTORY_H */ - -/* Define to 1 if you have the <editline/readline.h> header file. */ -/* #undef HAVE_EDITLINE_READLINE_H */ - -/* Define to 1 if you have the <execinfo.h> header file. */ -#define HAVE_EXECINFO_H 1 - -/* Define to 1 if you have the `explicit_bzero' function. */ -#define HAVE_EXPLICIT_BZERO 1 - -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ -#define HAVE_FSEEKO 1 - -/* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */ -#define HAVE_GCC__ATOMIC_INT32_CAS 1 - -/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, - int64). */ -#define HAVE_GCC__ATOMIC_INT64_CAS 1 - -/* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */ -#define HAVE_GCC__SYNC_CHAR_TAS 1 - -/* Define to 1 if you have __sync_val_compare_and_swap(int *, int, int). */ -#define HAVE_GCC__SYNC_INT32_CAS 1 - -/* Define to 1 if you have __sync_lock_test_and_set(int *) and friends. */ -#define HAVE_GCC__SYNC_INT32_TAS 1 - -/* Define to 1 if you have __sync_val_compare_and_swap(int64 *, int64, int64). - */ -#define HAVE_GCC__SYNC_INT64_CAS 1 - -/* Define to 1 if you have the `getifaddrs' function. */ -#define HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `getopt' function. */ -#define HAVE_GETOPT 1 - -/* Define to 1 if you have the <getopt.h> header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getopt_long' function. */ -#define HAVE_GETOPT_LONG 1 - -/* Define to 1 if you have the `getpeereid' function. */ -/* #undef HAVE_GETPEEREID */ - -/* Define to 1 if you have the `getpeerucred' function. */ -/* #undef HAVE_GETPEERUCRED */ - -/* Define to 1 if you have the <gssapi_ext.h> header file. */ -/* #undef HAVE_GSSAPI_EXT_H */ - -/* Define to 1 if you have the <gssapi/gssapi_ext.h> header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_EXT_H */ - -/* Define to 1 if you have the <gssapi/gssapi.h> header file. */ -/* #undef HAVE_GSSAPI_GSSAPI_H */ - -/* Define to 1 if you have the <gssapi.h> header file. */ -/* #undef HAVE_GSSAPI_H */ - -/* Define to 1 if you have the <history.h> header file. */ -/* #undef HAVE_HISTORY_H */ - -/* Define to 1 if you have the `history_truncate_file' function. */ -#define HAVE_HISTORY_TRUNCATE_FILE 1 - -/* Define to 1 if you have the `HMAC_CTX_free' function. */ -#define HAVE_HMAC_CTX_FREE 1 - -/* Define to 1 if you have the `HMAC_CTX_new' function. */ -#define HAVE_HMAC_CTX_NEW 1 - -/* Define to 1 if you have the <ifaddrs.h> header file. */ -#define HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the `inet_aton' function. */ -#define HAVE_INET_ATON 1 - -/* Define to 1 if you have the `inet_pton' function. */ -#define HAVE_INET_PTON 1 - -/* Define to 1 if the system has the type `int64'. */ -/* #undef HAVE_INT64 */ - -/* Define to 1 if the system has the type `int8'. */ -/* #undef HAVE_INT8 */ - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the global variable 'int opterr'. */ -#define HAVE_INT_OPTERR 1 - -/* Define to 1 if you have the global variable 'int optreset'. */ -/* #undef HAVE_INT_OPTRESET */ - -/* Define to 1 if you have the global variable 'int timezone'. */ -#define HAVE_INT_TIMEZONE 1 - -/* Define to 1 if __builtin_constant_p(x) implies "i"(x) acceptance. */ -/* #undef HAVE_I_CONSTRAINT__BUILTIN_CONSTANT_P */ - -/* Define to 1 if you have the `kqueue' function. */ -/* #undef HAVE_KQUEUE */ - -/* Define to 1 if you have the <langinfo.h> header file. */ -#define HAVE_LANGINFO_H 1 - -/* Define to 1 if you have the `ldap_initialize' function. */ -/* #undef HAVE_LDAP_INITIALIZE */ - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#define HAVE_LIBCRYPTO 1 - -/* Define to 1 if you have the `ldap' library (-lldap). */ -/* #undef HAVE_LIBLDAP */ - -/* Define to 1 if you have the `lz4' library (-llz4). */ -#define HAVE_LIBLZ4 1 - -/* Define to 1 if you have the `m' library (-lm). */ -#define HAVE_LIBM 1 - -/* Define to 1 if you have the `pam' library (-lpam). */ -/* #undef HAVE_LIBPAM */ - -/* Define if you have a function readline library */ -#define HAVE_LIBREADLINE 1 - -/* Define to 1 if you have the `selinux' library (-lselinux). */ -/* #undef HAVE_LIBSELINUX */ - -/* Define to 1 if you have the `ssl' library (-lssl). */ -#define HAVE_LIBSSL 1 - -/* Define to 1 if you have the `wldap32' library (-lwldap32). */ -/* #undef HAVE_LIBWLDAP32 */ - -/* Define to 1 if you have the `xml2' library (-lxml2). */ -#define HAVE_LIBXML2 1 - -/* Define to 1 if you have the `xslt' library (-lxslt). */ -/* #undef HAVE_LIBXSLT */ - -/* Define to 1 if you have the `z' library (-lz). */ -#define HAVE_LIBZ 1 - -/* Define to 1 if you have the `zstd' library (-lzstd). */ -/* #undef HAVE_LIBZSTD */ - -/* Define to 1 if the system has the type `locale_t'. */ -#define HAVE_LOCALE_T 1 - -/* Define to 1 if `long int' works and is 64 bits. */ -#define HAVE_LONG_INT_64 1 - -/* Define to 1 if `long long int' works and is 64 bits. */ -/* #undef HAVE_LONG_LONG_INT_64 */ - -/* Define to 1 if you have the <mbarrier.h> header file. */ -/* #undef HAVE_MBARRIER_H */ - -/* Define to 1 if you have the `mbstowcs_l' function. */ -/* #undef HAVE_MBSTOWCS_L */ - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset_s' function. */ -/* #undef HAVE_MEMSET_S */ - -/* Define to 1 if you have the `mkdtemp' function. */ -#define HAVE_MKDTEMP 1 - -/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ -#define HAVE_OPENSSL_INIT_SSL 1 - -/* Define to 1 if you have the <ossp/uuid.h> header file. */ -/* #undef HAVE_OSSP_UUID_H */ - -/* Define to 1 if you have the <pam/pam_appl.h> header file. */ -/* #undef HAVE_PAM_PAM_APPL_H */ - -/* Define to 1 if you have the `posix_fadvise' function. */ -#define HAVE_POSIX_FADVISE 1 - -/* Define to 1 if you have the `posix_fallocate' function. */ -#define HAVE_POSIX_FALLOCATE 1 - -/* Define to 1 if you have the `ppoll' function. */ -#define HAVE_PPOLL 1 - -/* Define if you have POSIX threads libraries and header files. */ -#define HAVE_PTHREAD 1 - -/* Define to 1 if you have the `pthread_barrier_wait' function. */ -#define HAVE_PTHREAD_BARRIER_WAIT 1 - -/* Define to 1 if you have the `pthread_is_threaded_np' function. */ -/* #undef HAVE_PTHREAD_IS_THREADED_NP */ - -/* Have PTHREAD_PRIO_INHERIT. */ -#define HAVE_PTHREAD_PRIO_INHERIT 1 - -/* Define to 1 if you have the <readline.h> header file. */ -/* #undef HAVE_READLINE_H */ - -/* Define to 1 if you have the <readline/history.h> header file. */ -#define HAVE_READLINE_HISTORY_H 1 - -/* Define to 1 if you have the <readline/readline.h> header file. */ -#define HAVE_READLINE_READLINE_H 1 - -/* Define to 1 if you have the `rl_completion_matches' function. */ -#define HAVE_RL_COMPLETION_MATCHES 1 - -/* Define to 1 if you have the global variable 'rl_completion_suppress_quote'. - */ -#define HAVE_RL_COMPLETION_SUPPRESS_QUOTE 1 - -/* Define to 1 if you have the `rl_filename_completion_function' function. */ -#define HAVE_RL_FILENAME_COMPLETION_FUNCTION 1 - -/* Define to 1 if you have the global variable 'rl_filename_quote_characters'. - */ -#define HAVE_RL_FILENAME_QUOTE_CHARACTERS 1 - -/* Define to 1 if you have the global variable 'rl_filename_quoting_function'. - */ -#define HAVE_RL_FILENAME_QUOTING_FUNCTION 1 - -/* Define to 1 if you have the `rl_reset_screen_size' function. */ -#define HAVE_RL_RESET_SCREEN_SIZE 1 - -/* Define to 1 if you have the `rl_variable_bind' function. */ -#define HAVE_RL_VARIABLE_BIND 1 - -/* Define to 1 if you have the <security/pam_appl.h> header file. */ -/* #undef HAVE_SECURITY_PAM_APPL_H */ - -/* Define to 1 if you have the `setproctitle' function. */ -/* #undef HAVE_SETPROCTITLE */ - -/* Define to 1 if you have the `setproctitle_fast' function. */ -/* #undef HAVE_SETPROCTITLE_FAST */ - -/* Define to 1 if the system has the type `socklen_t'. */ -#define HAVE_SOCKLEN_T 1 - -/* Define to 1 if you have spinlocks. */ -#define HAVE_SPINLOCKS 1 - -/* Define to 1 if you have the `SSL_CTX_set_cert_cb' function. */ -#define HAVE_SSL_CTX_SET_CERT_CB 1 - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strchrnul' function. */ -#define HAVE_STRCHRNUL 1 - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -/* #undef HAVE_STRLCAT */ - -/* Define to 1 if you have the `strlcpy' function. */ -/* #undef HAVE_STRLCPY */ - -/* Define to 1 if you have the `strnlen' function. */ -#define HAVE_STRNLEN 1 - -/* Define to 1 if you have the `strsignal' function. */ -#define HAVE_STRSIGNAL 1 - -/* Define to 1 if the system has the type `struct option'. */ -#define HAVE_STRUCT_OPTION 1 - -/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ -/* #undef HAVE_STRUCT_SOCKADDR_SA_LEN */ - -/* Define to 1 if `tm_zone' is a member of `struct tm'. */ -#define HAVE_STRUCT_TM_TM_ZONE 1 - -/* Define to 1 if you have the `syncfs' function. */ -#define HAVE_SYNCFS 1 - -/* Define to 1 if you have the `sync_file_range' function. */ -#define HAVE_SYNC_FILE_RANGE 1 - -/* Define to 1 if you have the syslog interface. */ -#define HAVE_SYSLOG 1 - -/* Define to 1 if you have the <sys/epoll.h> header file. */ -#define HAVE_SYS_EPOLL_H 1 - -/* Define to 1 if you have the <sys/event.h> header file. */ -/* #undef HAVE_SYS_EVENT_H */ - -/* Define to 1 if you have the <sys/personality.h> header file. */ -#define HAVE_SYS_PERSONALITY_H 1 - -/* Define to 1 if you have the <sys/prctl.h> header file. */ -#define HAVE_SYS_PRCTL_H 1 - -/* Define to 1 if you have the <sys/procctl.h> header file. */ -/* #undef HAVE_SYS_PROCCTL_H */ - -/* Define to 1 if you have the <sys/signalfd.h> header file. */ -#define HAVE_SYS_SIGNALFD_H 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <sys/ucred.h> header file. */ -/* #undef HAVE_SYS_UCRED_H */ - -/* Define to 1 if you have the <termios.h> header file. */ -#define HAVE_TERMIOS_H 1 - -/* Define to 1 if your compiler understands `typeof' or something similar. */ -#define HAVE_TYPEOF 1 - -/* Define to 1 if you have the <ucred.h> header file. */ -/* #undef HAVE_UCRED_H */ - -/* Define to 1 if the system has the type `uint64'. */ -/* #undef HAVE_UINT64 */ - -/* Define to 1 if the system has the type `uint8'. */ -/* #undef HAVE_UINT8 */ - -/* Define to 1 if the system has the type `union semun'. */ -/* #undef HAVE_UNION_SEMUN */ - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `uselocale' function. */ -#define HAVE_USELOCALE 1 - -/* Define to 1 if you have BSD UUID support. */ -/* #undef HAVE_UUID_BSD */ - -/* Define to 1 if you have E2FS UUID support. */ -/* #undef HAVE_UUID_E2FS */ - -/* Define to 1 if you have the <uuid.h> header file. */ -#define HAVE_UUID_H 1 - -/* Define to 1 if you have OSSP UUID support. */ -#define HAVE_UUID_OSSP 1 - -/* Define to 1 if you have the <uuid/uuid.h> header file. */ -/* #undef HAVE_UUID_UUID_H */ - -/* Define to 1 if your compiler knows the visibility("hidden") attribute. */ -#define HAVE_VISIBILITY_ATTRIBUTE 1 - -/* Define to 1 if you have the `wcstombs_l' function. */ -/* #undef HAVE_WCSTOMBS_L */ - -/* Define to 1 if you have the `X509_get_signature_info' function. */ -#define HAVE_X509_GET_SIGNATURE_INFO 1 - -/* Define to 1 if you have the `X509_get_signature_nid' function. */ -#define HAVE_X509_GET_SIGNATURE_NID 1 - -/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ -#define HAVE_X86_64_POPCNTQ 1 - -/* Define to 1 if the system has the type `_Bool'. */ -#define HAVE__BOOL 1 - -/* Define to 1 if your compiler understands __builtin_bswap16. */ -#define HAVE__BUILTIN_BSWAP16 1 - -/* Define to 1 if your compiler understands __builtin_bswap32. */ -#define HAVE__BUILTIN_BSWAP32 1 - -/* Define to 1 if your compiler understands __builtin_bswap64. */ -#define HAVE__BUILTIN_BSWAP64 1 - -/* Define to 1 if your compiler understands __builtin_clz. */ -#define HAVE__BUILTIN_CLZ 1 - -/* Define to 1 if your compiler understands __builtin_constant_p. */ -#define HAVE__BUILTIN_CONSTANT_P 1 - -/* Define to 1 if your compiler understands __builtin_ctz. */ -#define HAVE__BUILTIN_CTZ 1 - -/* Define to 1 if your compiler understands __builtin_frame_address. */ -#define HAVE__BUILTIN_FRAME_ADDRESS 1 - -/* Define to 1 if your compiler understands __builtin_$op_overflow. */ -#define HAVE__BUILTIN_OP_OVERFLOW 1 - -/* Define to 1 if your compiler understands __builtin_popcount. */ -#define HAVE__BUILTIN_POPCOUNT 1 - -/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ -#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1 - -/* Define to 1 if your compiler understands __builtin_unreachable. */ -#define HAVE__BUILTIN_UNREACHABLE 1 - -/* Define to 1 if you have the `_configthreadlocale' function. */ -/* #undef HAVE__CONFIGTHREADLOCALE */ - -/* Define to 1 if you have __cpuid. */ -/* #undef HAVE__CPUID */ - -/* Define to 1 if you have __get_cpuid. */ -#define HAVE__GET_CPUID 1 - -/* Define to 1 if your compiler understands _Static_assert. */ -#define HAVE__STATIC_ASSERT 1 - -/* Define to the appropriate printf length modifier for 64-bit ints. */ -#define INT64_MODIFIER "l" - -/* Define to 1 if `locale_t' requires <xlocale.h>. */ -/* #undef LOCALE_T_IN_XLOCALE */ - -/* Define as the maximum alignment requirement of any C data type. */ -#define MAXIMUM_ALIGNOF 8 - -/* Define bytes to use libc memset(). */ -#define MEMSET_LOOP_LIMIT 1024 - -/* Define to the OpenSSL API version in use. This avoids deprecation warnings - from newer OpenSSL versions. */ -/* #define OPENSSL_API_COMPAT 0x10001000L */ - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "pgsql-bugs@lists.postgresql.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "PostgreSQL" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PostgreSQL 16.2" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "postgresql" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "https://www.postgresql.org/" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "16.2" - -/* Define to the name of a signed 128-bit integer type. */ -#define PG_INT128_TYPE __int128 - -/* Define to the name of a signed 64-bit integer type. */ -#define PG_INT64_TYPE long int - -/* Define to the name of the default PostgreSQL service principal in Kerberos - (GSSAPI). (--with-krb-srvnam=NAME) */ -#define PG_KRB_SRVNAM "postgres" - -/* PostgreSQL major version as a string */ -#define PG_MAJORVERSION "16" - -/* PostgreSQL major version number */ -#define PG_MAJORVERSION_NUM 16 - -/* PostgreSQL minor version number */ -#define PG_MINORVERSION_NUM 2 - -/* Define to best printf format archetype, usually gnu_printf if available. */ -#define PG_PRINTF_ATTRIBUTE gnu_printf - -/* Define to 1 to use <stdbool.h> to define type bool. */ -#define PG_USE_STDBOOL 1 - -/* PostgreSQL version as a string */ -#define PG_VERSION "16.2" - -/* PostgreSQL version as a number */ -#define PG_VERSION_NUM 160002 - -/* A string containing the version number, platform, and C compiler */ -#define PG_VERSION_STR "PostgreSQL 16.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.3.0, 64-bit" - -/* Define to 1 to allow profiling output to be saved separately for each - process. */ -/* #undef PROFILE_PID_DIR */ - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* RELSEG_SIZE is the maximum number of blocks allowed in one disk file. Thus, - the maximum size of a single file is RELSEG_SIZE * BLCKSZ; relations bigger - than that are divided into multiple files. RELSEG_SIZE * BLCKSZ must be - less than your OS' limit on file size. This is often 2 GB or 4GB in a - 32-bit operating system, unless you have large file support enabled. By - default, we make the limit 1 GB to avoid any possible integer-overflow - problems within the OS. A limit smaller than necessary only means we divide - a large relation into more chunks than necessary, so it seems best to err - in the direction of a small limit. A power-of-2 value is recommended to - save a few cycles in md.c, but is not absolutely required. Changing - RELSEG_SIZE requires an initdb. */ -#define RELSEG_SIZE 131072 - -/* The size of `bool', as computed by sizeof. */ -#define SIZEOF_BOOL 1 - -/* The size of `long', as computed by sizeof. */ -#define SIZEOF_LONG 8 - -/* The size of `off_t', as computed by sizeof. */ -#define SIZEOF_OFF_T 8 - -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 8 - -/* The size of `void *', as computed by sizeof. */ -#define SIZEOF_VOID_P 8 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if strerror_r() returns int. */ -/* #undef STRERROR_R_INT */ - -/* Define to 1 to use ARMv8 CRC Extension. */ -/* #undef USE_ARMV8_CRC32C */ - -/* Define to 1 to use ARMv8 CRC Extension with a runtime check. */ -/* #undef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK */ - -/* Define to 1 to build with assertion checks. (--enable-cassert) */ -/* #undef USE_ASSERT_CHECKING */ - -/* Define to 1 to build with Bonjour support. (--with-bonjour) */ -/* #undef USE_BONJOUR */ - -/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */ -/* #undef USE_BSD_AUTH */ - -/* Define to build with ICU support. (--with-icu) */ -#define USE_ICU 1 - -/* Define to 1 to build with LDAP support. (--with-ldap) */ -/* #undef USE_LDAP */ - -/* Define to 1 to build with XML support. (--with-libxml) */ -#define USE_LIBXML 1 - -/* Define to 1 to use XSLT support when building contrib/xml2. - (--with-libxslt) */ -/* #undef USE_LIBXSLT */ - -/* Define to 1 to build with LLVM based JIT support. (--with-llvm) */ -/* #undef USE_LLVM */ - -/* Define to 1 to build with LZ4 support. (--with-lz4) */ -#define USE_LZ4 1 - -/* Define to select named POSIX semaphores. */ -/* #undef USE_NAMED_POSIX_SEMAPHORES */ - -/* Define to 1 to build with OpenSSL support. (--with-ssl=openssl) */ -#define USE_OPENSSL 1 - -/* Define to 1 to build with PAM support. (--with-pam) */ -/* #undef USE_PAM */ - -/* Define to 1 to use software CRC-32C implementation (slicing-by-8). */ -/* #undef USE_SLICING_BY_8_CRC32C */ - -/* Define to 1 use Intel SSE 4.2 CRC instructions. */ -/* #undef USE_SSE42_CRC32C */ - -/* Define to 1 to use Intel SSE 4.2 CRC instructions with a runtime check. */ -#define USE_SSE42_CRC32C_WITH_RUNTIME_CHECK 1 - -/* Define to build with systemd support. (--with-systemd) */ -#define USE_SYSTEMD 1 - -/* Define to select SysV-style semaphores. */ -/* #undef USE_SYSV_SEMAPHORES */ - -/* Define to select SysV-style shared memory. */ -#define USE_SYSV_SHARED_MEMORY 1 - -/* Define to select unnamed POSIX semaphores. */ -#define USE_UNNAMED_POSIX_SEMAPHORES 1 - -/* Define to select Win32-style semaphores. */ -/* #undef USE_WIN32_SEMAPHORES */ - -/* Define to select Win32-style shared memory. */ -/* #undef USE_WIN32_SHARED_MEMORY */ - -/* Define to 1 to build with ZSTD support. (--with-zstd) */ -/* #undef USE_ZSTD */ - -/* Define to 1 if `wcstombs_l' requires <xlocale.h>. */ -/* #undef WCSTOMBS_L_IN_XLOCALE */ - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Size of a WAL file block. This need have no particular relation to BLCKSZ. - XLOG_BLCKSZ must be a power of 2, and if your system supports O_DIRECT I/O, - XLOG_BLCKSZ must be a multiple of the alignment requirement for direct-I/O - buffers, else direct I/O may fail. Changing XLOG_BLCKSZ requires an initdb. - */ -#define XLOG_BLCKSZ 8192 - - - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to keyword to use for C99 restrict support, or to nothing if not - supported */ -#define pg_restrict __restrict - -/* Define to the equivalent of the C99 'restrict' keyword, or to - nothing if this is not supported. Do not define if restrict is - supported directly. */ -#define restrict __restrict -/* Work around a bug in Sun C++: it does not support _Restrict or - __restrict__, even though the corresponding Sun C compiler ends up with - "#define restrict _Restrict" or "#define restrict __restrict__" in the - previous line. Perhaps some future version of Sun C++ will work with - restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ -#if defined __SUNPRO_CC && !defined __RESTRICT -# define _Restrict -# define __restrict__ -#endif - -/* Define to how the compiler spells `typeof'. */ -/* #undef typeof */ diff --git a/contrib/libs/libpq/src/include/pg_config-osx-arm64.h b/contrib/libs/libpq/src/include/pg_config-osx-arm64.h deleted file mode 100644 index dde70a44c9..0000000000 --- a/contrib/libs/libpq/src/include/pg_config-osx-arm64.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include "pg_config-linux.h" - -/* Define to 1 if you have __get_cpuid. */ -#undef HAVE__GET_CPUID - -/* Define to 1 if you have the `append_history' function. */ -#undef HAVE_APPEND_HISTORY - -/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ -#undef HAVE_ASN1_STRING_GET0_DATA - -/* Define to 1 if you have the `copyfile' function. */ -#define HAVE_COPYFILE 1 - -/* Define to 1 if you have the <copyfile.h> header file. */ -#define HAVE_COPYFILE_H 1 - -/* Define to 1 if you have the <crypt.h> header file. */ -#undef HAVE_CRYPT_H - -/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you - don't. */ -#undef HAVE_DECL_FDATASYNC -#define HAVE_DECL_FDATASYNC 0 - -/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you - don't. */ -#undef HAVE_DECL_F_FULLFSYNC -#define HAVE_DECL_F_FULLFSYNC 1 - -/* Define to 1 if you have the declaration of `snprintf', and to 0 if you - don't. */ -#define HAVE_DECL_SNPRINTF 1 - -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you - don't. */ -#undef HAVE_DECL_STRLCAT -#define HAVE_DECL_STRLCAT 1 - -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you - don't. */ -#undef HAVE_DECL_STRLCPY -#define HAVE_DECL_STRLCPY 1 - -/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you - don't. */ -#define HAVE_DECL_SYS_SIGLIST 1 - -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you - don't. */ -#define HAVE_DECL_VSNPRINTF 1 - -/* Define to 1 if you have the <dld.h> header file. */ -#undef HAVE_DLD_H - -/* Define to 1 if you have the `fls' function. */ -#define HAVE_FLS 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -#undef HAVE_GETHOSTBYNAME_R - -/* Define to 1 if you have the `getpeereid' function. */ -#define HAVE_GETPEEREID 1 - -/* Define to 1 if you have the `mbstowcs_l' function. */ -#define HAVE_MBSTOWCS_L 1 - -/* Define to 1 if you have the `posix_fadvise' function. */ -#undef HAVE_POSIX_FADVISE - -/* Define to 1 if you have the `posix_fallocate' function. */ -#undef HAVE_POSIX_FALLOCATE - -/* Define to 1 if you have the `ppoll' function. */ -#undef HAVE_PPOLL - -/* Define to 1 if you have the `pread' function. */ -#undef HAVE_PREAD - -/* Define to 1 if you have the `pthread_is_threaded_np' function. */ -#define HAVE_PTHREAD_IS_THREADED_NP 1 - -/* Define to 1 if you have the `pwrite' function. */ -#undef HAVE_PWRITE - -/* Define to 1 if you have the `rl_reset_screen_size' function. */ -#undef HAVE_RL_RESET_SCREEN_SIZE - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `strchrnul' function. */ -#undef HAVE_STRCHRNUL - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `strlcat' function. */ -#define HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ -#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 - -/* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */ -#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 - -/* Define to 1 if you have the `sync_file_range' function. */ -#undef HAVE_SYNC_FILE_RANGE - -/* Define to 1 if you have the <sys/epoll.h> header file. */ -#undef HAVE_SYS_EPOLL_H - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -#define HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the <sys/ucred.h> header file. */ -#define HAVE_SYS_UCRED_H 1 - -/* Define to 1 if you have the `towlower' function. */ -#define HAVE_TOWLOWER 1 - -/* Define to 1 if you have the <uuid.h> header file. */ -/* #undef HAVE_UUID_H */ - -/* Define to 1 if you have OSSP UUID support. */ -/* #undef HAVE_UUID_OSSP */ - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the `wcstombs_l' function. */ -#define HAVE_WCSTOMBS_L 1 - -/* Define to 1 if `locale_t' requires <xlocale.h>. */ -#define LOCALE_T_IN_XLOCALE 1 - -/* Define to gnu_printf if compiler supports it, else printf. */ -#undef PG_PRINTF_ATTRIBUTE -#define PG_PRINTF_ATTRIBUTE printf - -/* Define to 1 if strerror_r() returns int. */ -#define STRERROR_R_INT 1 - -/* Define to build with systemd support. (--with-systemd) */ -/* #undef USE_SYSTEMD */ - -/* Define to select SysV-style semaphores. */ -#define USE_SYSV_SEMAPHORES 1 - -/* Define to select unnamed POSIX semaphores. */ -/* #undef USE_UNNAMED_POSIX_SEMAPHORES */ - -/* Define to 1 if `wcstombs_l' requires <xlocale.h>. */ -#define WCSTOMBS_L_IN_XLOCALE 1 diff --git a/contrib/libs/libpq/src/include/pg_config-osx.h b/contrib/libs/libpq/src/include/pg_config-osx.h deleted file mode 100644 index 4b1a8a294c..0000000000 --- a/contrib/libs/libpq/src/include/pg_config-osx.h +++ /dev/null @@ -1,156 +0,0 @@ -#pragma once - -#include "pg_config-linux.h" - -/* Define to 1 if you have the `append_history' function. */ -#undef HAVE_APPEND_HISTORY - -/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ -#undef HAVE_ASN1_STRING_GET0_DATA - -/* Define to 1 if you have the `copyfile' function. */ -#define HAVE_COPYFILE 1 - -/* Define to 1 if you have the <copyfile.h> header file. */ -#define HAVE_COPYFILE_H 1 - -/* Define to 1 if you have the <crypt.h> header file. */ -#undef HAVE_CRYPT_H - -/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you - don't. */ -#undef HAVE_DECL_FDATASYNC -#define HAVE_DECL_FDATASYNC 0 - -/* Define to 1 if you have the declaration of `F_FULLFSYNC', and to 0 if you - don't. */ -#undef HAVE_DECL_F_FULLFSYNC -#define HAVE_DECL_F_FULLFSYNC 1 - -/* Define to 1 if you have the declaration of `snprintf', and to 0 if you - don't. */ -#define HAVE_DECL_SNPRINTF 1 - -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you - don't. */ -#undef HAVE_DECL_STRLCAT -#define HAVE_DECL_STRLCAT 1 - -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you - don't. */ -#undef HAVE_DECL_STRLCPY -#define HAVE_DECL_STRLCPY 1 - -/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you - don't. */ -#define HAVE_DECL_SYS_SIGLIST 1 - -/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you - don't. */ -#define HAVE_DECL_VSNPRINTF 1 - -/* Define to 1 if you have the <dld.h> header file. */ -#undef HAVE_DLD_H - -/* Define to 1 if you have the `fls' function. */ -#define HAVE_FLS 1 - -/* Define to 1 if you have the `gethostbyname_r' function. */ -#undef HAVE_GETHOSTBYNAME_R - -/* Define to 1 if you have the `getpeereid' function. */ -#define HAVE_GETPEEREID 1 - -/* Define to 1 if you have the `mbstowcs_l' function. */ -#define HAVE_MBSTOWCS_L 1 - -/* Define to 1 if you have the `posix_fadvise' function. */ -#undef HAVE_POSIX_FADVISE - -/* Define to 1 if you have the `posix_fallocate' function. */ -#undef HAVE_POSIX_FALLOCATE - -/* Define to 1 if you have the `ppoll' function. */ -#undef HAVE_PPOLL - -/* Define to 1 if you have the `pread' function. */ -#undef HAVE_PREAD - -/* Define to 1 if you have the `pthread_is_threaded_np' function. */ -#define HAVE_PTHREAD_IS_THREADED_NP 1 - -/* Define to 1 if you have the `pwrite' function. */ -#undef HAVE_PWRITE - -/* Define to 1 if you have the `rl_reset_screen_size' function. */ -#undef HAVE_RL_RESET_SCREEN_SIZE - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the `strchrnul' function. */ -#undef HAVE_STRCHRNUL - -/* Define to 1 if you have the `strerror_r' function. */ -#define HAVE_STRERROR_R 1 - -/* Define to 1 if you have the `strlcat' function. */ -#define HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ -#define HAVE_STRUCT_SOCKADDR_SA_LEN 1 - -/* Define to 1 if `ss_len' is a member of `struct sockaddr_storage'. */ -#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 - -/* Define to 1 if you have the `sync_file_range' function. */ -#undef HAVE_SYNC_FILE_RANGE - -/* Define to 1 if you have the <sys/epoll.h> header file. */ -#undef HAVE_SYS_EPOLL_H - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -#define HAVE_SYS_SOCKIO_H 1 - -/* Define to 1 if you have the <sys/ucred.h> header file. */ -#define HAVE_SYS_UCRED_H 1 - -/* Define to 1 if you have the `towlower' function. */ -#define HAVE_TOWLOWER 1 - -/* Define to 1 if you have the <uuid.h> header file. */ -/* #undef HAVE_UUID_H */ - -/* Define to 1 if you have OSSP UUID support. */ -/* #undef HAVE_UUID_OSSP */ - -/* Define to 1 if you have the `vsnprintf' function. */ -#define HAVE_VSNPRINTF 1 - -/* Define to 1 if you have the `wcstombs_l' function. */ -#define HAVE_WCSTOMBS_L 1 - -/* Define to 1 if `locale_t' requires <xlocale.h>. */ -#define LOCALE_T_IN_XLOCALE 1 - -/* Define to gnu_printf if compiler supports it, else printf. */ -#undef PG_PRINTF_ATTRIBUTE -#define PG_PRINTF_ATTRIBUTE printf - -/* Define to 1 if strerror_r() returns int. */ -#define STRERROR_R_INT 1 - -/* Define to build with systemd support. (--with-systemd) */ -/* #undef USE_SYSTEMD */ - -/* Define to select SysV-style semaphores. */ -#define USE_SYSV_SEMAPHORES 1 - -/* Define to select unnamed POSIX semaphores. */ -/* #undef USE_UNNAMED_POSIX_SEMAPHORES */ - -/* Define to 1 if `wcstombs_l' requires <xlocale.h>. */ -#define WCSTOMBS_L_IN_XLOCALE 1 diff --git a/contrib/libs/libpq/src/include/pg_config-win.h b/contrib/libs/libpq/src/include/pg_config-win.h deleted file mode 100644 index 9574513dc0..0000000000 --- a/contrib/libs/libpq/src/include/pg_config-win.h +++ /dev/null @@ -1,318 +0,0 @@ -#pragma once - -#include "pg_config-linux.h" - -/* Define to the type of arg 1 of 'accept' */ -#define ACCEPT_TYPE_ARG1 unsigned int - -/* Define to the type of arg 3 of 'accept' */ -#define ACCEPT_TYPE_ARG3 int - -/* Define to the return type of 'accept' */ -#define ACCEPT_TYPE_RETURN unsigned int PASCAL - -/* Define to 1 if you have the `clock_gettime' function. */ -#undef HAVE_CLOCK_GETTIME - -/* Define to 1 if your compiler handles computed gotos. */ -#undef HAVE_COMPUTED_GOTO - -/* Define to 1 if you have the `crypt' function. */ -#undef HAVE_CRYPT - -/* Define to 1 if you have the <crypt.h> header file. */ -#undef HAVE_CRYPT_H - -/* Define to 1 if you have the declaration of `posix_fadvise', and to 0 if you - * don't. */ -#undef HAVE_DECL_POSIX_FADVISE - -/* Define to 1 if you have the declaration of `RTLD_GLOBAL', and to 0 if you - don't. */ -#undef HAVE_DECL_RTLD_GLOBAL - -/* Define to 1 if you have the declaration of `RTLD_NOW', and to 0 if you - don't. */ -#undef HAVE_DECL_RTLD_NOW - -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you - don't. */ -#define HAVE_DECL_STRLCAT 0 - -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you - don't. */ -#define HAVE_DECL_STRLCPY 0 - -/* Define to 1 if you have the `dlopen' function. */ -#undef HAVE_DLOPEN - -/* Define to 1 if you have the `fdatasync' function. */ -#undef HAVE_FDATASYNC - -/* Define to 1 if you have __atomic_compare_exchange_n(int *, int *, int). */ -#undef HAVE_GCC__ATOMIC_INT32_CAS - -/* Define to 1 if you have __atomic_compare_exchange_n(int64 *, int64 *, - int64). */ -#undef HAVE_GCC__ATOMIC_INT64_CAS - -/* Define to 1 if you have __sync_lock_test_and_set(char *) and friends. */ -#undef HAVE_GCC__SYNC_CHAR_TAS - -/* Define to 1 if you have the `getaddrinfo' function. */ -#undef HAVE_GETADDRINFO - -/* Define to 1 if you have the `gethostbyname_r' function. */ -#undef HAVE_GETHOSTBYNAME_R - -/* Define to 1 if you have the `getopt' function. */ -#undef HAVE_GETOPT - -/* Define to 1 if you have the <getopt.h> header file. */ -#undef HAVE_GETOPT_H - -/* Define to 1 if you have the `getopt_long' function. */ -#undef HAVE_GETOPT_LONG - -/* Define to 1 if you have the `getpwuid_r' function. */ -#undef HAVE_GETPWUID_R - -/* Define to 1 if you have the `getrlimit' function. */ -#undef HAVE_RLIMIT - -/* Define to 1 if you have the `getrusage' function. */ -#undef HAVE_GETRUSAGE - -/* Define to 1 if you have the `inet_aton' function. */ -#undef HAVE_INET_ATON - -/* Define to 1 if you have the <inttypes.h> header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the <langinfo.h> header file. */ -#undef HAVE_LANGINFO_H - -/* Define to 1 if you have the `crypto' library (-lcrypto). */ -#undef HAVE_LIBCRYPTO - -/* Define to 1 if `long int' works and is 64 bits. */ -#define HAVE_LONG_INT_64 1 - -/* Define to 1 if the system has the type `long long int'. */ -#define HAVE_LONG_LONG_INT 1 - -/* Define to 1 if you have the `mbstowcs_l' function. */ -#define HAVE_MBSTOWCS_L 1 - -/* Define to 1 if the system has the type `MINIDUMP_TYPE'. */ -#define HAVE_MINIDUMP_TYPE 1 - -/* Define to 1 if you have the `mkdtemp' function. */ -#undef HAVE_MKDTEMP - -/* Define to 1 if you have the <netinet/tcp.h> header file. */ -#undef HAVE_NETINET_TCP_H - -/* Define to 1 if you have the `poll' function. */ -#undef HAVE_POLL - -/* Define to 1 if you have the <poll.h> header file. */ -#undef HAVE_POLL_H - -/* Define to 1 if you have the `posix_fadvise' function. */ -#undef HAVE_POSIX_FADVISE - -/* Define to 1 if you have the `posix_fallocate' function. */ -#undef HAVE_POSIX_FALLOCATE - -/* Define to 1 if you have the `ppoll' function. */ -#undef HAVE_PPOLL - -/* Define to 1 if you have the `pread' function. */ -#undef HAVE_PREAD - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Have PTHREAD_PRIO_INHERIT. */ -#define HAVE_PTHREAD_PRIO_INHERIT 1 - -/* Define to 1 if you have the `pwrite' function. */ -#undef HAVE_PWRITE - -/* Define to 1 if you have the `readlink' function. */ -#undef HAVE_READLINK - -/* Define to 1 if you have the global variable - 'rl_completion_append_character'. */ -#undef HAVE_RL_COMPLETION_APPEND_CHARACTER - -/* Define to 1 if you have the `rl_completion_matches' function. */ -#undef HAVE_RL_COMPLETION_MATCHES - -/* Define to 1 if you have the `rl_filename_completion_function' function. */ -#undef HAVE_RL_FILENAME_COMPLETION_FUNCTION - -/* Define to 1 if you have the `setsid' function. */ -#undef HAVE_SETSID - -/* Define to 1 if you have the `strchrnul' function. */ -#undef HAVE_STRCHRNUL - -/* Define to 1 if you have the `strerror_r' function. */ -#undef HAVE_STRERROR_R - -/* Define to 1 if you have the <strings.h> header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the `strsignal' function. */ -#undef HAVE_STRSIGNAL - -/* Define to 1 if the system has the type `struct option'. */ -#undef HAVE_STRUCT_OPTION - -/* Define to 1 if `tm_zone' is member of `struct tm'. */ -#undef HAVE_STRUCT_TM_TM_ZONE - -/* Define to 1 if you have the `sync_file_range' function. */ -#undef HAVE_SYNC_FILE_RANGE - -/* Define to 1 if you have the syslog interface. */ -#undef HAVE_SYSLOG - -/* Define to 1 if you have the <sys/ipc.h> header file. */ -#undef HAVE_SYS_IPC_H - -/* Define to 1 if you have the <sys/personality.h> header file. */ -#undef HAVE_SYS_PERSONALITY_H - -/* Define to 1 if you have the <sys/prctl.h> header file. */ -#undef HAVE_SYS_PRCTL_H - -/* Define to 1 if you have the <sys/select.h> header file. */ -#undef HAVE_SYS_SELECT_H - -/* Define to 1 if you have the <sys/sem.h> header file. */ -#undef HAVE_SYS_SEM_H - -/* Define to 1 if you have the <sys/shm.h> header file. */ -#undef HAVE_SYS_SHM_H - -/* Define to 1 if you have the <sys/un.h> header file. */ -#undef HAVE_SYS_UN_H - -/* Define to 1 if you have the <termios.h> header file. */ -#undef HAVE_TERMIOS_H - -/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use - `HAVE_STRUCT_TM_TM_ZONE' instead. */ -#undef HAVE_TM_ZONE - -/* Define to 1 if your compiler understands `typeof' or something similar. */ -#undef HAVE_TYPEOF - -/* Define to 1 if you have the external array `tzname'. */ -#undef HAVE_TZNAME - -/* Define to 1 if you have unix sockets. */ -#undef HAVE_UNIX_SOCKETS - -/* Define to 1 if you have the `unsetenv' function. */ -#undef HAVE_UNSETENV - -/* Define to 1 if you have the `uselocale' function. */ -#undef HAVE_USELOCALE - -/* Define to 1 if you have the `utimes' function. */ -#undef HAVE_UTIMES - -/* Define to 1 if you have the `wcstombs_l' function. */ -#define HAVE_WCSTOMBS_L 1 - -/* Define to 1 if the assembler supports X86_64's POPCNTQ instruction. */ -#undef HAVE_X86_64_POPCNTQ - -/* Define to 1 if the system has the type `_Bool'. */ -#undef HAVE__BOOL - -/* Define to 1 if your compiler understands __builtin_bswap16. */ -#undef HAVE__BUILTIN_BSWAP16 - -/* Define to 1 if your compiler understands __builtin_bswap32. */ -#undef HAVE__BUILTIN_BSWAP32 - -/* Define to 1 if your compiler understands __builtin_bswap64. */ -#undef HAVE__BUILTIN_BSWAP64 - -/* Define to 1 if your compiler understands __builtin_clz. */ -#undef HAVE__BUILTIN_CLZ - -/* Define to 1 if your compiler understands __builtin_constant_p. */ -#undef HAVE__BUILTIN_CONSTANT_P - -/* Define to 1 if your compiler understands __builtin_ctz. */ -#undef HAVE__BUILTIN_CTZ - -/* Define to 1 if your compiler understands __builtin_$op_overflow. */ -#undef HAVE__BUILTIN_OP_OVERFLOW - -/* Define to 1 if your compiler understands __builtin_popcount. */ -#undef HAVE__BUILTIN_POPCOUNT - -/* Define to 1 if your compiler understands __builtin_types_compatible_p. */ -#undef HAVE__BUILTIN_TYPES_COMPATIBLE_P - -/* Define to 1 if your compiler understands __builtin_unreachable. */ -#undef HAVE__BUILTIN_UNREACHABLE - -/* Define to 1 if you have the `_configthreadlocale' function. */ -#define HAVE__CONFIGTHREADLOCALE 1 - -/* Define to 1 if you have __cpuid. */ -#define HAVE__CPUID 1 - -/* Define to 1 if you have __get_cpuid. */ -#undef HAVE__GET_CPUID - -/* Define to the appropriate printf length modifier for 64-bit ints. */ -#define INT64_MODIFIER "ll" - -/* Define to 1 if `locale_t' requires <xlocale.h>. */ -/* #undef LOCALE_T_IN_XLOCALE */ - -/* Define to the name of a signed 128-bit integer type. */ -#undef PG_INT128_TYPE - -/* Define to the name of a signed 64-bit integer type. */ -#define PG_INT64_TYPE long long int - -/* The size of `size_t', as computed by sizeof. */ -#ifdef _WIN64 -#define SIZEOF_SIZE_T 8 -#else -#define SIZEOF_SIZE_T 4 -#endif - -/* The size of `void *', as computed by sizeof. */ -#ifndef _WIN64 -#define SIZEOF_VOID_P 8 -#else -#define SIZEOF_VOID_P 4 -#endif - -/* Define to select named POSIX semaphores. */ -#undef USE_NAMED_POSIX_SEMAPHORES - -/* Define to build with systemd support. (--with-systemd) */ -#undef USE_SYSTEMD - -/* Define to select unnamed POSIX semaphores. */ -#undef USE_UNNAMED_POSIX_SEMAPHORES - -/* Define to use native Windows API for random number generation */ -#define USE_WIN32_RANDOM 1 - -/* Define to select Win32-style semaphores. */ -#define USE_WIN32_SEMAPHORES 1 - -#define pg_restrict __restrict diff --git a/contrib/libs/libpq/src/include/pg_config.h b/contrib/libs/libpq/src/include/pg_config.h deleted file mode 100644 index b63bb45246..0000000000 --- a/contrib/libs/libpq/src/include/pg_config.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#if defined(__APPLE__) && (defined(__aarch64__) || defined(_M_ARM64)) -# include "pg_config-osx-arm64.h" -#elif defined(__APPLE__) -# include "pg_config-osx.h" -#elif defined(_MSC_VER) -# include "pg_config-win.h" -#elif defined(__linux__) && (defined(__aarch64__) || defined(_M_ARM64)) -# include "pg_config-linux-aarch64.h" -#else -# include "pg_config-linux.h" -#endif diff --git a/contrib/libs/libpq/src/include/pg_config_ext.h b/contrib/libs/libpq/src/include/pg_config_ext.h deleted file mode 100644 index b4c07dd857..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_ext.h +++ /dev/null @@ -1,8 +0,0 @@ -/* src/include/pg_config_ext.h. Generated from pg_config_ext.h.in by configure. */ -/* - * src/include/pg_config_ext.h.in. This is generated manually, not by - * autoheader, since we want to limit which symbols get defined here. - */ - -/* Define to the name of a signed 64-bit integer type. */ -#define PG_INT64_TYPE long int diff --git a/contrib/libs/libpq/src/include/pg_config_manual.h b/contrib/libs/libpq/src/include/pg_config_manual.h deleted file mode 100644 index a1a93ad706..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_manual.h +++ /dev/null @@ -1,372 +0,0 @@ -/*------------------------------------------------------------------------ - * PostgreSQL manual configuration settings - * - * This file contains various configuration symbols and limits. In - * all cases, changing them is only useful in very rare situations or - * for developers. If you edit any of these, be sure to do a *full* - * rebuild (and an initdb if noted). - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/pg_config_manual.h - *------------------------------------------------------------------------ - */ - -/* - * This is the default value for wal_segment_size to be used when initdb is run - * without the --wal-segsize option. It must be a valid segment size. - */ -#define DEFAULT_XLOG_SEG_SIZE (16*1024*1024) - -/* - * Maximum length for identifiers (e.g. table names, column names, - * function names). Names actually are limited to one fewer byte than this, - * because the length must include a trailing zero byte. - * - * Changing this requires an initdb. - */ -#define NAMEDATALEN 64 - -/* - * Maximum number of arguments to a function. - * - * The minimum value is 8 (GIN indexes use 8-argument support functions). - * The maximum possible value is around 600 (limited by index tuple size in - * pg_proc's index; BLCKSZ larger than 8K would allow more). Values larger - * than needed will waste memory and processing time, but do not directly - * cost disk space. - * - * Changing this does not require an initdb, but it does require a full - * backend recompile (including any user-defined C functions). - */ -#define FUNC_MAX_ARGS 100 - -/* - * When creating a product derived from PostgreSQL with changes that cause - * incompatibilities for loadable modules, it is recommended to change this - * string so that dfmgr.c can refuse to load incompatible modules with a clean - * error message. Typical examples that cause incompatibilities are any - * changes to node tags or node structures. (Note that dfmgr.c already - * detects common sources of incompatibilities due to major version - * differences and due to some changed compile-time constants. This setting - * is for catching anything that cannot be detected in a straightforward way.) - * - * There is no prescribed format for the string. The suggestion is to include - * product or company name, and optionally any internally-relevant ABI - * version. Example: "ACME Postgres/1.2". Note that the string will appear - * in a user-facing error message if an ABI mismatch is detected. - */ -#define FMGR_ABI_EXTRA "PostgreSQL" - -/* - * Maximum number of columns in an index. There is little point in making - * this anything but a multiple of 32, because the main cost is associated - * with index tuple header size (see access/itup.h). - * - * Changing this requires an initdb. - */ -#define INDEX_MAX_KEYS 32 - -/* - * Maximum number of columns in a partition key - */ -#define PARTITION_MAX_KEYS 32 - -/* - * Decide whether built-in 8-byte types, including float8, int8, and - * timestamp, are passed by value. This is on by default if sizeof(Datum) >= - * 8 (that is, on 64-bit platforms). If sizeof(Datum) < 8 (32-bit platforms), - * this must be off. We keep this here as an option so that it is easy to - * test the pass-by-reference code paths on 64-bit platforms. - * - * Changing this requires an initdb. - */ -#if SIZEOF_VOID_P >= 8 -#define USE_FLOAT8_BYVAL 1 -#endif - -/* - * When we don't have native spinlocks, we use semaphores to simulate them. - * Decreasing this value reduces consumption of OS resources; increasing it - * may improve performance, but supplying a real spinlock implementation is - * probably far better. - */ -#define NUM_SPINLOCK_SEMAPHORES 128 - -/* - * When we have neither spinlocks nor atomic operations support we're - * implementing atomic operations on top of spinlock on top of semaphores. To - * be safe against atomic operations while holding a spinlock separate - * semaphores have to be used. - */ -#define NUM_ATOMICS_SEMAPHORES 64 - -/* - * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence, - * maximum usable pathname length is one less). - * - * We'd use a standard system header symbol for this, if there weren't - * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all - * defined by different "standards", and often have different values - * on the same platform! So we just punt and use a reasonably - * generous setting here. - */ -#define MAXPGPATH 1024 - -/* - * You can try changing this if you have a machine with bytes of - * another size, but no guarantee... - */ -#define BITS_PER_BYTE 8 - -/* - * Preferred alignment for disk I/O buffers. On some CPUs, copies between - * user space and kernel space are significantly faster if the user buffer - * is aligned on a larger-than-MAXALIGN boundary. Ideally this should be - * a platform-dependent value, but for now we just hard-wire it. - */ -#define ALIGNOF_BUFFER 32 - -/* - * If EXEC_BACKEND is defined, the postmaster uses an alternative method for - * starting subprocesses: Instead of simply using fork(), as is standard on - * Unix platforms, it uses fork()+exec() or something equivalent on Windows, - * as well as lots of extra code to bring the required global state to those - * new processes. This must be enabled on Windows (because there is no - * fork()). On other platforms, it's only useful for verifying those - * otherwise Windows-specific code paths. - */ -#if defined(WIN32) && !defined(__CYGWIN__) -#define EXEC_BACKEND -#endif - -/* - * USE_POSIX_FADVISE controls whether Postgres will attempt to use the - * posix_fadvise() kernel call. Usually the automatic configure tests are - * sufficient, but some older Linux distributions had broken versions of - * posix_fadvise(). If necessary you can remove the #define here. - */ -#if HAVE_DECL_POSIX_FADVISE && defined(HAVE_POSIX_FADVISE) -#define USE_POSIX_FADVISE -#endif - -/* - * USE_PREFETCH code should be compiled only if we have a way to implement - * prefetching. (This is decoupled from USE_POSIX_FADVISE because there - * might in future be support for alternative low-level prefetch APIs. - * If you change this, you probably need to adjust the error message in - * check_effective_io_concurrency.) - */ -#ifdef USE_POSIX_FADVISE -#define USE_PREFETCH -#endif - -/* - * Default and maximum values for backend_flush_after, bgwriter_flush_after - * and checkpoint_flush_after; measured in blocks. Currently, these are - * enabled by default if sync_file_range() exists, ie, only on Linux. Perhaps - * we could also enable by default if we have mmap and msync(MS_ASYNC)? - */ -#ifdef HAVE_SYNC_FILE_RANGE -#define DEFAULT_BACKEND_FLUSH_AFTER 0 /* never enabled by default */ -#define DEFAULT_BGWRITER_FLUSH_AFTER 64 -#define DEFAULT_CHECKPOINT_FLUSH_AFTER 32 -#else -#define DEFAULT_BACKEND_FLUSH_AFTER 0 -#define DEFAULT_BGWRITER_FLUSH_AFTER 0 -#define DEFAULT_CHECKPOINT_FLUSH_AFTER 0 -#endif -/* upper limit for all three variables */ -#define WRITEBACK_MAX_PENDING_FLUSHES 256 - -/* - * USE_SSL code should be compiled only when compiling with an SSL - * implementation. - */ -#ifdef USE_OPENSSL -#define USE_SSL -#endif - -/* - * This is the default directory in which AF_UNIX socket files are - * placed. Caution: changing this risks breaking your existing client - * applications, which are likely to continue to look in the old - * directory. But if you just hate the idea of sockets in /tmp, - * here's where to twiddle it. You can also override this at runtime - * with the postmaster's -k switch. - * - * If set to an empty string, then AF_UNIX sockets are not used by default: A - * server will not create an AF_UNIX socket unless the run-time configuration - * is changed, a client will connect via TCP/IP by default and will only use - * an AF_UNIX socket if one is explicitly specified. - * - * This is done by default on Windows because there is no good standard - * location for AF_UNIX sockets and many installations on Windows don't - * support them yet. - */ -#ifndef WIN32 -#define DEFAULT_PGSOCKET_DIR "/tmp" -#else -#define DEFAULT_PGSOCKET_DIR "" -#endif - -/* - * This is the default event source for Windows event log. - */ -#define DEFAULT_EVENT_SOURCE "PostgreSQL" - -/* - * Assumed cache line size. This doesn't affect correctness, but can be used - * for low-level optimizations. Currently, this is used to pad some data - * structures in xlog.c, to ensure that highly-contended fields are on - * different cache lines. Too small a value can hurt performance due to false - * sharing, while the only downside of too large a value is a few bytes of - * wasted memory. The default is 128, which should be large enough for all - * supported platforms. - */ -#define PG_CACHE_LINE_SIZE 128 - -/* - * Assumed alignment requirement for direct I/O. 4K corresponds to common - * sector and memory page size. - */ -#define PG_IO_ALIGN_SIZE 4096 - -/* - *------------------------------------------------------------------------ - * The following symbols are for enabling debugging code, not for - * controlling user-visible features or resource limits. - *------------------------------------------------------------------------ - */ - -/* - * Include Valgrind "client requests", mostly in the memory allocator, so - * Valgrind understands PostgreSQL memory contexts. This permits detecting - * memory errors that Valgrind would not detect on a vanilla build. It also - * enables detection of buffer accesses that take place without holding a - * buffer pin (or without holding a buffer lock in the case of index access - * methods that superimpose their own custom client requests on top of the - * generic bufmgr.c requests). - * - * "make installcheck" is significantly slower under Valgrind. The client - * requests fall in hot code paths, so USE_VALGRIND slows execution by a few - * percentage points even when not run under Valgrind. - * - * Do not try to test the server under Valgrind without having built the - * server with USE_VALGRIND; else you will get false positives from sinval - * messaging (see comments in AddCatcacheInvalidationMessage). It's also - * important to use the suppression file src/tools/valgrind.supp to - * exclude other known false positives. - * - * You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND; - * instrumentation of repalloc() is inferior without it. - */ -/* #define USE_VALGRIND */ - -/* - * Define this to cause pfree()'d memory to be cleared immediately, to - * facilitate catching bugs that refer to already-freed values. - * Right now, this gets defined automatically if --enable-cassert. - */ -#ifdef USE_ASSERT_CHECKING -#define CLOBBER_FREED_MEMORY -#endif - -/* - * Define this to check memory allocation errors (scribbling on more - * bytes than were allocated). Right now, this gets defined - * automatically if --enable-cassert or USE_VALGRIND. - */ -#if defined(USE_ASSERT_CHECKING) || defined(USE_VALGRIND) -#define MEMORY_CONTEXT_CHECKING -#endif - -/* - * Define this to cause palloc()'d memory to be filled with random data, to - * facilitate catching code that depends on the contents of uninitialized - * memory. Caution: this is horrendously expensive. - */ -/* #define RANDOMIZE_ALLOCATED_MEMORY */ - -/* - * For cache-invalidation debugging, define DISCARD_CACHES_ENABLED to enable - * use of the debug_discard_caches GUC to aggressively flush syscache/relcache - * entries whenever it's possible to deliver invalidations. See - * AcceptInvalidationMessages() in src/backend/utils/cache/inval.c for - * details. - * - * USE_ASSERT_CHECKING builds default to enabling this. It's possible to use - * DISCARD_CACHES_ENABLED without a cassert build and the implied - * CLOBBER_FREED_MEMORY and MEMORY_CONTEXT_CHECKING options, but it's unlikely - * to be as effective at identifying problems. - */ -/* #define DISCARD_CACHES_ENABLED */ - -#if defined(USE_ASSERT_CHECKING) && !defined(DISCARD_CACHES_ENABLED) -#define DISCARD_CACHES_ENABLED -#endif - -/* - * Backwards compatibility for the older compile-time-only clobber-cache - * macros. - */ -#if !defined(DISCARD_CACHES_ENABLED) && (defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY)) -#define DISCARD_CACHES_ENABLED -#endif - -/* - * Recover memory used for relcache entries when invalidated. See - * RelationBuildDesc() in src/backend/utils/cache/relcache.c. - * - * This is active automatically for clobber-cache builds when clobbering is - * active, but can be overridden here by explicitly defining - * RECOVER_RELATION_BUILD_MEMORY. Define to 1 to always free relation cache - * memory even when clobber is off, or to 0 to never free relation cache - * memory even when clobbering is on. - */ - /* #define RECOVER_RELATION_BUILD_MEMORY 0 */ /* Force disable */ - /* #define RECOVER_RELATION_BUILD_MEMORY 1 */ /* Force enable */ - -/* - * Define this to force all parse and plan trees to be passed through - * copyObject(), to facilitate catching errors and omissions in - * copyObject(). - */ -/* #define COPY_PARSE_PLAN_TREES */ - -/* - * Define this to force all parse and plan trees to be passed through - * outfuncs.c/readfuncs.c, to facilitate catching errors and omissions in - * those modules. - */ -/* #define WRITE_READ_PARSE_PLAN_TREES */ - -/* - * Define this to force all raw parse trees for DML statements to be scanned - * by raw_expression_tree_walker(), to facilitate catching errors and - * omissions in that function. - */ -/* #define RAW_EXPRESSION_COVERAGE_TEST */ - -/* - * Enable debugging print statements for lock-related operations. - */ -/* #define LOCK_DEBUG */ - -/* - * Enable debugging print statements for WAL-related operations; see - * also the wal_debug GUC var. - */ -/* #define WAL_DEBUG */ - -/* - * Enable tracing of resource consumption during sort operations; - * see also the trace_sort GUC var. For 8.1 this is enabled by default. - */ -#define TRACE_SORT 1 - -/* - * Enable tracing of syncscan operations (see also the trace_syncscan GUC var). - */ -/* #define TRACE_SYNCSCAN */ diff --git a/contrib/libs/libpq/src/include/pg_config_os-linux.h b/contrib/libs/libpq/src/include/pg_config_os-linux.h deleted file mode 100644 index 331e1b2cf1..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_os-linux.h +++ /dev/null @@ -1 +0,0 @@ -#include <contrib/libs/libpq/src/include/port/linux.h> diff --git a/contrib/libs/libpq/src/include/pg_config_os-osx.h b/contrib/libs/libpq/src/include/pg_config_os-osx.h deleted file mode 100644 index f77fb9d4da..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_os-osx.h +++ /dev/null @@ -1 +0,0 @@ -#include <contrib/libs/libpq/src/include/port/darwin.h> diff --git a/contrib/libs/libpq/src/include/pg_config_os-win.h b/contrib/libs/libpq/src/include/pg_config_os-win.h deleted file mode 100644 index e26ba92209..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_os-win.h +++ /dev/null @@ -1 +0,0 @@ -#include <contrib/libs/libpq/src/include/port/win32.h> diff --git a/contrib/libs/libpq/src/include/pg_config_os.h b/contrib/libs/libpq/src/include/pg_config_os.h deleted file mode 100644 index 86db251be2..0000000000 --- a/contrib/libs/libpq/src/include/pg_config_os.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#if defined(__APPLE__) -# include "pg_config_os-osx.h" -#elif defined(_MSC_VER) -# include "pg_config_os-win.h" -#else -# include "pg_config_os-linux.h" -#endif diff --git a/contrib/libs/libpq/src/include/pgtar.h b/contrib/libs/libpq/src/include/pgtar.h deleted file mode 100644 index 661f9d7c59..0000000000 --- a/contrib/libs/libpq/src/include/pgtar.h +++ /dev/null @@ -1,45 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgtar.h - * Functions for manipulating tarfile datastructures (src/port/tar.c) - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/pgtar.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_TAR_H -#define PG_TAR_H - -#define TAR_BLOCK_SIZE 512 - -enum tarError -{ - TAR_OK = 0, - TAR_NAME_TOO_LONG, - TAR_SYMLINK_TOO_LONG -}; - -extern enum tarError tarCreateHeader(char *h, const char *filename, - const char *linktarget, pgoff_t size, - mode_t mode, uid_t uid, gid_t gid, - time_t mtime); -extern uint64 read_tar_number(const char *s, int len); -extern void print_tar_number(char *s, int len, uint64 val); -extern int tarChecksum(char *header); - -/* - * Compute the number of padding bytes required for an entry in a tar - * archive. We must pad out to a multiple of TAR_BLOCK_SIZE. Since that's - * a power of 2, we can use TYPEALIGN(). - */ -static inline size_t -tarPaddingBytesRequired(size_t len) -{ - return TYPEALIGN(TAR_BLOCK_SIZE, len) - len; -} - -#endif diff --git a/contrib/libs/libpq/src/include/pgtime.h b/contrib/libs/libpq/src/include/pgtime.h deleted file mode 100644 index 9d4b2efe94..0000000000 --- a/contrib/libs/libpq/src/include/pgtime.h +++ /dev/null @@ -1,94 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgtime.h - * PostgreSQL internal timezone library - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/pgtime.h - * - *------------------------------------------------------------------------- - */ -#ifndef _PGTIME_H -#define _PGTIME_H - - -/* - * The API of this library is generally similar to the corresponding - * C library functions, except that we use pg_time_t which (we hope) is - * 64 bits wide, and which is most definitely signed not unsigned. - */ - -typedef int64 pg_time_t; - -/* - * Data structure representing a broken-down timestamp. - * - * CAUTION: the IANA timezone library (src/timezone/) follows the POSIX - * convention that tm_mon counts from 0 and tm_year is relative to 1900. - * However, Postgres' datetime functions generally treat tm_mon as counting - * from 1 and tm_year as relative to 1 BC. Be sure to make the appropriate - * adjustments when moving from one code domain to the other. - */ -struct pg_tm -{ - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; /* see above */ - int tm_year; /* see above */ - int tm_wday; - int tm_yday; - int tm_isdst; - long int tm_gmtoff; - const char *tm_zone; -}; - -/* These structs are opaque outside the timezone library */ -typedef struct pg_tz pg_tz; -typedef struct pg_tzenum pg_tzenum; - -/* Maximum length of a timezone name (not including trailing null) */ -#define TZ_STRLEN_MAX 255 - -/* these functions are in localtime.c */ - -extern struct pg_tm *pg_localtime(const pg_time_t *timep, const pg_tz *tz); -extern struct pg_tm *pg_gmtime(const pg_time_t *timep); -extern int pg_next_dst_boundary(const pg_time_t *timep, - long int *before_gmtoff, - int *before_isdst, - pg_time_t *boundary, - long int *after_gmtoff, - int *after_isdst, - const pg_tz *tz); -extern bool pg_interpret_timezone_abbrev(const char *abbrev, - const pg_time_t *timep, - long int *gmtoff, - int *isdst, - const pg_tz *tz); -extern bool pg_get_timezone_offset(const pg_tz *tz, long int *gmtoff); -extern const char *pg_get_timezone_name(pg_tz *tz); -extern bool pg_tz_acceptable(pg_tz *tz); - -/* these functions are in strftime.c */ - -extern size_t pg_strftime(char *s, size_t maxsize, const char *format, - const struct pg_tm *t); - -/* these functions and variables are in pgtz.c */ - -extern PGDLLIMPORT pg_tz *session_timezone; -extern PGDLLIMPORT pg_tz *log_timezone; - -extern void pg_timezone_initialize(void); -extern pg_tz *pg_tzset(const char *tzname); -extern pg_tz *pg_tzset_offset(long gmtoffset); - -extern pg_tzenum *pg_tzenumerate_start(void); -extern pg_tz *pg_tzenumerate_next(pg_tzenum *dir); -extern void pg_tzenumerate_end(pg_tzenum *dir); - -#endif /* _PGTIME_H */ diff --git a/contrib/libs/libpq/src/include/port.h b/contrib/libs/libpq/src/include/port.h deleted file mode 100644 index a88d403483..0000000000 --- a/contrib/libs/libpq/src/include/port.h +++ /dev/null @@ -1,520 +0,0 @@ -/*------------------------------------------------------------------------- - * - * port.h - * Header for src/port/ compatibility functions. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_PORT_H -#define PG_PORT_H - -#include <ctype.h> - -/* - * Windows has enough specialized port stuff that we push most of it off - * into another file. - * Note: Some CYGWIN includes might #define WIN32. - */ -#if defined(WIN32) && !defined(__CYGWIN__) -#include "port/win32_port.h" -#endif - -/* socket has a different definition on WIN32 */ -#ifndef WIN32 -typedef int pgsocket; - -#define PGINVALID_SOCKET (-1) -#else -typedef SOCKET pgsocket; - -#define PGINVALID_SOCKET INVALID_SOCKET -#endif - -/* if platform lacks socklen_t, we assume this will work */ -#ifndef HAVE_SOCKLEN_T -typedef unsigned int socklen_t; -#endif - -/* non-blocking */ -extern bool pg_set_noblock(pgsocket sock); -extern bool pg_set_block(pgsocket sock); - -/* Portable path handling for Unix/Win32 (in path.c) */ - -extern bool has_drive_prefix(const char *path); -extern char *first_dir_separator(const char *filename); -extern char *last_dir_separator(const char *filename); -extern char *first_path_var_separator(const char *pathlist); -extern void join_path_components(char *ret_path, - const char *head, const char *tail); -extern void canonicalize_path(char *path); -extern void make_native_path(char *filename); -extern void cleanup_path(char *path); -extern bool path_contains_parent_reference(const char *path); -extern bool path_is_relative_and_below_cwd(const char *path); -extern bool path_is_prefix_of_path(const char *path1, const char *path2); -extern char *make_absolute_path(const char *path); -extern const char *get_progname(const char *argv0); -extern void get_share_path(const char *my_exec_path, char *ret_path); -extern void get_etc_path(const char *my_exec_path, char *ret_path); -extern void get_include_path(const char *my_exec_path, char *ret_path); -extern void get_pkginclude_path(const char *my_exec_path, char *ret_path); -extern void get_includeserver_path(const char *my_exec_path, char *ret_path); -extern void get_lib_path(const char *my_exec_path, char *ret_path); -extern void get_pkglib_path(const char *my_exec_path, char *ret_path); -extern void get_locale_path(const char *my_exec_path, char *ret_path); -extern void get_doc_path(const char *my_exec_path, char *ret_path); -extern void get_html_path(const char *my_exec_path, char *ret_path); -extern void get_man_path(const char *my_exec_path, char *ret_path); -extern bool get_home_path(char *ret_path); -extern void get_parent_directory(char *path); - -/* common/pgfnames.c */ -extern char **pgfnames(const char *path); -extern void pgfnames_cleanup(char **filenames); - -#define IS_NONWINDOWS_DIR_SEP(ch) ((ch) == '/') -#define is_nonwindows_absolute_path(filename) \ -( \ - IS_NONWINDOWS_DIR_SEP((filename)[0]) \ -) - -#define IS_WINDOWS_DIR_SEP(ch) ((ch) == '/' || (ch) == '\\') -/* See path_is_relative_and_below_cwd() for how we handle 'E:abc'. */ -#define is_windows_absolute_path(filename) \ -( \ - IS_WINDOWS_DIR_SEP((filename)[0]) || \ - (isalpha((unsigned char) ((filename)[0])) && (filename)[1] == ':' && \ - IS_WINDOWS_DIR_SEP((filename)[2])) \ -) - -/* - * is_absolute_path and IS_DIR_SEP - * - * By using macros here we avoid needing to include path.c in libpq. - */ -#ifndef WIN32 -#define IS_DIR_SEP(ch) IS_NONWINDOWS_DIR_SEP(ch) -#define is_absolute_path(filename) is_nonwindows_absolute_path(filename) -#else -#define IS_DIR_SEP(ch) IS_WINDOWS_DIR_SEP(ch) -#define is_absolute_path(filename) is_windows_absolute_path(filename) -#endif - -/* - * This macro provides a centralized list of all errnos that identify - * hard failure of a previously-established network connection. - * The macro is intended to be used in a switch statement, in the form - * "case ALL_CONNECTION_FAILURE_ERRNOS:". - * - * Note: this groups EPIPE and ECONNRESET, which we take to indicate a - * probable server crash, with other errors that indicate loss of network - * connectivity without proving much about the server's state. Places that - * are actually reporting errors typically single out EPIPE and ECONNRESET, - * while allowing the network failures to be reported generically. - */ -#define ALL_CONNECTION_FAILURE_ERRNOS \ - EPIPE: \ - case ECONNRESET: \ - case ECONNABORTED: \ - case EHOSTDOWN: \ - case EHOSTUNREACH: \ - case ENETDOWN: \ - case ENETRESET: \ - case ENETUNREACH: \ - case ETIMEDOUT - -/* Portable locale initialization (in exec.c) */ -extern void set_pglocale_pgservice(const char *argv0, const char *app); - -/* Portable way to find and execute binaries (in exec.c) */ -extern int validate_exec(const char *path); -extern int find_my_exec(const char *argv0, char *retpath); -extern int find_other_exec(const char *argv0, const char *target, - const char *versionstr, char *retpath); -extern char *pipe_read_line(char *cmd, char *line, int maxsize); - -/* Doesn't belong here, but this is used with find_other_exec(), so... */ -#define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n" - -#ifdef EXEC_BACKEND -/* Disable ASLR before exec, for developer builds only (in exec.c) */ -extern int pg_disable_aslr(void); -#endif - - -#if defined(WIN32) || defined(__CYGWIN__) -#define EXE ".exe" -#else -#define EXE "" -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -#define DEVNULL "nul" -#else -#define DEVNULL "/dev/null" -#endif - -/* Portable delay handling */ -extern void pg_usleep(long microsec); - -/* Portable SQL-like case-independent comparisons and conversions */ -extern int pg_strcasecmp(const char *s1, const char *s2); -extern int pg_strncasecmp(const char *s1, const char *s2, size_t n); -extern unsigned char pg_toupper(unsigned char ch); -extern unsigned char pg_tolower(unsigned char ch); -extern unsigned char pg_ascii_toupper(unsigned char ch); -extern unsigned char pg_ascii_tolower(unsigned char ch); - -/* - * Beginning in v12, we always replace snprintf() and friends with our own - * implementation. This symbol is no longer consulted by the core code, - * but keep it defined anyway in case any extensions are looking at it. - */ -#define USE_REPL_SNPRINTF 1 - -/* - * Versions of libintl >= 0.13 try to replace printf() and friends with - * macros to their own versions that understand the %$ format. We do the - * same, so disable their macros, if they exist. - */ -#ifdef vsnprintf -#undef vsnprintf -#endif -#ifdef snprintf -#undef snprintf -#endif -#ifdef vsprintf -#undef vsprintf -#endif -#ifdef sprintf -#undef sprintf -#endif -#ifdef vfprintf -#undef vfprintf -#endif -#ifdef fprintf -#undef fprintf -#endif -#ifdef vprintf -#undef vprintf -#endif -#ifdef printf -#undef printf -#endif - -extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) pg_attribute_printf(3, 0); -extern int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3, 4); -extern int pg_vsprintf(char *str, const char *fmt, va_list args) pg_attribute_printf(2, 0); -extern int pg_sprintf(char *str, const char *fmt,...) pg_attribute_printf(2, 3); -extern int pg_vfprintf(FILE *stream, const char *fmt, va_list args) pg_attribute_printf(2, 0); -extern int pg_fprintf(FILE *stream, const char *fmt,...) pg_attribute_printf(2, 3); -extern int pg_vprintf(const char *fmt, va_list args) pg_attribute_printf(1, 0); -extern int pg_printf(const char *fmt,...) pg_attribute_printf(1, 2); - -#ifndef WIN32 -/* - * We add a pg_ prefix as a warning that the Windows implementations have the - * non-standard side-effect of changing the current file position. - */ -#define pg_pread pread -#define pg_pwrite pwrite -#endif - -/* - * We use __VA_ARGS__ for printf to prevent replacing references to - * the "printf" format archetype in format() attribute declarations. - * That unfortunately means that taking a function pointer to printf - * will not do what we'd wish. (If you need to do that, you must name - * pg_printf explicitly.) For printf's sibling functions, use - * parameterless macros so that function pointers will work unsurprisingly. - */ -#define vsnprintf pg_vsnprintf -#define snprintf pg_snprintf -#define vsprintf pg_vsprintf -#define sprintf pg_sprintf -#define vfprintf pg_vfprintf -#define fprintf pg_fprintf -#define vprintf pg_vprintf -#define printf(...) pg_printf(__VA_ARGS__) - -/* This is also provided by snprintf.c */ -extern int pg_strfromd(char *str, size_t count, int precision, double value); - -/* Replace strerror() with our own, somewhat more robust wrapper */ -extern char *pg_strerror(int errnum); -#define strerror pg_strerror - -/* Likewise for strerror_r(); note we prefer the GNU API for that */ -extern char *pg_strerror_r(int errnum, char *buf, size_t buflen); -#define strerror_r pg_strerror_r -#define PG_STRERROR_R_BUFLEN 256 /* Recommended buffer size for strerror_r */ - -/* Wrap strsignal(), or provide our own version if necessary */ -extern const char *pg_strsignal(int signum); - -extern int pclose_check(FILE *stream); - -/* Global variable holding time zone information. */ -#if defined(WIN32) || defined(__CYGWIN__) -#define TIMEZONE_GLOBAL _timezone -#define TZNAME_GLOBAL _tzname -#else -#define TIMEZONE_GLOBAL timezone -#define TZNAME_GLOBAL tzname -#endif - -#if defined(WIN32) || defined(__CYGWIN__) -/* - * Win32 doesn't have reliable rename/unlink during concurrent access. - */ -extern int pgrename(const char *from, const char *to); -extern int pgunlink(const char *path); - -/* Include this first so later includes don't see these defines */ -#ifdef _MSC_VER -#include <io.h> -#endif - -#define rename(from, to) pgrename(from, to) -#define unlink(path) pgunlink(path) -#endif /* defined(WIN32) || defined(__CYGWIN__) */ - -/* - * Win32 also doesn't have symlinks, but we can emulate them with - * junction points on newer Win32 versions. - * - * Cygwin has its own symlinks which work on Win95/98/ME where - * junction points don't, so use those instead. We have no way of - * knowing what type of system Cygwin binaries will be run on. - * Note: Some CYGWIN includes might #define WIN32. - */ -#if defined(WIN32) && !defined(__CYGWIN__) -extern int pgsymlink(const char *oldpath, const char *newpath); -extern int pgreadlink(const char *path, char *buf, size_t size); - -#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) -#define readlink(path, buf, size) pgreadlink(path, buf, size) -#endif - -extern bool rmtree(const char *path, bool rmtopdir); - -#if defined(WIN32) && !defined(__CYGWIN__) - -/* - * open() and fopen() replacements to allow deletion of open files and - * passing of other special options. - */ -#define O_DIRECT 0x80000000 -extern HANDLE pgwin32_open_handle(const char *, int, bool); -extern int pgwin32_open(const char *, int,...); -extern FILE *pgwin32_fopen(const char *, const char *); -#define open(a,b,c) pgwin32_open(a,b,c) -#define fopen(a,b) pgwin32_fopen(a,b) - -/* - * Mingw-w64 headers #define popen and pclose to _popen and _pclose. We want - * to use our popen wrapper, rather than plain _popen, so override that. For - * consistency, use our version of pclose, too. - */ -#ifdef popen -#undef popen -#endif -#ifdef pclose -#undef pclose -#endif - -/* - * system() and popen() replacements to enclose the command in an extra - * pair of quotes. - */ -extern int pgwin32_system(const char *command); -extern FILE *pgwin32_popen(const char *command, const char *type); - -#define system(a) pgwin32_system(a) -#define popen(a,b) pgwin32_popen(a,b) -#define pclose(a) _pclose(a) - -#else /* !WIN32 */ - -/* - * Win32 requires a special close for sockets and pipes, while on Unix - * close() does them all. - */ -#define closesocket close -#endif /* WIN32 */ - -/* - * On Windows, setvbuf() does not support _IOLBF mode, and interprets that - * as _IOFBF. To add insult to injury, setvbuf(file, NULL, _IOFBF, 0) - * crashes outright if "parameter validation" is enabled. Therefore, in - * places where we'd like to select line-buffered mode, we fall back to - * unbuffered mode instead on Windows. Always use PG_IOLBF not _IOLBF - * directly in order to implement this behavior. - */ -#ifndef WIN32 -#define PG_IOLBF _IOLBF -#else -#define PG_IOLBF _IONBF -#endif - -/* - * Default "extern" declarations or macro substitutes for library routines. - * When necessary, these routines are provided by files in src/port/. - */ - -/* Type to use with fseeko/ftello */ -#ifndef WIN32 /* WIN32 is handled in port/win32_port.h */ -#define pgoff_t off_t -#endif - -#ifndef HAVE_GETPEEREID -/* On Windows, Perl might have incompatible definitions of uid_t and gid_t. */ -#ifndef PLPERL_HAVE_UID_GID -extern int getpeereid(int sock, uid_t *uid, gid_t *gid); -#endif -#endif - -/* - * Glibc doesn't use the builtin for clang due to a *gcc* bug in a version - * newer than the gcc compatibility clang claims to have. This would cause a - * *lot* of superfluous function calls, therefore revert when using clang. In - * C++ there's issues with libc++ (not libstdc++), so disable as well. - */ -#if defined(__clang__) && !defined(__cplusplus) -/* needs to be separate to not confuse other compilers */ -#if __has_builtin(__builtin_isinf) -/* need to include before, to avoid getting overwritten */ -#include <math.h> -#undef isinf -#define isinf __builtin_isinf -#endif /* __has_builtin(isinf) */ -#endif /* __clang__ && !__cplusplus */ - -#ifndef HAVE_EXPLICIT_BZERO -extern void explicit_bzero(void *buf, size_t len); -#endif - -#ifdef HAVE_BUGGY_STRTOF -extern float pg_strtof(const char *nptr, char **endptr); -#define strtof(a,b) (pg_strtof((a),(b))) -#endif - -#ifdef WIN32 -/* src/port/win32link.c */ -extern int link(const char *src, const char *dst); -#endif - -#ifndef HAVE_MKDTEMP -extern char *mkdtemp(char *path); -#endif - -#ifndef HAVE_INET_ATON -#include <netinet/in.h> -#include <arpa/inet.h> -extern int inet_aton(const char *cp, struct in_addr *addr); -#endif - -#if !HAVE_DECL_STRLCAT -extern size_t strlcat(char *dst, const char *src, size_t siz); -#endif - -#if !HAVE_DECL_STRLCPY -extern size_t strlcpy(char *dst, const char *src, size_t siz); -#endif - -#if !HAVE_DECL_STRNLEN -extern size_t strnlen(const char *str, size_t maxlen); -#endif - -/* thread.c */ -#ifndef WIN32 -extern bool pg_get_user_name(uid_t user_id, char *buffer, size_t buflen); -extern bool pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen); -#endif - -extern void pg_qsort(void *base, size_t nel, size_t elsize, - int (*cmp) (const void *, const void *)); -extern int pg_qsort_strcmp(const void *a, const void *b); - -#define qsort(a,b,c,d) pg_qsort(a,b,c,d) - -typedef int (*qsort_arg_comparator) (const void *a, const void *b, void *arg); - -extern void qsort_arg(void *base, size_t nel, size_t elsize, - qsort_arg_comparator cmp, void *arg); - -extern void qsort_interruptible(void *base, size_t nel, size_t elsize, - qsort_arg_comparator cmp, void *arg); - -extern void *bsearch_arg(const void *key, const void *base0, - size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), - void *arg); - -/* port/chklocale.c */ -extern int pg_get_encoding_from_locale(const char *ctype, bool write_message); - -#if defined(WIN32) && !defined(FRONTEND) -extern int pg_codepage_to_encoding(UINT cp); -#endif - -/* port/inet_net_ntop.c */ -extern char *pg_inet_net_ntop(int af, const void *src, int bits, - char *dst, size_t size); - -/* port/pg_strong_random.c */ -extern void pg_strong_random_init(void); -extern bool pg_strong_random(void *buf, size_t len); - -/* - * pg_backend_random used to be a wrapper for pg_strong_random before - * Postgres 12 for the backend code. - */ -#define pg_backend_random pg_strong_random - -/* port/pgcheckdir.c */ -extern int pg_check_dir(const char *dir); - -/* port/pgmkdirp.c */ -extern int pg_mkdir_p(char *path, int omode); - -/* port/pqsignal.c */ -typedef void (*pqsigfunc) (SIGNAL_ARGS); -extern pqsigfunc pqsignal(int signo, pqsigfunc func); - -/* port/quotes.c */ -extern char *escape_single_quotes_ascii(const char *src); - -/* common/wait_error.c */ -extern char *wait_result_to_str(int exitstatus); -extern bool wait_result_is_signal(int exit_status, int signum); -extern bool wait_result_is_any_signal(int exit_status, bool include_command_not_found); -extern int wait_result_to_exit_code(int exit_status); - -/* - * Interfaces that we assume all Unix system have. We retain individual macros - * for better documentation. - * - * For symlink-related functions, there is often no need to test these macros, - * because we provided basic support on Windows that can work with absolute - * paths to directories. Code that wants to test for complete symlink support - * (including relative paths and non-directories) should be conditional on - * HAVE_READLINK or HAVE_SYMLINK. - */ -#ifndef WIN32 -#define HAVE_GETRLIMIT 1 -#define HAVE_POLL 1 -#define HAVE_POLL_H 1 -#define HAVE_READLINK 1 -#define HAVE_SETSID 1 -#define HAVE_SHM_OPEN 1 -#define HAVE_SYMLINK 1 -#endif - -#endif /* PG_PORT_H */ diff --git a/contrib/libs/libpq/src/include/port/darwin.h b/contrib/libs/libpq/src/include/port/darwin.h deleted file mode 100644 index 15fb69d6db..0000000000 --- a/contrib/libs/libpq/src/include/port/darwin.h +++ /dev/null @@ -1,8 +0,0 @@ -/* src/include/port/darwin.h */ - -#define __darwin__ 1 - -#if HAVE_DECL_F_FULLFSYNC /* not present before macOS 10.3 */ -#define HAVE_FSYNC_WRITETHROUGH - -#endif diff --git a/contrib/libs/libpq/src/include/port/linux.h b/contrib/libs/libpq/src/include/port/linux.h deleted file mode 100644 index 7a6e46cdbb..0000000000 --- a/contrib/libs/libpq/src/include/port/linux.h +++ /dev/null @@ -1,22 +0,0 @@ -/* src/include/port/linux.h */ - -/* - * As of July 2007, all known versions of the Linux kernel will sometimes - * return EIDRM for a shmctl() operation when EINVAL is correct (it happens - * when the low-order 15 bits of the supplied shm ID match the slot number - * assigned to a newer shmem segment). We deal with this by assuming that - * EIDRM means EINVAL in PGSharedMemoryIsInUse(). This is reasonably safe - * since in fact Linux has no excuse for ever returning EIDRM; it doesn't - * track removed segments in a way that would allow distinguishing them from - * private ones. But someday that code might get upgraded, and we'd have - * to have a kernel version test here. - */ -#define HAVE_LINUX_EIDRM_BUG - -/* - * Set the default wal_sync_method to fdatasync. With recent Linux versions, - * xlogdefs.h's normal rules will prefer open_datasync, which (a) doesn't - * perform better and (b) causes outright failures on ext4 data=journal - * filesystems, because those don't support O_DIRECT. - */ -#define PLATFORM_DEFAULT_SYNC_METHOD SYNC_METHOD_FDATASYNC diff --git a/contrib/libs/libpq/src/include/port/pg_bitutils.h b/contrib/libs/libpq/src/include/port/pg_bitutils.h deleted file mode 100644 index 21a4fa0341..0000000000 --- a/contrib/libs/libpq/src/include/port/pg_bitutils.h +++ /dev/null @@ -1,339 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_bitutils.h - * Miscellaneous functions for bit-wise operations. - * - * - * Copyright (c) 2019-2023, PostgreSQL Global Development Group - * - * src/include/port/pg_bitutils.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_BITUTILS_H -#define PG_BITUTILS_H - -#ifdef _MSC_VER -#include <intrin.h> -#define HAVE_BITSCAN_FORWARD -#define HAVE_BITSCAN_REVERSE - -#else -#if defined(HAVE__BUILTIN_CTZ) -#define HAVE_BITSCAN_FORWARD -#endif - -#if defined(HAVE__BUILTIN_CLZ) -#define HAVE_BITSCAN_REVERSE -#endif -#endif /* _MSC_VER */ - -extern PGDLLIMPORT const uint8 pg_leftmost_one_pos[256]; -extern PGDLLIMPORT const uint8 pg_rightmost_one_pos[256]; -extern PGDLLIMPORT const uint8 pg_number_of_ones[256]; - -/* - * pg_leftmost_one_pos32 - * Returns the position of the most significant set bit in "word", - * measured from the least significant bit. word must not be 0. - */ -static inline int -pg_leftmost_one_pos32(uint32 word) -{ -#ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); - - return 31 - __builtin_clz(word); -#elif defined(_MSC_VER) - unsigned long result; - bool non_zero; - - non_zero = _BitScanReverse(&result, word); - Assert(non_zero); - return (int) result; -#else - int shift = 32 - 8; - - Assert(word != 0); - - while ((word >> shift) == 0) - shift -= 8; - - return shift + pg_leftmost_one_pos[(word >> shift) & 255]; -#endif /* HAVE__BUILTIN_CLZ */ -} - -/* - * pg_leftmost_one_pos64 - * As above, but for a 64-bit word. - */ -static inline int -pg_leftmost_one_pos64(uint64 word) -{ -#ifdef HAVE__BUILTIN_CLZ - Assert(word != 0); - -#if defined(HAVE_LONG_INT_64) - return 63 - __builtin_clzl(word); -#elif defined(HAVE_LONG_LONG_INT_64) - return 63 - __builtin_clzll(word); -#else -#error must have a working 64-bit integer datatype -#endif /* HAVE_LONG_INT_64 */ - -#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64)) - unsigned long result; - bool non_zero; - - non_zero = _BitScanReverse64(&result, word); - Assert(non_zero); - return (int) result; -#else - int shift = 64 - 8; - - Assert(word != 0); - - while ((word >> shift) == 0) - shift -= 8; - - return shift + pg_leftmost_one_pos[(word >> shift) & 255]; -#endif /* HAVE__BUILTIN_CLZ */ -} - -/* - * pg_rightmost_one_pos32 - * Returns the position of the least significant set bit in "word", - * measured from the least significant bit. word must not be 0. - */ -static inline int -pg_rightmost_one_pos32(uint32 word) -{ -#ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); - - return __builtin_ctz(word); -#elif defined(_MSC_VER) - unsigned long result; - bool non_zero; - - non_zero = _BitScanForward(&result, word); - Assert(non_zero); - return (int) result; -#else - int result = 0; - - Assert(word != 0); - - while ((word & 255) == 0) - { - word >>= 8; - result += 8; - } - result += pg_rightmost_one_pos[word & 255]; - return result; -#endif /* HAVE__BUILTIN_CTZ */ -} - -/* - * pg_rightmost_one_pos64 - * As above, but for a 64-bit word. - */ -static inline int -pg_rightmost_one_pos64(uint64 word) -{ -#ifdef HAVE__BUILTIN_CTZ - Assert(word != 0); - -#if defined(HAVE_LONG_INT_64) - return __builtin_ctzl(word); -#elif defined(HAVE_LONG_LONG_INT_64) - return __builtin_ctzll(word); -#else -#error must have a working 64-bit integer datatype -#endif /* HAVE_LONG_INT_64 */ - -#elif defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_ARM64)) - unsigned long result; - bool non_zero; - - non_zero = _BitScanForward64(&result, word); - Assert(non_zero); - return (int) result; -#else - int result = 0; - - Assert(word != 0); - - while ((word & 255) == 0) - { - word >>= 8; - result += 8; - } - result += pg_rightmost_one_pos[word & 255]; - return result; -#endif /* HAVE__BUILTIN_CTZ */ -} - -/* - * pg_nextpower2_32 - * Returns the next higher power of 2 above 'num', or 'num' if it's - * already a power of 2. - * - * 'num' mustn't be 0 or be above PG_UINT32_MAX / 2 + 1. - */ -static inline uint32 -pg_nextpower2_32(uint32 num) -{ - Assert(num > 0 && num <= PG_UINT32_MAX / 2 + 1); - - /* - * A power 2 number has only 1 bit set. Subtracting 1 from such a number - * will turn on all previous bits resulting in no common bits being set - * between num and num-1. - */ - if ((num & (num - 1)) == 0) - return num; /* already power 2 */ - - return ((uint32) 1) << (pg_leftmost_one_pos32(num) + 1); -} - -/* - * pg_nextpower2_64 - * Returns the next higher power of 2 above 'num', or 'num' if it's - * already a power of 2. - * - * 'num' mustn't be 0 or be above PG_UINT64_MAX / 2 + 1. - */ -static inline uint64 -pg_nextpower2_64(uint64 num) -{ - Assert(num > 0 && num <= PG_UINT64_MAX / 2 + 1); - - /* - * A power 2 number has only 1 bit set. Subtracting 1 from such a number - * will turn on all previous bits resulting in no common bits being set - * between num and num-1. - */ - if ((num & (num - 1)) == 0) - return num; /* already power 2 */ - - return ((uint64) 1) << (pg_leftmost_one_pos64(num) + 1); -} - -/* - * pg_prevpower2_32 - * Returns the next lower power of 2 below 'num', or 'num' if it's - * already a power of 2. - * - * 'num' mustn't be 0. - */ -static inline uint32 -pg_prevpower2_32(uint32 num) -{ - return ((uint32) 1) << pg_leftmost_one_pos32(num); -} - -/* - * pg_prevpower2_64 - * Returns the next lower power of 2 below 'num', or 'num' if it's - * already a power of 2. - * - * 'num' mustn't be 0. - */ -static inline uint64 -pg_prevpower2_64(uint64 num) -{ - return ((uint64) 1) << pg_leftmost_one_pos64(num); -} - -/* - * pg_ceil_log2_32 - * Returns equivalent of ceil(log2(num)) - */ -static inline uint32 -pg_ceil_log2_32(uint32 num) -{ - if (num < 2) - return 0; - else - return pg_leftmost_one_pos32(num - 1) + 1; -} - -/* - * pg_ceil_log2_64 - * Returns equivalent of ceil(log2(num)) - */ -static inline uint64 -pg_ceil_log2_64(uint64 num) -{ - if (num < 2) - return 0; - else - return pg_leftmost_one_pos64(num - 1) + 1; -} - -/* - * With MSVC on x86_64 builds, try using native popcnt instructions via the - * __popcnt and __popcnt64 intrinsics. These don't work the same as GCC's - * __builtin_popcount* intrinsic functions as they always emit popcnt - * instructions. - */ -#if defined(_MSC_VER) && defined(_M_AMD64) -#define HAVE_X86_64_POPCNTQ -#endif - -/* - * On x86_64, we can use the hardware popcount instruction, but only if - * we can verify that the CPU supports it via the cpuid instruction. - * - * Otherwise, we fall back to a hand-rolled implementation. - */ -#ifdef HAVE_X86_64_POPCNTQ -#if defined(HAVE__GET_CPUID) || defined(HAVE__CPUID) -#define TRY_POPCNT_FAST 1 -#endif -#endif - -#ifdef TRY_POPCNT_FAST -/* Attempt to use the POPCNT instruction, but perform a runtime check first */ -extern int (*pg_popcount32) (uint32 word); -extern int (*pg_popcount64) (uint64 word); - -#else -/* Use a portable implementation -- no need for a function pointer. */ -extern int pg_popcount32(uint32 word); -extern int pg_popcount64(uint64 word); - -#endif /* TRY_POPCNT_FAST */ - -/* Count the number of one-bits in a byte array */ -extern uint64 pg_popcount(const char *buf, int bytes); - -/* - * Rotate the bits of "word" to the right/left by n bits. - */ -static inline uint32 -pg_rotate_right32(uint32 word, int n) -{ - return (word >> n) | (word << (32 - n)); -} - -static inline uint32 -pg_rotate_left32(uint32 word, int n) -{ - return (word << n) | (word >> (32 - n)); -} - -/* size_t variants of the above, as required */ - -#if SIZEOF_SIZE_T == 4 -#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos32 -#define pg_nextpower2_size_t pg_nextpower2_32 -#define pg_prevpower2_size_t pg_prevpower2_32 -#else -#define pg_leftmost_one_pos_size_t pg_leftmost_one_pos64 -#define pg_nextpower2_size_t pg_nextpower2_64 -#define pg_prevpower2_size_t pg_prevpower2_64 -#endif - -#endif /* PG_BITUTILS_H */ diff --git a/contrib/libs/libpq/src/include/port/pg_bswap.h b/contrib/libs/libpq/src/include/port/pg_bswap.h deleted file mode 100644 index 80abd750d4..0000000000 --- a/contrib/libs/libpq/src/include/port/pg_bswap.h +++ /dev/null @@ -1,161 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_bswap.h - * Byte swapping. - * - * Macros for reversing the byte order of 16, 32 and 64-bit unsigned integers. - * For example, 0xAABBCCDD becomes 0xDDCCBBAA. These are just wrappers for - * built-in functions provided by the compiler where support exists. - * - * Note that all of these functions accept unsigned integers as arguments and - * return the same. Use caution when using these wrapper macros with signed - * integers. - * - * Copyright (c) 2015-2023, PostgreSQL Global Development Group - * - * src/include/port/pg_bswap.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_BSWAP_H -#define PG_BSWAP_H - - -/* - * In all supported versions msvc provides _byteswap_* functions in stdlib.h, - * already included by c.h. - */ - - -/* implementation of uint16 pg_bswap16(uint16) */ -#if defined(HAVE__BUILTIN_BSWAP16) - -#define pg_bswap16(x) __builtin_bswap16(x) - -#elif defined(_MSC_VER) - -#define pg_bswap16(x) _byteswap_ushort(x) - -#else - -static inline uint16 -pg_bswap16(uint16 x) -{ - return - ((x << 8) & 0xff00) | - ((x >> 8) & 0x00ff); -} - -#endif /* HAVE__BUILTIN_BSWAP16 */ - - -/* implementation of uint32 pg_bswap32(uint32) */ -#if defined(HAVE__BUILTIN_BSWAP32) - -#define pg_bswap32(x) __builtin_bswap32(x) - -#elif defined(_MSC_VER) - -#define pg_bswap32(x) _byteswap_ulong(x) - -#else - -static inline uint32 -pg_bswap32(uint32 x) -{ - return - ((x << 24) & 0xff000000) | - ((x << 8) & 0x00ff0000) | - ((x >> 8) & 0x0000ff00) | - ((x >> 24) & 0x000000ff); -} - -#endif /* HAVE__BUILTIN_BSWAP32 */ - - -/* implementation of uint64 pg_bswap64(uint64) */ -#if defined(HAVE__BUILTIN_BSWAP64) - -#define pg_bswap64(x) __builtin_bswap64(x) - - -#elif defined(_MSC_VER) - -#define pg_bswap64(x) _byteswap_uint64(x) - -#else - -static inline uint64 -pg_bswap64(uint64 x) -{ - return - ((x << 56) & UINT64CONST(0xff00000000000000)) | - ((x << 40) & UINT64CONST(0x00ff000000000000)) | - ((x << 24) & UINT64CONST(0x0000ff0000000000)) | - ((x << 8) & UINT64CONST(0x000000ff00000000)) | - ((x >> 8) & UINT64CONST(0x00000000ff000000)) | - ((x >> 24) & UINT64CONST(0x0000000000ff0000)) | - ((x >> 40) & UINT64CONST(0x000000000000ff00)) | - ((x >> 56) & UINT64CONST(0x00000000000000ff)); -} -#endif /* HAVE__BUILTIN_BSWAP64 */ - - -/* - * Portable and fast equivalents for ntohs, ntohl, htons, htonl, - * additionally extended to 64 bits. - */ -#ifdef WORDS_BIGENDIAN - -#define pg_hton16(x) (x) -#define pg_hton32(x) (x) -#define pg_hton64(x) (x) - -#define pg_ntoh16(x) (x) -#define pg_ntoh32(x) (x) -#define pg_ntoh64(x) (x) - -#else - -#define pg_hton16(x) pg_bswap16(x) -#define pg_hton32(x) pg_bswap32(x) -#define pg_hton64(x) pg_bswap64(x) - -#define pg_ntoh16(x) pg_bswap16(x) -#define pg_ntoh32(x) pg_bswap32(x) -#define pg_ntoh64(x) pg_bswap64(x) - -#endif /* WORDS_BIGENDIAN */ - - -/* - * Rearrange the bytes of a Datum from big-endian order into the native byte - * order. On big-endian machines, this does nothing at all. Note that the C - * type Datum is an unsigned integer type on all platforms. - * - * One possible application of the DatumBigEndianToNative() macro is to make - * bitwise comparisons cheaper. A simple 3-way comparison of Datums - * transformed by the macro (based on native, unsigned comparisons) will return - * the same result as a memcmp() of the corresponding original Datums, but can - * be much cheaper. It's generally safe to do this on big-endian systems - * without any special transformation occurring first. - * - * If SIZEOF_DATUM is not defined, then postgres.h wasn't included and these - * macros probably shouldn't be used, so we define nothing. Note that - * SIZEOF_DATUM == 8 would evaluate as 0 == 8 in that case, potentially - * leading to the wrong implementation being selected and confusing errors, so - * defining nothing is safest. - */ -#ifdef SIZEOF_DATUM -#ifdef WORDS_BIGENDIAN -#define DatumBigEndianToNative(x) (x) -#else /* !WORDS_BIGENDIAN */ -#if SIZEOF_DATUM == 8 -#define DatumBigEndianToNative(x) pg_bswap64(x) -#else /* SIZEOF_DATUM != 8 */ -#define DatumBigEndianToNative(x) pg_bswap32(x) -#endif /* SIZEOF_DATUM == 8 */ -#endif /* WORDS_BIGENDIAN */ -#endif /* SIZEOF_DATUM */ - -#endif /* PG_BSWAP_H */ diff --git a/contrib/libs/libpq/src/include/port/pg_crc32c.h b/contrib/libs/libpq/src/include/port/pg_crc32c.h deleted file mode 100644 index 7f8779261c..0000000000 --- a/contrib/libs/libpq/src/include/port/pg_crc32c.h +++ /dev/null @@ -1,101 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_crc32c.h - * Routines for computing CRC-32C checksums. - * - * The speed of CRC-32C calculation has a big impact on performance, so we - * jump through some hoops to get the best implementation for each - * platform. Some CPU architectures have special instructions for speeding - * up CRC calculations (e.g. Intel SSE 4.2), on other platforms we use the - * Slicing-by-8 algorithm which uses lookup tables. - * - * The public interface consists of four macros: - * - * INIT_CRC32C(crc) - * Initialize a CRC accumulator - * - * COMP_CRC32C(crc, data, len) - * Accumulate some (more) bytes into a CRC - * - * FIN_CRC32C(crc) - * Finish a CRC calculation - * - * EQ_CRC32C(c1, c2) - * Check for equality of two CRCs. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port/pg_crc32c.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_CRC32C_H -#define PG_CRC32C_H - -#include "port/pg_bswap.h" - -typedef uint32 pg_crc32c; - -/* The INIT and EQ macros are the same for all implementations. */ -#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF) -#define EQ_CRC32C(c1, c2) ((c1) == (c2)) - -#if defined(USE_SSE42_CRC32C) -/* Use Intel SSE4.2 instructions. */ -#define COMP_CRC32C(crc, data, len) \ - ((crc) = pg_comp_crc32c_sse42((crc), (data), (len))) -#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) - -extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len); - -#elif defined(USE_ARMV8_CRC32C) -/* Use ARMv8 CRC Extension instructions. */ - -#define COMP_CRC32C(crc, data, len) \ - ((crc) = pg_comp_crc32c_armv8((crc), (data), (len))) -#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) - -extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len); - -#elif defined(USE_SSE42_CRC32C_WITH_RUNTIME_CHECK) || defined(USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK) - -/* - * Use Intel SSE 4.2 or ARMv8 instructions, but perform a runtime check first - * to check that they are available. - */ -#define COMP_CRC32C(crc, data, len) \ - ((crc) = pg_comp_crc32c((crc), (data), (len))) -#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) - -extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); -extern pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len); - -#ifdef USE_SSE42_CRC32C_WITH_RUNTIME_CHECK -extern pg_crc32c pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len); -#endif -#ifdef USE_ARMV8_CRC32C_WITH_RUNTIME_CHECK -extern pg_crc32c pg_comp_crc32c_armv8(pg_crc32c crc, const void *data, size_t len); -#endif - -#else -/* - * Use slicing-by-8 algorithm. - * - * On big-endian systems, the intermediate value is kept in reverse byte - * order, to avoid byte-swapping during the calculation. FIN_CRC32C reverses - * the bytes to the final order. - */ -#define COMP_CRC32C(crc, data, len) \ - ((crc) = pg_comp_crc32c_sb8((crc), (data), (len))) -#ifdef WORDS_BIGENDIAN -#define FIN_CRC32C(crc) ((crc) = pg_bswap32(crc) ^ 0xFFFFFFFF) -#else -#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF) -#endif - -extern pg_crc32c pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len); - -#endif - -#endif /* PG_CRC32C_H */ diff --git a/contrib/libs/libpq/src/include/port/pg_iovec.h b/contrib/libs/libpq/src/include/port/pg_iovec.h deleted file mode 100644 index 689799c425..0000000000 --- a/contrib/libs/libpq/src/include/port/pg_iovec.h +++ /dev/null @@ -1,55 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_iovec.h - * Header for vectored I/O functions, to use in place of <sys/uio.h>. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port/pg_iovec.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_IOVEC_H -#define PG_IOVEC_H - -#ifndef WIN32 - -#include <limits.h> -#include <sys/uio.h> - -#else - -/* POSIX requires at least 16 as a maximum iovcnt. */ -#define IOV_MAX 16 - -/* Define our own POSIX-compatible iovec struct. */ -struct iovec -{ - void *iov_base; - size_t iov_len; -}; - -#endif - -/* Define a reasonable maximum that is safe to use on the stack. */ -#define PG_IOV_MAX Min(IOV_MAX, 32) - -/* - * Note that pg_preadv and pg_pwritev have a pg_ prefix as a warning that the - * Windows implementations have the side-effect of changing the file position. - */ - -#if HAVE_DECL_PREADV -#define pg_preadv preadv -#else -extern ssize_t pg_preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset); -#endif - -#if HAVE_DECL_PWRITEV -#define pg_pwritev pwritev -#else -extern ssize_t pg_pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset); -#endif - -#endif /* PG_IOVEC_H */ diff --git a/contrib/libs/libpq/src/include/port/pg_lfind.h b/contrib/libs/libpq/src/include/port/pg_lfind.h deleted file mode 100644 index 59aa8245ed..0000000000 --- a/contrib/libs/libpq/src/include/port/pg_lfind.h +++ /dev/null @@ -1,180 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_lfind.h - * Optimized linear search routines using SIMD intrinsics where - * available. - * - * Copyright (c) 2022-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/include/port/pg_lfind.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_LFIND_H -#define PG_LFIND_H - -#include "port/simd.h" - -/* - * pg_lfind8 - * - * Return true if there is an element in 'base' that equals 'key', otherwise - * return false. - */ -static inline bool -pg_lfind8(uint8 key, uint8 *base, uint32 nelem) -{ - uint32 i; - - /* round down to multiple of vector length */ - uint32 tail_idx = nelem & ~(sizeof(Vector8) - 1); - Vector8 chunk; - - for (i = 0; i < tail_idx; i += sizeof(Vector8)) - { - vector8_load(&chunk, &base[i]); - if (vector8_has(chunk, key)) - return true; - } - - /* Process the remaining elements one at a time. */ - for (; i < nelem; i++) - { - if (key == base[i]) - return true; - } - - return false; -} - -/* - * pg_lfind8_le - * - * Return true if there is an element in 'base' that is less than or equal to - * 'key', otherwise return false. - */ -static inline bool -pg_lfind8_le(uint8 key, uint8 *base, uint32 nelem) -{ - uint32 i; - - /* round down to multiple of vector length */ - uint32 tail_idx = nelem & ~(sizeof(Vector8) - 1); - Vector8 chunk; - - for (i = 0; i < tail_idx; i += sizeof(Vector8)) - { - vector8_load(&chunk, &base[i]); - if (vector8_has_le(chunk, key)) - return true; - } - - /* Process the remaining elements one at a time. */ - for (; i < nelem; i++) - { - if (base[i] <= key) - return true; - } - - return false; -} - -/* - * pg_lfind32 - * - * Return true if there is an element in 'base' that equals 'key', otherwise - * return false. - */ -static inline bool -pg_lfind32(uint32 key, uint32 *base, uint32 nelem) -{ - uint32 i = 0; - -#ifndef USE_NO_SIMD - - /* - * For better instruction-level parallelism, each loop iteration operates - * on a block of four registers. Testing for SSE2 has showed this is ~40% - * faster than using a block of two registers. - */ - const Vector32 keys = vector32_broadcast(key); /* load copies of key */ - const uint32 nelem_per_vector = sizeof(Vector32) / sizeof(uint32); - const uint32 nelem_per_iteration = 4 * nelem_per_vector; - - /* round down to multiple of elements per iteration */ - const uint32 tail_idx = nelem & ~(nelem_per_iteration - 1); - -#if defined(USE_ASSERT_CHECKING) - bool assert_result = false; - - /* pre-compute the result for assert checking */ - for (i = 0; i < nelem; i++) - { - if (key == base[i]) - { - assert_result = true; - break; - } - } -#endif - - for (i = 0; i < tail_idx; i += nelem_per_iteration) - { - Vector32 vals1, - vals2, - vals3, - vals4, - result1, - result2, - result3, - result4, - tmp1, - tmp2, - result; - - /* load the next block into 4 registers */ - vector32_load(&vals1, &base[i]); - vector32_load(&vals2, &base[i + nelem_per_vector]); - vector32_load(&vals3, &base[i + nelem_per_vector * 2]); - vector32_load(&vals4, &base[i + nelem_per_vector * 3]); - - /* compare each value to the key */ - result1 = vector32_eq(keys, vals1); - result2 = vector32_eq(keys, vals2); - result3 = vector32_eq(keys, vals3); - result4 = vector32_eq(keys, vals4); - - /* combine the results into a single variable */ - tmp1 = vector32_or(result1, result2); - tmp2 = vector32_or(result3, result4); - result = vector32_or(tmp1, tmp2); - - /* see if there was a match */ - if (vector32_is_highbit_set(result)) - { - Assert(assert_result == true); - return true; - } - } -#endif /* ! USE_NO_SIMD */ - - /* Process the remaining elements one at a time. */ - for (; i < nelem; i++) - { - if (key == base[i]) - { -#ifndef USE_NO_SIMD - Assert(assert_result == true); -#endif - return true; - } - } - -#ifndef USE_NO_SIMD - Assert(assert_result == false); -#endif - return false; -} - -#endif /* PG_LFIND_H */ diff --git a/contrib/libs/libpq/src/include/port/simd.h b/contrib/libs/libpq/src/include/port/simd.h deleted file mode 100644 index 1fa6c3bc6c..0000000000 --- a/contrib/libs/libpq/src/include/port/simd.h +++ /dev/null @@ -1,375 +0,0 @@ -/*------------------------------------------------------------------------- - * - * simd.h - * Support for platform-specific vector operations. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port/simd.h - * - * NOTES - * - VectorN in this file refers to a register where the element operands - * are N bits wide. The vector width is platform-specific, so users that care - * about that will need to inspect "sizeof(VectorN)". - * - *------------------------------------------------------------------------- - */ -#ifndef SIMD_H -#define SIMD_H - -#if (defined(__x86_64__) || defined(_M_AMD64)) -/* - * SSE2 instructions are part of the spec for the 64-bit x86 ISA. We assume - * that compilers targeting this architecture understand SSE2 intrinsics. - * - * We use emmintrin.h rather than the comprehensive header immintrin.h in - * order to exclude extensions beyond SSE2. This is because MSVC, at least, - * will allow the use of intrinsics that haven't been enabled at compile - * time. - */ -#include <emmintrin.h> -#define USE_SSE2 -typedef __m128i Vector8; -typedef __m128i Vector32; - -#elif defined(__aarch64__) && defined(__ARM_NEON) -/* - * We use the Neon instructions if the compiler provides access to them (as - * indicated by __ARM_NEON) and we are on aarch64. While Neon support is - * technically optional for aarch64, it appears that all available 64-bit - * hardware does have it. Neon exists in some 32-bit hardware too, but we - * could not realistically use it there without a run-time check, which seems - * not worth the trouble for now. - */ -#include <arm_neon.h> -#define USE_NEON -typedef uint8x16_t Vector8; -typedef uint32x4_t Vector32; - -#else -/* - * If no SIMD instructions are available, we can in some cases emulate vector - * operations using bitwise operations on unsigned integers. Note that many - * of the functions in this file presently do not have non-SIMD - * implementations. In particular, none of the functions involving Vector32 - * are implemented without SIMD since it's likely not worthwhile to represent - * two 32-bit integers using a uint64. - */ -#define USE_NO_SIMD -typedef uint64 Vector8; -#endif - -/* load/store operations */ -static inline void vector8_load(Vector8 *v, const uint8 *s); -#ifndef USE_NO_SIMD -static inline void vector32_load(Vector32 *v, const uint32 *s); -#endif - -/* assignment operations */ -static inline Vector8 vector8_broadcast(const uint8 c); -#ifndef USE_NO_SIMD -static inline Vector32 vector32_broadcast(const uint32 c); -#endif - -/* element-wise comparisons to a scalar */ -static inline bool vector8_has(const Vector8 v, const uint8 c); -static inline bool vector8_has_zero(const Vector8 v); -static inline bool vector8_has_le(const Vector8 v, const uint8 c); -static inline bool vector8_is_highbit_set(const Vector8 v); -#ifndef USE_NO_SIMD -static inline bool vector32_is_highbit_set(const Vector32 v); -#endif - -/* arithmetic operations */ -static inline Vector8 vector8_or(const Vector8 v1, const Vector8 v2); -#ifndef USE_NO_SIMD -static inline Vector32 vector32_or(const Vector32 v1, const Vector32 v2); -static inline Vector8 vector8_ssub(const Vector8 v1, const Vector8 v2); -#endif - -/* - * comparisons between vectors - * - * Note: These return a vector rather than boolean, which is why we don't - * have non-SIMD implementations. - */ -#ifndef USE_NO_SIMD -static inline Vector8 vector8_eq(const Vector8 v1, const Vector8 v2); -static inline Vector32 vector32_eq(const Vector32 v1, const Vector32 v2); -#endif - -/* - * Load a chunk of memory into the given vector. - */ -static inline void -vector8_load(Vector8 *v, const uint8 *s) -{ -#if defined(USE_SSE2) - *v = _mm_loadu_si128((const __m128i *) s); -#elif defined(USE_NEON) - *v = vld1q_u8(s); -#else - memcpy(v, s, sizeof(Vector8)); -#endif -} - -#ifndef USE_NO_SIMD -static inline void -vector32_load(Vector32 *v, const uint32 *s) -{ -#ifdef USE_SSE2 - *v = _mm_loadu_si128((const __m128i *) s); -#elif defined(USE_NEON) - *v = vld1q_u32(s); -#endif -} -#endif /* ! USE_NO_SIMD */ - -/* - * Create a vector with all elements set to the same value. - */ -static inline Vector8 -vector8_broadcast(const uint8 c) -{ -#if defined(USE_SSE2) - return _mm_set1_epi8(c); -#elif defined(USE_NEON) - return vdupq_n_u8(c); -#else - return ~UINT64CONST(0) / 0xFF * c; -#endif -} - -#ifndef USE_NO_SIMD -static inline Vector32 -vector32_broadcast(const uint32 c) -{ -#ifdef USE_SSE2 - return _mm_set1_epi32(c); -#elif defined(USE_NEON) - return vdupq_n_u32(c); -#endif -} -#endif /* ! USE_NO_SIMD */ - -/* - * Return true if any elements in the vector are equal to the given scalar. - */ -static inline bool -vector8_has(const Vector8 v, const uint8 c) -{ - bool result; - - /* pre-compute the result for assert checking */ -#ifdef USE_ASSERT_CHECKING - bool assert_result = false; - - for (Size i = 0; i < sizeof(Vector8); i++) - { - if (((const uint8 *) &v)[i] == c) - { - assert_result = true; - break; - } - } -#endif /* USE_ASSERT_CHECKING */ - -#if defined(USE_NO_SIMD) - /* any bytes in v equal to c will evaluate to zero via XOR */ - result = vector8_has_zero(v ^ vector8_broadcast(c)); -#else - result = vector8_is_highbit_set(vector8_eq(v, vector8_broadcast(c))); -#endif - - Assert(assert_result == result); - return result; -} - -/* - * Convenience function equivalent to vector8_has(v, 0) - */ -static inline bool -vector8_has_zero(const Vector8 v) -{ -#if defined(USE_NO_SIMD) - /* - * We cannot call vector8_has() here, because that would lead to a - * circular definition. - */ - return vector8_has_le(v, 0); -#else - return vector8_has(v, 0); -#endif -} - -/* - * Return true if any elements in the vector are less than or equal to the - * given scalar. - */ -static inline bool -vector8_has_le(const Vector8 v, const uint8 c) -{ - bool result = false; - - /* pre-compute the result for assert checking */ -#ifdef USE_ASSERT_CHECKING - bool assert_result = false; - - for (Size i = 0; i < sizeof(Vector8); i++) - { - if (((const uint8 *) &v)[i] <= c) - { - assert_result = true; - break; - } - } -#endif /* USE_ASSERT_CHECKING */ - -#if defined(USE_NO_SIMD) - - /* - * To find bytes <= c, we can use bitwise operations to find bytes < c+1, - * but it only works if c+1 <= 128 and if the highest bit in v is not set. - * Adapted from - * https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord - */ - if ((int64) v >= 0 && c < 0x80) - result = (v - vector8_broadcast(c + 1)) & ~v & vector8_broadcast(0x80); - else - { - /* one byte at a time */ - for (Size i = 0; i < sizeof(Vector8); i++) - { - if (((const uint8 *) &v)[i] <= c) - { - result = true; - break; - } - } - } -#else - - /* - * Use saturating subtraction to find bytes <= c, which will present as - * NUL bytes. This approach is a workaround for the lack of unsigned - * comparison instructions on some architectures. - */ - result = vector8_has_zero(vector8_ssub(v, vector8_broadcast(c))); -#endif - - Assert(assert_result == result); - return result; -} - -/* - * Return true if the high bit of any element is set - */ -static inline bool -vector8_is_highbit_set(const Vector8 v) -{ -#ifdef USE_SSE2 - return _mm_movemask_epi8(v) != 0; -#elif defined(USE_NEON) - return vmaxvq_u8(v) > 0x7F; -#else - return v & vector8_broadcast(0x80); -#endif -} - -/* - * Exactly like vector8_is_highbit_set except for the input type, so it - * looks at each byte separately. - * - * XXX x86 uses the same underlying type for 8-bit, 16-bit, and 32-bit - * integer elements, but Arm does not, hence the need for a separate - * function. We could instead adopt the behavior of Arm's vmaxvq_u32(), i.e. - * check each 32-bit element, but that would require an additional mask - * operation on x86. - */ -#ifndef USE_NO_SIMD -static inline bool -vector32_is_highbit_set(const Vector32 v) -{ -#if defined(USE_NEON) - return vector8_is_highbit_set((Vector8) v); -#else - return vector8_is_highbit_set(v); -#endif -} -#endif /* ! USE_NO_SIMD */ - -/* - * Return the bitwise OR of the inputs - */ -static inline Vector8 -vector8_or(const Vector8 v1, const Vector8 v2) -{ -#ifdef USE_SSE2 - return _mm_or_si128(v1, v2); -#elif defined(USE_NEON) - return vorrq_u8(v1, v2); -#else - return v1 | v2; -#endif -} - -#ifndef USE_NO_SIMD -static inline Vector32 -vector32_or(const Vector32 v1, const Vector32 v2) -{ -#ifdef USE_SSE2 - return _mm_or_si128(v1, v2); -#elif defined(USE_NEON) - return vorrq_u32(v1, v2); -#endif -} -#endif /* ! USE_NO_SIMD */ - -/* - * Return the result of subtracting the respective elements of the input - * vectors using saturation (i.e., if the operation would yield a value less - * than zero, zero is returned instead). For more information on saturation - * arithmetic, see https://en.wikipedia.org/wiki/Saturation_arithmetic - */ -#ifndef USE_NO_SIMD -static inline Vector8 -vector8_ssub(const Vector8 v1, const Vector8 v2) -{ -#ifdef USE_SSE2 - return _mm_subs_epu8(v1, v2); -#elif defined(USE_NEON) - return vqsubq_u8(v1, v2); -#endif -} -#endif /* ! USE_NO_SIMD */ - -/* - * Return a vector with all bits set in each lane where the corresponding - * lanes in the inputs are equal. - */ -#ifndef USE_NO_SIMD -static inline Vector8 -vector8_eq(const Vector8 v1, const Vector8 v2) -{ -#ifdef USE_SSE2 - return _mm_cmpeq_epi8(v1, v2); -#elif defined(USE_NEON) - return vceqq_u8(v1, v2); -#endif -} -#endif /* ! USE_NO_SIMD */ - -#ifndef USE_NO_SIMD -static inline Vector32 -vector32_eq(const Vector32 v1, const Vector32 v2) -{ -#ifdef USE_SSE2 - return _mm_cmpeq_epi32(v1, v2); -#elif defined(USE_NEON) - return vceqq_u32(v1, v2); -#endif -} -#endif /* ! USE_NO_SIMD */ - -#endif /* SIMD_H */ diff --git a/contrib/libs/libpq/src/include/port/win32.h b/contrib/libs/libpq/src/include/port/win32.h deleted file mode 100644 index 5867e5622f..0000000000 --- a/contrib/libs/libpq/src/include/port/win32.h +++ /dev/null @@ -1,60 +0,0 @@ -/* src/include/port/win32.h */ -#pragma once - -/* - * We always rely on the WIN32 macro being set by our build system, - * but _WIN32 is the compiler pre-defined macro. So make sure we define - * WIN32 whenever _WIN32 is set, to facilitate standalone building. - */ -#if defined(_WIN32) && !defined(WIN32) -#define WIN32 -#endif - -/* - * Make sure _WIN32_WINNT has the minimum required value. - * Leave a higher value in place. The minimum requirement is Windows 10. - */ -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif - -#define _WIN32_WINNT 0x0A00 - -/* - * We need to prevent <crtdefs.h> from defining a symbol conflicting with - * our errcode() function. Since it's likely to get included by standard - * system headers, pre-emptively include it now. - */ -#if defined(_MSC_VER) || defined(HAVE_CRTDEFS_H) -#define errcode __msvc_errcode -#include <crtdefs.h> -#undef errcode -#endif - -/* - * defines for dynamic linking on Win32 platform - */ - -/* - * Variables declared in the core backend and referenced by loadable - * modules need to be marked "dllimport" in the core build, but - * "dllexport" when the declaration is read in a loadable module. - * No special markings should be used when compiling frontend code. - */ -#ifndef FRONTEND -#ifdef BUILDING_DLL -#define PGDLLIMPORT __declspec (dllexport) -#else -#define PGDLLIMPORT __declspec (dllimport) -#endif -#endif - -/* - * Functions exported by a loadable module must be marked "dllexport". - * - * While mingw would otherwise fall back to - * __attribute__((visibility("default"))), that appears to only work as long - * as no symbols are declared with __declspec(dllexport). But we can end up - * with some, e.g. plpython's Py_Init. - */ -#define PGDLLEXPORT __declspec (dllexport) diff --git a/contrib/libs/libpq/src/include/port/win32/arpa/inet.h b/contrib/libs/libpq/src/include/port/win32/arpa/inet.h deleted file mode 100644 index ad1803179c..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/arpa/inet.h +++ /dev/null @@ -1,3 +0,0 @@ -/* src/include/port/win32/arpa/inet.h */ - -#include <sys/socket.h> diff --git a/contrib/libs/libpq/src/include/port/win32/netdb.h b/contrib/libs/libpq/src/include/port/win32/netdb.h deleted file mode 100644 index 9ed13e457b..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/netdb.h +++ /dev/null @@ -1,7 +0,0 @@ -/* src/include/port/win32/netdb.h */ -#ifndef WIN32_NETDB_H -#define WIN32_NETDB_H - -#include <ws2tcpip.h> - -#endif diff --git a/contrib/libs/libpq/src/include/port/win32/netinet/in.h b/contrib/libs/libpq/src/include/port/win32/netinet/in.h deleted file mode 100644 index a4e22f89f4..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/netinet/in.h +++ /dev/null @@ -1,3 +0,0 @@ -/* src/include/port/win32/netinet/in.h */ - -#include <sys/socket.h> diff --git a/contrib/libs/libpq/src/include/port/win32/netinet/tcp.h b/contrib/libs/libpq/src/include/port/win32/netinet/tcp.h deleted file mode 100644 index 1d377b6adc..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/netinet/tcp.h +++ /dev/null @@ -1,7 +0,0 @@ -/* src/include/port/win32/netinet/tcp.h */ -#ifndef WIN32_NETINET_TCP_H -#define WIN32_NETINET_TCP_H - -#include <sys/socket.h> - -#endif diff --git a/contrib/libs/libpq/src/include/port/win32/pwd.h b/contrib/libs/libpq/src/include/port/win32/pwd.h deleted file mode 100644 index b8c7178fc0..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/pwd.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * src/include/port/win32/pwd.h - */ diff --git a/contrib/libs/libpq/src/include/port/win32/sys/select.h b/contrib/libs/libpq/src/include/port/win32/sys/select.h deleted file mode 100644 index f8a877accd..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/sys/select.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * src/include/port/win32/sys/select.h - */ diff --git a/contrib/libs/libpq/src/include/port/win32/sys/socket.h b/contrib/libs/libpq/src/include/port/win32/sys/socket.h deleted file mode 100644 index 0c32c0f7b2..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/sys/socket.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * src/include/port/win32/sys/socket.h - */ -#ifndef WIN32_SYS_SOCKET_H -#define WIN32_SYS_SOCKET_H - -/* - * Unfortunately, <wingdi.h> of VC++ also defines ERROR. - * To avoid the conflict, we include <windows.h> here and undefine ERROR - * immediately. - * - * Note: Don't include <wingdi.h> directly. It causes compile errors. - */ -#include <winsock2.h> -#include <ws2tcpip.h> -#include <windows.h> - -#undef ERROR -#undef small - -/* Restore old ERROR value */ -#ifdef PGERROR -#define ERROR PGERROR -#endif - -#endif /* WIN32_SYS_SOCKET_H */ diff --git a/contrib/libs/libpq/src/include/port/win32/sys/un.h b/contrib/libs/libpq/src/include/port/win32/sys/un.h deleted file mode 100644 index 4fc13a23fd..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/sys/un.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * src/include/port/win32/sys/un.h - */ -#ifndef WIN32_SYS_UN_H -#define WIN32_SYS_UN_H - -/* - * Windows defines this structure in <afunix.h>, but not all tool chains have - * the header yet, so we define it here for now. - */ -struct sockaddr_un -{ - unsigned short sun_family; - char sun_path[108]; -}; - -#endif diff --git a/contrib/libs/libpq/src/include/port/win32/sys/wait.h b/contrib/libs/libpq/src/include/port/win32/sys/wait.h deleted file mode 100644 index eaeb5661c9..0000000000 --- a/contrib/libs/libpq/src/include/port/win32/sys/wait.h +++ /dev/null @@ -1,3 +0,0 @@ -/* - * src/include/port/win32/sys/wait.h - */ diff --git a/contrib/libs/libpq/src/include/port/win32_msvc/dirent.h b/contrib/libs/libpq/src/include/port/win32_msvc/dirent.h deleted file mode 100644 index 62799db001..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_msvc/dirent.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Headers for port/dirent.c, win32 native implementation of dirent functions - * - * src/include/port/win32_msvc/dirent.h - */ - -#ifndef _WIN32VC_DIRENT_H -#define _WIN32VC_DIRENT_H -struct dirent -{ - long d_ino; - unsigned short d_reclen; - unsigned char d_type; - unsigned short d_namlen; - char d_name[MAX_PATH]; -}; - -typedef struct DIR DIR; - -DIR *opendir(const char *); -struct dirent *readdir(DIR *); -int closedir(DIR *); - -/* File types for 'd_type'. */ -#define DT_UNKNOWN 0 -#define DT_FIFO 1 -#define DT_CHR 2 -#define DT_DIR 4 -#define DT_BLK 6 -#define DT_REG 8 -#define DT_LNK 10 -#define DT_SOCK 12 -#define DT_WHT 14 -#endif diff --git a/contrib/libs/libpq/src/include/port/win32_msvc/sys/file.h b/contrib/libs/libpq/src/include/port/win32_msvc/sys/file.h deleted file mode 100644 index 76be3e7774..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_msvc/sys/file.h +++ /dev/null @@ -1 +0,0 @@ -/* src/include/port/win32_msvc/sys/file.h */ diff --git a/contrib/libs/libpq/src/include/port/win32_msvc/sys/param.h b/contrib/libs/libpq/src/include/port/win32_msvc/sys/param.h deleted file mode 100644 index 160df3b25e..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_msvc/sys/param.h +++ /dev/null @@ -1 +0,0 @@ -/* src/include/port/win32_msvc/sys/param.h */ diff --git a/contrib/libs/libpq/src/include/port/win32_msvc/sys/time.h b/contrib/libs/libpq/src/include/port/win32_msvc/sys/time.h deleted file mode 100644 index 9d943ecc6f..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_msvc/sys/time.h +++ /dev/null @@ -1 +0,0 @@ -/* src/include/port/win32_msvc/sys/time.h */ diff --git a/contrib/libs/libpq/src/include/port/win32_msvc/unistd.h b/contrib/libs/libpq/src/include/port/win32_msvc/unistd.h deleted file mode 100644 index b7795ba03c..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_msvc/unistd.h +++ /dev/null @@ -1,9 +0,0 @@ -/* src/include/port/win32_msvc/unistd.h */ - -/* - * MSVC does not define these, nor does _fileno(stdin) etc reliably work - * (returns -1 if stdin/out/err are closed). - */ -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 diff --git a/contrib/libs/libpq/src/include/port/win32_port.h b/contrib/libs/libpq/src/include/port/win32_port.h deleted file mode 100644 index b957d5c598..0000000000 --- a/contrib/libs/libpq/src/include/port/win32_port.h +++ /dev/null @@ -1,594 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32_port.h - * Windows-specific compatibility stuff. - * - * Note this is read in MinGW as well as native Windows builds, - * but not in Cygwin builds. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port/win32_port.h - * - *------------------------------------------------------------------------- - */ -#ifndef PG_WIN32_PORT_H -#define PG_WIN32_PORT_H - -/* - * Always build with SSPI support. Keep it as a #define in case - * we want a switch to disable it sometime in the future. - */ -#define ENABLE_SSPI 1 - -/* undefine and redefine after #include */ -#undef mkdir - -#undef ERROR - -/* - * VS2013 and later issue warnings about using the old Winsock API, - * which we don't really want to hear about. - */ -#ifdef _MSC_VER -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#endif - -/* - * The MinGW64 headers choke if this is already defined - they - * define it themselves. - */ -#if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER) -#define _WINSOCKAPI_ -#endif - -/* - * windows.h includes a lot of other headers, slowing down compilation - * significantly. WIN32_LEAN_AND_MEAN reduces that a bit. It'd be better to - * remove the include of windows.h (as well as indirect inclusions of it) from - * such a central place, but until then... - * - * To be able to include ntstatus.h tell windows.h to not declare NTSTATUS by - * temporarily defining UMDF_USING_NTSTATUS, otherwise we'll get warning about - * macro redefinitions, as windows.h also defines NTSTATUS (yuck). That in - * turn requires including ntstatus.h, winternl.h to get common symbols. - */ -#define WIN32_LEAN_AND_MEAN -#define UMDF_USING_NTSTATUS - -#include <winsock2.h> -#include <ws2tcpip.h> -#include <windows.h> -#include <ntstatus.h> -#include <winternl.h> - -#undef small -#include <process.h> -#include <signal.h> -#include <direct.h> -#undef near - -/* needed before sys/stat hacking below: */ -#define fstat microsoft_native_fstat -#define stat microsoft_native_stat -#include <sys/stat.h> -#undef fstat -#undef stat - -/* Must be here to avoid conflicting with prototype in windows.h */ -#define mkdir(a,b) mkdir(a) - -#define ftruncate(a,b) chsize(a,b) - -/* Windows doesn't have fsync() as such, use _commit() */ -#define fsync(fd) _commit(fd) - -/* - * For historical reasons, we allow setting wal_sync_method to - * fsync_writethrough on Windows, even though it's really identical to fsync - * (both code paths wind up at _commit()). - */ -#define HAVE_FSYNC_WRITETHROUGH -#define FSYNC_WRITETHROUGH_IS_FSYNC - -#define USES_WINSOCK - -/* - * IPC defines - */ -#undef HAVE_UNION_SEMUN -#define HAVE_UNION_SEMUN 1 - -#define IPC_RMID 256 -#define IPC_CREAT 512 -#define IPC_EXCL 1024 -#define IPC_PRIVATE 234564 -#define IPC_NOWAIT 2048 -#define IPC_STAT 4096 - -#define EACCESS 2048 -#ifndef EIDRM -#define EIDRM 4096 -#endif - -#define SETALL 8192 -#define GETNCNT 16384 -#define GETVAL 65536 -#define SETVAL 131072 -#define GETPID 262144 - - -/* - * Signal stuff - * - * For WIN32, there is no wait() call so there are no wait() macros - * to interpret the return value of system(). Instead, system() - * return values < 0x100 are used for exit() termination, and higher - * values are used to indicate non-exit() termination, which is - * similar to a unix-style signal exit (think SIGSEGV == - * STATUS_ACCESS_VIOLATION). Return values are broken up into groups: - * - * https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values - * - * NT_SUCCESS 0 - 0x3FFFFFFF - * NT_INFORMATION 0x40000000 - 0x7FFFFFFF - * NT_WARNING 0x80000000 - 0xBFFFFFFF - * NT_ERROR 0xC0000000 - 0xFFFFFFFF - * - * Effectively, we don't care on the severity of the return value from - * system(), we just need to know if it was because of exit() or generated - * by the system, and it seems values >= 0x100 are system-generated. - * See this URL for a list of WIN32 STATUS_* values: - * - * Wine (URL used in our error messages) - - * http://source.winehq.org/source/include/ntstatus.h - * Descriptions - - * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 - * - * The comprehensive exception list is included in ntstatus.h from the - * Windows Driver Kit (WDK). A subset of the list is also included in - * winnt.h from the Windows SDK. Defining WIN32_NO_STATUS before including - * windows.h helps to avoid any conflicts. - * - * Some day we might want to print descriptions for the most common - * exceptions, rather than printing an include file name. We could use - * RtlNtStatusToDosError() and pass to FormatMessage(), which can print - * the text of error values, but MinGW does not support - * RtlNtStatusToDosError(). - */ -#define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) -#define WIFSIGNALED(w) (!WIFEXITED(w)) -#define WEXITSTATUS(w) (w) -#define WTERMSIG(w) (w) - -#define sigmask(sig) ( 1 << ((sig)-1) ) - -/* Signal function return values */ -#undef SIG_DFL -#undef SIG_ERR -#undef SIG_IGN -#define SIG_DFL ((pqsigfunc)0) -#define SIG_ERR ((pqsigfunc)-1) -#define SIG_IGN ((pqsigfunc)1) - -/* Some extra signals */ -#define SIGHUP 1 -#define SIGQUIT 3 -#define SIGTRAP 5 -#define SIGABRT 22 /* Set to match W32 value -- not UNIX value */ -#define SIGKILL 9 -#define SIGPIPE 13 -#define SIGALRM 14 -#define SIGSTOP 17 -#define SIGTSTP 18 -#define SIGCONT 19 -#define SIGCHLD 20 -#define SIGWINCH 28 -#define SIGUSR1 30 -#define SIGUSR2 31 - -/* MinGW has gettimeofday(), but MSVC doesn't */ -#ifdef _MSC_VER -/* Last parameter not used */ -extern int gettimeofday(struct timeval *tp, void *tzp); -#endif - -/* for setitimer in backend/port/win32/timer.c */ -#define ITIMER_REAL 0 -struct itimerval -{ - struct timeval it_interval; - struct timeval it_value; -}; - -int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); - -/* Convenience wrapper for GetFileType() */ -extern DWORD pgwin32_get_file_type(HANDLE hFile); - -/* - * WIN32 does not provide 64-bit off_t, but does provide the functions operating - * with 64-bit offsets. Also, fseek() might not give an error for unseekable - * streams, so harden that function with our version. - */ -#define pgoff_t __int64 - -#ifdef _MSC_VER -extern int _pgfseeko64(FILE *stream, pgoff_t offset, int origin); -extern pgoff_t _pgftello64(FILE *stream); -#define fseeko(stream, offset, origin) _pgfseeko64(stream, offset, origin) -#define ftello(stream) _pgftello64(stream) -#else -#ifndef fseeko -#define fseeko(stream, offset, origin) fseeko64(stream, offset, origin) -#endif -#ifndef ftello -#define ftello(stream) ftello64(stream) -#endif -#endif - -/* - * Win32 also doesn't have symlinks, but we can emulate them with - * junction points on newer Win32 versions. - * - * Cygwin has its own symlinks which work on Win95/98/ME where - * junction points don't, so use those instead. We have no way of - * knowing what type of system Cygwin binaries will be run on. - * Note: Some CYGWIN includes might #define WIN32. - */ -extern int pgsymlink(const char *oldpath, const char *newpath); -extern int pgreadlink(const char *path, char *buf, size_t size); - -#define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) -#define readlink(path, buf, size) pgreadlink(path, buf, size) - -/* - * Supplement to <sys/types.h>. - * - * Perl already has typedefs for uid_t and gid_t. - */ -#ifndef PLPERL_HAVE_UID_GID -typedef int uid_t; -typedef int gid_t; -#endif -typedef long key_t; - -#ifdef _MSC_VER -typedef int pid_t; -#endif - -/* - * Supplement to <sys/stat.h>. - * - * We must pull in sys/stat.h before this part, else our overrides lose. - * - * stat() is not guaranteed to set the st_size field on win32, so we - * redefine it to our own implementation. See src/port/win32stat.c. - * - * The struct stat is 32 bit in MSVC, so we redefine it as a copy of - * struct __stat64. This also fixes the struct size for MINGW builds. - */ -struct stat /* This should match struct __stat64 */ -{ - _dev_t st_dev; - _ino_t st_ino; - unsigned short st_mode; - short st_nlink; - short st_uid; - short st_gid; - _dev_t st_rdev; - __int64 st_size; - __time64_t st_atime; - __time64_t st_mtime; - __time64_t st_ctime; -}; - -extern int _pgfstat64(int fileno, struct stat *buf); -extern int _pgstat64(const char *name, struct stat *buf); -extern int _pglstat64(const char *name, struct stat *buf); - -#define fstat(fileno, sb) _pgfstat64(fileno, sb) -#define stat(path, sb) _pgstat64(path, sb) -#define lstat(path, sb) _pglstat64(path, sb) - -/* These macros are not provided by older MinGW, nor by MSVC */ -#ifndef S_IRUSR -#define S_IRUSR _S_IREAD -#endif -#ifndef S_IWUSR -#define S_IWUSR _S_IWRITE -#endif -#ifndef S_IXUSR -#define S_IXUSR _S_IEXEC -#endif -#ifndef S_IRWXU -#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) -#endif -#ifndef S_IRGRP -#define S_IRGRP 0 -#endif -#ifndef S_IWGRP -#define S_IWGRP 0 -#endif -#ifndef S_IXGRP -#define S_IXGRP 0 -#endif -#ifndef S_IRWXG -#define S_IRWXG 0 -#endif -#ifndef S_IROTH -#define S_IROTH 0 -#endif -#ifndef S_IWOTH -#define S_IWOTH 0 -#endif -#ifndef S_IXOTH -#define S_IXOTH 0 -#endif -#ifndef S_IRWXO -#define S_IRWXO 0 -#endif -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -/* - * In order for lstat() to be able to report junction points as symlinks, we - * need to hijack a bit in st_mode, since neither MSVC nor MinGW provides - * S_ISLNK and there aren't any spare bits. We'll steal the one for character - * devices, because we don't otherwise make use of those. - */ -#ifdef S_ISLNK -#error "S_ISLNK is already defined" -#endif -#ifdef S_IFLNK -#error "S_IFLNK is already defined" -#endif -#define S_IFLNK S_IFCHR -#define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK) - -/* - * Supplement to <fcntl.h>. - * This is the same value as _O_NOINHERIT in the MS header file. This is - * to ensure that we don't collide with a future definition. It means - * we cannot use _O_NOINHERIT ourselves. - */ -#define O_DSYNC 0x0080 - -/* - * Our open() replacement does not create inheritable handles, so it is safe to - * ignore O_CLOEXEC. (If we were using Windows' own open(), it might be - * necessary to convert this to _O_NOINHERIT.) - */ -#define O_CLOEXEC 0 - -/* - * Supplement to <errno.h>. - * - * We redefine network-related Berkeley error symbols as the corresponding WSA - * constants. This allows strerror.c to recognize them as being in the Winsock - * error code range and pass them off to win32_socket_strerror(), since - * Windows' version of plain strerror() won't cope. Note that this will break - * if these names are used for anything else besides Windows Sockets errors. - * See TranslateSocketError() when changing this list. - */ -#undef EAGAIN -#define EAGAIN WSAEWOULDBLOCK -#undef EINTR -#define EINTR WSAEINTR -#undef EMSGSIZE -#define EMSGSIZE WSAEMSGSIZE -#undef EAFNOSUPPORT -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#undef EWOULDBLOCK -#define EWOULDBLOCK WSAEWOULDBLOCK -#undef ECONNABORTED -#define ECONNABORTED WSAECONNABORTED -#undef ECONNRESET -#define ECONNRESET WSAECONNRESET -#undef EINPROGRESS -#define EINPROGRESS WSAEINPROGRESS -#undef EISCONN -#define EISCONN WSAEISCONN -#undef ENOBUFS -#define ENOBUFS WSAENOBUFS -#undef EPROTONOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#undef ECONNREFUSED -#define ECONNREFUSED WSAECONNREFUSED -#undef ENOTSOCK -#define ENOTSOCK WSAENOTSOCK -#undef EOPNOTSUPP -#define EOPNOTSUPP WSAEOPNOTSUPP -#undef EADDRINUSE -#define EADDRINUSE WSAEADDRINUSE -#undef EADDRNOTAVAIL -#define EADDRNOTAVAIL WSAEADDRNOTAVAIL -#undef EHOSTDOWN -#define EHOSTDOWN WSAEHOSTDOWN -#undef EHOSTUNREACH -#define EHOSTUNREACH WSAEHOSTUNREACH -#undef ENETDOWN -#define ENETDOWN WSAENETDOWN -#undef ENETRESET -#define ENETRESET WSAENETRESET -#undef ENETUNREACH -#define ENETUNREACH WSAENETUNREACH -#undef ENOTCONN -#define ENOTCONN WSAENOTCONN -#undef ETIMEDOUT -#define ETIMEDOUT WSAETIMEDOUT - -/* - * Locale stuff. - * - * Extended locale functions with gratuitous underscore prefixes. - * (These APIs are nevertheless fully documented by Microsoft.) - */ -#define locale_t _locale_t -#define tolower_l _tolower_l -#define toupper_l _toupper_l -#define towlower_l _towlower_l -#define towupper_l _towupper_l -#define isdigit_l _isdigit_l -#define iswdigit_l _iswdigit_l -#define isalpha_l _isalpha_l -#define iswalpha_l _iswalpha_l -#define isalnum_l _isalnum_l -#define iswalnum_l _iswalnum_l -#define isupper_l _isupper_l -#define iswupper_l _iswupper_l -#define islower_l _islower_l -#define iswlower_l _iswlower_l -#define isgraph_l _isgraph_l -#define iswgraph_l _iswgraph_l -#define isprint_l _isprint_l -#define iswprint_l _iswprint_l -#define ispunct_l _ispunct_l -#define iswpunct_l _iswpunct_l -#define isspace_l _isspace_l -#define iswspace_l _iswspace_l -#define strcoll_l _strcoll_l -#define strxfrm_l _strxfrm_l -#define wcscoll_l _wcscoll_l -#define wcstombs_l _wcstombs_l -#define mbstowcs_l _mbstowcs_l - -/* - * Versions of libintl >= 0.18? try to replace setlocale() with a macro - * to their own versions. Remove the macro, if it exists, because it - * ends up calling the wrong version when the backend and libintl use - * different versions of msvcrt. - */ -#if defined(setlocale) -#undef setlocale -#endif - -/* - * Define our own wrapper macro around setlocale() to work around bugs in - * Windows' native setlocale() function. - */ -extern char *pgwin32_setlocale(int category, const char *locale); - -#define setlocale(a,b) pgwin32_setlocale(a,b) - - -/* In backend/port/win32/signal.c */ -extern PGDLLIMPORT volatile int pg_signal_queue; -extern PGDLLIMPORT int pg_signal_mask; -extern PGDLLIMPORT HANDLE pgwin32_signal_event; -extern PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe; - -#define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask) -#define PG_SIGNAL_COUNT 32 - -extern void pgwin32_signal_initialize(void); -extern HANDLE pgwin32_create_signal_listener(pid_t pid); -extern void pgwin32_dispatch_queued_signals(void); -extern void pg_queue_signal(int signum); - -/* In src/port/kill.c */ -#define kill(pid,sig) pgkill(pid,sig) -extern int pgkill(int pid, int sig); - -/* In backend/port/win32/socket.c */ -#ifndef FRONTEND -#define socket(af, type, protocol) pgwin32_socket(af, type, protocol) -#define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen) -#define listen(s, backlog) pgwin32_listen(s, backlog) -#define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen) -#define connect(s, name, namelen) pgwin32_connect(s, name, namelen) -#define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout) -#define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags) -#define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags) - -extern SOCKET pgwin32_socket(int af, int type, int protocol); -extern int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen); -extern int pgwin32_listen(SOCKET s, int backlog); -extern SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen); -extern int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen); -extern int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout); -extern int pgwin32_recv(SOCKET s, char *buf, int len, int flags); -extern int pgwin32_send(SOCKET s, const void *buf, int len, int flags); -extern int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout); - -extern PGDLLIMPORT int pgwin32_noblock; - -#endif /* FRONTEND */ - -/* in backend/port/win32_shmem.c */ -extern int pgwin32_ReserveSharedMemoryRegion(HANDLE); - -/* in backend/port/win32/crashdump.c */ -extern void pgwin32_install_crashdump_handler(void); - -/* in port/win32dlopen.c */ -extern void *dlopen(const char *file, int mode); -extern void *dlsym(void *handle, const char *symbol); -extern int dlclose(void *handle); -extern char *dlerror(void); - -#define RTLD_NOW 1 -#define RTLD_GLOBAL 0 - -/* in port/win32error.c */ -extern void _dosmaperr(unsigned long); - -/* in port/win32env.c */ -extern int pgwin32_putenv(const char *); -extern int pgwin32_setenv(const char *name, const char *value, int overwrite); -extern int pgwin32_unsetenv(const char *name); - -#define putenv(x) pgwin32_putenv(x) -#define setenv(x,y,z) pgwin32_setenv(x,y,z) -#define unsetenv(x) pgwin32_unsetenv(x) - -/* in port/win32security.c */ -extern int pgwin32_is_service(void); -extern int pgwin32_is_admin(void); - -/* Windows security token manipulation (in src/common/exec.c) */ -extern BOOL AddUserToTokenDacl(HANDLE hToken); - -/* Things that exist in MinGW headers, but need to be added to MSVC */ -#ifdef _MSC_VER - -#ifndef _WIN64 -typedef long ssize_t; -#else -typedef __int64 ssize_t; -#endif - -typedef unsigned short mode_t; - -#define F_OK 0 -#define W_OK 2 -#define R_OK 4 - -#endif /* _MSC_VER */ - -#if defined(__MINGW32__) || defined(__MINGW64__) -/* - * Mingw claims to have a strtof, and my reading of its source code suggests - * that it ought to work (and not need this hack), but the regression test - * results disagree with me; whether this is a version issue or not is not - * clear. However, using our wrapper (and the misrounded-input variant file, - * already required for supporting ancient systems) can't make things any - * worse, except for a tiny performance loss when reading zeros. - * - * See also cygwin.h for another instance of this. - */ -#define HAVE_BUGGY_STRTOF 1 -#endif - -/* in port/win32pread.c */ -extern ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset); - -/* in port/win32pwrite.c */ -extern ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset); - -#endif /* PG_WIN32_PORT_H */ diff --git a/contrib/libs/libpq/src/include/port/win32ntdll.h b/contrib/libs/libpq/src/include/port/win32ntdll.h deleted file mode 100644 index 1ce9360ec1..0000000000 --- a/contrib/libs/libpq/src/include/port/win32ntdll.h +++ /dev/null @@ -1,34 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32ntdll.h - * Dynamically loaded Windows NT functions. - * - * Portions Copyright (c) 2021-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/port/win32ntdll.h - * - *------------------------------------------------------------------------- - */ - -#ifndef WIN32NTDLL_H -#define WIN32NTDLL_H - -#include <ntstatus.h> -#include <winternl.h> - -#ifndef FLUSH_FLAGS_FILE_DATA_SYNC_ONLY -#define FLUSH_FLAGS_FILE_DATA_SYNC_ONLY 0x4 -#endif - -typedef NTSTATUS (__stdcall * RtlGetLastNtStatus_t) (void); -typedef ULONG (__stdcall * RtlNtStatusToDosError_t) (NTSTATUS); -typedef NTSTATUS (__stdcall * NtFlushBuffersFileEx_t) (HANDLE, ULONG, PVOID, ULONG, PIO_STATUS_BLOCK); - -extern PGDLLIMPORT RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; -extern PGDLLIMPORT RtlNtStatusToDosError_t pg_RtlNtStatusToDosError; -extern PGDLLIMPORT NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx; - -extern int initialize_ntdll(void); - -#endif /* WIN32NTDLL_H */ diff --git a/contrib/libs/libpq/src/include/postgres.h b/contrib/libs/libpq/src/include/postgres.h deleted file mode 100644 index 8a028ff789..0000000000 --- a/contrib/libs/libpq/src/include/postgres.h +++ /dev/null @@ -1,579 +0,0 @@ -/*------------------------------------------------------------------------- - * - * postgres.h - * Primary include file for PostgreSQL server .c files - * - * This should be the first file included by PostgreSQL backend modules. - * Client-side code should include postgres_fe.h instead. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1995, Regents of the University of California - * - * src/include/postgres.h - * - *------------------------------------------------------------------------- - */ -/* - *---------------------------------------------------------------- - * TABLE OF CONTENTS - * - * When adding stuff to this file, please try to put stuff - * into the relevant section, or add new sections as appropriate. - * - * section description - * ------- ------------------------------------------------ - * 1) Datum type + support functions - * 2) miscellaneous - * - * NOTES - * - * In general, this file should contain declarations that are widely needed - * in the backend environment, but are of no interest outside the backend. - * - * Simple type definitions live in c.h, where they are shared with - * postgres_fe.h. We do that since those type definitions are needed by - * frontend modules that want to deal with binary data transmission to or - * from the backend. Type definitions in this file should be for - * representations that never escape the backend, such as Datum. - * - *---------------------------------------------------------------- - */ -#ifndef POSTGRES_H -#define POSTGRES_H - -#include "c.h" -#include "utils/elog.h" -#include "utils/palloc.h" - -/* ---------------------------------------------------------------- - * Section 1: Datum type + support functions - * ---------------------------------------------------------------- - */ - -/* - * A Datum contains either a value of a pass-by-value type or a pointer to a - * value of a pass-by-reference type. Therefore, we require: - * - * sizeof(Datum) == sizeof(void *) == 4 or 8 - * - * The functions below and the analogous functions for other types should be used to - * convert between a Datum and the appropriate C type. - */ - -typedef uintptr_t Datum; - -/* - * A NullableDatum is used in places where both a Datum and its nullness needs - * to be stored. This can be more efficient than storing datums and nullness - * in separate arrays, due to better spatial locality, even if more space may - * be wasted due to padding. - */ -typedef struct NullableDatum -{ -#define FIELDNO_NULLABLE_DATUM_DATUM 0 - Datum value; -#define FIELDNO_NULLABLE_DATUM_ISNULL 1 - bool isnull; - /* due to alignment padding this could be used for flags for free */ -} NullableDatum; - -#define SIZEOF_DATUM SIZEOF_VOID_P - -/* - * DatumGetBool - * Returns boolean value of a datum. - * - * Note: any nonzero value will be considered true. - */ -static inline bool -DatumGetBool(Datum X) -{ - return (X != 0); -} - -/* - * BoolGetDatum - * Returns datum representation for a boolean. - * - * Note: any nonzero value will be considered true. - */ -static inline Datum -BoolGetDatum(bool X) -{ - return (Datum) (X ? 1 : 0); -} - -/* - * DatumGetChar - * Returns character value of a datum. - */ -static inline char -DatumGetChar(Datum X) -{ - return (char) X; -} - -/* - * CharGetDatum - * Returns datum representation for a character. - */ -static inline Datum -CharGetDatum(char X) -{ - return (Datum) X; -} - -/* - * Int8GetDatum - * Returns datum representation for an 8-bit integer. - */ -static inline Datum -Int8GetDatum(int8 X) -{ - return (Datum) X; -} - -/* - * DatumGetUInt8 - * Returns 8-bit unsigned integer value of a datum. - */ -static inline uint8 -DatumGetUInt8(Datum X) -{ - return (uint8) X; -} - -/* - * UInt8GetDatum - * Returns datum representation for an 8-bit unsigned integer. - */ -static inline Datum -UInt8GetDatum(uint8 X) -{ - return (Datum) X; -} - -/* - * DatumGetInt16 - * Returns 16-bit integer value of a datum. - */ -static inline int16 -DatumGetInt16(Datum X) -{ - return (int16) X; -} - -/* - * Int16GetDatum - * Returns datum representation for a 16-bit integer. - */ -static inline Datum -Int16GetDatum(int16 X) -{ - return (Datum) X; -} - -/* - * DatumGetUInt16 - * Returns 16-bit unsigned integer value of a datum. - */ -static inline uint16 -DatumGetUInt16(Datum X) -{ - return (uint16) X; -} - -/* - * UInt16GetDatum - * Returns datum representation for a 16-bit unsigned integer. - */ -static inline Datum -UInt16GetDatum(uint16 X) -{ - return (Datum) X; -} - -/* - * DatumGetInt32 - * Returns 32-bit integer value of a datum. - */ -static inline int32 -DatumGetInt32(Datum X) -{ - return (int32) X; -} - -/* - * Int32GetDatum - * Returns datum representation for a 32-bit integer. - */ -static inline Datum -Int32GetDatum(int32 X) -{ - return (Datum) X; -} - -/* - * DatumGetUInt32 - * Returns 32-bit unsigned integer value of a datum. - */ -static inline uint32 -DatumGetUInt32(Datum X) -{ - return (uint32) X; -} - -/* - * UInt32GetDatum - * Returns datum representation for a 32-bit unsigned integer. - */ -static inline Datum -UInt32GetDatum(uint32 X) -{ - return (Datum) X; -} - -/* - * DatumGetObjectId - * Returns object identifier value of a datum. - */ -static inline Oid -DatumGetObjectId(Datum X) -{ - return (Oid) X; -} - -/* - * ObjectIdGetDatum - * Returns datum representation for an object identifier. - */ -static inline Datum -ObjectIdGetDatum(Oid X) -{ - return (Datum) X; -} - -/* - * DatumGetTransactionId - * Returns transaction identifier value of a datum. - */ -static inline TransactionId -DatumGetTransactionId(Datum X) -{ - return (TransactionId) X; -} - -/* - * TransactionIdGetDatum - * Returns datum representation for a transaction identifier. - */ -static inline Datum -TransactionIdGetDatum(TransactionId X) -{ - return (Datum) X; -} - -/* - * MultiXactIdGetDatum - * Returns datum representation for a multixact identifier. - */ -static inline Datum -MultiXactIdGetDatum(MultiXactId X) -{ - return (Datum) X; -} - -/* - * DatumGetCommandId - * Returns command identifier value of a datum. - */ -static inline CommandId -DatumGetCommandId(Datum X) -{ - return (CommandId) X; -} - -/* - * CommandIdGetDatum - * Returns datum representation for a command identifier. - */ -static inline Datum -CommandIdGetDatum(CommandId X) -{ - return (Datum) X; -} - -/* - * DatumGetPointer - * Returns pointer value of a datum. - */ -static inline Pointer -DatumGetPointer(Datum X) -{ - return (Pointer) X; -} - -/* - * PointerGetDatum - * Returns datum representation for a pointer. - */ -static inline Datum -PointerGetDatum(const void *X) -{ - return (Datum) X; -} - -/* - * DatumGetCString - * Returns C string (null-terminated string) value of a datum. - * - * Note: C string is not a full-fledged Postgres type at present, - * but type input functions use this conversion for their inputs. - */ -static inline char * -DatumGetCString(Datum X) -{ - return (char *) DatumGetPointer(X); -} - -/* - * CStringGetDatum - * Returns datum representation for a C string (null-terminated string). - * - * Note: C string is not a full-fledged Postgres type at present, - * but type output functions use this conversion for their outputs. - * Note: CString is pass-by-reference; caller must ensure the pointed-to - * value has adequate lifetime. - */ -static inline Datum -CStringGetDatum(const char *X) -{ - return PointerGetDatum(X); -} - -/* - * DatumGetName - * Returns name value of a datum. - */ -static inline Name -DatumGetName(Datum X) -{ - return (Name) DatumGetPointer(X); -} - -/* - * NameGetDatum - * Returns datum representation for a name. - * - * Note: Name is pass-by-reference; caller must ensure the pointed-to - * value has adequate lifetime. - */ -static inline Datum -NameGetDatum(const NameData *X) -{ - return CStringGetDatum(NameStr(*X)); -} - -/* - * DatumGetInt64 - * Returns 64-bit integer value of a datum. - * - * Note: this function hides whether int64 is pass by value or by reference. - */ -static inline int64 -DatumGetInt64(Datum X) -{ -#ifdef USE_FLOAT8_BYVAL - return (int64) X; -#else - return *((int64 *) DatumGetPointer(X)); -#endif -} - -/* - * Int64GetDatum - * Returns datum representation for a 64-bit integer. - * - * Note: if int64 is pass by reference, this function returns a reference - * to palloc'd space. - */ -#ifdef USE_FLOAT8_BYVAL -static inline Datum -Int64GetDatum(int64 X) -{ - return (Datum) X; -} -#else -extern Datum Int64GetDatum(int64 X); -#endif - - -/* - * DatumGetUInt64 - * Returns 64-bit unsigned integer value of a datum. - * - * Note: this function hides whether int64 is pass by value or by reference. - */ -static inline uint64 -DatumGetUInt64(Datum X) -{ -#ifdef USE_FLOAT8_BYVAL - return (uint64) X; -#else - return *((uint64 *) DatumGetPointer(X)); -#endif -} - -/* - * UInt64GetDatum - * Returns datum representation for a 64-bit unsigned integer. - * - * Note: if int64 is pass by reference, this function returns a reference - * to palloc'd space. - */ -static inline Datum -UInt64GetDatum(uint64 X) -{ -#ifdef USE_FLOAT8_BYVAL - return (Datum) X; -#else - return Int64GetDatum((int64) X); -#endif -} - -/* - * Float <-> Datum conversions - * - * These have to be implemented as inline functions rather than macros, when - * passing by value, because many machines pass int and float function - * parameters/results differently; so we need to play weird games with unions. - */ - -/* - * DatumGetFloat4 - * Returns 4-byte floating point value of a datum. - */ -static inline float4 -DatumGetFloat4(Datum X) -{ - union - { - int32 value; - float4 retval; - } myunion; - - myunion.value = DatumGetInt32(X); - return myunion.retval; -} - -/* - * Float4GetDatum - * Returns datum representation for a 4-byte floating point number. - */ -static inline Datum -Float4GetDatum(float4 X) -{ - union - { - float4 value; - int32 retval; - } myunion; - - myunion.value = X; - return Int32GetDatum(myunion.retval); -} - -/* - * DatumGetFloat8 - * Returns 8-byte floating point value of a datum. - * - * Note: this function hides whether float8 is pass by value or by reference. - */ -static inline float8 -DatumGetFloat8(Datum X) -{ -#ifdef USE_FLOAT8_BYVAL - union - { - int64 value; - float8 retval; - } myunion; - - myunion.value = DatumGetInt64(X); - return myunion.retval; -#else - return *((float8 *) DatumGetPointer(X)); -#endif -} - -/* - * Float8GetDatum - * Returns datum representation for an 8-byte floating point number. - * - * Note: if float8 is pass by reference, this function returns a reference - * to palloc'd space. - */ -#ifdef USE_FLOAT8_BYVAL -static inline Datum -Float8GetDatum(float8 X) -{ - union - { - float8 value; - int64 retval; - } myunion; - - myunion.value = X; - return Int64GetDatum(myunion.retval); -} -#else -extern Datum Float8GetDatum(float8 X); -#endif - - -/* - * Int64GetDatumFast - * Float8GetDatumFast - * - * These macros are intended to allow writing code that does not depend on - * whether int64 and float8 are pass-by-reference types, while not - * sacrificing performance when they are. The argument must be a variable - * that will exist and have the same value for as long as the Datum is needed. - * In the pass-by-ref case, the address of the variable is taken to use as - * the Datum. In the pass-by-val case, these are the same as the non-Fast - * functions, except for asserting that the variable is of the correct type. - */ - -#ifdef USE_FLOAT8_BYVAL -#define Int64GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, int64), Int64GetDatum(X)) -#define Float8GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, double), Float8GetDatum(X)) -#else -#define Int64GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, int64), PointerGetDatum(&(X))) -#define Float8GetDatumFast(X) \ - (AssertVariableIsOfTypeMacro(X, double), PointerGetDatum(&(X))) -#endif - - -/* ---------------------------------------------------------------- - * Section 2: miscellaneous - * ---------------------------------------------------------------- - */ - -/* - * NON_EXEC_STATIC: It's sometimes useful to define a variable or function - * that is normally static but extern when using EXEC_BACKEND (see - * pg_config_manual.h). There would then typically be some code in - * postmaster.c that uses those extern symbols to transfer state between - * processes or do whatever other things it needs to do in EXEC_BACKEND mode. - */ -#ifdef EXEC_BACKEND -#define NON_EXEC_STATIC -#else -#define NON_EXEC_STATIC static -#endif - -#endif /* POSTGRES_H */ diff --git a/contrib/libs/libpq/src/include/postgres_ext.h b/contrib/libs/libpq/src/include/postgres_ext.h deleted file mode 100644 index 240ad4e93b..0000000000 --- a/contrib/libs/libpq/src/include/postgres_ext.h +++ /dev/null @@ -1,73 +0,0 @@ -/*------------------------------------------------------------------------- - * - * postgres_ext.h - * - * This file contains declarations of things that are visible everywhere - * in PostgreSQL *and* are visible to clients of frontend interface libraries. - * For example, the Oid type is part of the API of libpq and other libraries. - * - * Declarations which are specific to a particular interface should - * go in the header file for that interface (such as libpq-fe.h). This - * file is only for fundamental Postgres declarations. - * - * User-written C functions don't count as "external to Postgres." - * Those function much as local modifications to the backend itself, and - * use header files that are otherwise internal to Postgres to interface - * with the backend. - * - * src/include/postgres_ext.h - * - *------------------------------------------------------------------------- - */ - -#ifndef POSTGRES_EXT_H -#define POSTGRES_EXT_H - -#include "pg_config_ext.h" - -/* - * Object ID is a fundamental type in Postgres. - */ -typedef unsigned int Oid; - -#ifdef __cplusplus -#define InvalidOid (Oid(0)) -#else -#define InvalidOid ((Oid) 0) -#endif - -#define OID_MAX UINT_MAX -/* you will need to include <limits.h> to use the above #define */ - -#define atooid(x) ((Oid) strtoul((x), NULL, 10)) -/* the above needs <stdlib.h> */ - - -/* Define a signed 64-bit integer type for use in client API declarations. */ -typedef PG_INT64_TYPE pg_int64; - -/* - * Identifiers of error message fields. Kept here to keep common - * between frontend and backend, and also to export them to libpq - * applications. - */ -#define PG_DIAG_SEVERITY 'S' -#define PG_DIAG_SEVERITY_NONLOCALIZED 'V' -#define PG_DIAG_SQLSTATE 'C' -#define PG_DIAG_MESSAGE_PRIMARY 'M' -#define PG_DIAG_MESSAGE_DETAIL 'D' -#define PG_DIAG_MESSAGE_HINT 'H' -#define PG_DIAG_STATEMENT_POSITION 'P' -#define PG_DIAG_INTERNAL_POSITION 'p' -#define PG_DIAG_INTERNAL_QUERY 'q' -#define PG_DIAG_CONTEXT 'W' -#define PG_DIAG_SCHEMA_NAME 's' -#define PG_DIAG_TABLE_NAME 't' -#define PG_DIAG_COLUMN_NAME 'c' -#define PG_DIAG_DATATYPE_NAME 'd' -#define PG_DIAG_CONSTRAINT_NAME 'n' -#define PG_DIAG_SOURCE_FILE 'F' -#define PG_DIAG_SOURCE_LINE 'L' -#define PG_DIAG_SOURCE_FUNCTION 'R' - -#endif /* POSTGRES_EXT_H */ diff --git a/contrib/libs/libpq/src/include/postgres_fe.h b/contrib/libs/libpq/src/include/postgres_fe.h deleted file mode 100644 index 5bc71dd0b3..0000000000 --- a/contrib/libs/libpq/src/include/postgres_fe.h +++ /dev/null @@ -1,29 +0,0 @@ -/*------------------------------------------------------------------------- - * - * postgres_fe.h - * Primary include file for PostgreSQL client-side .c files - * - * This should be the first file included by PostgreSQL client libraries and - * application programs --- but not by backend modules, which should include - * postgres.h. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1995, Regents of the University of California - * - * src/include/postgres_fe.h - * - *------------------------------------------------------------------------- - */ -#ifndef POSTGRES_FE_H -#define POSTGRES_FE_H - -#ifndef FRONTEND -#define FRONTEND 1 -#endif - -#include "c.h" - -#include "common/fe_memutils.h" - -#endif /* POSTGRES_FE_H */ diff --git a/contrib/libs/libpq/src/include/storage/backendid.h b/contrib/libs/libpq/src/include/storage/backendid.h deleted file mode 100644 index 1e90b602f0..0000000000 --- a/contrib/libs/libpq/src/include/storage/backendid.h +++ /dev/null @@ -1,37 +0,0 @@ -/*------------------------------------------------------------------------- - * - * backendid.h - * POSTGRES backend id communication definitions - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/storage/backendid.h - * - *------------------------------------------------------------------------- - */ -#ifndef BACKENDID_H -#define BACKENDID_H - -/* ---------------- - * -cim 8/17/90 - * ---------------- - */ -typedef int BackendId; /* unique currently active backend identifier */ - -#define InvalidBackendId (-1) - -extern PGDLLIMPORT BackendId MyBackendId; /* backend id of this backend */ - -/* backend id of our parallel session leader, or InvalidBackendId if none */ -extern PGDLLIMPORT BackendId ParallelLeaderBackendId; - -/* - * The BackendId to use for our session's temp relations is normally our own, - * but parallel workers should use their leader's ID. - */ -#define BackendIdForTempRelations() \ - (ParallelLeaderBackendId == InvalidBackendId ? MyBackendId : ParallelLeaderBackendId) - -#endif /* BACKENDID_H */ diff --git a/contrib/libs/libpq/src/include/storage/block.h b/contrib/libs/libpq/src/include/storage/block.h deleted file mode 100644 index 31a036df0d..0000000000 --- a/contrib/libs/libpq/src/include/storage/block.h +++ /dev/null @@ -1,108 +0,0 @@ -/*------------------------------------------------------------------------- - * - * block.h - * POSTGRES disk block definitions. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/storage/block.h - * - *------------------------------------------------------------------------- - */ -#ifndef BLOCK_H -#define BLOCK_H - -/* - * BlockNumber: - * - * each data file (heap or index) is divided into postgres disk blocks - * (which may be thought of as the unit of i/o -- a postgres buffer - * contains exactly one disk block). the blocks are numbered - * sequentially, 0 to 0xFFFFFFFE. - * - * InvalidBlockNumber is the same thing as P_NEW in bufmgr.h. - * - * the access methods, the buffer manager and the storage manager are - * more or less the only pieces of code that should be accessing disk - * blocks directly. - */ -typedef uint32 BlockNumber; - -#define InvalidBlockNumber ((BlockNumber) 0xFFFFFFFF) - -#define MaxBlockNumber ((BlockNumber) 0xFFFFFFFE) - -/* - * BlockId: - * - * this is a storage type for BlockNumber. in other words, this type - * is used for on-disk structures (e.g., in HeapTupleData) whereas - * BlockNumber is the type on which calculations are performed (e.g., - * in access method code). - * - * there doesn't appear to be any reason to have separate types except - * for the fact that BlockIds can be SHORTALIGN'd (and therefore any - * structures that contains them, such as ItemPointerData, can also be - * SHORTALIGN'd). this is an important consideration for reducing the - * space requirements of the line pointer (ItemIdData) array on each - * page and the header of each heap or index tuple, so it doesn't seem - * wise to change this without good reason. - */ -typedef struct BlockIdData -{ - uint16 bi_hi; - uint16 bi_lo; -} BlockIdData; - -typedef BlockIdData *BlockId; /* block identifier */ - -/* ---------------- - * support functions - * ---------------- - */ - -/* - * BlockNumberIsValid - * True iff blockNumber is valid. - */ -static inline bool -BlockNumberIsValid(BlockNumber blockNumber) -{ - return blockNumber != InvalidBlockNumber; -} - -/* - * BlockIdSet - * Sets a block identifier to the specified value. - */ -static inline void -BlockIdSet(BlockIdData *blockId, BlockNumber blockNumber) -{ - blockId->bi_hi = blockNumber >> 16; - blockId->bi_lo = blockNumber & 0xffff; -} - -/* - * BlockIdEquals - * Check for block number equality. - */ -static inline bool -BlockIdEquals(const BlockIdData *blockId1, const BlockIdData *blockId2) -{ - return (blockId1->bi_hi == blockId2->bi_hi && - blockId1->bi_lo == blockId2->bi_lo); -} - -/* - * BlockIdGetBlockNumber - * Retrieve the block number from a block identifier. - */ -static inline BlockNumber -BlockIdGetBlockNumber(const BlockIdData *blockId) -{ - return (((BlockNumber) blockId->bi_hi) << 16) | ((BlockNumber) blockId->bi_lo); -} - -#endif /* BLOCK_H */ diff --git a/contrib/libs/libpq/src/include/storage/buf.h b/contrib/libs/libpq/src/include/storage/buf.h deleted file mode 100644 index 6520d9ae1e..0000000000 --- a/contrib/libs/libpq/src/include/storage/buf.h +++ /dev/null @@ -1,46 +0,0 @@ -/*------------------------------------------------------------------------- - * - * buf.h - * Basic buffer manager data types. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/storage/buf.h - * - *------------------------------------------------------------------------- - */ -#ifndef BUF_H -#define BUF_H - -/* - * Buffer identifiers. - * - * Zero is invalid, positive is the index of a shared buffer (1..NBuffers), - * negative is the index of a local buffer (-1 .. -NLocBuffer). - */ -typedef int Buffer; - -#define InvalidBuffer 0 - -/* - * BufferIsInvalid - * True iff the buffer is invalid. - */ -#define BufferIsInvalid(buffer) ((buffer) == InvalidBuffer) - -/* - * BufferIsLocal - * True iff the buffer is local (not visible to other backends). - */ -#define BufferIsLocal(buffer) ((buffer) < 0) - -/* - * Buffer access strategy objects. - * - * BufferAccessStrategyData is private to freelist.c - */ -typedef struct BufferAccessStrategyData *BufferAccessStrategy; - -#endif /* BUF_H */ diff --git a/contrib/libs/libpq/src/include/storage/relfilelocator.h b/contrib/libs/libpq/src/include/storage/relfilelocator.h deleted file mode 100644 index 61cf0169bd..0000000000 --- a/contrib/libs/libpq/src/include/storage/relfilelocator.h +++ /dev/null @@ -1,99 +0,0 @@ -/*------------------------------------------------------------------------- - * - * relfilelocator.h - * Physical access information for relations. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/storage/relfilelocator.h - * - *------------------------------------------------------------------------- - */ -#ifndef RELFILELOCATOR_H -#define RELFILELOCATOR_H - -#include "common/relpath.h" -#include "storage/backendid.h" - -/* - * RelFileLocator must provide all that we need to know to physically access - * a relation, with the exception of the backend ID, which can be provided - * separately. Note, however, that a "physical" relation is comprised of - * multiple files on the filesystem, as each fork is stored as a separate - * file, and each fork can be divided into multiple segments. See md.c. - * - * spcOid identifies the tablespace of the relation. It corresponds to - * pg_tablespace.oid. - * - * dbOid identifies the database of the relation. It is zero for - * "shared" relations (those common to all databases of a cluster). - * Nonzero dbOid values correspond to pg_database.oid. - * - * relNumber identifies the specific relation. relNumber corresponds to - * pg_class.relfilenode (NOT pg_class.oid, because we need to be able - * to assign new physical files to relations in some situations). - * Notice that relNumber is only unique within a database in a particular - * tablespace. - * - * Note: spcOid must be GLOBALTABLESPACE_OID if and only if dbOid is - * zero. We support shared relations only in the "global" tablespace. - * - * Note: in pg_class we allow reltablespace == 0 to denote that the - * relation is stored in its database's "default" tablespace (as - * identified by pg_database.dattablespace). However this shorthand - * is NOT allowed in RelFileLocator structs --- the real tablespace ID - * must be supplied when setting spcOid. - * - * Note: in pg_class, relfilenode can be zero to denote that the relation - * is a "mapped" relation, whose current true filenode number is available - * from relmapper.c. Again, this case is NOT allowed in RelFileLocators. - * - * Note: various places use RelFileLocator in hashtable keys. Therefore, - * there *must not* be any unused padding bytes in this struct. That - * should be safe as long as all the fields are of type Oid. - */ -typedef struct RelFileLocator -{ - Oid spcOid; /* tablespace */ - Oid dbOid; /* database */ - RelFileNumber relNumber; /* relation */ -} RelFileLocator; - -/* - * Augmenting a relfilelocator with the backend ID provides all the information - * we need to locate the physical storage. The backend ID is InvalidBackendId - * for regular relations (those accessible to more than one backend), or the - * owning backend's ID for backend-local relations. Backend-local relations - * are always transient and removed in case of a database crash; they are - * never WAL-logged or fsync'd. - */ -typedef struct RelFileLocatorBackend -{ - RelFileLocator locator; - BackendId backend; -} RelFileLocatorBackend; - -#define RelFileLocatorBackendIsTemp(rlocator) \ - ((rlocator).backend != InvalidBackendId) - -/* - * Note: RelFileLocatorEquals and RelFileLocatorBackendEquals compare relNumber - * first since that is most likely to be different in two unequal - * RelFileLocators. It is probably redundant to compare spcOid if the other - * fields are found equal, but do it anyway to be sure. Likewise for checking - * the backend ID in RelFileLocatorBackendEquals. - */ -#define RelFileLocatorEquals(locator1, locator2) \ - ((locator1).relNumber == (locator2).relNumber && \ - (locator1).dbOid == (locator2).dbOid && \ - (locator1).spcOid == (locator2).spcOid) - -#define RelFileLocatorBackendEquals(locator1, locator2) \ - ((locator1).locator.relNumber == (locator2).locator.relNumber && \ - (locator1).locator.dbOid == (locator2).locator.dbOid && \ - (locator1).backend == (locator2).backend && \ - (locator1).locator.spcOid == (locator2).locator.spcOid) - -#endif /* RELFILELOCATOR_H */ diff --git a/contrib/libs/libpq/src/include/utils/ascii.h b/contrib/libs/libpq/src/include/utils/ascii.h deleted file mode 100644 index 7df024dad3..0000000000 --- a/contrib/libs/libpq/src/include/utils/ascii.h +++ /dev/null @@ -1,84 +0,0 @@ -/*----------------------------------------------------------------------- - * ascii.h - * - * Portions Copyright (c) 1999-2023, PostgreSQL Global Development Group - * - * src/include/utils/ascii.h - * - *----------------------------------------------------------------------- - */ - -#ifndef _ASCII_H_ -#define _ASCII_H_ - -#include "port/simd.h" - -extern void ascii_safe_strlcpy(char *dest, const char *src, size_t destsiz); - -/* - * Verify a chunk of bytes for valid ASCII. - * - * Returns false if the input contains any zero bytes or bytes with the - * high-bit set. Input len must be a multiple of the chunk size (8 or 16). - */ -static inline bool -is_valid_ascii(const unsigned char *s, int len) -{ - const unsigned char *const s_end = s + len; - Vector8 chunk; - Vector8 highbit_cum = vector8_broadcast(0); -#ifdef USE_NO_SIMD - Vector8 zero_cum = vector8_broadcast(0x80); -#endif - - Assert(len % sizeof(chunk) == 0); - - while (s < s_end) - { - vector8_load(&chunk, s); - - /* Capture any zero bytes in this chunk. */ -#ifdef USE_NO_SIMD - - /* - * First, add 0x7f to each byte. This sets the high bit in each byte, - * unless it was a zero. If any resulting high bits are zero, the - * corresponding high bits in the zero accumulator will be cleared. - * - * If none of the bytes in the chunk had the high bit set, the max - * value each byte can have after the addition is 0x7f + 0x7f = 0xfe, - * and we don't need to worry about carrying over to the next byte. If - * any input bytes did have the high bit set, it doesn't matter - * because we check for those separately. - */ - zero_cum &= (chunk + vector8_broadcast(0x7F)); -#else - - /* - * Set all bits in each lane of the highbit accumulator where input - * bytes are zero. - */ - highbit_cum = vector8_or(highbit_cum, - vector8_eq(chunk, vector8_broadcast(0))); -#endif - - /* Capture all set bits in this chunk. */ - highbit_cum = vector8_or(highbit_cum, chunk); - - s += sizeof(chunk); - } - - /* Check if any high bits in the high bit accumulator got set. */ - if (vector8_is_highbit_set(highbit_cum)) - return false; - -#ifdef USE_NO_SIMD - /* Check if any high bits in the zero accumulator got cleared. */ - if (zero_cum != vector8_broadcast(0x80)) - return false; -#endif - - return true; -} - -#endif /* _ASCII_H_ */ diff --git a/contrib/libs/libpq/src/include/utils/elog.h b/contrib/libs/libpq/src/include/utils/elog.h deleted file mode 100644 index 0292e88b4f..0000000000 --- a/contrib/libs/libpq/src/include/utils/elog.h +++ /dev/null @@ -1,545 +0,0 @@ -/*------------------------------------------------------------------------- - * - * elog.h - * POSTGRES error reporting/logging definitions. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/elog.h - * - *------------------------------------------------------------------------- - */ -#ifndef ELOG_H -#define ELOG_H - -#include <setjmp.h> - -#include "lib/stringinfo.h" - -/* We cannot include nodes.h yet, so forward-declare struct Node */ -struct Node; - - -/* Error level codes */ -#define DEBUG5 10 /* Debugging messages, in categories of - * decreasing detail. */ -#define DEBUG4 11 -#define DEBUG3 12 -#define DEBUG2 13 -#define DEBUG1 14 /* used by GUC debug_* variables */ -#define LOG 15 /* Server operational messages; sent only to - * server log by default. */ -#define LOG_SERVER_ONLY 16 /* Same as LOG for server reporting, but never - * sent to client. */ -#define COMMERROR LOG_SERVER_ONLY /* Client communication problems; same as - * LOG for server reporting, but never - * sent to client. */ -#define INFO 17 /* Messages specifically requested by user (eg - * VACUUM VERBOSE output); always sent to - * client regardless of client_min_messages, - * but by default not sent to server log. */ -#define NOTICE 18 /* Helpful messages to users about query - * operation; sent to client and not to server - * log by default. */ -#define WARNING 19 /* Warnings. NOTICE is for expected messages - * like implicit sequence creation by SERIAL. - * WARNING is for unexpected messages. */ -#define PGWARNING 19 /* Must equal WARNING; see NOTE below. */ -#define WARNING_CLIENT_ONLY 20 /* Warnings to be sent to client as usual, but - * never to the server log. */ -#define ERROR 21 /* user error - abort transaction; return to - * known state */ -#define PGERROR 21 /* Must equal ERROR; see NOTE below. */ -#define FATAL 22 /* fatal error - abort process */ -#define PANIC 23 /* take down the other backends with me */ - -/* - * NOTE: the alternate names PGWARNING and PGERROR are useful for dealing - * with third-party headers that make other definitions of WARNING and/or - * ERROR. One can, for example, re-define ERROR as PGERROR after including - * such a header. - */ - - -/* macros for representing SQLSTATE strings compactly */ -#define PGSIXBIT(ch) (((ch) - '0') & 0x3F) -#define PGUNSIXBIT(val) (((val) & 0x3F) + '0') - -#define MAKE_SQLSTATE(ch1,ch2,ch3,ch4,ch5) \ - (PGSIXBIT(ch1) + (PGSIXBIT(ch2) << 6) + (PGSIXBIT(ch3) << 12) + \ - (PGSIXBIT(ch4) << 18) + (PGSIXBIT(ch5) << 24)) - -/* These macros depend on the fact that '0' becomes a zero in PGSIXBIT */ -#define ERRCODE_TO_CATEGORY(ec) ((ec) & ((1 << 12) - 1)) -#define ERRCODE_IS_CATEGORY(ec) (((ec) & ~((1 << 12) - 1)) == 0) - -/* SQLSTATE codes for errors are defined in a separate file */ -#include "utils/errcodes.h" - -/* - * Provide a way to prevent "errno" from being accidentally used inside an - * elog() or ereport() invocation. Since we know that some operating systems - * define errno as something involving a function call, we'll put a local - * variable of the same name as that function in the local scope to force a - * compile error. On platforms that don't define errno in that way, nothing - * happens, so we get no warning ... but we can live with that as long as it - * happens on some popular platforms. - */ -#if defined(errno) && defined(__linux__) -#define pg_prevent_errno_in_scope() int __errno_location pg_attribute_unused() -#elif defined(errno) && (defined(__darwin__) || defined(__FreeBSD__)) -#define pg_prevent_errno_in_scope() int __error pg_attribute_unused() -#else -#define pg_prevent_errno_in_scope() -#endif - - -/*---------- - * New-style error reporting API: to be used in this way: - * ereport(ERROR, - * errcode(ERRCODE_UNDEFINED_CURSOR), - * errmsg("portal \"%s\" not found", stmt->portalname), - * ... other errxxx() fields as needed ...); - * - * The error level is required, and so is a primary error message (errmsg - * or errmsg_internal). All else is optional. errcode() defaults to - * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING - * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is - * NOTICE or below. - * - * Before Postgres v12, extra parentheses were required around the - * list of auxiliary function calls; that's now optional. - * - * ereport_domain() allows a message domain to be specified, for modules that - * wish to use a different message catalog from the backend's. To avoid having - * one copy of the default text domain per .o file, we define it as NULL here - * and have errstart insert the default text domain. Modules can either use - * ereport_domain() directly, or preferably they can override the TEXTDOMAIN - * macro. - * - * When __builtin_constant_p is available and elevel >= ERROR we make a call - * to errstart_cold() instead of errstart(). This version of the function is - * marked with pg_attribute_cold which will coax supporting compilers into - * generating code which is more optimized towards non-ERROR cases. Because - * we use __builtin_constant_p() in the condition, when elevel is not a - * compile-time constant, or if it is, but it's < ERROR, the compiler has no - * need to generate any code for this branch. It can simply call errstart() - * unconditionally. - * - * If elevel >= ERROR, the call will not return; we try to inform the compiler - * of that via pg_unreachable(). However, no useful optimization effect is - * obtained unless the compiler sees elevel as a compile-time constant, else - * we're just adding code bloat. So, if __builtin_constant_p is available, - * use that to cause the second if() to vanish completely for non-constant - * cases. We avoid using a local variable because it's not necessary and - * prevents gcc from making the unreachability deduction at optlevel -O0. - *---------- - */ -#ifdef HAVE__BUILTIN_CONSTANT_P -#define ereport_domain(elevel, domain, ...) \ - do { \ - pg_prevent_errno_in_scope(); \ - if (__builtin_constant_p(elevel) && (elevel) >= ERROR ? \ - errstart_cold(elevel, domain) : \ - errstart(elevel, domain)) \ - __VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \ - if (__builtin_constant_p(elevel) && (elevel) >= ERROR) \ - pg_unreachable(); \ - } while(0) -#else /* !HAVE__BUILTIN_CONSTANT_P */ -#define ereport_domain(elevel, domain, ...) \ - do { \ - const int elevel_ = (elevel); \ - pg_prevent_errno_in_scope(); \ - if (errstart(elevel_, domain)) \ - __VA_ARGS__, errfinish(__FILE__, __LINE__, __func__); \ - if (elevel_ >= ERROR) \ - pg_unreachable(); \ - } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ - -#define ereport(elevel, ...) \ - ereport_domain(elevel, TEXTDOMAIN, __VA_ARGS__) - -#define TEXTDOMAIN NULL - -extern bool message_level_is_interesting(int elevel); - -extern bool errstart(int elevel, const char *domain); -extern pg_attribute_cold bool errstart_cold(int elevel, const char *domain); -extern void errfinish(const char *filename, int lineno, const char *funcname); - -extern int errcode(int sqlerrcode); - -extern int errcode_for_file_access(void); -extern int errcode_for_socket_access(void); - -extern int errmsg(const char *fmt,...) pg_attribute_printf(1, 2); -extern int errmsg_internal(const char *fmt,...) pg_attribute_printf(1, 2); - -extern int errmsg_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); - -extern int errdetail(const char *fmt,...) pg_attribute_printf(1, 2); -extern int errdetail_internal(const char *fmt,...) pg_attribute_printf(1, 2); - -extern int errdetail_log(const char *fmt,...) pg_attribute_printf(1, 2); - -extern int errdetail_log_plural(const char *fmt_singular, - const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); - -extern int errdetail_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); - -extern int errhint(const char *fmt,...) pg_attribute_printf(1, 2); - -extern int errhint_plural(const char *fmt_singular, const char *fmt_plural, - unsigned long n,...) pg_attribute_printf(1, 4) pg_attribute_printf(2, 4); - -/* - * errcontext() is typically called in error context callback functions, not - * within an ereport() invocation. The callback function can be in a different - * module than the ereport() call, so the message domain passed in errstart() - * is not usually the correct domain for translating the context message. - * set_errcontext_domain() first sets the domain to be used, and - * errcontext_msg() passes the actual message. - */ -#define errcontext set_errcontext_domain(TEXTDOMAIN), errcontext_msg - -extern int set_errcontext_domain(const char *domain); - -extern int errcontext_msg(const char *fmt,...) pg_attribute_printf(1, 2); - -extern int errhidestmt(bool hide_stmt); -extern int errhidecontext(bool hide_ctx); - -extern int errbacktrace(void); - -extern int errposition(int cursorpos); - -extern int internalerrposition(int cursorpos); -extern int internalerrquery(const char *query); - -extern int err_generic_string(int field, const char *str); - -extern int geterrcode(void); -extern int geterrposition(void); -extern int getinternalerrposition(void); - - -/*---------- - * Old-style error reporting API: to be used in this way: - * elog(ERROR, "portal \"%s\" not found", stmt->portalname); - *---------- - */ -#define elog(elevel, ...) \ - ereport(elevel, errmsg_internal(__VA_ARGS__)) - - -/*---------- - * Support for reporting "soft" errors that don't require a full transaction - * abort to clean up. This is to be used in this way: - * errsave(context, - * errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - * errmsg("invalid input syntax for type %s: \"%s\"", - * "boolean", in_str), - * ... other errxxx() fields as needed ...); - * - * "context" is a node pointer or NULL, and the remaining auxiliary calls - * provide the same error details as in ereport(). If context is not a - * pointer to an ErrorSaveContext node, then errsave(context, ...) - * behaves identically to ereport(ERROR, ...). If context is a pointer - * to an ErrorSaveContext node, then the information provided by the - * auxiliary calls is stored in the context node and control returns - * normally. The caller of errsave() must then do any required cleanup - * and return control back to its caller. That caller must check the - * ErrorSaveContext node to see whether an error occurred before - * it can trust the function's result to be meaningful. - * - * errsave_domain() allows a message domain to be specified; it is - * precisely analogous to ereport_domain(). - *---------- - */ -#define errsave_domain(context, domain, ...) \ - do { \ - struct Node *context_ = (context); \ - pg_prevent_errno_in_scope(); \ - if (errsave_start(context_, domain)) \ - __VA_ARGS__, errsave_finish(context_, __FILE__, __LINE__, __func__); \ - } while(0) - -#define errsave(context, ...) \ - errsave_domain(context, TEXTDOMAIN, __VA_ARGS__) - -/* - * "ereturn(context, dummy_value, ...);" is exactly the same as - * "errsave(context, ...); return dummy_value;". This saves a bit - * of typing in the common case where a function has no cleanup - * actions to take after reporting a soft error. "dummy_value" - * can be empty if the function returns void. - */ -#define ereturn_domain(context, dummy_value, domain, ...) \ - do { \ - errsave_domain(context, domain, __VA_ARGS__); \ - return dummy_value; \ - } while(0) - -#define ereturn(context, dummy_value, ...) \ - ereturn_domain(context, dummy_value, TEXTDOMAIN, __VA_ARGS__) - -extern bool errsave_start(struct Node *context, const char *domain); -extern void errsave_finish(struct Node *context, - const char *filename, int lineno, - const char *funcname); - - -/* Support for constructing error strings separately from ereport() calls */ - -extern void pre_format_elog_string(int errnumber, const char *domain); -extern char *format_elog_string(const char *fmt,...) pg_attribute_printf(1, 2); - - -/* Support for attaching context information to error reports */ - -typedef struct ErrorContextCallback -{ - struct ErrorContextCallback *previous; - void (*callback) (void *arg); - void *arg; -} ErrorContextCallback; - -extern PGDLLIMPORT ErrorContextCallback *error_context_stack; - - -/*---------- - * API for catching ereport(ERROR) exits. Use these macros like so: - * - * PG_TRY(); - * { - * ... code that might throw ereport(ERROR) ... - * } - * PG_CATCH(); - * { - * ... error recovery code ... - * } - * PG_END_TRY(); - * - * (The braces are not actually necessary, but are recommended so that - * pgindent will indent the construct nicely.) The error recovery code - * can either do PG_RE_THROW to propagate the error outwards, or do a - * (sub)transaction abort. Failure to do so may leave the system in an - * inconsistent state for further processing. - * - * For the common case that the error recovery code and the cleanup in the - * normal code path are identical, the following can be used instead: - * - * PG_TRY(); - * { - * ... code that might throw ereport(ERROR) ... - * } - * PG_FINALLY(); - * { - * ... cleanup code ... - * } - * PG_END_TRY(); - * - * The cleanup code will be run in either case, and any error will be rethrown - * afterwards. - * - * You cannot use both PG_CATCH() and PG_FINALLY() in the same - * PG_TRY()/PG_END_TRY() block. - * - * Note: while the system will correctly propagate any new ereport(ERROR) - * occurring in the recovery section, there is a small limit on the number - * of levels this will work for. It's best to keep the error recovery - * section simple enough that it can't generate any new errors, at least - * not before popping the error stack. - * - * Note: an ereport(FATAL) will not be caught by this construct; control will - * exit straight through proc_exit(). Therefore, do NOT put any cleanup - * of non-process-local resources into the error recovery section, at least - * not without taking thought for what will happen during ereport(FATAL). - * The PG_ENSURE_ERROR_CLEANUP macros provided by storage/ipc.h may be - * helpful in such cases. - * - * Note: if a local variable of the function containing PG_TRY is modified - * in the PG_TRY section and used in the PG_CATCH section, that variable - * must be declared "volatile" for POSIX compliance. This is not mere - * pedantry; we have seen bugs from compilers improperly optimizing code - * away when such a variable was not marked. Beware that gcc's -Wclobbered - * warnings are just about entirely useless for catching such oversights. - * - * Each of these macros accepts an optional argument which can be specified - * to apply a suffix to the variables declared within the macros. This suffix - * can be used to avoid the compiler emitting warnings about shadowed - * variables when compiling with -Wshadow in situations where nested PG_TRY() - * statements are required. The optional suffix may contain any character - * that's allowed in a variable name. The suffix, if specified, must be the - * same within each component macro of the given PG_TRY() statement. - *---------- - */ -#define PG_TRY(...) \ - do { \ - sigjmp_buf *_save_exception_stack##__VA_ARGS__ = PG_exception_stack; \ - ErrorContextCallback *_save_context_stack##__VA_ARGS__ = error_context_stack; \ - sigjmp_buf _local_sigjmp_buf##__VA_ARGS__; \ - bool _do_rethrow##__VA_ARGS__ = false; \ - if (sigsetjmp(_local_sigjmp_buf##__VA_ARGS__, 0) == 0) \ - { \ - PG_exception_stack = &_local_sigjmp_buf##__VA_ARGS__ - -#define PG_CATCH(...) \ - } \ - else \ - { \ - PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ - error_context_stack = _save_context_stack##__VA_ARGS__ - -#define PG_FINALLY(...) \ - } \ - else \ - _do_rethrow##__VA_ARGS__ = true; \ - { \ - PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ - error_context_stack = _save_context_stack##__VA_ARGS__ - -#define PG_END_TRY(...) \ - } \ - if (_do_rethrow##__VA_ARGS__) \ - PG_RE_THROW(); \ - PG_exception_stack = _save_exception_stack##__VA_ARGS__; \ - error_context_stack = _save_context_stack##__VA_ARGS__; \ - } while (0) - -/* - * Some compilers understand pg_attribute_noreturn(); for other compilers, - * insert pg_unreachable() so that the compiler gets the point. - */ -#ifdef HAVE_PG_ATTRIBUTE_NORETURN -#define PG_RE_THROW() \ - pg_re_throw() -#else -#define PG_RE_THROW() \ - (pg_re_throw(), pg_unreachable()) -#endif - -extern PGDLLIMPORT sigjmp_buf *PG_exception_stack; - - -/* Stuff that error handlers might want to use */ - -/* - * ErrorData holds the data accumulated during any one ereport() cycle. - * Any non-NULL pointers must point to palloc'd data. - * (The const pointers are an exception; we assume they point at non-freeable - * constant strings.) - */ -typedef struct ErrorData -{ - int elevel; /* error level */ - bool output_to_server; /* will report to server log? */ - bool output_to_client; /* will report to client? */ - bool hide_stmt; /* true to prevent STATEMENT: inclusion */ - bool hide_ctx; /* true to prevent CONTEXT: inclusion */ - const char *filename; /* __FILE__ of ereport() call */ - int lineno; /* __LINE__ of ereport() call */ - const char *funcname; /* __func__ of ereport() call */ - const char *domain; /* message domain */ - const char *context_domain; /* message domain for context message */ - int sqlerrcode; /* encoded ERRSTATE */ - char *message; /* primary error message (translated) */ - char *detail; /* detail error message */ - char *detail_log; /* detail error message for server log only */ - char *hint; /* hint message */ - char *context; /* context message */ - char *backtrace; /* backtrace */ - const char *message_id; /* primary message's id (original string) */ - char *schema_name; /* name of schema */ - char *table_name; /* name of table */ - char *column_name; /* name of column */ - char *datatype_name; /* name of datatype */ - char *constraint_name; /* name of constraint */ - int cursorpos; /* cursor index into query string */ - int internalpos; /* cursor index into internalquery */ - char *internalquery; /* text of internally-generated query */ - int saved_errno; /* errno at entry */ - - /* context containing associated non-constant strings */ - struct MemoryContextData *assoc_context; -} ErrorData; - -extern void EmitErrorReport(void); -extern ErrorData *CopyErrorData(void); -extern void FreeErrorData(ErrorData *edata); -extern void FlushErrorState(void); -extern void ReThrowError(ErrorData *edata) pg_attribute_noreturn(); -extern void ThrowErrorData(ErrorData *edata); -extern void pg_re_throw(void) pg_attribute_noreturn(); - -extern char *GetErrorContextStack(void); - -/* Hook for intercepting messages before they are sent to the server log */ -typedef void (*emit_log_hook_type) (ErrorData *edata); -extern PGDLLIMPORT emit_log_hook_type emit_log_hook; - - -/* GUC-configurable parameters */ - -typedef enum -{ - PGERROR_TERSE, /* single-line error messages */ - PGERROR_DEFAULT, /* recommended style */ - PGERROR_VERBOSE /* all the facts, ma'am */ -} PGErrorVerbosity; - -extern PGDLLIMPORT int Log_error_verbosity; -extern PGDLLIMPORT char *Log_line_prefix; -extern PGDLLIMPORT int Log_destination; -extern PGDLLIMPORT char *Log_destination_string; -extern PGDLLIMPORT bool syslog_sequence_numbers; -extern PGDLLIMPORT bool syslog_split_messages; - -/* Log destination bitmap */ -#define LOG_DESTINATION_STDERR 1 -#define LOG_DESTINATION_SYSLOG 2 -#define LOG_DESTINATION_EVENTLOG 4 -#define LOG_DESTINATION_CSVLOG 8 -#define LOG_DESTINATION_JSONLOG 16 - -/* Other exported functions */ -extern void log_status_format(StringInfo buf, const char *format, - ErrorData *edata); -extern void DebugFileOpen(void); -extern char *unpack_sql_state(int sql_state); -extern bool in_error_recursion_trouble(void); - -/* Common functions shared across destinations */ -extern void reset_formatted_start_time(void); -extern char *get_formatted_start_time(void); -extern char *get_formatted_log_time(void); -extern const char *get_backend_type_for_log(void); -extern bool check_log_of_query(ErrorData *edata); -extern const char *error_severity(int elevel); -extern void write_pipe_chunks(char *data, int len, int dest); - -/* Destination-specific functions */ -extern void write_csvlog(ErrorData *edata); -extern void write_jsonlog(ErrorData *edata); - -/* - * Write errors to stderr (or by equal means when stderr is - * not available). Used before ereport/elog can be used - * safely (memory context, GUC load etc) - */ -extern void write_stderr(const char *fmt,...) pg_attribute_printf(1, 2); - -/* - * Write a message to STDERR using only async-signal-safe functions. This can - * be used to safely emit a message from a signal handler. - */ -extern void write_stderr_signal_safe(const char *fmt); - -#endif /* ELOG_H */ diff --git a/contrib/libs/libpq/src/include/utils/palloc.h b/contrib/libs/libpq/src/include/utils/palloc.h deleted file mode 100644 index d1146c1235..0000000000 --- a/contrib/libs/libpq/src/include/utils/palloc.h +++ /dev/null @@ -1,165 +0,0 @@ -/*------------------------------------------------------------------------- - * - * palloc.h - * POSTGRES memory allocator definitions. - * - * This file contains the basic memory allocation interface that is - * needed by almost every backend module. It is included directly by - * postgres.h, so the definitions here are automatically available - * everywhere. Keep it lean! - * - * Memory allocation occurs within "contexts". Every chunk obtained from - * palloc()/MemoryContextAlloc() is allocated within a specific context. - * The entire contents of a context can be freed easily and quickly by - * resetting or deleting the context --- this is both faster and less - * prone to memory-leakage bugs than releasing chunks individually. - * We organize contexts into context trees to allow fine-grain control - * over chunk lifetime while preserving the certainty that we will free - * everything that should be freed. See utils/mmgr/README for more info. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/include/utils/palloc.h - * - *------------------------------------------------------------------------- - */ -#ifndef PALLOC_H -#define PALLOC_H - -/* - * Type MemoryContextData is declared in nodes/memnodes.h. Most users - * of memory allocation should just treat it as an abstract type, so we - * do not provide the struct contents here. - */ -typedef struct MemoryContextData *MemoryContext; - -/* - * A memory context can have callback functions registered on it. Any such - * function will be called once just before the context is next reset or - * deleted. The MemoryContextCallback struct describing such a callback - * typically would be allocated within the context itself, thereby avoiding - * any need to manage it explicitly (the reset/delete action will free it). - */ -typedef void (*MemoryContextCallbackFunction) (void *arg); - -typedef struct MemoryContextCallback -{ - MemoryContextCallbackFunction func; /* function to call */ - void *arg; /* argument to pass it */ - struct MemoryContextCallback *next; /* next in list of callbacks */ -} MemoryContextCallback; - -/* - * CurrentMemoryContext is the default allocation context for palloc(). - * Avoid accessing it directly! Instead, use MemoryContextSwitchTo() - * to change the setting. - */ -extern PGDLLIMPORT MemoryContext CurrentMemoryContext; - -/* - * Flags for MemoryContextAllocExtended. - */ -#define MCXT_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */ -#define MCXT_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */ -#define MCXT_ALLOC_ZERO 0x04 /* zero allocated memory */ - -/* - * Fundamental memory-allocation operations (more are in utils/memutils.h) - */ -extern void *MemoryContextAlloc(MemoryContext context, Size size); -extern void *MemoryContextAllocZero(MemoryContext context, Size size); -extern void *MemoryContextAllocZeroAligned(MemoryContext context, Size size); -extern void *MemoryContextAllocExtended(MemoryContext context, - Size size, int flags); -extern void *MemoryContextAllocAligned(MemoryContext context, - Size size, Size alignto, int flags); - -extern void *palloc(Size size); -extern void *palloc0(Size size); -extern void *palloc_extended(Size size, int flags); -extern void *palloc_aligned(Size size, Size alignto, int flags); -extern pg_nodiscard void *repalloc(void *pointer, Size size); -extern pg_nodiscard void *repalloc_extended(void *pointer, - Size size, int flags); -extern pg_nodiscard void *repalloc0(void *pointer, Size oldsize, Size size); -extern void pfree(void *pointer); - -/* - * Variants with easier notation and more type safety - */ - -/* - * Allocate space for one object of type "type" - */ -#define palloc_object(type) ((type *) palloc(sizeof(type))) -#define palloc0_object(type) ((type *) palloc0(sizeof(type))) - -/* - * Allocate space for "count" objects of type "type" - */ -#define palloc_array(type, count) ((type *) palloc(sizeof(type) * (count))) -#define palloc0_array(type, count) ((type *) palloc0(sizeof(type) * (count))) - -/* - * Change size of allocation pointed to by "pointer" to have space for "count" - * objects of type "type" - */ -#define repalloc_array(pointer, type, count) ((type *) repalloc(pointer, sizeof(type) * (count))) -#define repalloc0_array(pointer, type, oldcount, count) ((type *) repalloc0(pointer, sizeof(type) * (oldcount), sizeof(type) * (count))) - -/* - * The result of palloc() is always word-aligned, so we can skip testing - * alignment of the pointer when deciding which MemSet variant to use. - * Note that this variant does not offer any advantage, and should not be - * used, unless its "sz" argument is a compile-time constant; therefore, the - * issue that it evaluates the argument multiple times isn't a problem in - * practice. - */ -#define palloc0fast(sz) \ - ( MemSetTest(0, sz) ? \ - MemoryContextAllocZeroAligned(CurrentMemoryContext, sz) : \ - MemoryContextAllocZero(CurrentMemoryContext, sz) ) - -/* Higher-limit allocators. */ -extern void *MemoryContextAllocHuge(MemoryContext context, Size size); -extern pg_nodiscard void *repalloc_huge(void *pointer, Size size); - -/* - * Although this header file is nominally backend-only, certain frontend - * programs like pg_controldata include it via postgres.h. For some compilers - * it's necessary to hide the inline definition of MemoryContextSwitchTo in - * this scenario; hence the #ifndef FRONTEND. - */ - -#ifndef FRONTEND -static inline MemoryContext -MemoryContextSwitchTo(MemoryContext context) -{ - MemoryContext old = CurrentMemoryContext; - - CurrentMemoryContext = context; - return old; -} -#endif /* FRONTEND */ - -/* Registration of memory context reset/delete callbacks */ -extern void MemoryContextRegisterResetCallback(MemoryContext context, - MemoryContextCallback *cb); - -/* - * These are like standard strdup() except the copied string is - * allocated in a context, not with malloc(). - */ -extern char *MemoryContextStrdup(MemoryContext context, const char *string); -extern char *pstrdup(const char *in); -extern char *pnstrdup(const char *in, Size len); - -extern char *pchomp(const char *in); - -/* sprintf into a palloc'd buffer --- these are in psprintf.c */ -extern char *psprintf(const char *fmt,...) pg_attribute_printf(1, 2); -extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) pg_attribute_printf(3, 0); - -#endif /* PALLOC_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/README b/contrib/libs/libpq/src/interfaces/libpq/README deleted file mode 100644 index 0dcef75a83..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/README +++ /dev/null @@ -1,3 +0,0 @@ -src/interfaces/libpq/README - -This directory contains the C version of Libpq, the POSTGRES frontend library. diff --git a/contrib/libs/libpq/src/interfaces/libpq/exports.txt b/contrib/libs/libpq/src/interfaces/libpq/exports.txt deleted file mode 100644 index 7ded77aff3..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/exports.txt +++ /dev/null @@ -1,189 +0,0 @@ -# src/interfaces/libpq/exports.txt -# Functions to be exported by libpq DLLs -PQconnectdb 1 -PQsetdbLogin 2 -PQconndefaults 3 -PQfinish 4 -PQreset 5 -PQrequestCancel 6 -PQdb 7 -PQuser 8 -PQpass 9 -PQhost 10 -PQport 11 -PQtty 12 -PQoptions 13 -PQstatus 14 -PQerrorMessage 15 -PQsocket 16 -PQbackendPID 17 -PQtrace 18 -PQuntrace 19 -PQsetNoticeProcessor 20 -PQexec 21 -PQnotifies 22 -PQsendQuery 23 -PQgetResult 24 -PQisBusy 25 -PQconsumeInput 26 -PQgetline 27 -PQputline 28 -PQgetlineAsync 29 -PQputnbytes 30 -PQendcopy 31 -PQfn 32 -PQresultStatus 33 -PQntuples 34 -PQnfields 35 -PQbinaryTuples 36 -PQfname 37 -PQfnumber 38 -PQftype 39 -PQfsize 40 -PQfmod 41 -PQcmdStatus 42 -PQoidStatus 43 -PQcmdTuples 44 -PQgetvalue 45 -PQgetlength 46 -PQgetisnull 47 -PQclear 48 -PQmakeEmptyPGresult 49 -PQprint 50 -PQdisplayTuples 51 -PQprintTuples 52 -lo_open 53 -lo_close 54 -lo_read 55 -lo_write 56 -lo_lseek 57 -lo_creat 58 -lo_tell 59 -lo_unlink 60 -lo_import 61 -lo_export 62 -pgresStatus 63 -PQmblen 64 -PQresultErrorMessage 65 -PQresStatus 66 -termPQExpBuffer 67 -appendPQExpBufferChar 68 -initPQExpBuffer 69 -resetPQExpBuffer 70 -PQoidValue 71 -PQclientEncoding 72 -PQenv2encoding 73 -appendBinaryPQExpBuffer 74 -appendPQExpBufferStr 75 -destroyPQExpBuffer 76 -createPQExpBuffer 77 -PQconninfoFree 78 -PQconnectPoll 79 -PQconnectStart 80 -PQflush 81 -PQisnonblocking 82 -PQresetPoll 83 -PQresetStart 84 -PQsetClientEncoding 85 -PQsetnonblocking 86 -PQfreeNotify 87 -PQescapeString 88 -PQescapeBytea 89 -printfPQExpBuffer 90 -appendPQExpBuffer 91 -pg_encoding_to_char 92 -pg_utf_mblen 93 -PQunescapeBytea 94 -PQfreemem 95 -PQtransactionStatus 96 -PQparameterStatus 97 -PQprotocolVersion 98 -PQsetErrorVerbosity 99 -PQsetNoticeReceiver 100 -PQexecParams 101 -PQsendQueryParams 102 -PQputCopyData 103 -PQputCopyEnd 104 -PQgetCopyData 105 -PQresultErrorField 106 -PQftable 107 -PQftablecol 108 -PQfformat 109 -PQexecPrepared 110 -PQsendQueryPrepared 111 -PQdsplen 112 -PQserverVersion 113 -PQgetssl 114 -pg_char_to_encoding 115 -pg_valid_server_encoding 116 -pqsignal 117 -PQprepare 118 -PQsendPrepare 119 -PQgetCancel 120 -PQfreeCancel 121 -PQcancel 122 -lo_create 123 -PQinitSSL 124 -PQregisterThreadLock 125 -PQescapeStringConn 126 -PQescapeByteaConn 127 -PQencryptPassword 128 -PQisthreadsafe 129 -enlargePQExpBuffer 130 -PQnparams 131 -PQparamtype 132 -PQdescribePrepared 133 -PQdescribePortal 134 -PQsendDescribePrepared 135 -PQsendDescribePortal 136 -lo_truncate 137 -PQconnectionUsedPassword 138 -pg_valid_server_encoding_id 139 -PQconnectionNeedsPassword 140 -lo_import_with_oid 141 -PQcopyResult 142 -PQsetResultAttrs 143 -PQsetvalue 144 -PQresultAlloc 145 -PQregisterEventProc 146 -PQinstanceData 147 -PQsetInstanceData 148 -PQresultInstanceData 149 -PQresultSetInstanceData 150 -PQfireResultCreateEvents 151 -PQconninfoParse 152 -PQinitOpenSSL 153 -PQescapeLiteral 154 -PQescapeIdentifier 155 -PQconnectdbParams 156 -PQconnectStartParams 157 -PQping 158 -PQpingParams 159 -PQlibVersion 160 -PQsetSingleRowMode 161 -lo_lseek64 162 -lo_tell64 163 -lo_truncate64 164 -PQconninfo 165 -PQsslInUse 166 -PQsslStruct 167 -PQsslAttributeNames 168 -PQsslAttribute 169 -PQsetErrorContextVisibility 170 -PQresultVerboseErrorMessage 171 -PQencryptPasswordConn 172 -PQresultMemorySize 173 -PQhostaddr 174 -PQgssEncInUse 175 -PQgetgssctx 176 -PQsetSSLKeyPassHook_OpenSSL 177 -PQgetSSLKeyPassHook_OpenSSL 178 -PQdefaultSSLKeyPassHook_OpenSSL 179 -PQenterPipelineMode 180 -PQexitPipelineMode 181 -PQpipelineSync 182 -PQpipelineStatus 183 -PQsetTraceFlags 184 -PQmblenBounded 185 -PQsendFlushRequest 186 -PQconnectionUsedGSSAPI 187 diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-auth-sasl.h b/contrib/libs/libpq/src/interfaces/libpq/fe-auth-sasl.h deleted file mode 100644 index ddf6ea3f3f..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-auth-sasl.h +++ /dev/null @@ -1,131 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-auth-sasl.h - * Defines the SASL mechanism interface for libpq. - * - * Each SASL mechanism defines a frontend and a backend callback structure. - * This is not part of the public API for applications. - * - * See src/include/libpq/sasl.h for the backend counterpart. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/fe-auth-sasl.h - * - *------------------------------------------------------------------------- - */ - -#ifndef FE_AUTH_SASL_H -#define FE_AUTH_SASL_H - -#include "libpq-fe.h" - -/* - * Frontend SASL mechanism callbacks. - * - * To implement a frontend mechanism, declare a pg_be_sasl_mech struct with - * appropriate callback implementations, then hook it into conn->sasl during - * pg_SASL_init()'s mechanism negotiation. - */ -typedef struct pg_fe_sasl_mech -{ - /*------- - * init() - * - * Initializes mechanism-specific state for a connection. This - * callback must return a pointer to its allocated state, which will - * be passed as-is as the first argument to the other callbacks. - * the free() callback is called to release any state resources. - * - * If state allocation fails, the implementation should return NULL to - * fail the authentication exchange. - * - * Input parameters: - * - * conn: The connection to the server - * - * password: The user's supplied password for the current connection - * - * mech: The mechanism name in use, for implementations that may - * advertise more than one name (such as *-PLUS variants). - *------- - */ - void *(*init) (PGconn *conn, const char *password, const char *mech); - - /*-------- - * exchange() - * - * Produces a client response to a server challenge. As a special case - * for client-first SASL mechanisms, exchange() is called with a NULL - * server response once at the start of the authentication exchange to - * generate an initial response. - * - * Input parameters: - * - * state: The opaque mechanism state returned by init() - * - * input: The challenge data sent by the server, or NULL when - * generating a client-first initial response (that is, when - * the server expects the client to send a message to start - * the exchange). This is guaranteed to be null-terminated - * for safety, but SASL allows embedded nulls in challenges, - * so mechanisms must be careful to check inputlen. - * - * inputlen: The length of the challenge data sent by the server, or -1 - * during client-first initial response generation. - * - * Output parameters, to be set by the callback function: - * - * output: A malloc'd buffer containing the client's response to - * the server (can be empty), or NULL if the exchange should - * be aborted. (*success should be set to false in the - * latter case.) - * - * outputlen: The length (0 or higher) of the client response buffer, - * ignored if output is NULL. - * - * done: Set to true if the SASL exchange should not continue, - * because the exchange is either complete or failed - * - * success: Set to true if the SASL exchange completed successfully. - * Ignored if *done is false. - *-------- - */ - void (*exchange) (void *state, char *input, int inputlen, - char **output, int *outputlen, - bool *done, bool *success); - - /*-------- - * channel_bound() - * - * Returns true if the connection has an established channel binding. A - * mechanism implementation must ensure that a SASL exchange has actually - * been completed, in addition to checking that channel binding is in use. - * - * Mechanisms that do not implement channel binding may simply return - * false. - * - * Input parameters: - * - * state: The opaque mechanism state returned by init() - *-------- - */ - bool (*channel_bound) (void *state); - - /*-------- - * free() - * - * Frees the state allocated by init(). This is called when the connection - * is dropped, not when the exchange is completed. - * - * Input parameters: - * - * state: The opaque mechanism state returned by init() - *-------- - */ - void (*free) (void *state); - -} pg_fe_sasl_mech; - -#endif /* FE_AUTH_SASL_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-auth-scram.c b/contrib/libs/libpq/src/interfaces/libpq/fe-auth-scram.c deleted file mode 100644 index 6b779ec7ff..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-auth-scram.c +++ /dev/null @@ -1,936 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-auth-scram.c - * The front-end (client) implementation of SCRAM authentication. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-auth-scram.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include "common/base64.h" -#include "common/hmac.h" -#include "common/saslprep.h" -#include "common/scram-common.h" -#include "fe-auth.h" - - -/* The exported SCRAM callback mechanism. */ -static void *scram_init(PGconn *conn, const char *password, - const char *sasl_mechanism); -static void scram_exchange(void *opaq, char *input, int inputlen, - char **output, int *outputlen, - bool *done, bool *success); -static bool scram_channel_bound(void *opaq); -static void scram_free(void *opaq); - -const pg_fe_sasl_mech pg_scram_mech = { - scram_init, - scram_exchange, - scram_channel_bound, - scram_free -}; - -/* - * Status of exchange messages used for SCRAM authentication via the - * SASL protocol. - */ -typedef enum -{ - FE_SCRAM_INIT, - FE_SCRAM_NONCE_SENT, - FE_SCRAM_PROOF_SENT, - FE_SCRAM_FINISHED -} fe_scram_state_enum; - -typedef struct -{ - fe_scram_state_enum state; - - /* These are supplied by the user */ - PGconn *conn; - char *password; - char *sasl_mechanism; - - /* State data depending on the hash type */ - pg_cryptohash_type hash_type; - int key_length; - - /* We construct these */ - uint8 SaltedPassword[SCRAM_MAX_KEY_LEN]; - char *client_nonce; - char *client_first_message_bare; - char *client_final_message_without_proof; - - /* These come from the server-first message */ - char *server_first_message; - char *salt; - int saltlen; - int iterations; - char *nonce; - - /* These come from the server-final message */ - char *server_final_message; - char ServerSignature[SCRAM_MAX_KEY_LEN]; -} fe_scram_state; - -static bool read_server_first_message(fe_scram_state *state, char *input); -static bool read_server_final_message(fe_scram_state *state, char *input); -static char *build_client_first_message(fe_scram_state *state); -static char *build_client_final_message(fe_scram_state *state); -static bool verify_server_signature(fe_scram_state *state, bool *match, - const char **errstr); -static bool calculate_client_proof(fe_scram_state *state, - const char *client_final_message_without_proof, - uint8 *result, const char **errstr); - -/* - * Initialize SCRAM exchange status. - */ -static void * -scram_init(PGconn *conn, - const char *password, - const char *sasl_mechanism) -{ - fe_scram_state *state; - char *prep_password; - pg_saslprep_rc rc; - - Assert(sasl_mechanism != NULL); - - state = (fe_scram_state *) malloc(sizeof(fe_scram_state)); - if (!state) - return NULL; - memset(state, 0, sizeof(fe_scram_state)); - state->conn = conn; - state->state = FE_SCRAM_INIT; - state->key_length = SCRAM_SHA_256_KEY_LEN; - state->hash_type = PG_SHA256; - - state->sasl_mechanism = strdup(sasl_mechanism); - if (!state->sasl_mechanism) - { - free(state); - return NULL; - } - - /* Normalize the password with SASLprep, if possible */ - rc = pg_saslprep(password, &prep_password); - if (rc == SASLPREP_OOM) - { - free(state->sasl_mechanism); - free(state); - return NULL; - } - if (rc != SASLPREP_SUCCESS) - { - prep_password = strdup(password); - if (!prep_password) - { - free(state->sasl_mechanism); - free(state); - return NULL; - } - } - state->password = prep_password; - - return state; -} - -/* - * Return true if channel binding was employed and the SCRAM exchange - * completed. This should be used after a successful exchange to determine - * whether the server authenticated itself to the client. - * - * Note that the caller must also ensure that the exchange was actually - * successful. - */ -static bool -scram_channel_bound(void *opaq) -{ - fe_scram_state *state = (fe_scram_state *) opaq; - - /* no SCRAM exchange done */ - if (state == NULL) - return false; - - /* SCRAM exchange not completed */ - if (state->state != FE_SCRAM_FINISHED) - return false; - - /* channel binding mechanism not used */ - if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0) - return false; - - /* all clear! */ - return true; -} - -/* - * Free SCRAM exchange status - */ -static void -scram_free(void *opaq) -{ - fe_scram_state *state = (fe_scram_state *) opaq; - - free(state->password); - free(state->sasl_mechanism); - - /* client messages */ - free(state->client_nonce); - free(state->client_first_message_bare); - free(state->client_final_message_without_proof); - - /* first message from server */ - free(state->server_first_message); - free(state->salt); - free(state->nonce); - - /* final message from server */ - free(state->server_final_message); - - free(state); -} - -/* - * Exchange a SCRAM message with backend. - */ -static void -scram_exchange(void *opaq, char *input, int inputlen, - char **output, int *outputlen, - bool *done, bool *success) -{ - fe_scram_state *state = (fe_scram_state *) opaq; - PGconn *conn = state->conn; - const char *errstr = NULL; - - *done = false; - *success = false; - *output = NULL; - *outputlen = 0; - - /* - * Check that the input length agrees with the string length of the input. - * We can ignore inputlen after this. - */ - if (state->state != FE_SCRAM_INIT) - { - if (inputlen == 0) - { - libpq_append_conn_error(conn, "malformed SCRAM message (empty message)"); - goto error; - } - if (inputlen != strlen(input)) - { - libpq_append_conn_error(conn, "malformed SCRAM message (length mismatch)"); - goto error; - } - } - - switch (state->state) - { - case FE_SCRAM_INIT: - /* Begin the SCRAM handshake, by sending client nonce */ - *output = build_client_first_message(state); - if (*output == NULL) - goto error; - - *outputlen = strlen(*output); - *done = false; - state->state = FE_SCRAM_NONCE_SENT; - break; - - case FE_SCRAM_NONCE_SENT: - /* Receive salt and server nonce, send response. */ - if (!read_server_first_message(state, input)) - goto error; - - *output = build_client_final_message(state); - if (*output == NULL) - goto error; - - *outputlen = strlen(*output); - *done = false; - state->state = FE_SCRAM_PROOF_SENT; - break; - - case FE_SCRAM_PROOF_SENT: - /* Receive server signature */ - if (!read_server_final_message(state, input)) - goto error; - - /* - * Verify server signature, to make sure we're talking to the - * genuine server. - */ - if (!verify_server_signature(state, success, &errstr)) - { - libpq_append_conn_error(conn, "could not verify server signature: %s", errstr); - goto error; - } - - if (!*success) - { - libpq_append_conn_error(conn, "incorrect server signature"); - } - *done = true; - state->state = FE_SCRAM_FINISHED; - state->conn->client_finished_auth = true; - break; - - default: - /* shouldn't happen */ - libpq_append_conn_error(conn, "invalid SCRAM exchange state"); - goto error; - } - return; - -error: - *done = true; - *success = false; -} - -/* - * Read value for an attribute part of a SCRAM message. - * - * The buffer at **input is destructively modified, and *input is - * advanced over the "attr=value" string and any following comma. - * - * On failure, append an error message to *errorMessage and return NULL. - */ -static char * -read_attr_value(char **input, char attr, PQExpBuffer errorMessage) -{ - char *begin = *input; - char *end; - - if (*begin != attr) - { - libpq_append_error(errorMessage, - "malformed SCRAM message (attribute \"%c\" expected)", - attr); - return NULL; - } - begin++; - - if (*begin != '=') - { - libpq_append_error(errorMessage, - "malformed SCRAM message (expected character \"=\" for attribute \"%c\")", - attr); - return NULL; - } - begin++; - - end = begin; - while (*end && *end != ',') - end++; - - if (*end) - { - *end = '\0'; - *input = end + 1; - } - else - *input = end; - - return begin; -} - -/* - * Build the first exchange message sent by the client. - */ -static char * -build_client_first_message(fe_scram_state *state) -{ - PGconn *conn = state->conn; - char raw_nonce[SCRAM_RAW_NONCE_LEN + 1]; - char *result; - int channel_info_len; - int encoded_len; - PQExpBufferData buf; - - /* - * Generate a "raw" nonce. This is converted to ASCII-printable form by - * base64-encoding it. - */ - if (!pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN)) - { - libpq_append_conn_error(conn, "could not generate nonce"); - return NULL; - } - - encoded_len = pg_b64_enc_len(SCRAM_RAW_NONCE_LEN); - /* don't forget the zero-terminator */ - state->client_nonce = malloc(encoded_len + 1); - if (state->client_nonce == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return NULL; - } - encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN, - state->client_nonce, encoded_len); - if (encoded_len < 0) - { - libpq_append_conn_error(conn, "could not encode nonce"); - return NULL; - } - state->client_nonce[encoded_len] = '\0'; - - /* - * Generate message. The username is left empty as the backend uses the - * value provided by the startup packet. Also, as this username is not - * prepared with SASLprep, the message parsing would fail if it includes - * '=' or ',' characters. - */ - - initPQExpBuffer(&buf); - - /* - * First build the gs2-header with channel binding information. - */ - if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) == 0) - { - Assert(conn->ssl_in_use); - appendPQExpBufferStr(&buf, "p=tls-server-end-point"); - } -#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH - else if (conn->channel_binding[0] != 'd' && /* disable */ - conn->ssl_in_use) - { - /* - * Client supports channel binding, but thinks the server does not. - */ - appendPQExpBufferChar(&buf, 'y'); - } -#endif - else - { - /* - * Client does not support channel binding, or has disabled it. - */ - appendPQExpBufferChar(&buf, 'n'); - } - - if (PQExpBufferDataBroken(buf)) - goto oom_error; - - channel_info_len = buf.len; - - appendPQExpBuffer(&buf, ",,n=,r=%s", state->client_nonce); - if (PQExpBufferDataBroken(buf)) - goto oom_error; - - /* - * The first message content needs to be saved without channel binding - * information. - */ - state->client_first_message_bare = strdup(buf.data + channel_info_len + 2); - if (!state->client_first_message_bare) - goto oom_error; - - result = strdup(buf.data); - if (result == NULL) - goto oom_error; - - termPQExpBuffer(&buf); - return result; - -oom_error: - termPQExpBuffer(&buf); - libpq_append_conn_error(conn, "out of memory"); - return NULL; -} - -/* - * Build the final exchange message sent from the client. - */ -static char * -build_client_final_message(fe_scram_state *state) -{ - PQExpBufferData buf; - PGconn *conn = state->conn; - uint8 client_proof[SCRAM_MAX_KEY_LEN]; - char *result; - int encoded_len; - const char *errstr = NULL; - - initPQExpBuffer(&buf); - - /* - * Construct client-final-message-without-proof. We need to remember it - * for verifying the server proof in the final step of authentication. - * - * The channel binding flag handling (p/y/n) must be consistent with - * build_client_first_message(), because the server will check that it's - * the same flag both times. - */ - if (strcmp(state->sasl_mechanism, SCRAM_SHA_256_PLUS_NAME) == 0) - { -#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH - char *cbind_data = NULL; - size_t cbind_data_len = 0; - size_t cbind_header_len; - char *cbind_input; - size_t cbind_input_len; - int encoded_cbind_len; - - /* Fetch hash data of server's SSL certificate */ - cbind_data = - pgtls_get_peer_certificate_hash(state->conn, - &cbind_data_len); - if (cbind_data == NULL) - { - /* error message is already set on error */ - termPQExpBuffer(&buf); - return NULL; - } - - appendPQExpBufferStr(&buf, "c="); - - /* p=type,, */ - cbind_header_len = strlen("p=tls-server-end-point,,"); - cbind_input_len = cbind_header_len + cbind_data_len; - cbind_input = malloc(cbind_input_len); - if (!cbind_input) - { - free(cbind_data); - goto oom_error; - } - memcpy(cbind_input, "p=tls-server-end-point,,", cbind_header_len); - memcpy(cbind_input + cbind_header_len, cbind_data, cbind_data_len); - - encoded_cbind_len = pg_b64_enc_len(cbind_input_len); - if (!enlargePQExpBuffer(&buf, encoded_cbind_len)) - { - free(cbind_data); - free(cbind_input); - goto oom_error; - } - encoded_cbind_len = pg_b64_encode(cbind_input, cbind_input_len, - buf.data + buf.len, - encoded_cbind_len); - if (encoded_cbind_len < 0) - { - free(cbind_data); - free(cbind_input); - termPQExpBuffer(&buf); - appendPQExpBufferStr(&conn->errorMessage, - "could not encode cbind data for channel binding\n"); - return NULL; - } - buf.len += encoded_cbind_len; - buf.data[buf.len] = '\0'; - - free(cbind_data); - free(cbind_input); -#else - /* - * Chose channel binding, but the SSL library doesn't support it. - * Shouldn't happen. - */ - termPQExpBuffer(&buf); - appendPQExpBufferStr(&conn->errorMessage, - "channel binding not supported by this build\n"); - return NULL; -#endif /* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */ - } -#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH - else if (conn->channel_binding[0] != 'd' && /* disable */ - conn->ssl_in_use) - appendPQExpBufferStr(&buf, "c=eSws"); /* base64 of "y,," */ -#endif - else - appendPQExpBufferStr(&buf, "c=biws"); /* base64 of "n,," */ - - if (PQExpBufferDataBroken(buf)) - goto oom_error; - - appendPQExpBuffer(&buf, ",r=%s", state->nonce); - if (PQExpBufferDataBroken(buf)) - goto oom_error; - - state->client_final_message_without_proof = strdup(buf.data); - if (state->client_final_message_without_proof == NULL) - goto oom_error; - - /* Append proof to it, to form client-final-message. */ - if (!calculate_client_proof(state, - state->client_final_message_without_proof, - client_proof, &errstr)) - { - termPQExpBuffer(&buf); - libpq_append_conn_error(conn, "could not calculate client proof: %s", errstr); - return NULL; - } - - appendPQExpBufferStr(&buf, ",p="); - encoded_len = pg_b64_enc_len(state->key_length); - if (!enlargePQExpBuffer(&buf, encoded_len)) - goto oom_error; - encoded_len = pg_b64_encode((char *) client_proof, - state->key_length, - buf.data + buf.len, - encoded_len); - if (encoded_len < 0) - { - termPQExpBuffer(&buf); - libpq_append_conn_error(conn, "could not encode client proof"); - return NULL; - } - buf.len += encoded_len; - buf.data[buf.len] = '\0'; - - result = strdup(buf.data); - if (result == NULL) - goto oom_error; - - termPQExpBuffer(&buf); - return result; - -oom_error: - termPQExpBuffer(&buf); - libpq_append_conn_error(conn, "out of memory"); - return NULL; -} - -/* - * Read the first exchange message coming from the server. - */ -static bool -read_server_first_message(fe_scram_state *state, char *input) -{ - PGconn *conn = state->conn; - char *iterations_str; - char *endptr; - char *encoded_salt; - char *nonce; - int decoded_salt_len; - - state->server_first_message = strdup(input); - if (state->server_first_message == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - - /* parse the message */ - nonce = read_attr_value(&input, 'r', - &conn->errorMessage); - if (nonce == NULL) - { - /* read_attr_value() has appended an error string */ - return false; - } - - /* Verify immediately that the server used our part of the nonce */ - if (strlen(nonce) < strlen(state->client_nonce) || - memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0) - { - libpq_append_conn_error(conn, "invalid SCRAM response (nonce mismatch)"); - return false; - } - - state->nonce = strdup(nonce); - if (state->nonce == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - - encoded_salt = read_attr_value(&input, 's', &conn->errorMessage); - if (encoded_salt == NULL) - { - /* read_attr_value() has appended an error string */ - return false; - } - decoded_salt_len = pg_b64_dec_len(strlen(encoded_salt)); - state->salt = malloc(decoded_salt_len); - if (state->salt == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - state->saltlen = pg_b64_decode(encoded_salt, - strlen(encoded_salt), - state->salt, - decoded_salt_len); - if (state->saltlen < 0) - { - libpq_append_conn_error(conn, "malformed SCRAM message (invalid salt)"); - return false; - } - - iterations_str = read_attr_value(&input, 'i', &conn->errorMessage); - if (iterations_str == NULL) - { - /* read_attr_value() has appended an error string */ - return false; - } - state->iterations = strtol(iterations_str, &endptr, 10); - if (*endptr != '\0' || state->iterations < 1) - { - libpq_append_conn_error(conn, "malformed SCRAM message (invalid iteration count)"); - return false; - } - - if (*input != '\0') - libpq_append_conn_error(conn, "malformed SCRAM message (garbage at end of server-first-message)"); - - return true; -} - -/* - * Read the final exchange message coming from the server. - */ -static bool -read_server_final_message(fe_scram_state *state, char *input) -{ - PGconn *conn = state->conn; - char *encoded_server_signature; - char *decoded_server_signature; - int server_signature_len; - - state->server_final_message = strdup(input); - if (!state->server_final_message) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - - /* Check for error result. */ - if (*input == 'e') - { - char *errmsg = read_attr_value(&input, 'e', - &conn->errorMessage); - - if (errmsg == NULL) - { - /* read_attr_value() has appended an error message */ - return false; - } - libpq_append_conn_error(conn, "error received from server in SCRAM exchange: %s", - errmsg); - return false; - } - - /* Parse the message. */ - encoded_server_signature = read_attr_value(&input, 'v', - &conn->errorMessage); - if (encoded_server_signature == NULL) - { - /* read_attr_value() has appended an error message */ - return false; - } - - if (*input != '\0') - libpq_append_conn_error(conn, "malformed SCRAM message (garbage at end of server-final-message)"); - - server_signature_len = pg_b64_dec_len(strlen(encoded_server_signature)); - decoded_server_signature = malloc(server_signature_len); - if (!decoded_server_signature) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - - server_signature_len = pg_b64_decode(encoded_server_signature, - strlen(encoded_server_signature), - decoded_server_signature, - server_signature_len); - if (server_signature_len != state->key_length) - { - free(decoded_server_signature); - libpq_append_conn_error(conn, "malformed SCRAM message (invalid server signature)"); - return false; - } - memcpy(state->ServerSignature, decoded_server_signature, - state->key_length); - free(decoded_server_signature); - - return true; -} - -/* - * Calculate the client proof, part of the final exchange message sent - * by the client. Returns true on success, false on failure with *errstr - * pointing to a message about the error details. - */ -static bool -calculate_client_proof(fe_scram_state *state, - const char *client_final_message_without_proof, - uint8 *result, const char **errstr) -{ - uint8 StoredKey[SCRAM_MAX_KEY_LEN]; - uint8 ClientKey[SCRAM_MAX_KEY_LEN]; - uint8 ClientSignature[SCRAM_MAX_KEY_LEN]; - int i; - pg_hmac_ctx *ctx; - - ctx = pg_hmac_create(state->hash_type); - if (ctx == NULL) - { - *errstr = pg_hmac_error(NULL); /* returns OOM */ - return false; - } - - /* - * Calculate SaltedPassword, and store it in 'state' so that we can reuse - * it later in verify_server_signature. - */ - if (scram_SaltedPassword(state->password, state->hash_type, - state->key_length, state->salt, state->saltlen, - state->iterations, state->SaltedPassword, - errstr) < 0 || - scram_ClientKey(state->SaltedPassword, state->hash_type, - state->key_length, ClientKey, errstr) < 0 || - scram_H(ClientKey, state->hash_type, state->key_length, - StoredKey, errstr) < 0) - { - /* errstr is already filled here */ - pg_hmac_free(ctx); - return false; - } - - if (pg_hmac_init(ctx, StoredKey, state->key_length) < 0 || - pg_hmac_update(ctx, - (uint8 *) state->client_first_message_bare, - strlen(state->client_first_message_bare)) < 0 || - pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || - pg_hmac_update(ctx, - (uint8 *) state->server_first_message, - strlen(state->server_first_message)) < 0 || - pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || - pg_hmac_update(ctx, - (uint8 *) client_final_message_without_proof, - strlen(client_final_message_without_proof)) < 0 || - pg_hmac_final(ctx, ClientSignature, state->key_length) < 0) - { - *errstr = pg_hmac_error(ctx); - pg_hmac_free(ctx); - return false; - } - - for (i = 0; i < state->key_length; i++) - result[i] = ClientKey[i] ^ ClientSignature[i]; - - pg_hmac_free(ctx); - return true; -} - -/* - * Validate the server signature, received as part of the final exchange - * message received from the server. *match tracks if the server signature - * matched or not. Returns true if the server signature got verified, and - * false for a processing error with *errstr pointing to a message about the - * error details. - */ -static bool -verify_server_signature(fe_scram_state *state, bool *match, - const char **errstr) -{ - uint8 expected_ServerSignature[SCRAM_MAX_KEY_LEN]; - uint8 ServerKey[SCRAM_MAX_KEY_LEN]; - pg_hmac_ctx *ctx; - - ctx = pg_hmac_create(state->hash_type); - if (ctx == NULL) - { - *errstr = pg_hmac_error(NULL); /* returns OOM */ - return false; - } - - if (scram_ServerKey(state->SaltedPassword, state->hash_type, - state->key_length, ServerKey, errstr) < 0) - { - /* errstr is filled already */ - pg_hmac_free(ctx); - return false; - } - - /* calculate ServerSignature */ - if (pg_hmac_init(ctx, ServerKey, state->key_length) < 0 || - pg_hmac_update(ctx, - (uint8 *) state->client_first_message_bare, - strlen(state->client_first_message_bare)) < 0 || - pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || - pg_hmac_update(ctx, - (uint8 *) state->server_first_message, - strlen(state->server_first_message)) < 0 || - pg_hmac_update(ctx, (uint8 *) ",", 1) < 0 || - pg_hmac_update(ctx, - (uint8 *) state->client_final_message_without_proof, - strlen(state->client_final_message_without_proof)) < 0 || - pg_hmac_final(ctx, expected_ServerSignature, - state->key_length) < 0) - { - *errstr = pg_hmac_error(ctx); - pg_hmac_free(ctx); - return false; - } - - pg_hmac_free(ctx); - - /* signature processed, so now check after it */ - if (memcmp(expected_ServerSignature, state->ServerSignature, - state->key_length) != 0) - *match = false; - else - *match = true; - - return true; -} - -/* - * Build a new SCRAM secret. - * - * On error, returns NULL and sets *errstr to point to a message about the - * error details. - */ -char * -pg_fe_scram_build_secret(const char *password, int iterations, const char **errstr) -{ - char *prep_password; - pg_saslprep_rc rc; - char saltbuf[SCRAM_DEFAULT_SALT_LEN]; - char *result; - - /* - * Normalize the password with SASLprep. If that doesn't work, because - * the password isn't valid UTF-8 or contains prohibited characters, just - * proceed with the original password. (See comments at the top of - * auth-scram.c.) - */ - rc = pg_saslprep(password, &prep_password); - if (rc == SASLPREP_OOM) - { - *errstr = libpq_gettext("out of memory"); - return NULL; - } - if (rc == SASLPREP_SUCCESS) - password = (const char *) prep_password; - - /* Generate a random salt */ - if (!pg_strong_random(saltbuf, SCRAM_DEFAULT_SALT_LEN)) - { - *errstr = libpq_gettext("could not generate random salt"); - free(prep_password); - return NULL; - } - - result = scram_build_secret(PG_SHA256, SCRAM_SHA_256_KEY_LEN, saltbuf, - SCRAM_DEFAULT_SALT_LEN, - iterations, password, - errstr); - - free(prep_password); - - return result; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-auth.c b/contrib/libs/libpq/src/interfaces/libpq/fe-auth.c deleted file mode 100644 index fce7f3da38..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-auth.c +++ /dev/null @@ -1,1385 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-auth.c - * The front-end (client) authorization routines - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-auth.c - * - *------------------------------------------------------------------------- - */ - -/* - * INTERFACE ROUTINES - * frontend (client) routines: - * pg_fe_sendauth send authentication information - * pg_fe_getauthname get user's name according to the client side - * of the authentication system - */ - -#include "postgres_fe.h" - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> -#include <sys/param.h> /* for MAXHOSTNAMELEN on most */ -#include <sys/socket.h> -#ifdef HAVE_SYS_UCRED_H -#include <sys/ucred.h> -#endif -#ifndef MAXHOSTNAMELEN -#include <netdb.h> /* for MAXHOSTNAMELEN on some */ -#endif -#endif - -#include "common/md5.h" -#include "common/scram-common.h" -#include "fe-auth.h" -#include "fe-auth-sasl.h" -#include "libpq-fe.h" - -#ifdef ENABLE_GSS -/* - * GSSAPI authentication system. - */ - -#error #include "fe-gssapi-common.h" - -/* - * Continue GSS authentication with next token as needed. - */ -static int -pg_GSS_continue(PGconn *conn, int payloadlen) -{ - OM_uint32 maj_stat, - min_stat, - lmin_s, - gss_flags = GSS_C_MUTUAL_FLAG; - gss_buffer_desc ginbuf; - gss_buffer_desc goutbuf; - - /* - * On first call, there's no input token. On subsequent calls, read the - * input token into a GSS buffer. - */ - if (conn->gctx != GSS_C_NO_CONTEXT) - { - ginbuf.length = payloadlen; - ginbuf.value = malloc(payloadlen); - if (!ginbuf.value) - { - libpq_append_conn_error(conn, "out of memory allocating GSSAPI buffer (%d)", - payloadlen); - return STATUS_ERROR; - } - if (pqGetnchar(ginbuf.value, payloadlen, conn)) - { - /* - * Shouldn't happen, because the caller should've ensured that the - * whole message is already in the input buffer. - */ - free(ginbuf.value); - return STATUS_ERROR; - } - } - else - { - ginbuf.length = 0; - ginbuf.value = NULL; - } - - /* Only try to acquire credentials if GSS delegation isn't disabled. */ - if (!pg_GSS_have_cred_cache(&conn->gcred)) - conn->gcred = GSS_C_NO_CREDENTIAL; - - if (conn->gssdelegation && conn->gssdelegation[0] == '1') - gss_flags |= GSS_C_DELEG_FLAG; - - maj_stat = gss_init_sec_context(&min_stat, - conn->gcred, - &conn->gctx, - conn->gtarg_nam, - GSS_C_NO_OID, - gss_flags, - 0, - GSS_C_NO_CHANNEL_BINDINGS, - (ginbuf.value == NULL) ? GSS_C_NO_BUFFER : &ginbuf, - NULL, - &goutbuf, - NULL, - NULL); - - free(ginbuf.value); - - if (goutbuf.length != 0) - { - /* - * GSS generated data to send to the server. We don't care if it's the - * first or subsequent packet, just send the same kind of password - * packet. - */ - if (pqPacketSend(conn, 'p', - goutbuf.value, goutbuf.length) != STATUS_OK) - { - gss_release_buffer(&lmin_s, &goutbuf); - return STATUS_ERROR; - } - } - gss_release_buffer(&lmin_s, &goutbuf); - - if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) - { - pg_GSS_error(libpq_gettext("GSSAPI continuation error"), - conn, - maj_stat, min_stat); - gss_release_name(&lmin_s, &conn->gtarg_nam); - if (conn->gctx) - gss_delete_sec_context(&lmin_s, &conn->gctx, GSS_C_NO_BUFFER); - return STATUS_ERROR; - } - - if (maj_stat == GSS_S_COMPLETE) - { - conn->client_finished_auth = true; - gss_release_name(&lmin_s, &conn->gtarg_nam); - conn->gssapi_used = true; - } - - return STATUS_OK; -} - -/* - * Send initial GSS authentication token - */ -static int -pg_GSS_startup(PGconn *conn, int payloadlen) -{ - int ret; - char *host = conn->connhost[conn->whichhost].host; - - if (!(host && host[0] != '\0')) - { - libpq_append_conn_error(conn, "host name must be specified"); - return STATUS_ERROR; - } - - if (conn->gctx) - { - libpq_append_conn_error(conn, "duplicate GSS authentication request"); - return STATUS_ERROR; - } - - ret = pg_GSS_load_servicename(conn); - if (ret != STATUS_OK) - return ret; - - /* - * Initial packet is the same as a continuation packet with no initial - * context. - */ - conn->gctx = GSS_C_NO_CONTEXT; - - return pg_GSS_continue(conn, payloadlen); -} -#endif /* ENABLE_GSS */ - - -#ifdef ENABLE_SSPI -/* - * SSPI authentication system (Windows only) - */ - -static void -pg_SSPI_error(PGconn *conn, const char *mprefix, SECURITY_STATUS r) -{ - char sysmsg[256]; - - if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, r, 0, - sysmsg, sizeof(sysmsg), NULL) == 0) - appendPQExpBuffer(&conn->errorMessage, "%s: SSPI error %x\n", - mprefix, (unsigned int) r); - else - appendPQExpBuffer(&conn->errorMessage, "%s: %s (%x)\n", - mprefix, sysmsg, (unsigned int) r); -} - -/* - * Continue SSPI authentication with next token as needed. - */ -static int -pg_SSPI_continue(PGconn *conn, int payloadlen) -{ - SECURITY_STATUS r; - CtxtHandle newContext; - ULONG contextAttr; - SecBufferDesc inbuf; - SecBufferDesc outbuf; - SecBuffer OutBuffers[1]; - SecBuffer InBuffers[1]; - char *inputbuf = NULL; - - if (conn->sspictx != NULL) - { - /* - * On runs other than the first we have some data to send. Put this - * data in a SecBuffer type structure. - */ - inputbuf = malloc(payloadlen); - if (!inputbuf) - { - libpq_append_conn_error(conn, "out of memory allocating SSPI buffer (%d)", - payloadlen); - return STATUS_ERROR; - } - if (pqGetnchar(inputbuf, payloadlen, conn)) - { - /* - * Shouldn't happen, because the caller should've ensured that the - * whole message is already in the input buffer. - */ - free(inputbuf); - return STATUS_ERROR; - } - - inbuf.ulVersion = SECBUFFER_VERSION; - inbuf.cBuffers = 1; - inbuf.pBuffers = InBuffers; - InBuffers[0].pvBuffer = inputbuf; - InBuffers[0].cbBuffer = payloadlen; - InBuffers[0].BufferType = SECBUFFER_TOKEN; - } - - OutBuffers[0].pvBuffer = NULL; - OutBuffers[0].BufferType = SECBUFFER_TOKEN; - OutBuffers[0].cbBuffer = 0; - outbuf.cBuffers = 1; - outbuf.pBuffers = OutBuffers; - outbuf.ulVersion = SECBUFFER_VERSION; - - r = InitializeSecurityContext(conn->sspicred, - conn->sspictx, - conn->sspitarget, - ISC_REQ_ALLOCATE_MEMORY, - 0, - SECURITY_NETWORK_DREP, - (conn->sspictx == NULL) ? NULL : &inbuf, - 0, - &newContext, - &outbuf, - &contextAttr, - NULL); - - /* we don't need the input anymore */ - free(inputbuf); - - if (r != SEC_E_OK && r != SEC_I_CONTINUE_NEEDED) - { - pg_SSPI_error(conn, libpq_gettext("SSPI continuation error"), r); - - return STATUS_ERROR; - } - - if (conn->sspictx == NULL) - { - /* On first run, transfer retrieved context handle */ - conn->sspictx = malloc(sizeof(CtxtHandle)); - if (conn->sspictx == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return STATUS_ERROR; - } - memcpy(conn->sspictx, &newContext, sizeof(CtxtHandle)); - } - - /* - * If SSPI returned any data to be sent to the server (as it normally - * would), send this data as a password packet. - */ - if (outbuf.cBuffers > 0) - { - if (outbuf.cBuffers != 1) - { - /* - * This should never happen, at least not for Kerberos - * authentication. Keep check in case it shows up with other - * authentication methods later. - */ - appendPQExpBufferStr(&conn->errorMessage, - "SSPI returned invalid number of output buffers\n"); - return STATUS_ERROR; - } - - /* - * If the negotiation is complete, there may be zero bytes to send. - * The server is at this point not expecting any more data, so don't - * send it. - */ - if (outbuf.pBuffers[0].cbBuffer > 0) - { - if (pqPacketSend(conn, 'p', - outbuf.pBuffers[0].pvBuffer, outbuf.pBuffers[0].cbBuffer)) - { - FreeContextBuffer(outbuf.pBuffers[0].pvBuffer); - return STATUS_ERROR; - } - } - FreeContextBuffer(outbuf.pBuffers[0].pvBuffer); - } - - if (r == SEC_E_OK) - conn->client_finished_auth = true; - - /* Cleanup is handled by the code in freePGconn() */ - return STATUS_OK; -} - -/* - * Send initial SSPI authentication token. - * If use_negotiate is 0, use kerberos authentication package which is - * compatible with Unix. If use_negotiate is 1, use the negotiate package - * which supports both kerberos and NTLM, but is not compatible with Unix. - */ -static int -pg_SSPI_startup(PGconn *conn, int use_negotiate, int payloadlen) -{ - SECURITY_STATUS r; - TimeStamp expire; - char *host = conn->connhost[conn->whichhost].host; - - if (conn->sspictx) - { - libpq_append_conn_error(conn, "duplicate SSPI authentication request"); - return STATUS_ERROR; - } - - /* - * Retrieve credentials handle - */ - conn->sspicred = malloc(sizeof(CredHandle)); - if (conn->sspicred == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return STATUS_ERROR; - } - - r = AcquireCredentialsHandle(NULL, - use_negotiate ? "negotiate" : "kerberos", - SECPKG_CRED_OUTBOUND, - NULL, - NULL, - NULL, - NULL, - conn->sspicred, - &expire); - if (r != SEC_E_OK) - { - pg_SSPI_error(conn, libpq_gettext("could not acquire SSPI credentials"), r); - free(conn->sspicred); - conn->sspicred = NULL; - return STATUS_ERROR; - } - - /* - * Compute target principal name. SSPI has a different format from GSSAPI, - * but not more complex. We can skip the @REALM part, because Windows will - * fill that in for us automatically. - */ - if (!(host && host[0] != '\0')) - { - libpq_append_conn_error(conn, "host name must be specified"); - return STATUS_ERROR; - } - conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(host) + 2); - if (!conn->sspitarget) - { - libpq_append_conn_error(conn, "out of memory"); - return STATUS_ERROR; - } - sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, host); - - /* - * Indicate that we're in SSPI authentication mode to make sure that - * pg_SSPI_continue is called next time in the negotiation. - */ - conn->usesspi = 1; - - return pg_SSPI_continue(conn, payloadlen); -} -#endif /* ENABLE_SSPI */ - -/* - * Initialize SASL authentication exchange. - */ -static int -pg_SASL_init(PGconn *conn, int payloadlen) -{ - char *initialresponse = NULL; - int initialresponselen; - bool done; - bool success; - const char *selected_mechanism; - PQExpBufferData mechanism_buf; - char *password; - - initPQExpBuffer(&mechanism_buf); - - if (conn->channel_binding[0] == 'r' && /* require */ - !conn->ssl_in_use) - { - libpq_append_conn_error(conn, "channel binding required, but SSL not in use"); - goto error; - } - - if (conn->sasl_state) - { - libpq_append_conn_error(conn, "duplicate SASL authentication request"); - goto error; - } - - /* - * Parse the list of SASL authentication mechanisms in the - * AuthenticationSASL message, and select the best mechanism that we - * support. SCRAM-SHA-256-PLUS and SCRAM-SHA-256 are the only ones - * supported at the moment, listed by order of decreasing importance. - */ - selected_mechanism = NULL; - for (;;) - { - if (pqGets(&mechanism_buf, conn)) - { - appendPQExpBufferStr(&conn->errorMessage, - "fe_sendauth: invalid authentication request from server: invalid list of authentication mechanisms\n"); - goto error; - } - if (PQExpBufferDataBroken(mechanism_buf)) - goto oom_error; - - /* An empty string indicates end of list */ - if (mechanism_buf.data[0] == '\0') - break; - - /* - * Select the mechanism to use. Pick SCRAM-SHA-256-PLUS over anything - * else if a channel binding type is set and if the client supports it - * (and did not set channel_binding=disable). Pick SCRAM-SHA-256 if - * nothing else has already been picked. If we add more mechanisms, a - * more refined priority mechanism might become necessary. - */ - if (strcmp(mechanism_buf.data, SCRAM_SHA_256_PLUS_NAME) == 0) - { - if (conn->ssl_in_use) - { - /* The server has offered SCRAM-SHA-256-PLUS. */ - -#ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH - /* - * The client supports channel binding, which is chosen if - * channel_binding is not disabled. - */ - if (conn->channel_binding[0] != 'd') /* disable */ - { - selected_mechanism = SCRAM_SHA_256_PLUS_NAME; - conn->sasl = &pg_scram_mech; - } -#else - /* - * The client does not support channel binding. If it is - * required, complain immediately instead of the error below - * which would be confusing as the server is publishing - * SCRAM-SHA-256-PLUS. - */ - if (conn->channel_binding[0] == 'r') /* require */ - { - libpq_append_conn_error(conn, "channel binding is required, but client does not support it"); - goto error; - } -#endif - } - else - { - /* - * The server offered SCRAM-SHA-256-PLUS, but the connection - * is not SSL-encrypted. That's not sane. Perhaps SSL was - * stripped by a proxy? There's no point in continuing, - * because the server will reject the connection anyway if we - * try authenticate without channel binding even though both - * the client and server supported it. The SCRAM exchange - * checks for that, to prevent downgrade attacks. - */ - libpq_append_conn_error(conn, "server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection"); - goto error; - } - } - else if (strcmp(mechanism_buf.data, SCRAM_SHA_256_NAME) == 0 && - !selected_mechanism) - { - selected_mechanism = SCRAM_SHA_256_NAME; - conn->sasl = &pg_scram_mech; - } - } - - if (!selected_mechanism) - { - libpq_append_conn_error(conn, "none of the server's SASL authentication mechanisms are supported"); - goto error; - } - - if (conn->channel_binding[0] == 'r' && /* require */ - strcmp(selected_mechanism, SCRAM_SHA_256_PLUS_NAME) != 0) - { - libpq_append_conn_error(conn, "channel binding is required, but server did not offer an authentication method that supports channel binding"); - goto error; - } - - /* - * Now that the SASL mechanism has been chosen for the exchange, - * initialize its state information. - */ - - /* - * First, select the password to use for the exchange, complaining if - * there isn't one. Currently, all supported SASL mechanisms require a - * password, so we can just go ahead here without further distinction. - */ - conn->password_needed = true; - password = conn->connhost[conn->whichhost].password; - if (password == NULL) - password = conn->pgpass; - if (password == NULL || password[0] == '\0') - { - appendPQExpBufferStr(&conn->errorMessage, - PQnoPasswordSupplied); - goto error; - } - - Assert(conn->sasl); - - /* - * Initialize the SASL state information with all the information gathered - * during the initial exchange. - * - * Note: Only tls-unique is supported for the moment. - */ - conn->sasl_state = conn->sasl->init(conn, - password, - selected_mechanism); - if (!conn->sasl_state) - goto oom_error; - - /* Get the mechanism-specific Initial Client Response, if any */ - conn->sasl->exchange(conn->sasl_state, - NULL, -1, - &initialresponse, &initialresponselen, - &done, &success); - - if (done && !success) - goto error; - - /* - * Build a SASLInitialResponse message, and send it. - */ - if (pqPutMsgStart('p', conn)) - goto error; - if (pqPuts(selected_mechanism, conn)) - goto error; - if (initialresponse) - { - if (pqPutInt(initialresponselen, 4, conn)) - goto error; - if (pqPutnchar(initialresponse, initialresponselen, conn)) - goto error; - } - if (pqPutMsgEnd(conn)) - goto error; - if (pqFlush(conn)) - goto error; - - termPQExpBuffer(&mechanism_buf); - free(initialresponse); - - return STATUS_OK; - -error: - termPQExpBuffer(&mechanism_buf); - free(initialresponse); - return STATUS_ERROR; - -oom_error: - termPQExpBuffer(&mechanism_buf); - free(initialresponse); - libpq_append_conn_error(conn, "out of memory"); - return STATUS_ERROR; -} - -/* - * Exchange a message for SASL communication protocol with the backend. - * This should be used after calling pg_SASL_init to set up the status of - * the protocol. - */ -static int -pg_SASL_continue(PGconn *conn, int payloadlen, bool final) -{ - char *output; - int outputlen; - bool done; - bool success; - int res; - char *challenge; - - /* Read the SASL challenge from the AuthenticationSASLContinue message. */ - challenge = malloc(payloadlen + 1); - if (!challenge) - { - libpq_append_conn_error(conn, "out of memory allocating SASL buffer (%d)", - payloadlen); - return STATUS_ERROR; - } - - if (pqGetnchar(challenge, payloadlen, conn)) - { - free(challenge); - return STATUS_ERROR; - } - /* For safety and convenience, ensure the buffer is NULL-terminated. */ - challenge[payloadlen] = '\0'; - - conn->sasl->exchange(conn->sasl_state, - challenge, payloadlen, - &output, &outputlen, - &done, &success); - free(challenge); /* don't need the input anymore */ - - if (final && !done) - { - if (outputlen != 0) - free(output); - - libpq_append_conn_error(conn, "AuthenticationSASLFinal received from server, but SASL authentication was not completed"); - return STATUS_ERROR; - } - - /* - * If the exchange is not completed yet, we need to make sure that the - * SASL mechanism has generated a message to send back. - */ - if (output == NULL && !done) - { - libpq_append_conn_error(conn, "no client response found after SASL exchange success"); - return STATUS_ERROR; - } - - /* - * SASL allows zero-length responses, so this check uses "output" and not - * "outputlen" to allow the case of an empty message. - */ - if (output) - { - /* - * Send the SASL response to the server. - */ - res = pqPacketSend(conn, 'p', output, outputlen); - free(output); - - if (res != STATUS_OK) - return STATUS_ERROR; - } - - if (done && !success) - return STATUS_ERROR; - - return STATUS_OK; -} - -static int -pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq) -{ - int ret; - char *crypt_pwd = NULL; - const char *pwd_to_send; - char md5Salt[4]; - - /* Read the salt from the AuthenticationMD5Password message. */ - if (areq == AUTH_REQ_MD5) - { - if (pqGetnchar(md5Salt, 4, conn)) - return STATUS_ERROR; /* shouldn't happen */ - } - - /* Encrypt the password if needed. */ - - switch (areq) - { - case AUTH_REQ_MD5: - { - char *crypt_pwd2; - const char *errstr = NULL; - - /* Allocate enough space for two MD5 hashes */ - crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1)); - if (!crypt_pwd) - { - libpq_append_conn_error(conn, "out of memory"); - return STATUS_ERROR; - } - - crypt_pwd2 = crypt_pwd + MD5_PASSWD_LEN + 1; - if (!pg_md5_encrypt(password, conn->pguser, - strlen(conn->pguser), crypt_pwd2, - &errstr)) - { - libpq_append_conn_error(conn, "could not encrypt password: %s", errstr); - free(crypt_pwd); - return STATUS_ERROR; - } - if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"), md5Salt, - 4, crypt_pwd, &errstr)) - { - libpq_append_conn_error(conn, "could not encrypt password: %s", errstr); - free(crypt_pwd); - return STATUS_ERROR; - } - - pwd_to_send = crypt_pwd; - break; - } - case AUTH_REQ_PASSWORD: - pwd_to_send = password; - break; - default: - return STATUS_ERROR; - } - ret = pqPacketSend(conn, 'p', pwd_to_send, strlen(pwd_to_send) + 1); - free(crypt_pwd); - return ret; -} - -/* - * Translate a disallowed AuthRequest code into an error message. - */ -static const char * -auth_method_description(AuthRequest areq) -{ - switch (areq) - { - case AUTH_REQ_PASSWORD: - return libpq_gettext("server requested a cleartext password"); - case AUTH_REQ_MD5: - return libpq_gettext("server requested a hashed password"); - case AUTH_REQ_GSS: - case AUTH_REQ_GSS_CONT: - return libpq_gettext("server requested GSSAPI authentication"); - case AUTH_REQ_SSPI: - return libpq_gettext("server requested SSPI authentication"); - case AUTH_REQ_SASL: - case AUTH_REQ_SASL_CONT: - case AUTH_REQ_SASL_FIN: - return libpq_gettext("server requested SASL authentication"); - } - - return libpq_gettext("server requested an unknown authentication type"); -} - -/* - * Convenience macro for checking the allowed_auth_methods bitmask. Caller - * must ensure that type is not greater than 31 (high bit of the bitmask). - */ -#define auth_method_allowed(conn, type) \ - (((conn)->allowed_auth_methods & (1 << (type))) != 0) - -/* - * Verify that the authentication request is expected, given the connection - * parameters. This is especially important when the client wishes to - * authenticate the server before any sensitive information is exchanged. - */ -static bool -check_expected_areq(AuthRequest areq, PGconn *conn) -{ - bool result = true; - const char *reason = NULL; - - StaticAssertDecl((sizeof(conn->allowed_auth_methods) * CHAR_BIT) > AUTH_REQ_MAX, - "AUTH_REQ_MAX overflows the allowed_auth_methods bitmask"); - - if (conn->sslcertmode[0] == 'r' /* require */ - && areq == AUTH_REQ_OK) - { - /* - * Trade off a little bit of complexity to try to get these error - * messages as precise as possible. - */ - if (!conn->ssl_cert_requested) - { - libpq_append_conn_error(conn, "server did not request an SSL certificate"); - return false; - } - else if (!conn->ssl_cert_sent) - { - libpq_append_conn_error(conn, "server accepted connection without a valid SSL certificate"); - return false; - } - } - - /* - * If the user required a specific auth method, or specified an allowed - * set, then reject all others here, and make sure the server actually - * completes an authentication exchange. - */ - if (conn->require_auth) - { - switch (areq) - { - case AUTH_REQ_OK: - - /* - * Check to make sure we've actually finished our exchange (or - * else that the user has allowed an authentication-less - * connection). - * - * If the user has allowed both SCRAM and unauthenticated - * (trust) connections, then this check will silently accept - * partial SCRAM exchanges, where a misbehaving server does - * not provide its verifier before sending an OK. This is - * consistent with historical behavior, but it may be a point - * to revisit in the future, since it could allow a server - * that doesn't know the user's password to silently harvest - * material for a brute force attack. - */ - if (!conn->auth_required || conn->client_finished_auth) - break; - - /* - * No explicit authentication request was made by the server - * -- or perhaps it was made and not completed, in the case of - * SCRAM -- but there is one special case to check. If the - * user allowed "gss", then a GSS-encrypted channel also - * satisfies the check. - */ -#ifdef ENABLE_GSS - if (auth_method_allowed(conn, AUTH_REQ_GSS) && conn->gssenc) - { - /* - * If implicit GSS auth has already been performed via GSS - * encryption, we don't need to have performed an - * AUTH_REQ_GSS exchange. This allows require_auth=gss to - * be combined with gssencmode, since there won't be an - * explicit authentication request in that case. - */ - } - else -#endif - { - reason = libpq_gettext("server did not complete authentication"); - result = false; - } - - break; - - case AUTH_REQ_PASSWORD: - case AUTH_REQ_MD5: - case AUTH_REQ_GSS: - case AUTH_REQ_GSS_CONT: - case AUTH_REQ_SSPI: - case AUTH_REQ_SASL: - case AUTH_REQ_SASL_CONT: - case AUTH_REQ_SASL_FIN: - - /* - * We don't handle these with the default case, to avoid - * bit-shifting past the end of the allowed_auth_methods mask - * if the server sends an unexpected AuthRequest. - */ - result = auth_method_allowed(conn, areq); - break; - - default: - result = false; - break; - } - } - - if (!result) - { - if (!reason) - reason = auth_method_description(areq); - - libpq_append_conn_error(conn, "authentication method requirement \"%s\" failed: %s", - conn->require_auth, reason); - return result; - } - - /* - * When channel_binding=require, we must protect against two cases: (1) we - * must not respond to non-SASL authentication requests, which might leak - * information such as the client's password; and (2) even if we receive - * AUTH_REQ_OK, we still must ensure that channel binding has happened in - * order to authenticate the server. - */ - if (conn->channel_binding[0] == 'r' /* require */ ) - { - switch (areq) - { - case AUTH_REQ_SASL: - case AUTH_REQ_SASL_CONT: - case AUTH_REQ_SASL_FIN: - break; - case AUTH_REQ_OK: - if (!conn->sasl || !conn->sasl->channel_bound(conn->sasl_state)) - { - libpq_append_conn_error(conn, "channel binding required, but server authenticated client without channel binding"); - result = false; - } - break; - default: - libpq_append_conn_error(conn, "channel binding required but not supported by server's authentication request"); - result = false; - break; - } - } - - return result; -} - -/* - * pg_fe_sendauth - * client demux routine for processing an authentication request - * - * The server has sent us an authentication challenge (or OK). Send an - * appropriate response. The caller has ensured that the whole message is - * now in the input buffer, and has already read the type and length of - * it. We are responsible for reading any remaining extra data, specific - * to the authentication method. 'payloadlen' is the remaining length in - * the message. - */ -int -pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn) -{ - int oldmsglen; - - if (!check_expected_areq(areq, conn)) - return STATUS_ERROR; - - switch (areq) - { - case AUTH_REQ_OK: - break; - - case AUTH_REQ_KRB4: - libpq_append_conn_error(conn, "Kerberos 4 authentication not supported"); - return STATUS_ERROR; - - case AUTH_REQ_KRB5: - libpq_append_conn_error(conn, "Kerberos 5 authentication not supported"); - return STATUS_ERROR; - -#if defined(ENABLE_GSS) || defined(ENABLE_SSPI) - case AUTH_REQ_GSS: -#if !defined(ENABLE_SSPI) - /* no native SSPI, so use GSSAPI library for it */ - case AUTH_REQ_SSPI: -#endif - { - int r; - - pglock_thread(); - - /* - * If we have both GSS and SSPI support compiled in, use SSPI - * support by default. This is overridable by a connection - * string parameter. Note that when using SSPI we still leave - * the negotiate parameter off, since we want SSPI to use the - * GSSAPI kerberos protocol. For actual SSPI negotiate - * protocol, we use AUTH_REQ_SSPI. - */ -#if defined(ENABLE_GSS) && defined(ENABLE_SSPI) - if (conn->gsslib && (pg_strcasecmp(conn->gsslib, "gssapi") == 0)) - r = pg_GSS_startup(conn, payloadlen); - else - r = pg_SSPI_startup(conn, 0, payloadlen); -#elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI) - r = pg_GSS_startup(conn, payloadlen); -#elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI) - r = pg_SSPI_startup(conn, 0, payloadlen); -#endif - if (r != STATUS_OK) - { - /* Error message already filled in. */ - pgunlock_thread(); - return STATUS_ERROR; - } - pgunlock_thread(); - } - break; - - case AUTH_REQ_GSS_CONT: - { - int r; - - pglock_thread(); -#if defined(ENABLE_GSS) && defined(ENABLE_SSPI) - if (conn->usesspi) - r = pg_SSPI_continue(conn, payloadlen); - else - r = pg_GSS_continue(conn, payloadlen); -#elif defined(ENABLE_GSS) && !defined(ENABLE_SSPI) - r = pg_GSS_continue(conn, payloadlen); -#elif !defined(ENABLE_GSS) && defined(ENABLE_SSPI) - r = pg_SSPI_continue(conn, payloadlen); -#endif - if (r != STATUS_OK) - { - /* Error message already filled in. */ - pgunlock_thread(); - return STATUS_ERROR; - } - pgunlock_thread(); - } - break; -#else /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */ - /* No GSSAPI *or* SSPI support */ - case AUTH_REQ_GSS: - case AUTH_REQ_GSS_CONT: - libpq_append_conn_error(conn, "GSSAPI authentication not supported"); - return STATUS_ERROR; -#endif /* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */ - -#ifdef ENABLE_SSPI - case AUTH_REQ_SSPI: - - /* - * SSPI has its own startup message so libpq can decide which - * method to use. Indicate to pg_SSPI_startup that we want SSPI - * negotiation instead of Kerberos. - */ - pglock_thread(); - if (pg_SSPI_startup(conn, 1, payloadlen) != STATUS_OK) - { - /* Error message already filled in. */ - pgunlock_thread(); - return STATUS_ERROR; - } - pgunlock_thread(); - break; -#else - - /* - * No SSPI support. However, if we have GSSAPI but not SSPI - * support, AUTH_REQ_SSPI will have been handled in the codepath - * for AUTH_REQ_GSS above, so don't duplicate the case label in - * that case. - */ -#if !defined(ENABLE_GSS) - case AUTH_REQ_SSPI: - libpq_append_conn_error(conn, "SSPI authentication not supported"); - return STATUS_ERROR; -#endif /* !define(ENABLE_GSS) */ -#endif /* ENABLE_SSPI */ - - - case AUTH_REQ_CRYPT: - libpq_append_conn_error(conn, "Crypt authentication not supported"); - return STATUS_ERROR; - - case AUTH_REQ_MD5: - case AUTH_REQ_PASSWORD: - { - char *password; - - conn->password_needed = true; - password = conn->connhost[conn->whichhost].password; - if (password == NULL) - password = conn->pgpass; - if (password == NULL || password[0] == '\0') - { - appendPQExpBufferStr(&conn->errorMessage, - PQnoPasswordSupplied); - return STATUS_ERROR; - } - if (pg_password_sendauth(conn, password, areq) != STATUS_OK) - { - appendPQExpBufferStr(&conn->errorMessage, - "fe_sendauth: error sending password authentication\n"); - return STATUS_ERROR; - } - - /* We expect no further authentication requests. */ - conn->client_finished_auth = true; - break; - } - - case AUTH_REQ_SASL: - - /* - * The request contains the name (as assigned by IANA) of the - * authentication mechanism. - */ - if (pg_SASL_init(conn, payloadlen) != STATUS_OK) - { - /* pg_SASL_init already set the error message */ - return STATUS_ERROR; - } - break; - - case AUTH_REQ_SASL_CONT: - case AUTH_REQ_SASL_FIN: - if (conn->sasl_state == NULL) - { - appendPQExpBufferStr(&conn->errorMessage, - "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n"); - return STATUS_ERROR; - } - oldmsglen = conn->errorMessage.len; - if (pg_SASL_continue(conn, payloadlen, - (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK) - { - /* Use this message if pg_SASL_continue didn't supply one */ - if (conn->errorMessage.len == oldmsglen) - appendPQExpBufferStr(&conn->errorMessage, - "fe_sendauth: error in SASL authentication\n"); - return STATUS_ERROR; - } - break; - - default: - libpq_append_conn_error(conn, "authentication method %u not supported", areq); - return STATUS_ERROR; - } - - return STATUS_OK; -} - - -/* - * pg_fe_getusername - * - * Returns a pointer to malloc'd space containing the name of the - * specified user_id. If there is an error, return NULL, and append - * a suitable error message to *errorMessage if that's not NULL. - * - * Caution: on Windows, the user_id argument is ignored, and we always - * fetch the current user's name. - */ -char * -pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage) -{ - char *result = NULL; - const char *name = NULL; - -#ifdef WIN32 - /* Microsoft recommends buffer size of UNLEN+1, where UNLEN = 256 */ - char username[256 + 1]; - DWORD namesize = sizeof(username); -#else - char pwdbuf[BUFSIZ]; -#endif - - /* - * Some users are using configure --enable-thread-safety-force, so we - * might as well do the locking within our library to protect getpwuid(). - * In fact, application developers can use getpwuid() in their application - * if they use the locking call we provide, or install their own locking - * function using PQregisterThreadLock(). - */ - pglock_thread(); - -#ifdef WIN32 - if (GetUserName(username, &namesize)) - name = username; - else if (errorMessage) - libpq_append_error(errorMessage, - "user name lookup failure: error code %lu", - GetLastError()); -#else - if (pg_get_user_name(user_id, pwdbuf, sizeof(pwdbuf))) - name = pwdbuf; - else if (errorMessage) - appendPQExpBuffer(errorMessage, "%s\n", pwdbuf); -#endif - - if (name) - { - result = strdup(name); - if (result == NULL && errorMessage) - libpq_append_error(errorMessage, "out of memory"); - } - - pgunlock_thread(); - - return result; -} - -/* - * pg_fe_getauthname - * - * Returns a pointer to malloc'd space containing whatever name the user - * has authenticated to the system. If there is an error, return NULL, - * and append a suitable error message to *errorMessage if that's not NULL. - */ -char * -pg_fe_getauthname(PQExpBuffer errorMessage) -{ -#ifdef WIN32 - return pg_fe_getusername(0, errorMessage); -#else - return pg_fe_getusername(geteuid(), errorMessage); -#endif -} - - -/* - * PQencryptPassword -- exported routine to encrypt a password with MD5 - * - * This function is equivalent to calling PQencryptPasswordConn with - * "md5" as the encryption method, except that this doesn't require - * a connection object. This function is deprecated, use - * PQencryptPasswordConn instead. - */ -char * -PQencryptPassword(const char *passwd, const char *user) -{ - char *crypt_pwd; - const char *errstr = NULL; - - crypt_pwd = malloc(MD5_PASSWD_LEN + 1); - if (!crypt_pwd) - return NULL; - - if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd, &errstr)) - { - free(crypt_pwd); - return NULL; - } - - return crypt_pwd; -} - -/* - * PQencryptPasswordConn -- exported routine to encrypt a password - * - * This is intended to be used by client applications that wish to send - * commands like ALTER USER joe PASSWORD 'pwd'. The password need not - * be sent in cleartext if it is encrypted on the client side. This is - * good because it ensures the cleartext password won't end up in logs, - * pg_stat displays, etc. We export the function so that clients won't - * be dependent on low-level details like whether the encryption is MD5 - * or something else. - * - * Arguments are a connection object, the cleartext password, the SQL - * name of the user it is for, and a string indicating the algorithm to - * use for encrypting the password. If algorithm is NULL, this queries - * the server for the current 'password_encryption' value. If you wish - * to avoid that, e.g. to avoid blocking, you can execute - * 'show password_encryption' yourself before calling this function, and - * pass it as the algorithm. - * - * Return value is a malloc'd string. The client may assume the string - * doesn't contain any special characters that would require escaping. - * On error, an error message is stored in the connection object, and - * returns NULL. - */ -char * -PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, - const char *algorithm) -{ -#define MAX_ALGORITHM_NAME_LEN 50 - char algobuf[MAX_ALGORITHM_NAME_LEN + 1]; - char *crypt_pwd = NULL; - - if (!conn) - return NULL; - - pqClearConnErrorState(conn); - - /* If no algorithm was given, ask the server. */ - if (algorithm == NULL) - { - PGresult *res; - char *val; - - res = PQexec(conn, "show password_encryption"); - if (res == NULL) - { - /* PQexec() should've set conn->errorMessage already */ - return NULL; - } - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - /* PQexec() should've set conn->errorMessage already */ - PQclear(res); - return NULL; - } - if (PQntuples(res) != 1 || PQnfields(res) != 1) - { - PQclear(res); - libpq_append_conn_error(conn, "unexpected shape of result set returned for SHOW"); - return NULL; - } - val = PQgetvalue(res, 0, 0); - - if (strlen(val) > MAX_ALGORITHM_NAME_LEN) - { - PQclear(res); - libpq_append_conn_error(conn, "password_encryption value too long"); - return NULL; - } - strcpy(algobuf, val); - PQclear(res); - - algorithm = algobuf; - } - - /* - * Also accept "on" and "off" as aliases for "md5", because - * password_encryption was a boolean before PostgreSQL 10. We refuse to - * send the password in plaintext even if it was "off". - */ - if (strcmp(algorithm, "on") == 0 || - strcmp(algorithm, "off") == 0) - algorithm = "md5"; - - /* - * Ok, now we know what algorithm to use - */ - if (strcmp(algorithm, "scram-sha-256") == 0) - { - const char *errstr = NULL; - - crypt_pwd = pg_fe_scram_build_secret(passwd, - conn->scram_sha_256_iterations, - &errstr); - if (!crypt_pwd) - libpq_append_conn_error(conn, "could not encrypt password: %s", errstr); - } - else if (strcmp(algorithm, "md5") == 0) - { - crypt_pwd = malloc(MD5_PASSWD_LEN + 1); - if (crypt_pwd) - { - const char *errstr = NULL; - - if (!pg_md5_encrypt(passwd, user, strlen(user), crypt_pwd, &errstr)) - { - libpq_append_conn_error(conn, "could not encrypt password: %s", errstr); - free(crypt_pwd); - crypt_pwd = NULL; - } - } - else - libpq_append_conn_error(conn, "out of memory"); - } - else - { - libpq_append_conn_error(conn, "unrecognized password encryption algorithm \"%s\"", - algorithm); - return NULL; - } - - return crypt_pwd; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-auth.h b/contrib/libs/libpq/src/interfaces/libpq/fe-auth.h deleted file mode 100644 index 124dd5d031..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-auth.h +++ /dev/null @@ -1,32 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-auth.h - * - * Definitions for network authentication routines - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/fe-auth.h - * - *------------------------------------------------------------------------- - */ -#ifndef FE_AUTH_H -#define FE_AUTH_H - -#include "libpq-fe.h" -#include "libpq-int.h" - - -/* Prototypes for functions in fe-auth.c */ -extern int pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn); -extern char *pg_fe_getusername(uid_t user_id, PQExpBuffer errorMessage); -extern char *pg_fe_getauthname(PQExpBuffer errorMessage); - -/* Mechanisms in fe-auth-scram.c */ -extern const pg_fe_sasl_mech pg_scram_mech; -extern char *pg_fe_scram_build_secret(const char *password, - int iterations, - const char **errstr); - -#endif /* FE_AUTH_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-connect.c b/contrib/libs/libpq/src/interfaces/libpq/fe-connect.c deleted file mode 100644 index a61eec7282..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-connect.c +++ /dev/null @@ -1,7831 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-connect.c - * functions related to setting up a connection to the backend - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-connect.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <sys/stat.h> -#include <fcntl.h> -#include <ctype.h> -#include <netdb.h> -#include <time.h> -#include <unistd.h> - -#include "common/ip.h" -#include "common/link-canary.h" -#include "common/scram-common.h" -#include "common/string.h" -#include "fe-auth.h" -#include "libpq-fe.h" -#include "libpq-int.h" -#include "mb/pg_wchar.h" -#include "pg_config_paths.h" -#include "port/pg_bswap.h" - -#ifdef WIN32 -#include "win32.h" -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0500 -#ifdef near -#undef near -#endif -#define near -#include <shlobj.h> -#include <mstcpip.h> -#else -#include <sys/socket.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#endif - -#ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 -#include "pthread-win32.h" -#else -#include <pthread.h> -#endif -#endif - -#ifdef USE_LDAP -#ifdef WIN32 -#include <winldap.h> -#else -/* OpenLDAP deprecates RFC 1823, but we want standard conformance */ -#define LDAP_DEPRECATED 1 -#error #include <ldap.h> -typedef struct timeval LDAP_TIMEVAL; -#endif -static int ldapServiceLookup(const char *purl, PQconninfoOption *options, - PQExpBuffer errorMessage); -#endif - -#ifndef WIN32 -#define PGPASSFILE ".pgpass" -#else -#define PGPASSFILE "pgpass.conf" -#endif - -/* - * Pre-9.0 servers will return this SQLSTATE if asked to set - * application_name in a startup packet. We hard-wire the value rather - * than looking into errcodes.h since it reflects historical behavior - * rather than that of the current code. - */ -#define ERRCODE_APPNAME_UNKNOWN "42704" - -/* This is part of the protocol so just define it */ -#define ERRCODE_INVALID_PASSWORD "28P01" -/* This too */ -#define ERRCODE_CANNOT_CONNECT_NOW "57P03" - -/* - * Cope with the various platform-specific ways to spell TCP keepalive socket - * options. This doesn't cover Windows, which as usual does its own thing. - */ -#if defined(TCP_KEEPIDLE) -/* TCP_KEEPIDLE is the name of this option on Linux and *BSD */ -#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPIDLE -#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPIDLE" -#elif defined(TCP_KEEPALIVE_THRESHOLD) -/* TCP_KEEPALIVE_THRESHOLD is the name of this option on Solaris >= 11 */ -#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE_THRESHOLD -#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE_THRESHOLD" -#elif defined(TCP_KEEPALIVE) && defined(__darwin__) -/* TCP_KEEPALIVE is the name of this option on macOS */ -/* Caution: Solaris has this symbol but it means something different */ -#define PG_TCP_KEEPALIVE_IDLE TCP_KEEPALIVE -#define PG_TCP_KEEPALIVE_IDLE_STR "TCP_KEEPALIVE" -#endif - -/* - * fall back options if they are not specified by arguments or defined - * by environment variables - */ -#define DefaultHost "localhost" -#define DefaultOption "" -#ifdef USE_SSL -#define DefaultChannelBinding "prefer" -#else -#define DefaultChannelBinding "disable" -#endif -#define DefaultTargetSessionAttrs "any" -#define DefaultLoadBalanceHosts "disable" -#ifdef USE_SSL -#define DefaultSSLMode "prefer" -#define DefaultSSLCertMode "allow" -#else -#define DefaultSSLMode "disable" -#define DefaultSSLCertMode "disable" -#endif -#ifdef ENABLE_GSS -#error #include "fe-gssapi-common.h" -#define DefaultGSSMode "prefer" -#else -#define DefaultGSSMode "disable" -#endif - -/* ---------- - * Definition of the conninfo parameters and their fallback resources. - * - * If Environment-Var and Compiled-in are specified as NULL, no - * fallback is available. If after all no value can be determined - * for an option, an error is returned. - * - * The value for the username is treated specially in conninfo_add_defaults. - * If the value is not obtained any other way, the username is determined - * by pg_fe_getauthname(). - * - * The Label and Disp-Char entries are provided for applications that - * want to use PQconndefaults() to create a generic database connection - * dialog. Disp-Char is defined as follows: - * "" Normal input field - * "*" Password field - hide value - * "D" Debug option - don't show by default - * - * PQconninfoOptions[] is a constant static array that we use to initialize - * a dynamically allocated working copy. All the "val" fields in - * PQconninfoOptions[] *must* be NULL. In a working copy, non-null "val" - * fields point to malloc'd strings that should be freed when the working - * array is freed (see PQconninfoFree). - * - * The first part of each struct is identical to the one in libpq-fe.h, - * which is required since we memcpy() data between the two! - * ---------- - */ -typedef struct _internalPQconninfoOption -{ - char *keyword; /* The keyword of the option */ - char *envvar; /* Fallback environment variable name */ - char *compiled; /* Fallback compiled in default value */ - char *val; /* Option's current value, or NULL */ - char *label; /* Label for field in connect dialog */ - char *dispchar; /* Indicates how to display this field in a - * connect dialog. Values are: "" Display - * entered value as is "*" Password field - - * hide value "D" Debug option - don't show - * by default */ - int dispsize; /* Field size in characters for dialog */ - /* --- - * Anything above this comment must be synchronized with - * PQconninfoOption in libpq-fe.h, since we memcpy() data - * between them! - * --- - */ - off_t connofs; /* Offset into PGconn struct, -1 if not there */ -} internalPQconninfoOption; - -static const internalPQconninfoOption PQconninfoOptions[] = { - {"service", "PGSERVICE", NULL, NULL, - "Database-Service", "", 20, -1}, - - {"user", "PGUSER", NULL, NULL, - "Database-User", "", 20, - offsetof(struct pg_conn, pguser)}, - - {"password", "PGPASSWORD", NULL, NULL, - "Database-Password", "*", 20, - offsetof(struct pg_conn, pgpass)}, - - {"passfile", "PGPASSFILE", NULL, NULL, - "Database-Password-File", "", 64, - offsetof(struct pg_conn, pgpassfile)}, - - {"channel_binding", "PGCHANNELBINDING", DefaultChannelBinding, NULL, - "Channel-Binding", "", 8, /* sizeof("require") == 8 */ - offsetof(struct pg_conn, channel_binding)}, - - {"connect_timeout", "PGCONNECT_TIMEOUT", NULL, NULL, - "Connect-timeout", "", 10, /* strlen(INT32_MAX) == 10 */ - offsetof(struct pg_conn, connect_timeout)}, - - {"dbname", "PGDATABASE", NULL, NULL, - "Database-Name", "", 20, - offsetof(struct pg_conn, dbName)}, - - {"host", "PGHOST", NULL, NULL, - "Database-Host", "", 40, - offsetof(struct pg_conn, pghost)}, - - {"hostaddr", "PGHOSTADDR", NULL, NULL, - "Database-Host-IP-Address", "", 45, - offsetof(struct pg_conn, pghostaddr)}, - - {"port", "PGPORT", DEF_PGPORT_STR, NULL, - "Database-Port", "", 6, - offsetof(struct pg_conn, pgport)}, - - {"client_encoding", "PGCLIENTENCODING", NULL, NULL, - "Client-Encoding", "", 10, - offsetof(struct pg_conn, client_encoding_initial)}, - - {"options", "PGOPTIONS", DefaultOption, NULL, - "Backend-Options", "", 40, - offsetof(struct pg_conn, pgoptions)}, - - {"application_name", "PGAPPNAME", NULL, NULL, - "Application-Name", "", 64, - offsetof(struct pg_conn, appname)}, - - {"fallback_application_name", NULL, NULL, NULL, - "Fallback-Application-Name", "", 64, - offsetof(struct pg_conn, fbappname)}, - - {"keepalives", NULL, NULL, NULL, - "TCP-Keepalives", "", 1, /* should be just '0' or '1' */ - offsetof(struct pg_conn, keepalives)}, - - {"keepalives_idle", NULL, NULL, NULL, - "TCP-Keepalives-Idle", "", 10, /* strlen(INT32_MAX) == 10 */ - offsetof(struct pg_conn, keepalives_idle)}, - - {"keepalives_interval", NULL, NULL, NULL, - "TCP-Keepalives-Interval", "", 10, /* strlen(INT32_MAX) == 10 */ - offsetof(struct pg_conn, keepalives_interval)}, - - {"keepalives_count", NULL, NULL, NULL, - "TCP-Keepalives-Count", "", 10, /* strlen(INT32_MAX) == 10 */ - offsetof(struct pg_conn, keepalives_count)}, - - {"tcp_user_timeout", NULL, NULL, NULL, - "TCP-User-Timeout", "", 10, /* strlen(INT32_MAX) == 10 */ - offsetof(struct pg_conn, pgtcp_user_timeout)}, - - /* - * ssl options are allowed even without client SSL support because the - * client can still handle SSL modes "disable" and "allow". Other - * parameters have no effect on non-SSL connections, so there is no reason - * to exclude them since none of them are mandatory. - */ - {"sslmode", "PGSSLMODE", DefaultSSLMode, NULL, - "SSL-Mode", "", 12, /* sizeof("verify-full") == 12 */ - offsetof(struct pg_conn, sslmode)}, - - {"sslcompression", "PGSSLCOMPRESSION", "0", NULL, - "SSL-Compression", "", 1, - offsetof(struct pg_conn, sslcompression)}, - - {"sslcert", "PGSSLCERT", NULL, NULL, - "SSL-Client-Cert", "", 64, - offsetof(struct pg_conn, sslcert)}, - - {"sslkey", "PGSSLKEY", NULL, NULL, - "SSL-Client-Key", "", 64, - offsetof(struct pg_conn, sslkey)}, - - {"sslcertmode", "PGSSLCERTMODE", NULL, NULL, - "SSL-Client-Cert-Mode", "", 8, /* sizeof("disable") == 8 */ - offsetof(struct pg_conn, sslcertmode)}, - - {"sslpassword", NULL, NULL, NULL, - "SSL-Client-Key-Password", "*", 20, - offsetof(struct pg_conn, sslpassword)}, - - {"sslrootcert", "PGSSLROOTCERT", NULL, NULL, - "SSL-Root-Certificate", "", 64, - offsetof(struct pg_conn, sslrootcert)}, - - {"sslcrl", "PGSSLCRL", NULL, NULL, - "SSL-Revocation-List", "", 64, - offsetof(struct pg_conn, sslcrl)}, - - {"sslcrldir", "PGSSLCRLDIR", NULL, NULL, - "SSL-Revocation-List-Dir", "", 64, - offsetof(struct pg_conn, sslcrldir)}, - - {"sslsni", "PGSSLSNI", "1", NULL, - "SSL-SNI", "", 1, - offsetof(struct pg_conn, sslsni)}, - - {"requirepeer", "PGREQUIREPEER", NULL, NULL, - "Require-Peer", "", 10, - offsetof(struct pg_conn, requirepeer)}, - - {"require_auth", "PGREQUIREAUTH", NULL, NULL, - "Require-Auth", "", 14, /* sizeof("scram-sha-256") == 14 */ - offsetof(struct pg_conn, require_auth)}, - - {"ssl_min_protocol_version", "PGSSLMINPROTOCOLVERSION", "TLSv1.2", NULL, - "SSL-Minimum-Protocol-Version", "", 8, /* sizeof("TLSv1.x") == 8 */ - offsetof(struct pg_conn, ssl_min_protocol_version)}, - - {"ssl_max_protocol_version", "PGSSLMAXPROTOCOLVERSION", NULL, NULL, - "SSL-Maximum-Protocol-Version", "", 8, /* sizeof("TLSv1.x") == 8 */ - offsetof(struct pg_conn, ssl_max_protocol_version)}, - - /* - * As with SSL, all GSS options are exposed even in builds that don't have - * support. - */ - {"gssencmode", "PGGSSENCMODE", DefaultGSSMode, NULL, - "GSSENC-Mode", "", 8, /* sizeof("disable") == 8 */ - offsetof(struct pg_conn, gssencmode)}, - - /* Kerberos and GSSAPI authentication support specifying the service name */ - {"krbsrvname", "PGKRBSRVNAME", PG_KRB_SRVNAM, NULL, - "Kerberos-service-name", "", 20, - offsetof(struct pg_conn, krbsrvname)}, - - {"gsslib", "PGGSSLIB", NULL, NULL, - "GSS-library", "", 7, /* sizeof("gssapi") == 7 */ - offsetof(struct pg_conn, gsslib)}, - - {"gssdelegation", "PGGSSDELEGATION", "0", NULL, - "GSS-delegation", "", 1, - offsetof(struct pg_conn, gssdelegation)}, - - {"replication", NULL, NULL, NULL, - "Replication", "D", 5, - offsetof(struct pg_conn, replication)}, - - {"target_session_attrs", "PGTARGETSESSIONATTRS", - DefaultTargetSessionAttrs, NULL, - "Target-Session-Attrs", "", 15, /* sizeof("prefer-standby") = 15 */ - offsetof(struct pg_conn, target_session_attrs)}, - - {"load_balance_hosts", "PGLOADBALANCEHOSTS", - DefaultLoadBalanceHosts, NULL, - "Load-Balance-Hosts", "", 8, /* sizeof("disable") = 8 */ - offsetof(struct pg_conn, load_balance_hosts)}, - - /* Terminating entry --- MUST BE LAST */ - {NULL, NULL, NULL, NULL, - NULL, NULL, 0} -}; - -static const PQEnvironmentOption EnvironmentOptions[] = -{ - /* common user-interface settings */ - { - "PGDATESTYLE", "datestyle" - }, - { - "PGTZ", "timezone" - }, - /* internal performance-related settings */ - { - "PGGEQO", "geqo" - }, - { - NULL, NULL - } -}; - -/* The connection URI must start with either of the following designators: */ -static const char uri_designator[] = "postgresql://"; -static const char short_uri_designator[] = "postgres://"; - -static bool connectOptions1(PGconn *conn, const char *conninfo); -static bool connectOptions2(PGconn *conn); -static int connectDBStart(PGconn *conn); -static int connectDBComplete(PGconn *conn); -static PGPing internal_ping(PGconn *conn); -static PGconn *makeEmptyPGconn(void); -static void pqFreeCommandQueue(PGcmdQueueEntry *queue); -static bool fillPGconn(PGconn *conn, PQconninfoOption *connOptions); -static void freePGconn(PGconn *conn); -static void closePGconn(PGconn *conn); -static void release_conn_addrinfo(PGconn *conn); -static int store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist); -static void sendTerminateConn(PGconn *conn); -static PQconninfoOption *conninfo_init(PQExpBuffer errorMessage); -static PQconninfoOption *parse_connection_string(const char *connstr, - PQExpBuffer errorMessage, bool use_defaults); -static int uri_prefix_length(const char *connstr); -static bool recognized_connection_string(const char *connstr); -static PQconninfoOption *conninfo_parse(const char *conninfo, - PQExpBuffer errorMessage, bool use_defaults); -static PQconninfoOption *conninfo_array_parse(const char *const *keywords, - const char *const *values, PQExpBuffer errorMessage, - bool use_defaults, int expand_dbname); -static bool conninfo_add_defaults(PQconninfoOption *options, - PQExpBuffer errorMessage); -static PQconninfoOption *conninfo_uri_parse(const char *uri, - PQExpBuffer errorMessage, bool use_defaults); -static bool conninfo_uri_parse_options(PQconninfoOption *options, - const char *uri, PQExpBuffer errorMessage); -static bool conninfo_uri_parse_params(char *params, - PQconninfoOption *connOptions, - PQExpBuffer errorMessage); -static char *conninfo_uri_decode(const char *str, PQExpBuffer errorMessage); -static bool get_hexdigit(char digit, int *value); -static const char *conninfo_getval(PQconninfoOption *connOptions, - const char *keyword); -static PQconninfoOption *conninfo_storeval(PQconninfoOption *connOptions, - const char *keyword, const char *value, - PQExpBuffer errorMessage, bool ignoreMissing, bool uri_decode); -static PQconninfoOption *conninfo_find(PQconninfoOption *connOptions, - const char *keyword); -static void defaultNoticeReceiver(void *arg, const PGresult *res); -static void defaultNoticeProcessor(void *arg, const char *message); -static int parseServiceInfo(PQconninfoOption *options, - PQExpBuffer errorMessage); -static int parseServiceFile(const char *serviceFile, - const char *service, - PQconninfoOption *options, - PQExpBuffer errorMessage, - bool *group_found); -static char *pwdfMatchesString(char *buf, const char *token); -static char *passwordFromFile(const char *hostname, const char *port, const char *dbname, - const char *username, const char *pgpassfile); -static void pgpassfileWarning(PGconn *conn); -static void default_threadlock(int acquire); -static bool sslVerifyProtocolVersion(const char *version); -static bool sslVerifyProtocolRange(const char *min, const char *max); -static bool parse_int_param(const char *value, int *result, PGconn *conn, - const char *context); - - -/* global variable because fe-auth.c needs to access it */ -pgthreadlock_t pg_g_threadlock = default_threadlock; - - -/* - * pqDropConnection - * - * Close any physical connection to the server, and reset associated - * state inside the connection object. We don't release state that - * would be needed to reconnect, though, nor local state that might still - * be useful later. - * - * We can always flush the output buffer, since there's no longer any hope - * of sending that data. However, unprocessed input data might still be - * valuable, so the caller must tell us whether to flush that or not. - */ -void -pqDropConnection(PGconn *conn, bool flushInput) -{ - /* Drop any SSL state */ - pqsecure_close(conn); - - /* Close the socket itself */ - if (conn->sock != PGINVALID_SOCKET) - closesocket(conn->sock); - conn->sock = PGINVALID_SOCKET; - - /* Optionally discard any unread data */ - if (flushInput) - conn->inStart = conn->inCursor = conn->inEnd = 0; - - /* Always discard any unsent data */ - conn->outCount = 0; - - /* Likewise, discard any pending pipelined commands */ - pqFreeCommandQueue(conn->cmd_queue_head); - conn->cmd_queue_head = conn->cmd_queue_tail = NULL; - pqFreeCommandQueue(conn->cmd_queue_recycle); - conn->cmd_queue_recycle = NULL; - - /* Free authentication/encryption state */ -#ifdef ENABLE_GSS - { - OM_uint32 min_s; - - if (conn->gcred != GSS_C_NO_CREDENTIAL) - { - gss_release_cred(&min_s, &conn->gcred); - conn->gcred = GSS_C_NO_CREDENTIAL; - } - if (conn->gctx) - gss_delete_sec_context(&min_s, &conn->gctx, GSS_C_NO_BUFFER); - if (conn->gtarg_nam) - gss_release_name(&min_s, &conn->gtarg_nam); - if (conn->gss_SendBuffer) - { - free(conn->gss_SendBuffer); - conn->gss_SendBuffer = NULL; - } - if (conn->gss_RecvBuffer) - { - free(conn->gss_RecvBuffer); - conn->gss_RecvBuffer = NULL; - } - if (conn->gss_ResultBuffer) - { - free(conn->gss_ResultBuffer); - conn->gss_ResultBuffer = NULL; - } - conn->gssenc = false; - } -#endif -#ifdef ENABLE_SSPI - if (conn->sspitarget) - { - free(conn->sspitarget); - conn->sspitarget = NULL; - } - if (conn->sspicred) - { - FreeCredentialsHandle(conn->sspicred); - free(conn->sspicred); - conn->sspicred = NULL; - } - if (conn->sspictx) - { - DeleteSecurityContext(conn->sspictx); - free(conn->sspictx); - conn->sspictx = NULL; - } - conn->usesspi = 0; -#endif - if (conn->sasl_state) - { - conn->sasl->free(conn->sasl_state); - conn->sasl_state = NULL; - } -} - -/* - * pqFreeCommandQueue - * Free all the entries of PGcmdQueueEntry queue passed. - */ -static void -pqFreeCommandQueue(PGcmdQueueEntry *queue) -{ - while (queue != NULL) - { - PGcmdQueueEntry *cur = queue; - - queue = cur->next; - free(cur->query); - free(cur); - } -} - -/* - * pqDropServerData - * - * Clear all connection state data that was received from (or deduced about) - * the server. This is essential to do between connection attempts to - * different servers, else we may incorrectly hold over some data from the - * old server. - * - * It would be better to merge this into pqDropConnection, perhaps, but - * right now we cannot because that function is called immediately on - * detection of connection loss (cf. pqReadData, for instance). This data - * should be kept until we are actually starting a new connection. - */ -static void -pqDropServerData(PGconn *conn) -{ - PGnotify *notify; - pgParameterStatus *pstatus; - - /* Forget pending notifies */ - notify = conn->notifyHead; - while (notify != NULL) - { - PGnotify *prev = notify; - - notify = notify->next; - free(prev); - } - conn->notifyHead = conn->notifyTail = NULL; - - /* Reset ParameterStatus data, as well as variables deduced from it */ - pstatus = conn->pstatus; - while (pstatus != NULL) - { - pgParameterStatus *prev = pstatus; - - pstatus = pstatus->next; - free(prev); - } - conn->pstatus = NULL; - conn->client_encoding = PG_SQL_ASCII; - conn->std_strings = false; - conn->default_transaction_read_only = PG_BOOL_UNKNOWN; - conn->in_hot_standby = PG_BOOL_UNKNOWN; - conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS; - conn->sversion = 0; - - /* Drop large-object lookup data */ - free(conn->lobjfuncs); - conn->lobjfuncs = NULL; - - /* Reset assorted other per-connection state */ - conn->last_sqlstate[0] = '\0'; - conn->auth_req_received = false; - conn->client_finished_auth = false; - conn->password_needed = false; - conn->gssapi_used = false; - conn->write_failed = false; - free(conn->write_err_msg); - conn->write_err_msg = NULL; - conn->be_pid = 0; - conn->be_key = 0; -} - - -/* - * Connecting to a Database - * - * There are now six different ways a user of this API can connect to the - * database. Two are not recommended for use in new code, because of their - * lack of extensibility with respect to the passing of options to the - * backend. These are PQsetdb and PQsetdbLogin (the former now being a macro - * to the latter). - * - * If it is desired to connect in a synchronous (blocking) manner, use the - * function PQconnectdb or PQconnectdbParams. The former accepts a string of - * option = value pairs (or a URI) which must be parsed; the latter takes two - * NULL terminated arrays instead. - * - * To connect in an asynchronous (non-blocking) manner, use the functions - * PQconnectStart or PQconnectStartParams (which differ in the same way as - * PQconnectdb and PQconnectdbParams) and PQconnectPoll. - * - * Internally, the static functions connectDBStart, connectDBComplete - * are part of the connection procedure. - */ - -/* - * PQconnectdbParams - * - * establishes a connection to a postgres backend through the postmaster - * using connection information in two arrays. - * - * The keywords array is defined as - * - * const char *params[] = {"option1", "option2", NULL} - * - * The values array is defined as - * - * const char *values[] = {"value1", "value2", NULL} - * - * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL - * if a memory allocation failed. - * If the status field of the connection returned is CONNECTION_BAD, - * then some fields may be null'ed out instead of having valid values. - * - * You should call PQfinish (if conn is not NULL) regardless of whether this - * call succeeded. - */ -PGconn * -PQconnectdbParams(const char *const *keywords, - const char *const *values, - int expand_dbname) -{ - PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname); - - if (conn && conn->status != CONNECTION_BAD) - (void) connectDBComplete(conn); - - return conn; -} - -/* - * PQpingParams - * - * check server status, accepting parameters identical to PQconnectdbParams - */ -PGPing -PQpingParams(const char *const *keywords, - const char *const *values, - int expand_dbname) -{ - PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname); - PGPing ret; - - ret = internal_ping(conn); - PQfinish(conn); - - return ret; -} - -/* - * PQconnectdb - * - * establishes a connection to a postgres backend through the postmaster - * using connection information in a string. - * - * The conninfo string is either a whitespace-separated list of - * - * option = value - * - * definitions or a URI (refer to the documentation for details.) Value - * might be a single value containing no whitespaces or a single quoted - * string. If a single quote should appear anywhere in the value, it must be - * escaped with a backslash like \' - * - * Returns a PGconn* which is needed for all subsequent libpq calls, or NULL - * if a memory allocation failed. - * If the status field of the connection returned is CONNECTION_BAD, - * then some fields may be null'ed out instead of having valid values. - * - * You should call PQfinish (if conn is not NULL) regardless of whether this - * call succeeded. - */ -PGconn * -PQconnectdb(const char *conninfo) -{ - PGconn *conn = PQconnectStart(conninfo); - - if (conn && conn->status != CONNECTION_BAD) - (void) connectDBComplete(conn); - - return conn; -} - -/* - * PQping - * - * check server status, accepting parameters identical to PQconnectdb - */ -PGPing -PQping(const char *conninfo) -{ - PGconn *conn = PQconnectStart(conninfo); - PGPing ret; - - ret = internal_ping(conn); - PQfinish(conn); - - return ret; -} - -/* - * PQconnectStartParams - * - * Begins the establishment of a connection to a postgres backend through the - * postmaster using connection information in a struct. - * - * See comment for PQconnectdbParams for the definition of the string format. - * - * Returns a PGconn*. If NULL is returned, a malloc error has occurred, and - * you should not attempt to proceed with this connection. If the status - * field of the connection returned is CONNECTION_BAD, an error has - * occurred. In this case you should call PQfinish on the result, (perhaps - * inspecting the error message first). Other fields of the structure may not - * be valid if that occurs. If the status field is not CONNECTION_BAD, then - * this stage has succeeded - call PQconnectPoll, using select(2) to see when - * this is necessary. - * - * See PQconnectPoll for more info. - */ -PGconn * -PQconnectStartParams(const char *const *keywords, - const char *const *values, - int expand_dbname) -{ - PGconn *conn; - PQconninfoOption *connOptions; - - /* - * Allocate memory for the conn structure. Note that we also expect this - * to initialize conn->errorMessage to empty. All subsequent steps during - * connection initialization will only append to that buffer. - */ - conn = makeEmptyPGconn(); - if (conn == NULL) - return NULL; - - /* - * Parse the conninfo arrays - */ - connOptions = conninfo_array_parse(keywords, values, - &conn->errorMessage, - true, expand_dbname); - if (connOptions == NULL) - { - conn->status = CONNECTION_BAD; - /* errorMessage is already set */ - return conn; - } - - /* - * Move option values into conn structure - */ - if (!fillPGconn(conn, connOptions)) - { - PQconninfoFree(connOptions); - return conn; - } - - /* - * Free the option info - all is in conn now - */ - PQconninfoFree(connOptions); - - /* - * Compute derived options - */ - if (!connectOptions2(conn)) - return conn; - - /* - * Connect to the database - */ - if (!connectDBStart(conn)) - { - /* Just in case we failed to set it in connectDBStart */ - conn->status = CONNECTION_BAD; - } - - return conn; -} - -/* - * PQconnectStart - * - * Begins the establishment of a connection to a postgres backend through the - * postmaster using connection information in a string. - * - * See comment for PQconnectdb for the definition of the string format. - * - * Returns a PGconn*. If NULL is returned, a malloc error has occurred, and - * you should not attempt to proceed with this connection. If the status - * field of the connection returned is CONNECTION_BAD, an error has - * occurred. In this case you should call PQfinish on the result, (perhaps - * inspecting the error message first). Other fields of the structure may not - * be valid if that occurs. If the status field is not CONNECTION_BAD, then - * this stage has succeeded - call PQconnectPoll, using select(2) to see when - * this is necessary. - * - * See PQconnectPoll for more info. - */ -PGconn * -PQconnectStart(const char *conninfo) -{ - PGconn *conn; - - /* - * Allocate memory for the conn structure. Note that we also expect this - * to initialize conn->errorMessage to empty. All subsequent steps during - * connection initialization will only append to that buffer. - */ - conn = makeEmptyPGconn(); - if (conn == NULL) - return NULL; - - /* - * Parse the conninfo string - */ - if (!connectOptions1(conn, conninfo)) - return conn; - - /* - * Compute derived options - */ - if (!connectOptions2(conn)) - return conn; - - /* - * Connect to the database - */ - if (!connectDBStart(conn)) - { - /* Just in case we failed to set it in connectDBStart */ - conn->status = CONNECTION_BAD; - } - - return conn; -} - -/* - * Move option values into conn structure - * - * Don't put anything cute here --- intelligence should be in - * connectOptions2 ... - * - * Returns true on success. On failure, returns false and sets error message. - */ -static bool -fillPGconn(PGconn *conn, PQconninfoOption *connOptions) -{ - const internalPQconninfoOption *option; - - for (option = PQconninfoOptions; option->keyword; option++) - { - if (option->connofs >= 0) - { - const char *tmp = conninfo_getval(connOptions, option->keyword); - - if (tmp) - { - char **connmember = (char **) ((char *) conn + option->connofs); - - free(*connmember); - *connmember = strdup(tmp); - if (*connmember == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return false; - } - } - } - } - - return true; -} - -/* - * connectOptions1 - * - * Internal subroutine to set up connection parameters given an already- - * created PGconn and a conninfo string. Derived settings should be - * processed by calling connectOptions2 next. (We split them because - * PQsetdbLogin overrides defaults in between.) - * - * Returns true if OK, false if trouble (in which case errorMessage is set - * and so is conn->status). - */ -static bool -connectOptions1(PGconn *conn, const char *conninfo) -{ - PQconninfoOption *connOptions; - - /* - * Parse the conninfo string - */ - connOptions = parse_connection_string(conninfo, &conn->errorMessage, true); - if (connOptions == NULL) - { - conn->status = CONNECTION_BAD; - /* errorMessage is already set */ - return false; - } - - /* - * Move option values into conn structure - */ - if (!fillPGconn(conn, connOptions)) - { - conn->status = CONNECTION_BAD; - PQconninfoFree(connOptions); - return false; - } - - /* - * Free the option info - all is in conn now - */ - PQconninfoFree(connOptions); - - return true; -} - -/* - * Count the number of elements in a simple comma-separated list. - */ -static int -count_comma_separated_elems(const char *input) -{ - int n; - - n = 1; - for (; *input != '\0'; input++) - { - if (*input == ',') - n++; - } - - return n; -} - -/* - * Parse a simple comma-separated list. - * - * On each call, returns a malloc'd copy of the next element, and sets *more - * to indicate whether there are any more elements in the list after this, - * and updates *startptr to point to the next element, if any. - * - * On out of memory, returns NULL. - */ -static char * -parse_comma_separated_list(char **startptr, bool *more) -{ - char *p; - char *s = *startptr; - char *e; - int len; - - /* - * Search for the end of the current element; a comma or end-of-string - * acts as a terminator. - */ - e = s; - while (*e != '\0' && *e != ',') - ++e; - *more = (*e == ','); - - len = e - s; - p = (char *) malloc(sizeof(char) * (len + 1)); - if (p) - { - memcpy(p, s, len); - p[len] = '\0'; - } - *startptr = e + 1; - - return p; -} - -/* - * Initializes the prng_state field of the connection. We want something - * unpredictable, so if possible, use high-quality random bits for the - * seed. Otherwise, fall back to a seed based on the connection address, - * timestamp and PID. - */ -static void -libpq_prng_init(PGconn *conn) -{ - uint64 rseed; - struct timeval tval = {0}; - - if (pg_prng_strong_seed(&conn->prng_state)) - return; - - gettimeofday(&tval, NULL); - - rseed = ((uintptr_t) conn) ^ - ((uint64) getpid()) ^ - ((uint64) tval.tv_usec) ^ - ((uint64) tval.tv_sec); - - pg_prng_seed(&conn->prng_state, rseed); -} - -/* - * connectOptions2 - * - * Compute derived connection options after absorbing all user-supplied info. - * - * Returns true if OK, false if trouble (in which case errorMessage is set - * and so is conn->status). - */ -static bool -connectOptions2(PGconn *conn) -{ - int i; - - /* - * Allocate memory for details about each host to which we might possibly - * try to connect. For that, count the number of elements in the hostaddr - * or host options. If neither is given, assume one host. - */ - conn->whichhost = 0; - if (conn->pghostaddr && conn->pghostaddr[0] != '\0') - conn->nconnhost = count_comma_separated_elems(conn->pghostaddr); - else if (conn->pghost && conn->pghost[0] != '\0') - conn->nconnhost = count_comma_separated_elems(conn->pghost); - else - conn->nconnhost = 1; - conn->connhost = (pg_conn_host *) - calloc(conn->nconnhost, sizeof(pg_conn_host)); - if (conn->connhost == NULL) - goto oom_error; - - /* - * We now have one pg_conn_host structure per possible host. Fill in the - * host and hostaddr fields for each, by splitting the parameter strings. - */ - if (conn->pghostaddr != NULL && conn->pghostaddr[0] != '\0') - { - char *s = conn->pghostaddr; - bool more = true; - - for (i = 0; i < conn->nconnhost && more; i++) - { - conn->connhost[i].hostaddr = parse_comma_separated_list(&s, &more); - if (conn->connhost[i].hostaddr == NULL) - goto oom_error; - } - - /* - * If hostaddr was given, the array was allocated according to the - * number of elements in the hostaddr list, so it really should be the - * right size. - */ - Assert(!more); - Assert(i == conn->nconnhost); - } - - if (conn->pghost != NULL && conn->pghost[0] != '\0') - { - char *s = conn->pghost; - bool more = true; - - for (i = 0; i < conn->nconnhost && more; i++) - { - conn->connhost[i].host = parse_comma_separated_list(&s, &more); - if (conn->connhost[i].host == NULL) - goto oom_error; - } - - /* Check for wrong number of host items. */ - if (more || i != conn->nconnhost) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "could not match %d host names to %d hostaddr values", - count_comma_separated_elems(conn->pghost), conn->nconnhost); - return false; - } - } - - /* - * Now, for each host slot, identify the type of address spec, and fill in - * the default address if nothing was given. - */ - for (i = 0; i < conn->nconnhost; i++) - { - pg_conn_host *ch = &conn->connhost[i]; - - if (ch->hostaddr != NULL && ch->hostaddr[0] != '\0') - ch->type = CHT_HOST_ADDRESS; - else if (ch->host != NULL && ch->host[0] != '\0') - { - ch->type = CHT_HOST_NAME; - if (is_unixsock_path(ch->host)) - ch->type = CHT_UNIX_SOCKET; - } - else - { - free(ch->host); - - /* - * This bit selects the default host location. If you change - * this, see also pg_regress. - */ - if (DEFAULT_PGSOCKET_DIR[0]) - { - ch->host = strdup(DEFAULT_PGSOCKET_DIR); - ch->type = CHT_UNIX_SOCKET; - } - else - { - ch->host = strdup(DefaultHost); - ch->type = CHT_HOST_NAME; - } - if (ch->host == NULL) - goto oom_error; - } - } - - /* - * Next, work out the port number corresponding to each host name. - * - * Note: unlike the above for host names, this could leave the port fields - * as null or empty strings. We will substitute DEF_PGPORT whenever we - * read such a port field. - */ - if (conn->pgport != NULL && conn->pgport[0] != '\0') - { - char *s = conn->pgport; - bool more = true; - - for (i = 0; i < conn->nconnhost && more; i++) - { - conn->connhost[i].port = parse_comma_separated_list(&s, &more); - if (conn->connhost[i].port == NULL) - goto oom_error; - } - - /* - * If exactly one port was given, use it for every host. Otherwise, - * there must be exactly as many ports as there were hosts. - */ - if (i == 1 && !more) - { - for (i = 1; i < conn->nconnhost; i++) - { - conn->connhost[i].port = strdup(conn->connhost[0].port); - if (conn->connhost[i].port == NULL) - goto oom_error; - } - } - else if (more || i != conn->nconnhost) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "could not match %d port numbers to %d hosts", - count_comma_separated_elems(conn->pgport), conn->nconnhost); - return false; - } - } - - /* - * If user name was not given, fetch it. (Most likely, the fetch will - * fail, since the only way we get here is if pg_fe_getauthname() failed - * during conninfo_add_defaults(). But now we want an error message.) - */ - if (conn->pguser == NULL || conn->pguser[0] == '\0') - { - free(conn->pguser); - conn->pguser = pg_fe_getauthname(&conn->errorMessage); - if (!conn->pguser) - { - conn->status = CONNECTION_BAD; - return false; - } - } - - /* - * If database name was not given, default it to equal user name - */ - if (conn->dbName == NULL || conn->dbName[0] == '\0') - { - free(conn->dbName); - conn->dbName = strdup(conn->pguser); - if (!conn->dbName) - goto oom_error; - } - - /* - * If password was not given, try to look it up in password file. Note - * that the result might be different for each host/port pair. - */ - if (conn->pgpass == NULL || conn->pgpass[0] == '\0') - { - /* If password file wasn't specified, use ~/PGPASSFILE */ - if (conn->pgpassfile == NULL || conn->pgpassfile[0] == '\0') - { - char homedir[MAXPGPATH]; - - if (pqGetHomeDirectory(homedir, sizeof(homedir))) - { - free(conn->pgpassfile); - conn->pgpassfile = malloc(MAXPGPATH); - if (!conn->pgpassfile) - goto oom_error; - snprintf(conn->pgpassfile, MAXPGPATH, "%s/%s", - homedir, PGPASSFILE); - } - } - - if (conn->pgpassfile != NULL && conn->pgpassfile[0] != '\0') - { - for (i = 0; i < conn->nconnhost; i++) - { - /* - * Try to get a password for this host from file. We use host - * for the hostname search key if given, else hostaddr (at - * least one of them is guaranteed nonempty by now). - */ - const char *pwhost = conn->connhost[i].host; - - if (pwhost == NULL || pwhost[0] == '\0') - pwhost = conn->connhost[i].hostaddr; - - conn->connhost[i].password = - passwordFromFile(pwhost, - conn->connhost[i].port, - conn->dbName, - conn->pguser, - conn->pgpassfile); - } - } - } - - /* - * parse and validate require_auth option - */ - if (conn->require_auth && conn->require_auth[0]) - { - char *s = conn->require_auth; - bool first, - more; - bool negated = false; - - /* - * By default, start from an empty set of allowed options and add to - * it. - */ - conn->auth_required = true; - conn->allowed_auth_methods = 0; - - for (first = true, more = true; more; first = false) - { - char *method, - *part; - uint32 bits; - - part = parse_comma_separated_list(&s, &more); - if (part == NULL) - goto oom_error; - - /* - * Check for negation, e.g. '!password'. If one element is - * negated, they all have to be. - */ - method = part; - if (*method == '!') - { - if (first) - { - /* - * Switch to a permissive set of allowed options, and - * subtract from it. - */ - conn->auth_required = false; - conn->allowed_auth_methods = -1; - } - else if (!negated) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "negative require_auth method \"%s\" cannot be mixed with non-negative methods", - method); - - free(part); - return false; - } - - negated = true; - method++; - } - else if (negated) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "require_auth method \"%s\" cannot be mixed with negative methods", - method); - - free(part); - return false; - } - - if (strcmp(method, "password") == 0) - { - bits = (1 << AUTH_REQ_PASSWORD); - } - else if (strcmp(method, "md5") == 0) - { - bits = (1 << AUTH_REQ_MD5); - } - else if (strcmp(method, "gss") == 0) - { - bits = (1 << AUTH_REQ_GSS); - bits |= (1 << AUTH_REQ_GSS_CONT); - } - else if (strcmp(method, "sspi") == 0) - { - bits = (1 << AUTH_REQ_SSPI); - bits |= (1 << AUTH_REQ_GSS_CONT); - } - else if (strcmp(method, "scram-sha-256") == 0) - { - /* This currently assumes that SCRAM is the only SASL method. */ - bits = (1 << AUTH_REQ_SASL); - bits |= (1 << AUTH_REQ_SASL_CONT); - bits |= (1 << AUTH_REQ_SASL_FIN); - } - else if (strcmp(method, "none") == 0) - { - /* - * Special case: let the user explicitly allow (or disallow) - * connections where the server does not send an explicit - * authentication challenge, such as "trust" and "cert" auth. - */ - if (negated) /* "!none" */ - { - if (conn->auth_required) - goto duplicate; - - conn->auth_required = true; - } - else /* "none" */ - { - if (!conn->auth_required) - goto duplicate; - - conn->auth_required = false; - } - - free(part); - continue; /* avoid the bitmask manipulation below */ - } - else - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "require_auth", method); - - free(part); - return false; - } - - /* Update the bitmask. */ - if (negated) - { - if ((conn->allowed_auth_methods & bits) == 0) - goto duplicate; - - conn->allowed_auth_methods &= ~bits; - } - else - { - if ((conn->allowed_auth_methods & bits) == bits) - goto duplicate; - - conn->allowed_auth_methods |= bits; - } - - free(part); - continue; - - duplicate: - - /* - * A duplicated method probably indicates a typo in a setting - * where typos are extremely risky. - */ - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "require_auth method \"%s\" is specified more than once", - part); - - free(part); - return false; - } - } - - /* - * validate channel_binding option - */ - if (conn->channel_binding) - { - if (strcmp(conn->channel_binding, "disable") != 0 - && strcmp(conn->channel_binding, "prefer") != 0 - && strcmp(conn->channel_binding, "require") != 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "channel_binding", conn->channel_binding); - return false; - } - } - else - { - conn->channel_binding = strdup(DefaultChannelBinding); - if (!conn->channel_binding) - goto oom_error; - } - -#ifndef USE_SSL - - /* - * sslrootcert=system is not supported. Since setting this changes the - * default sslmode, check this _before_ we validate sslmode, to avoid - * confusing the user with errors for an option they may not have set. - */ - if (conn->sslrootcert - && strcmp(conn->sslrootcert, "system") == 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in", - "sslrootcert", conn->sslrootcert); - return false; - } -#endif - - /* - * validate sslmode option - */ - if (conn->sslmode) - { - if (strcmp(conn->sslmode, "disable") != 0 - && strcmp(conn->sslmode, "allow") != 0 - && strcmp(conn->sslmode, "prefer") != 0 - && strcmp(conn->sslmode, "require") != 0 - && strcmp(conn->sslmode, "verify-ca") != 0 - && strcmp(conn->sslmode, "verify-full") != 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "sslmode", conn->sslmode); - return false; - } - -#ifndef USE_SSL - switch (conn->sslmode[0]) - { - case 'a': /* "allow" */ - case 'p': /* "prefer" */ - - /* - * warn user that an SSL connection will never be negotiated - * since SSL was not compiled in? - */ - break; - - case 'r': /* "require" */ - case 'v': /* "verify-ca" or "verify-full" */ - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in", - "sslmode", conn->sslmode); - return false; - } -#endif - } - else - { - conn->sslmode = strdup(DefaultSSLMode); - if (!conn->sslmode) - goto oom_error; - } - -#ifdef USE_SSL - - /* - * If sslrootcert=system, make sure our chosen sslmode is compatible. - */ - if (conn->sslrootcert - && strcmp(conn->sslrootcert, "system") == 0 - && strcmp(conn->sslmode, "verify-full") != 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslrootcert=system (use \"verify-full\")", - conn->sslmode); - return false; - } -#endif - - /* - * Validate TLS protocol versions for ssl_min_protocol_version and - * ssl_max_protocol_version. - */ - if (!sslVerifyProtocolVersion(conn->ssl_min_protocol_version)) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "ssl_min_protocol_version", - conn->ssl_min_protocol_version); - return false; - } - if (!sslVerifyProtocolVersion(conn->ssl_max_protocol_version)) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "ssl_max_protocol_version", - conn->ssl_max_protocol_version); - return false; - } - - /* - * Check if the range of SSL protocols defined is correct. This is done - * at this early step because this is independent of the SSL - * implementation used, and this avoids unnecessary cycles with an - * already-built SSL context when the connection is being established, as - * it would be doomed anyway. - */ - if (!sslVerifyProtocolRange(conn->ssl_min_protocol_version, - conn->ssl_max_protocol_version)) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid SSL protocol version range"); - return false; - } - - /* - * validate sslcertmode option - */ - if (conn->sslcertmode) - { - if (strcmp(conn->sslcertmode, "disable") != 0 && - strcmp(conn->sslcertmode, "allow") != 0 && - strcmp(conn->sslcertmode, "require") != 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "sslcertmode", conn->sslcertmode); - return false; - } -#ifndef USE_SSL - if (strcmp(conn->sslcertmode, "require") == 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "%s value \"%s\" invalid when SSL support is not compiled in", - "sslcertmode", conn->sslcertmode); - return false; - } -#endif -#ifndef HAVE_SSL_CTX_SET_CERT_CB - - /* - * Without a certificate callback, the current implementation can't - * figure out if a certificate was actually requested, so "require" is - * useless. - */ - if (strcmp(conn->sslcertmode, "require") == 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "%s value \"%s\" is not supported (check OpenSSL version)", - "sslcertmode", conn->sslcertmode); - return false; - } -#endif - } - else - { - conn->sslcertmode = strdup(DefaultSSLCertMode); - if (!conn->sslcertmode) - goto oom_error; - } - - /* - * validate gssencmode option - */ - if (conn->gssencmode) - { - if (strcmp(conn->gssencmode, "disable") != 0 && - strcmp(conn->gssencmode, "prefer") != 0 && - strcmp(conn->gssencmode, "require") != 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", "gssencmode", conn->gssencmode); - return false; - } -#ifndef ENABLE_GSS - if (strcmp(conn->gssencmode, "require") == 0) - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "gssencmode value \"%s\" invalid when GSSAPI support is not compiled in", - conn->gssencmode); - return false; - } -#endif - } - else - { - conn->gssencmode = strdup(DefaultGSSMode); - if (!conn->gssencmode) - goto oom_error; - } - - /* - * validate target_session_attrs option, and set target_server_type - */ - if (conn->target_session_attrs) - { - if (strcmp(conn->target_session_attrs, "any") == 0) - conn->target_server_type = SERVER_TYPE_ANY; - else if (strcmp(conn->target_session_attrs, "read-write") == 0) - conn->target_server_type = SERVER_TYPE_READ_WRITE; - else if (strcmp(conn->target_session_attrs, "read-only") == 0) - conn->target_server_type = SERVER_TYPE_READ_ONLY; - else if (strcmp(conn->target_session_attrs, "primary") == 0) - conn->target_server_type = SERVER_TYPE_PRIMARY; - else if (strcmp(conn->target_session_attrs, "standby") == 0) - conn->target_server_type = SERVER_TYPE_STANDBY; - else if (strcmp(conn->target_session_attrs, "prefer-standby") == 0) - conn->target_server_type = SERVER_TYPE_PREFER_STANDBY; - else - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "target_session_attrs", - conn->target_session_attrs); - return false; - } - } - else - conn->target_server_type = SERVER_TYPE_ANY; - - /* - * validate load_balance_hosts option, and set load_balance_type - */ - if (conn->load_balance_hosts) - { - if (strcmp(conn->load_balance_hosts, "disable") == 0) - conn->load_balance_type = LOAD_BALANCE_DISABLE; - else if (strcmp(conn->load_balance_hosts, "random") == 0) - conn->load_balance_type = LOAD_BALANCE_RANDOM; - else - { - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "invalid %s value: \"%s\"", - "load_balance_hosts", - conn->load_balance_hosts); - return false; - } - } - else - conn->load_balance_type = LOAD_BALANCE_DISABLE; - - if (conn->load_balance_type == LOAD_BALANCE_RANDOM) - { - libpq_prng_init(conn); - - /* - * This is the "inside-out" variant of the Fisher-Yates shuffle - * algorithm. Notionally, we append each new value to the array and - * then swap it with a randomly-chosen array element (possibly - * including itself, else we fail to generate permutations with the - * last integer last). The swap step can be optimized by combining it - * with the insertion. - */ - for (i = 1; i < conn->nconnhost; i++) - { - int j = pg_prng_uint64_range(&conn->prng_state, 0, i); - pg_conn_host temp = conn->connhost[j]; - - conn->connhost[j] = conn->connhost[i]; - conn->connhost[i] = temp; - } - } - - /* - * Resolve special "auto" client_encoding from the locale - */ - if (conn->client_encoding_initial && - strcmp(conn->client_encoding_initial, "auto") == 0) - { - free(conn->client_encoding_initial); - conn->client_encoding_initial = strdup(pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true))); - if (!conn->client_encoding_initial) - goto oom_error; - } - - /* - * Only if we get this far is it appropriate to try to connect. (We need a - * state flag, rather than just the boolean result of this function, in - * case someone tries to PQreset() the PGconn.) - */ - conn->options_valid = true; - - return true; - -oom_error: - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "out of memory"); - return false; -} - -/* - * PQconndefaults - * - * Construct a default connection options array, which identifies all the - * available options and shows any default values that are available from the - * environment etc. On error (eg out of memory), NULL is returned. - * - * Using this function, an application may determine all possible options - * and their current default values. - * - * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated - * and should be freed when no longer needed via PQconninfoFree(). (In prior - * versions, the returned array was static, but that's not thread-safe.) - * Pre-7.0 applications that use this function will see a small memory leak - * until they are updated to call PQconninfoFree. - */ -PQconninfoOption * -PQconndefaults(void) -{ - PQExpBufferData errorBuf; - PQconninfoOption *connOptions; - - /* We don't actually report any errors here, but callees want a buffer */ - initPQExpBuffer(&errorBuf); - if (PQExpBufferDataBroken(errorBuf)) - return NULL; /* out of memory already :-( */ - - connOptions = conninfo_init(&errorBuf); - if (connOptions != NULL) - { - /* pass NULL errorBuf to ignore errors */ - if (!conninfo_add_defaults(connOptions, NULL)) - { - PQconninfoFree(connOptions); - connOptions = NULL; - } - } - - termPQExpBuffer(&errorBuf); - return connOptions; -} - -/* ---------------- - * PQsetdbLogin - * - * establishes a connection to a postgres backend through the postmaster - * at the specified host and port. - * - * returns a PGconn* which is needed for all subsequent libpq calls - * - * if the status field of the connection returned is CONNECTION_BAD, - * then only the errorMessage is likely to be useful. - * ---------------- - */ -PGconn * -PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, - const char *pgtty, const char *dbName, const char *login, - const char *pwd) -{ - PGconn *conn; - - /* - * Allocate memory for the conn structure. Note that we also expect this - * to initialize conn->errorMessage to empty. All subsequent steps during - * connection initialization will only append to that buffer. - */ - conn = makeEmptyPGconn(); - if (conn == NULL) - return NULL; - - /* - * If the dbName parameter contains what looks like a connection string, - * parse it into conn struct using connectOptions1. - */ - if (dbName && recognized_connection_string(dbName)) - { - if (!connectOptions1(conn, dbName)) - return conn; - } - else - { - /* - * Old-style path: first, parse an empty conninfo string in order to - * set up the same defaults that PQconnectdb() would use. - */ - if (!connectOptions1(conn, "")) - return conn; - - /* Insert dbName parameter value into struct */ - if (dbName && dbName[0] != '\0') - { - free(conn->dbName); - conn->dbName = strdup(dbName); - if (!conn->dbName) - goto oom_error; - } - } - - /* - * Insert remaining parameters into struct, overriding defaults (as well - * as any conflicting data from dbName taken as a conninfo). - */ - if (pghost && pghost[0] != '\0') - { - free(conn->pghost); - conn->pghost = strdup(pghost); - if (!conn->pghost) - goto oom_error; - } - - if (pgport && pgport[0] != '\0') - { - free(conn->pgport); - conn->pgport = strdup(pgport); - if (!conn->pgport) - goto oom_error; - } - - if (pgoptions && pgoptions[0] != '\0') - { - free(conn->pgoptions); - conn->pgoptions = strdup(pgoptions); - if (!conn->pgoptions) - goto oom_error; - } - - if (login && login[0] != '\0') - { - free(conn->pguser); - conn->pguser = strdup(login); - if (!conn->pguser) - goto oom_error; - } - - if (pwd && pwd[0] != '\0') - { - free(conn->pgpass); - conn->pgpass = strdup(pwd); - if (!conn->pgpass) - goto oom_error; - } - - /* - * Compute derived options - */ - if (!connectOptions2(conn)) - return conn; - - /* - * Connect to the database - */ - if (connectDBStart(conn)) - (void) connectDBComplete(conn); - - return conn; - -oom_error: - conn->status = CONNECTION_BAD; - libpq_append_conn_error(conn, "out of memory"); - return conn; -} - - -/* ---------- - * connectNoDelay - - * Sets the TCP_NODELAY socket option. - * Returns 1 if successful, 0 if not. - * ---------- - */ -static int -connectNoDelay(PGconn *conn) -{ -#ifdef TCP_NODELAY - int on = 1; - - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_NODELAY, - (char *) &on, - sizeof(on)) < 0) - { - char sebuf[PG_STRERROR_R_BUFLEN]; - - libpq_append_conn_error(conn, "could not set socket to TCP no delay mode: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#endif - - return 1; -} - -/* ---------- - * Write currently connected IP address into host_addr (of len host_addr_len). - * If unable to, set it to the empty string. - * ---------- - */ -static void -getHostaddr(PGconn *conn, char *host_addr, int host_addr_len) -{ - struct sockaddr_storage *addr = &conn->raddr.addr; - - if (addr->ss_family == AF_INET) - { - if (pg_inet_net_ntop(AF_INET, - &((struct sockaddr_in *) addr)->sin_addr.s_addr, - 32, - host_addr, host_addr_len) == NULL) - host_addr[0] = '\0'; - } - else if (addr->ss_family == AF_INET6) - { - if (pg_inet_net_ntop(AF_INET6, - &((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, - 128, - host_addr, host_addr_len) == NULL) - host_addr[0] = '\0'; - } - else - host_addr[0] = '\0'; -} - -/* - * emitHostIdentityInfo - - * Speculatively append "connection to server so-and-so failed: " to - * conn->errorMessage once we've identified the current connection target - * address. This ensures that any subsequent error message will be properly - * attributed to the server we couldn't connect to. conn->raddr must be - * valid, and the result of getHostaddr() must be supplied. - */ -static void -emitHostIdentityInfo(PGconn *conn, const char *host_addr) -{ - if (conn->raddr.addr.ss_family == AF_UNIX) - { - char service[NI_MAXHOST]; - - pg_getnameinfo_all(&conn->raddr.addr, conn->raddr.salen, - NULL, 0, - service, sizeof(service), - NI_NUMERICSERV); - appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("connection to server on socket \"%s\" failed: "), - service); - } - else - { - const char *displayed_host; - const char *displayed_port; - - /* To which host and port were we actually connecting? */ - if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS) - displayed_host = conn->connhost[conn->whichhost].hostaddr; - else - displayed_host = conn->connhost[conn->whichhost].host; - displayed_port = conn->connhost[conn->whichhost].port; - if (displayed_port == NULL || displayed_port[0] == '\0') - displayed_port = DEF_PGPORT_STR; - - /* - * If the user did not supply an IP address using 'hostaddr', and - * 'host' was missing or does not match our lookup, display the - * looked-up IP address. - */ - if (conn->connhost[conn->whichhost].type != CHT_HOST_ADDRESS && - host_addr[0] && - strcmp(displayed_host, host_addr) != 0) - appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("connection to server at \"%s\" (%s), port %s failed: "), - displayed_host, host_addr, - displayed_port); - else - appendPQExpBuffer(&conn->errorMessage, - libpq_gettext("connection to server at \"%s\", port %s failed: "), - displayed_host, - displayed_port); - } -} - -/* ---------- - * connectFailureMessage - - * create a friendly error message on connection failure, - * using the given errno value. Use this for error cases that - * imply that there's no server there. - * ---------- - */ -static void -connectFailureMessage(PGconn *conn, int errorno) -{ - char sebuf[PG_STRERROR_R_BUFLEN]; - - appendPQExpBuffer(&conn->errorMessage, - "%s\n", - SOCK_STRERROR(errorno, sebuf, sizeof(sebuf))); - - if (conn->raddr.addr.ss_family == AF_UNIX) - libpq_append_conn_error(conn, "\tIs the server running locally and accepting connections on that socket?"); - else - libpq_append_conn_error(conn, "\tIs the server running on that host and accepting TCP/IP connections?"); -} - -/* - * Should we use keepalives? Returns 1 if yes, 0 if no, and -1 if - * conn->keepalives is set to a value which is not parseable as an - * integer. - */ -static int -useKeepalives(PGconn *conn) -{ - char *ep; - int val; - - if (conn->keepalives == NULL) - return 1; - val = strtol(conn->keepalives, &ep, 10); - if (*ep) - return -1; - return val != 0 ? 1 : 0; -} - -/* - * Parse and try to interpret "value" as an integer value, and if successful, - * store it in *result, complaining if there is any trailing garbage or an - * overflow. This allows any number of leading and trailing whitespaces. - */ -static bool -parse_int_param(const char *value, int *result, PGconn *conn, - const char *context) -{ - char *end; - long numval; - - Assert(value != NULL); - - *result = 0; - - /* strtol(3) skips leading whitespaces */ - errno = 0; - numval = strtol(value, &end, 10); - - /* - * If no progress was done during the parsing or an error happened, fail. - * This tests properly for overflows of the result. - */ - if (value == end || errno != 0 || numval != (int) numval) - goto error; - - /* - * Skip any trailing whitespace; if anything but whitespace remains before - * the terminating character, fail - */ - while (*end != '\0' && isspace((unsigned char) *end)) - end++; - - if (*end != '\0') - goto error; - - *result = numval; - return true; - -error: - libpq_append_conn_error(conn, "invalid integer value \"%s\" for connection option \"%s\"", - value, context); - return false; -} - -#ifndef WIN32 -/* - * Set the keepalive idle timer. - */ -static int -setKeepalivesIdle(PGconn *conn) -{ - int idle; - - if (conn->keepalives_idle == NULL) - return 1; - - if (!parse_int_param(conn->keepalives_idle, &idle, conn, - "keepalives_idle")) - return 0; - if (idle < 0) - idle = 0; - -#ifdef PG_TCP_KEEPALIVE_IDLE - if (setsockopt(conn->sock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, - (char *) &idle, sizeof(idle)) < 0) - { - char sebuf[PG_STRERROR_R_BUFLEN]; - - libpq_append_conn_error(conn, "%s(%s) failed: %s", - "setsockopt", - PG_TCP_KEEPALIVE_IDLE_STR, - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#endif - - return 1; -} - -/* - * Set the keepalive interval. - */ -static int -setKeepalivesInterval(PGconn *conn) -{ - int interval; - - if (conn->keepalives_interval == NULL) - return 1; - - if (!parse_int_param(conn->keepalives_interval, &interval, conn, - "keepalives_interval")) - return 0; - if (interval < 0) - interval = 0; - -#ifdef TCP_KEEPINTVL - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPINTVL, - (char *) &interval, sizeof(interval)) < 0) - { - char sebuf[PG_STRERROR_R_BUFLEN]; - - libpq_append_conn_error(conn, "%s(%s) failed: %s", - "setsockopt", - "TCP_KEEPINTVL", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#endif - - return 1; -} - -/* - * Set the count of lost keepalive packets that will trigger a connection - * break. - */ -static int -setKeepalivesCount(PGconn *conn) -{ - int count; - - if (conn->keepalives_count == NULL) - return 1; - - if (!parse_int_param(conn->keepalives_count, &count, conn, - "keepalives_count")) - return 0; - if (count < 0) - count = 0; - -#ifdef TCP_KEEPCNT - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_KEEPCNT, - (char *) &count, sizeof(count)) < 0) - { - char sebuf[PG_STRERROR_R_BUFLEN]; - - libpq_append_conn_error(conn, "%s(%s) failed: %s", - "setsockopt", - "TCP_KEEPCNT", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#endif - - return 1; -} -#else /* WIN32 */ -#ifdef SIO_KEEPALIVE_VALS -/* - * Enable keepalives and set the keepalive values on Win32, - * where they are always set in one batch. - * - * CAUTION: This needs to be signal safe, since it's used by PQcancel. - */ -static int -setKeepalivesWin32(pgsocket sock, int idle, int interval) -{ - struct tcp_keepalive ka; - DWORD retsize; - - if (idle <= 0) - idle = 2 * 60 * 60; /* 2 hours = default */ - if (interval <= 0) - interval = 1; /* 1 second = default */ - - ka.onoff = 1; - ka.keepalivetime = idle * 1000; - ka.keepaliveinterval = interval * 1000; - - if (WSAIoctl(sock, - SIO_KEEPALIVE_VALS, - (LPVOID) &ka, - sizeof(ka), - NULL, - 0, - &retsize, - NULL, - NULL) - != 0) - return 0; - return 1; -} - -static int -prepKeepalivesWin32(PGconn *conn) -{ - int idle = -1; - int interval = -1; - - if (conn->keepalives_idle && - !parse_int_param(conn->keepalives_idle, &idle, conn, - "keepalives_idle")) - return 0; - if (conn->keepalives_interval && - !parse_int_param(conn->keepalives_interval, &interval, conn, - "keepalives_interval")) - return 0; - - if (!setKeepalivesWin32(conn->sock, idle, interval)) - { - libpq_append_conn_error(conn, "%s(%s) failed: error code %d", - "WSAIoctl", "SIO_KEEPALIVE_VALS", - WSAGetLastError()); - return 0; - } - return 1; -} -#endif /* SIO_KEEPALIVE_VALS */ -#endif /* WIN32 */ - -/* - * Set the TCP user timeout. - */ -static int -setTCPUserTimeout(PGconn *conn) -{ - int timeout; - - if (conn->pgtcp_user_timeout == NULL) - return 1; - - if (!parse_int_param(conn->pgtcp_user_timeout, &timeout, conn, - "tcp_user_timeout")) - return 0; - - if (timeout < 0) - timeout = 0; - -// Compilation must fail on linux if TCP_USER_TIMEOUT is not defined -#ifdef __linux__ - if (setsockopt(conn->sock, IPPROTO_TCP, TCP_USER_TIMEOUT, - (char *) &timeout, sizeof(timeout)) < 0) - { - char sebuf[256]; - - libpq_append_conn_error(conn, "%s(%s) failed: %s", - "setsockopt", - "TCP_USER_TIMEOUT", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - return 0; - } -#endif - - return 1; -} - -/* ---------- - * connectDBStart - - * Begin the process of making a connection to the backend. - * - * Returns 1 if successful, 0 if not. - * ---------- - */ -static int -connectDBStart(PGconn *conn) -{ - if (!conn) - return 0; - - if (!conn->options_valid) - goto connect_errReturn; - - /* - * Check for bad linking to backend-internal versions of src/common - * functions (see comments in link-canary.c for the reason we need this). - * Nobody but developers should see this message, so we don't bother - * translating it. - */ - if (!pg_link_canary_is_frontend()) - { - appendPQExpBufferStr(&conn->errorMessage, - "libpq is incorrectly linked to backend functions\n"); - goto connect_errReturn; - } - - /* Ensure our buffers are empty */ - conn->inStart = conn->inCursor = conn->inEnd = 0; - conn->outCount = 0; - - /* - * Set up to try to connect to the first host. (Setting whichhost = -1 is - * a bit of a cheat, but PQconnectPoll will advance it to 0 before - * anything else looks at it.) - */ - conn->whichhost = -1; - conn->try_next_addr = false; - conn->try_next_host = true; - conn->status = CONNECTION_NEEDED; - - /* Also reset the target_server_type state if needed */ - if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY_PASS2) - conn->target_server_type = SERVER_TYPE_PREFER_STANDBY; - - /* - * The code for processing CONNECTION_NEEDED state is in PQconnectPoll(), - * so that it can easily be re-executed if needed again during the - * asynchronous startup process. However, we must run it once here, - * because callers expect a success return from this routine to mean that - * we are in PGRES_POLLING_WRITING connection state. - */ - if (PQconnectPoll(conn) == PGRES_POLLING_WRITING) - return 1; - -connect_errReturn: - - /* - * If we managed to open a socket, close it immediately rather than - * waiting till PQfinish. (The application cannot have gotten the socket - * from PQsocket yet, so this doesn't risk breaking anything.) - */ - pqDropConnection(conn, true); - conn->status = CONNECTION_BAD; - return 0; -} - - -/* - * connectDBComplete - * - * Block and complete a connection. - * - * Returns 1 on success, 0 on failure. - */ -static int -connectDBComplete(PGconn *conn) -{ - PostgresPollingStatusType flag = PGRES_POLLING_WRITING; - time_t finish_time = ((time_t) -1); - int timeout = 0; - int last_whichhost = -2; /* certainly different from whichhost */ - int last_whichaddr = -2; /* certainly different from whichaddr */ - - if (conn == NULL || conn->status == CONNECTION_BAD) - return 0; - - /* - * Set up a time limit, if connect_timeout isn't zero. - */ - if (conn->connect_timeout != NULL) - { - if (!parse_int_param(conn->connect_timeout, &timeout, conn, - "connect_timeout")) - { - /* mark the connection as bad to report the parsing failure */ - conn->status = CONNECTION_BAD; - return 0; - } - - if (timeout > 0) - { - /* - * Rounding could cause connection to fail unexpectedly quickly; - * to prevent possibly waiting hardly-at-all, insist on at least - * two seconds. - */ - if (timeout < 2) - timeout = 2; - } - else /* negative means 0 */ - timeout = 0; - } - - for (;;) - { - int ret = 0; - - /* - * (Re)start the connect_timeout timer if it's active and we are - * considering a different host than we were last time through. If - * we've already succeeded, though, needn't recalculate. - */ - if (flag != PGRES_POLLING_OK && - timeout > 0 && - (conn->whichhost != last_whichhost || - conn->whichaddr != last_whichaddr)) - { - finish_time = time(NULL) + timeout; - last_whichhost = conn->whichhost; - last_whichaddr = conn->whichaddr; - } - - /* - * Wait, if necessary. Note that the initial state (just after - * PQconnectStart) is to wait for the socket to select for writing. - */ - switch (flag) - { - case PGRES_POLLING_OK: - return 1; /* success! */ - - case PGRES_POLLING_READING: - ret = pqWaitTimed(1, 0, conn, finish_time); - if (ret == -1) - { - /* hard failure, eg select() problem, aborts everything */ - conn->status = CONNECTION_BAD; - return 0; - } - break; - - case PGRES_POLLING_WRITING: - ret = pqWaitTimed(0, 1, conn, finish_time); - if (ret == -1) - { - /* hard failure, eg select() problem, aborts everything */ - conn->status = CONNECTION_BAD; - return 0; - } - break; - - default: - /* Just in case we failed to set it in PQconnectPoll */ - conn->status = CONNECTION_BAD; - return 0; - } - - if (ret == 1) /* connect_timeout elapsed */ - { - /* - * Give up on current server/address, try the next one. - */ - conn->try_next_addr = true; - conn->status = CONNECTION_NEEDED; - } - - /* - * Now try to advance the state machine. - */ - flag = PQconnectPoll(conn); - } -} - -/* ---------------- - * PQconnectPoll - * - * Poll an asynchronous connection. - * - * Returns a PostgresPollingStatusType. - * Before calling this function, use select(2) to determine when data - * has arrived.. - * - * You must call PQfinish whether or not this fails. - * - * This function and PQconnectStart are intended to allow connections to be - * made without blocking the execution of your program on remote I/O. However, - * there are a number of caveats: - * - * o If you call PQtrace, ensure that the stream object into which you trace - * will not block. - * o If you do not supply an IP address for the remote host (i.e. you - * supply a host name instead) then PQconnectStart will block on - * getaddrinfo. You will be fine if using Unix sockets (i.e. by - * supplying neither a host name nor a host address). - * o If your backend wants to use Kerberos authentication then you must - * supply both a host name and a host address, otherwise this function - * may block on gethostname. - * - * ---------------- - */ -PostgresPollingStatusType -PQconnectPoll(PGconn *conn) -{ - bool reset_connection_state_machine = false; - bool need_new_connection = false; - PGresult *res; - char sebuf[PG_STRERROR_R_BUFLEN]; - int optval; - - if (conn == NULL) - return PGRES_POLLING_FAILED; - - /* Get the new data */ - switch (conn->status) - { - /* - * We really shouldn't have been polled in these two cases, but we - * can handle it. - */ - case CONNECTION_BAD: - return PGRES_POLLING_FAILED; - case CONNECTION_OK: - return PGRES_POLLING_OK; - - /* These are reading states */ - case CONNECTION_AWAITING_RESPONSE: - case CONNECTION_AUTH_OK: - case CONNECTION_CHECK_WRITABLE: - case CONNECTION_CONSUME: - case CONNECTION_CHECK_STANDBY: - { - /* Load waiting data */ - int n = pqReadData(conn); - - if (n < 0) - goto error_return; - if (n == 0) - return PGRES_POLLING_READING; - - break; - } - - /* These are writing states, so we just proceed. */ - case CONNECTION_STARTED: - case CONNECTION_MADE: - break; - - /* Special cases: proceed without waiting. */ - case CONNECTION_SSL_STARTUP: - case CONNECTION_NEEDED: - case CONNECTION_GSS_STARTUP: - case CONNECTION_CHECK_TARGET: - break; - - default: - libpq_append_conn_error(conn, "invalid connection state, probably indicative of memory corruption"); - goto error_return; - } - - -keep_going: /* We will come back to here until there is - * nothing left to do. */ - - /* Time to advance to next address, or next host if no more addresses? */ - if (conn->try_next_addr) - { - if (conn->whichaddr < conn->naddr) - { - conn->whichaddr++; - reset_connection_state_machine = true; - } - else - conn->try_next_host = true; - conn->try_next_addr = false; - } - - /* Time to advance to next connhost[] entry? */ - if (conn->try_next_host) - { - pg_conn_host *ch; - struct addrinfo hint; - struct addrinfo *addrlist; - int thisport; - int ret; - char portstr[MAXPGPATH]; - - if (conn->whichhost + 1 < conn->nconnhost) - conn->whichhost++; - else - { - /* - * Oops, no more hosts. - * - * If we are trying to connect in "prefer-standby" mode, then drop - * the standby requirement and start over. - * - * Otherwise, an appropriate error message is already set up, so - * we just need to set the right status. - */ - if (conn->target_server_type == SERVER_TYPE_PREFER_STANDBY && - conn->nconnhost > 0) - { - conn->target_server_type = SERVER_TYPE_PREFER_STANDBY_PASS2; - conn->whichhost = 0; - } - else - goto error_return; - } - - /* Drop any address info for previous host */ - release_conn_addrinfo(conn); - - /* - * Look up info for the new host. On failure, log the problem in - * conn->errorMessage, then loop around to try the next host. (Note - * we don't clear try_next_host until we've succeeded.) - */ - ch = &conn->connhost[conn->whichhost]; - - /* Initialize hint structure */ - MemSet(&hint, 0, sizeof(hint)); - hint.ai_socktype = SOCK_STREAM; - hint.ai_family = AF_UNSPEC; - - /* Figure out the port number we're going to use. */ - if (ch->port == NULL || ch->port[0] == '\0') - thisport = DEF_PGPORT; - else - { - if (!parse_int_param(ch->port, &thisport, conn, "port")) - goto error_return; - - if (thisport < 1 || thisport > 65535) - { - libpq_append_conn_error(conn, "invalid port number: \"%s\"", ch->port); - goto keep_going; - } - } - snprintf(portstr, sizeof(portstr), "%d", thisport); - - /* Use pg_getaddrinfo_all() to resolve the address */ - switch (ch->type) - { - case CHT_HOST_NAME: - ret = pg_getaddrinfo_all(ch->host, portstr, &hint, - &addrlist); - if (ret || !addrlist) - { - libpq_append_conn_error(conn, "could not translate host name \"%s\" to address: %s", - ch->host, gai_strerror(ret)); - goto keep_going; - } - break; - - case CHT_HOST_ADDRESS: - hint.ai_flags = AI_NUMERICHOST; - ret = pg_getaddrinfo_all(ch->hostaddr, portstr, &hint, - &addrlist); - if (ret || !addrlist) - { - libpq_append_conn_error(conn, "could not parse network address \"%s\": %s", - ch->hostaddr, gai_strerror(ret)); - goto keep_going; - } - break; - - case CHT_UNIX_SOCKET: - hint.ai_family = AF_UNIX; - UNIXSOCK_PATH(portstr, thisport, ch->host); - if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN) - { - libpq_append_conn_error(conn, "Unix-domain socket path \"%s\" is too long (maximum %d bytes)", - portstr, - (int) (UNIXSOCK_PATH_BUFLEN - 1)); - goto keep_going; - } - - /* - * NULL hostname tells pg_getaddrinfo_all to parse the service - * name as a Unix-domain socket path. - */ - ret = pg_getaddrinfo_all(NULL, portstr, &hint, - &addrlist); - if (ret || !addrlist) - { - libpq_append_conn_error(conn, "could not translate Unix-domain socket path \"%s\" to address: %s", - portstr, gai_strerror(ret)); - goto keep_going; - } - break; - } - - /* - * Store a copy of the addrlist in private memory so we can perform - * randomization for load balancing. - */ - ret = store_conn_addrinfo(conn, addrlist); - pg_freeaddrinfo_all(hint.ai_family, addrlist); - if (ret) - goto error_return; /* message already logged */ - - /* - * If random load balancing is enabled we shuffle the addresses. - */ - if (conn->load_balance_type == LOAD_BALANCE_RANDOM) - { - /* - * This is the "inside-out" variant of the Fisher-Yates shuffle - * algorithm. Notionally, we append each new value to the array - * and then swap it with a randomly-chosen array element (possibly - * including itself, else we fail to generate permutations with - * the last integer last). The swap step can be optimized by - * combining it with the insertion. - * - * We don't need to initialize conn->prng_state here, because that - * already happened in connectOptions2. - */ - for (int i = 1; i < conn->naddr; i++) - { - int j = pg_prng_uint64_range(&conn->prng_state, 0, i); - AddrInfo temp = conn->addr[j]; - - conn->addr[j] = conn->addr[i]; - conn->addr[i] = temp; - } - } - - reset_connection_state_machine = true; - conn->try_next_host = false; - } - - /* Reset connection state machine? */ - if (reset_connection_state_machine) - { - /* - * (Re) initialize our connection control variables for a set of - * connection attempts to a single server address. These variables - * must persist across individual connection attempts, but we must - * reset them when we start to consider a new server. - */ - conn->pversion = PG_PROTOCOL(3, 0); - conn->send_appname = true; -#ifdef USE_SSL - /* initialize these values based on SSL mode */ - conn->allow_ssl_try = (conn->sslmode[0] != 'd'); /* "disable" */ - conn->wait_ssl_try = (conn->sslmode[0] == 'a'); /* "allow" */ -#endif -#ifdef ENABLE_GSS - conn->try_gss = (conn->gssencmode[0] != 'd'); /* "disable" */ -#endif - - reset_connection_state_machine = false; - need_new_connection = true; - } - - /* Force a new connection (perhaps to the same server as before)? */ - if (need_new_connection) - { - /* Drop any existing connection */ - pqDropConnection(conn, true); - - /* Reset all state obtained from old server */ - pqDropServerData(conn); - - /* Drop any PGresult we might have, too */ - conn->asyncStatus = PGASYNC_IDLE; - conn->xactStatus = PQTRANS_IDLE; - conn->pipelineStatus = PQ_PIPELINE_OFF; - pqClearAsyncResult(conn); - - /* Reset conn->status to put the state machine in the right state */ - conn->status = CONNECTION_NEEDED; - - need_new_connection = false; - } - - /* Now try to advance the state machine for this connection */ - switch (conn->status) - { - case CONNECTION_NEEDED: - { - /* - * Try to initiate a connection to one of the addresses - * returned by pg_getaddrinfo_all(). conn->whichaddr is the - * next one to try. - * - * The extra level of braces here is historical. It's not - * worth reindenting this whole switch case to remove 'em. - */ - { - char host_addr[NI_MAXHOST]; - int sock_type; - AddrInfo *addr_cur; - - /* - * Advance to next possible host, if we've tried all of - * the addresses for the current host. - */ - if (conn->whichaddr == conn->naddr) - { - conn->try_next_host = true; - goto keep_going; - } - addr_cur = &conn->addr[conn->whichaddr]; - - /* Remember current address for possible use later */ - memcpy(&conn->raddr, &addr_cur->addr, sizeof(SockAddr)); - - /* - * Set connip, too. Note we purposely ignore strdup - * failure; not a big problem if it fails. - */ - if (conn->connip != NULL) - { - free(conn->connip); - conn->connip = NULL; - } - getHostaddr(conn, host_addr, NI_MAXHOST); - if (host_addr[0]) - conn->connip = strdup(host_addr); - - /* Try to create the socket */ - sock_type = SOCK_STREAM; -#ifdef SOCK_CLOEXEC - - /* - * Atomically mark close-on-exec, if possible on this - * platform, so that there isn't a window where a - * subprogram executed by another thread inherits the - * socket. See fallback code below. - */ - sock_type |= SOCK_CLOEXEC; -#endif -#ifdef SOCK_NONBLOCK - - /* - * We might as well skip a system call for nonblocking - * mode too, if we can. - */ - sock_type |= SOCK_NONBLOCK; -#endif - conn->sock = socket(addr_cur->family, sock_type, 0); - if (conn->sock == PGINVALID_SOCKET) - { - int errorno = SOCK_ERRNO; - - /* - * Silently ignore socket() failure if we have more - * addresses to try; this reduces useless chatter in - * cases where the address list includes both IPv4 and - * IPv6 but kernel only accepts one family. - */ - if (conn->whichaddr < conn->naddr || - conn->whichhost + 1 < conn->nconnhost) - { - conn->try_next_addr = true; - goto keep_going; - } - emitHostIdentityInfo(conn, host_addr); - libpq_append_conn_error(conn, "could not create socket: %s", - SOCK_STRERROR(errorno, sebuf, sizeof(sebuf))); - goto error_return; - } - - /* - * Once we've identified a target address, all errors - * except the preceding socket()-failure case should be - * prefixed with host-identity information. (If the - * connection succeeds, the contents of conn->errorMessage - * won't matter, so this is harmless.) - */ - emitHostIdentityInfo(conn, host_addr); - - /* - * Select socket options: no delay of outgoing data for - * TCP sockets, nonblock mode, close-on-exec. Try the - * next address if any of this fails. - */ - if (addr_cur->family != AF_UNIX) - { - if (!connectNoDelay(conn)) - { - /* error message already created */ - conn->try_next_addr = true; - goto keep_going; - } - } -#ifndef SOCK_NONBLOCK - if (!pg_set_noblock(conn->sock)) - { - libpq_append_conn_error(conn, "could not set socket to nonblocking mode: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - conn->try_next_addr = true; - goto keep_going; - } -#endif - -#ifndef SOCK_CLOEXEC -#ifdef F_SETFD - if (fcntl(conn->sock, F_SETFD, FD_CLOEXEC) == -1) - { - libpq_append_conn_error(conn, "could not set socket to close-on-exec mode: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - conn->try_next_addr = true; - goto keep_going; - } -#endif /* F_SETFD */ -#endif - - if (addr_cur->family != AF_UNIX) - { -#ifndef WIN32 - int on = 1; -#endif - int usekeepalives = useKeepalives(conn); - int err = 0; - - if (usekeepalives < 0) - { - libpq_append_conn_error(conn, "keepalives parameter must be an integer"); - err = 1; - } - else if (usekeepalives == 0) - { - /* Do nothing */ - } -#ifndef WIN32 - else if (setsockopt(conn->sock, - SOL_SOCKET, SO_KEEPALIVE, - (char *) &on, sizeof(on)) < 0) - { - libpq_append_conn_error(conn, "%s(%s) failed: %s", - "setsockopt", - "SO_KEEPALIVE", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - err = 1; - } - else if (!setKeepalivesIdle(conn) - || !setKeepalivesInterval(conn) - || !setKeepalivesCount(conn)) - err = 1; -#else /* WIN32 */ -#ifdef SIO_KEEPALIVE_VALS - else if (!prepKeepalivesWin32(conn)) - err = 1; -#endif /* SIO_KEEPALIVE_VALS */ -#endif /* WIN32 */ - else if (!setTCPUserTimeout(conn)) - err = 1; - - if (err) - { - conn->try_next_addr = true; - goto keep_going; - } - } - - /*---------- - * We have three methods of blocking SIGPIPE during - * send() calls to this socket: - * - * - setsockopt(sock, SO_NOSIGPIPE) - * - send(sock, ..., MSG_NOSIGNAL) - * - setting the signal mask to SIG_IGN during send() - * - * The third method requires three syscalls per send, - * so we prefer either of the first two, but they are - * less portable. The state is tracked in the following - * members of PGconn: - * - * conn->sigpipe_so - we have set up SO_NOSIGPIPE - * conn->sigpipe_flag - we're specifying MSG_NOSIGNAL - * - * If we can use SO_NOSIGPIPE, then set sigpipe_so here - * and we're done. Otherwise, set sigpipe_flag so that - * we will try MSG_NOSIGNAL on sends. If we get an error - * with MSG_NOSIGNAL, we'll clear that flag and revert to - * signal masking. - *---------- - */ - conn->sigpipe_so = false; -#ifdef MSG_NOSIGNAL - conn->sigpipe_flag = true; -#else - conn->sigpipe_flag = false; -#endif /* MSG_NOSIGNAL */ - -#ifdef SO_NOSIGPIPE - optval = 1; - if (setsockopt(conn->sock, SOL_SOCKET, SO_NOSIGPIPE, - (char *) &optval, sizeof(optval)) == 0) - { - conn->sigpipe_so = true; - conn->sigpipe_flag = false; - } -#endif /* SO_NOSIGPIPE */ - - /* - * Start/make connection. This should not block, since we - * are in nonblock mode. If it does, well, too bad. - */ - if (connect(conn->sock, (struct sockaddr *) &addr_cur->addr.addr, - addr_cur->addr.salen) < 0) - { - if (SOCK_ERRNO == EINPROGRESS || -#ifdef WIN32 - SOCK_ERRNO == EWOULDBLOCK || -#endif - SOCK_ERRNO == EINTR) - { - /* - * This is fine - we're in non-blocking mode, and - * the connection is in progress. Tell caller to - * wait for write-ready on socket. - */ - conn->status = CONNECTION_STARTED; - return PGRES_POLLING_WRITING; - } - /* otherwise, trouble */ - } - else - { - /* - * Hm, we're connected already --- seems the "nonblock - * connection" wasn't. Advance the state machine and - * go do the next stuff. - */ - conn->status = CONNECTION_STARTED; - goto keep_going; - } - - /* - * This connection failed. Add the error report to - * conn->errorMessage, then try the next address if any. - */ - connectFailureMessage(conn, SOCK_ERRNO); - conn->try_next_addr = true; - goto keep_going; - } - } - - case CONNECTION_STARTED: - { - socklen_t optlen = sizeof(optval); - - /* - * Write ready, since we've made it here, so the connection - * has been made ... or has failed. - */ - - /* - * Now check (using getsockopt) that there is not an error - * state waiting for us on the socket. - */ - - if (getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, - (char *) &optval, &optlen) == -1) - { - libpq_append_conn_error(conn, "could not get socket error status: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - goto error_return; - } - else if (optval != 0) - { - /* - * When using a nonblocking connect, we will typically see - * connect failures at this point, so provide a friendly - * error message. - */ - connectFailureMessage(conn, optval); - - /* - * Try the next address if any, just as in the case where - * connect() returned failure immediately. - */ - conn->try_next_addr = true; - goto keep_going; - } - - /* Fill in the client address */ - conn->laddr.salen = sizeof(conn->laddr.addr); - if (getsockname(conn->sock, - (struct sockaddr *) &conn->laddr.addr, - &conn->laddr.salen) < 0) - { - libpq_append_conn_error(conn, "could not get client address from socket: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - goto error_return; - } - - /* - * Make sure we can write before advancing to next step. - */ - conn->status = CONNECTION_MADE; - return PGRES_POLLING_WRITING; - } - - case CONNECTION_MADE: - { - char *startpacket; - int packetlen; - - /* - * Implement requirepeer check, if requested and it's a - * Unix-domain socket. - */ - if (conn->requirepeer && conn->requirepeer[0] && - conn->raddr.addr.ss_family == AF_UNIX) - { -#ifndef WIN32 - char *remote_username; -#endif - uid_t uid; - gid_t gid; - - errno = 0; - if (getpeereid(conn->sock, &uid, &gid) != 0) - { - /* - * Provide special error message if getpeereid is a - * stub - */ - if (errno == ENOSYS) - libpq_append_conn_error(conn, "requirepeer parameter is not supported on this platform"); - else - libpq_append_conn_error(conn, "could not get peer credentials: %s", - strerror_r(errno, sebuf, sizeof(sebuf))); - goto error_return; - } - -#ifndef WIN32 - remote_username = pg_fe_getusername(uid, - &conn->errorMessage); - if (remote_username == NULL) - goto error_return; /* message already logged */ - - if (strcmp(remote_username, conn->requirepeer) != 0) - { - libpq_append_conn_error(conn, "requirepeer specifies \"%s\", but actual peer user name is \"%s\"", - conn->requirepeer, remote_username); - free(remote_username); - goto error_return; - } - free(remote_username); -#else /* WIN32 */ - /* should have failed with ENOSYS above */ - Assert(false); -#endif /* WIN32 */ - } - - if (conn->raddr.addr.ss_family == AF_UNIX) - { - /* Don't request SSL or GSSAPI over Unix sockets */ -#ifdef USE_SSL - conn->allow_ssl_try = false; -#endif -#ifdef ENABLE_GSS - conn->try_gss = false; -#endif - } - -#ifdef ENABLE_GSS - - /* - * If GSSAPI encryption is enabled, then call - * pg_GSS_have_cred_cache() which will return true if we can - * acquire credentials (and give us a handle to use in - * conn->gcred), and then send a packet to the server asking - * for GSSAPI Encryption (and skip past SSL negotiation and - * regular startup below). - */ - if (conn->try_gss && !conn->gctx) - conn->try_gss = pg_GSS_have_cred_cache(&conn->gcred); - if (conn->try_gss && !conn->gctx) - { - ProtocolVersion pv = pg_hton32(NEGOTIATE_GSS_CODE); - - if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK) - { - libpq_append_conn_error(conn, "could not send GSSAPI negotiation packet: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - goto error_return; - } - - /* Ok, wait for response */ - conn->status = CONNECTION_GSS_STARTUP; - return PGRES_POLLING_READING; - } - else if (!conn->gctx && conn->gssencmode[0] == 'r') - { - libpq_append_conn_error(conn, - "GSSAPI encryption required but was impossible (possibly no credential cache, no server support, or using a local socket)"); - goto error_return; - } -#endif - -#ifdef USE_SSL - - /* - * Enable the libcrypto callbacks before checking if SSL needs - * to be done. This is done before sending the startup packet - * as depending on the type of authentication done, like MD5 - * or SCRAM that use cryptohashes, the callbacks would be - * required even without a SSL connection - */ - if (pqsecure_initialize(conn, false, true) < 0) - goto error_return; - - /* - * If SSL is enabled and we haven't already got encryption of - * some sort running, request SSL instead of sending the - * startup message. - */ - if (conn->allow_ssl_try && !conn->wait_ssl_try && - !conn->ssl_in_use -#ifdef ENABLE_GSS - && !conn->gssenc -#endif - ) - { - ProtocolVersion pv; - - /* - * Send the SSL request packet. - * - * Theoretically, this could block, but it really - * shouldn't since we only got here if the socket is - * write-ready. - */ - pv = pg_hton32(NEGOTIATE_SSL_CODE); - if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK) - { - libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - goto error_return; - } - /* Ok, wait for response */ - conn->status = CONNECTION_SSL_STARTUP; - return PGRES_POLLING_READING; - } -#endif /* USE_SSL */ - - /* - * Build the startup packet. - */ - startpacket = pqBuildStartupPacket3(conn, &packetlen, - EnvironmentOptions); - if (!startpacket) - { - libpq_append_conn_error(conn, "out of memory"); - goto error_return; - } - - /* - * Send the startup packet. - * - * Theoretically, this could block, but it really shouldn't - * since we only got here if the socket is write-ready. - */ - if (pqPacketSend(conn, 0, startpacket, packetlen) != STATUS_OK) - { - libpq_append_conn_error(conn, "could not send startup packet: %s", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - free(startpacket); - goto error_return; - } - - free(startpacket); - - conn->status = CONNECTION_AWAITING_RESPONSE; - return PGRES_POLLING_READING; - } - - /* - * Handle SSL negotiation: wait for postmaster messages and - * respond as necessary. - */ - case CONNECTION_SSL_STARTUP: - { -#ifdef USE_SSL - PostgresPollingStatusType pollres; - - /* - * On first time through, get the postmaster's response to our - * SSL negotiation packet. - */ - if (!conn->ssl_in_use) - { - /* - * We use pqReadData here since it has the logic to - * distinguish no-data-yet from connection closure. Since - * conn->ssl isn't set, a plain recv() will occur. - */ - char SSLok; - int rdresult; - - rdresult = pqReadData(conn); - if (rdresult < 0) - { - /* errorMessage is already filled in */ - goto error_return; - } - if (rdresult == 0) - { - /* caller failed to wait for data */ - return PGRES_POLLING_READING; - } - if (pqGetc(&SSLok, conn) < 0) - { - /* should not happen really */ - return PGRES_POLLING_READING; - } - if (SSLok == 'S') - { - /* mark byte consumed */ - conn->inStart = conn->inCursor; - - /* - * Set up global SSL state if required. The crypto - * state has already been set if libpq took care of - * doing that, so there is no need to make that happen - * again. - */ - if (pqsecure_initialize(conn, true, false) != 0) - goto error_return; - } - else if (SSLok == 'N') - { - /* mark byte consumed */ - conn->inStart = conn->inCursor; - /* OK to do without SSL? */ - if (conn->sslmode[0] == 'r' || /* "require" */ - conn->sslmode[0] == 'v') /* "verify-ca" or - * "verify-full" */ - { - /* Require SSL, but server does not want it */ - libpq_append_conn_error(conn, "server does not support SSL, but SSL was required"); - goto error_return; - } - /* Otherwise, proceed with normal startup */ - conn->allow_ssl_try = false; - /* We can proceed using this connection */ - conn->status = CONNECTION_MADE; - return PGRES_POLLING_WRITING; - } - else if (SSLok == 'E') - { - /* - * Server failure of some sort, such as failure to - * fork a backend process. We need to process and - * report the error message, which might be formatted - * according to either protocol 2 or protocol 3. - * Rather than duplicate the code for that, we flip - * into AWAITING_RESPONSE state and let the code there - * deal with it. Note we have *not* consumed the "E" - * byte here. - */ - conn->status = CONNECTION_AWAITING_RESPONSE; - goto keep_going; - } - else - { - libpq_append_conn_error(conn, "received invalid response to SSL negotiation: %c", - SSLok); - goto error_return; - } - } - - /* - * Begin or continue the SSL negotiation process. - */ - pollres = pqsecure_open_client(conn); - if (pollres == PGRES_POLLING_OK) - { - /* - * At this point we should have no data already buffered. - * If we do, it was received before we performed the SSL - * handshake, so it wasn't encrypted and indeed may have - * been injected by a man-in-the-middle. - */ - if (conn->inCursor != conn->inEnd) - { - libpq_append_conn_error(conn, "received unencrypted data after SSL response"); - goto error_return; - } - - /* SSL handshake done, ready to send startup packet */ - conn->status = CONNECTION_MADE; - return PGRES_POLLING_WRITING; - } - if (pollres == PGRES_POLLING_FAILED) - { - /* - * Failed ... if sslmode is "prefer" then do a non-SSL - * retry - */ - if (conn->sslmode[0] == 'p' /* "prefer" */ - && conn->allow_ssl_try /* redundant? */ - && !conn->wait_ssl_try) /* redundant? */ - { - /* only retry once */ - conn->allow_ssl_try = false; - need_new_connection = true; - goto keep_going; - } - /* Else it's a hard failure */ - goto error_return; - } - /* Else, return POLLING_READING or POLLING_WRITING status */ - return pollres; -#else /* !USE_SSL */ - /* can't get here */ - goto error_return; -#endif /* USE_SSL */ - } - - case CONNECTION_GSS_STARTUP: - { -#ifdef ENABLE_GSS - PostgresPollingStatusType pollres; - - /* - * If we haven't yet, get the postmaster's response to our - * negotiation packet - */ - if (conn->try_gss && !conn->gctx) - { - char gss_ok; - int rdresult = pqReadData(conn); - - if (rdresult < 0) - /* pqReadData fills in error message */ - goto error_return; - else if (rdresult == 0) - /* caller failed to wait for data */ - return PGRES_POLLING_READING; - if (pqGetc(&gss_ok, conn) < 0) - /* shouldn't happen... */ - return PGRES_POLLING_READING; - - if (gss_ok == 'E') - { - /* - * Server failure of some sort. Assume it's a - * protocol version support failure, and let's see if - * we can't recover (if it's not, we'll get a better - * error message on retry). Server gets fussy if we - * don't hang up the socket, though. - */ - conn->try_gss = false; - need_new_connection = true; - goto keep_going; - } - - /* mark byte consumed */ - conn->inStart = conn->inCursor; - - if (gss_ok == 'N') - { - /* Server doesn't want GSSAPI; fall back if we can */ - if (conn->gssencmode[0] == 'r') - { - libpq_append_conn_error(conn, "server doesn't support GSSAPI encryption, but it was required"); - goto error_return; - } - - conn->try_gss = false; - /* We can proceed using this connection */ - conn->status = CONNECTION_MADE; - return PGRES_POLLING_WRITING; - } - else if (gss_ok != 'G') - { - libpq_append_conn_error(conn, "received invalid response to GSSAPI negotiation: %c", - gss_ok); - goto error_return; - } - } - - /* Begin or continue GSSAPI negotiation */ - pollres = pqsecure_open_gss(conn); - if (pollres == PGRES_POLLING_OK) - { - /* - * At this point we should have no data already buffered. - * If we do, it was received before we performed the GSS - * handshake, so it wasn't encrypted and indeed may have - * been injected by a man-in-the-middle. - */ - if (conn->inCursor != conn->inEnd) - { - libpq_append_conn_error(conn, "received unencrypted data after GSSAPI encryption response"); - goto error_return; - } - - /* All set for startup packet */ - conn->status = CONNECTION_MADE; - return PGRES_POLLING_WRITING; - } - else if (pollres == PGRES_POLLING_FAILED) - { - if (conn->gssencmode[0] == 'p') - { - /* - * We failed, but we can retry on "prefer". Have to - * drop the current connection to do so, though. - */ - conn->try_gss = false; - need_new_connection = true; - goto keep_going; - } - /* Else it's a hard failure */ - goto error_return; - } - /* Else, return POLLING_READING or POLLING_WRITING status */ - return pollres; -#else /* !ENABLE_GSS */ - /* unreachable */ - goto error_return; -#endif /* ENABLE_GSS */ - } - - /* - * Handle authentication exchange: wait for postmaster messages - * and respond as necessary. - */ - case CONNECTION_AWAITING_RESPONSE: - { - char beresp; - int msgLength; - int avail; - AuthRequest areq; - int res; - - /* - * Scan the message from current point (note that if we find - * the message is incomplete, we will return without advancing - * inStart, and resume here next time). - */ - conn->inCursor = conn->inStart; - - /* Read type byte */ - if (pqGetc(&beresp, conn)) - { - /* We'll come back when there is more data */ - return PGRES_POLLING_READING; - } - - /* - * Validate message type: we expect only an authentication - * request, NegotiateProtocolVersion, or an error here. - * Anything else probably means it's not Postgres on the other - * end at all. - */ - if (!(beresp == 'R' || beresp == 'v' || beresp == 'E')) - { - libpq_append_conn_error(conn, "expected authentication request from server, but received %c", - beresp); - goto error_return; - } - - /* Read message length word */ - if (pqGetInt(&msgLength, 4, conn)) - { - /* We'll come back when there is more data */ - return PGRES_POLLING_READING; - } - - /* - * Try to validate message length before using it. - * - * Authentication requests can't be very large, although GSS - * auth requests may not be that small. Same for - * NegotiateProtocolVersion. - * - * Errors can be a little larger, but not huge. If we see a - * large apparent length in an error, it means we're really - * talking to a pre-3.0-protocol server; cope. (Before - * version 14, the server also used the old protocol for - * errors that happened before processing the startup packet.) - */ - if (beresp == 'R' && (msgLength < 8 || msgLength > 2000)) - { - libpq_append_conn_error(conn, "received invalid authentication request"); - goto error_return; - } - if (beresp == 'v' && (msgLength < 8 || msgLength > 2000)) - { - libpq_append_conn_error(conn, "received invalid protocol negotiation message"); - goto error_return; - } - -#define MAX_ERRLEN 30000 - if (beresp == 'E' && (msgLength < 8 || msgLength > MAX_ERRLEN)) - { - /* Handle error from a pre-3.0 server */ - conn->inCursor = conn->inStart + 1; /* reread data */ - if (pqGets_append(&conn->errorMessage, conn)) - { - /* - * We may not have authenticated the server yet, so - * don't let the buffer grow forever. - */ - avail = conn->inEnd - conn->inCursor; - if (avail > MAX_ERRLEN) - { - libpq_append_conn_error(conn, "received invalid error message"); - goto error_return; - } - - /* We'll come back when there is more data */ - return PGRES_POLLING_READING; - } - /* OK, we read the message; mark data consumed */ - conn->inStart = conn->inCursor; - - /* - * Before 7.2, the postmaster didn't always end its - * messages with a newline, so add one if needed to - * conform to libpq conventions. - */ - if (conn->errorMessage.len == 0 || - conn->errorMessage.data[conn->errorMessage.len - 1] != '\n') - { - appendPQExpBufferChar(&conn->errorMessage, '\n'); - } - - goto error_return; - } -#undef MAX_ERRLEN - - /* - * Can't process if message body isn't all here yet. - * - * After this check passes, any further EOF during parsing - * implies that the server sent a bad/truncated message. - * Reading more bytes won't help in that case, so don't return - * PGRES_POLLING_READING after this point. - */ - msgLength -= 4; - avail = conn->inEnd - conn->inCursor; - if (avail < msgLength) - { - /* - * Before returning, try to enlarge the input buffer if - * needed to hold the whole message; see notes in - * pqParseInput3. - */ - if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength, - conn)) - goto error_return; - /* We'll come back when there is more data */ - return PGRES_POLLING_READING; - } - - /* Handle errors. */ - if (beresp == 'E') - { - if (pqGetErrorNotice3(conn, true)) - { - libpq_append_conn_error(conn, "received invalid error message"); - goto error_return; - } - /* OK, we read the message; mark data consumed */ - conn->inStart = conn->inCursor; - - /* - * If error is "cannot connect now", try the next host if - * any (but we don't want to consider additional addresses - * for this host, nor is there much point in changing SSL - * or GSS mode). This is helpful when dealing with - * standby servers that might not be in hot-standby state. - */ - if (strcmp(conn->last_sqlstate, - ERRCODE_CANNOT_CONNECT_NOW) == 0) - { - conn->try_next_host = true; - goto keep_going; - } - - /* Check to see if we should mention pgpassfile */ - pgpassfileWarning(conn); - -#ifdef ENABLE_GSS - - /* - * If gssencmode is "prefer" and we're using GSSAPI, retry - * without it. - */ - if (conn->gssenc && conn->gssencmode[0] == 'p') - { - /* only retry once */ - conn->try_gss = false; - need_new_connection = true; - goto keep_going; - } -#endif - -#ifdef USE_SSL - - /* - * if sslmode is "allow" and we haven't tried an SSL - * connection already, then retry with an SSL connection - */ - if (conn->sslmode[0] == 'a' /* "allow" */ - && !conn->ssl_in_use - && conn->allow_ssl_try - && conn->wait_ssl_try) - { - /* only retry once */ - conn->wait_ssl_try = false; - need_new_connection = true; - goto keep_going; - } - - /* - * if sslmode is "prefer" and we're in an SSL connection, - * then do a non-SSL retry - */ - if (conn->sslmode[0] == 'p' /* "prefer" */ - && conn->ssl_in_use - && conn->allow_ssl_try /* redundant? */ - && !conn->wait_ssl_try) /* redundant? */ - { - /* only retry once */ - conn->allow_ssl_try = false; - need_new_connection = true; - goto keep_going; - } -#endif - - goto error_return; - } - else if (beresp == 'v') - { - if (pqGetNegotiateProtocolVersion3(conn)) - { - libpq_append_conn_error(conn, "received invalid protocol negotiation message"); - goto error_return; - } - /* OK, we read the message; mark data consumed */ - conn->inStart = conn->inCursor; - goto error_return; - } - - /* It is an authentication request. */ - conn->auth_req_received = true; - - /* Get the type of request. */ - if (pqGetInt((int *) &areq, 4, conn)) - { - /* can't happen because we checked the length already */ - libpq_append_conn_error(conn, "received invalid authentication request"); - goto error_return; - } - msgLength -= 4; - - /* - * Process the rest of the authentication request message, and - * respond to it if necessary. - * - * Note that conn->pghost must be non-NULL if we are going to - * avoid the Kerberos code doing a hostname look-up. - */ - res = pg_fe_sendauth(areq, msgLength, conn); - - /* OK, we have processed the message; mark data consumed */ - conn->inStart = conn->inCursor; - - if (res != STATUS_OK) - goto error_return; - - /* - * Just make sure that any data sent by pg_fe_sendauth is - * flushed out. Although this theoretically could block, it - * really shouldn't since we don't send large auth responses. - */ - if (pqFlush(conn)) - goto error_return; - - if (areq == AUTH_REQ_OK) - { - /* We are done with authentication exchange */ - conn->status = CONNECTION_AUTH_OK; - - /* - * Set asyncStatus so that PQgetResult will think that - * what comes back next is the result of a query. See - * below. - */ - conn->asyncStatus = PGASYNC_BUSY; - } - - /* Look to see if we have more data yet. */ - goto keep_going; - } - - case CONNECTION_AUTH_OK: - { - /* - * Now we expect to hear from the backend. A ReadyForQuery - * message indicates that startup is successful, but we might - * also get an Error message indicating failure. (Notice - * messages indicating nonfatal warnings are also allowed by - * the protocol, as are ParameterStatus and BackendKeyData - * messages.) Easiest way to handle this is to let - * PQgetResult() read the messages. We just have to fake it - * out about the state of the connection, by setting - * asyncStatus = PGASYNC_BUSY (done above). - */ - - if (PQisBusy(conn)) - return PGRES_POLLING_READING; - - res = PQgetResult(conn); - - /* - * NULL return indicating we have gone to IDLE state is - * expected - */ - if (res) - { - if (res->resultStatus != PGRES_FATAL_ERROR) - libpq_append_conn_error(conn, "unexpected message from server during startup"); - else if (conn->send_appname && - (conn->appname || conn->fbappname)) - { - /* - * If we tried to send application_name, check to see - * if the error is about that --- pre-9.0 servers will - * reject it at this stage of the process. If so, - * close the connection and retry without sending - * application_name. We could possibly get a false - * SQLSTATE match here and retry uselessly, but there - * seems no great harm in that; we'll just get the - * same error again if it's unrelated. - */ - const char *sqlstate; - - sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE); - if (sqlstate && - strcmp(sqlstate, ERRCODE_APPNAME_UNKNOWN) == 0) - { - PQclear(res); - conn->send_appname = false; - need_new_connection = true; - goto keep_going; - } - } - - /* - * if the resultStatus is FATAL, then conn->errorMessage - * already has a copy of the error; needn't copy it back. - * But add a newline if it's not there already, since - * postmaster error messages may not have one. - */ - if (conn->errorMessage.len <= 0 || - conn->errorMessage.data[conn->errorMessage.len - 1] != '\n') - appendPQExpBufferChar(&conn->errorMessage, '\n'); - PQclear(res); - goto error_return; - } - - /* Almost there now ... */ - conn->status = CONNECTION_CHECK_TARGET; - goto keep_going; - } - - case CONNECTION_CHECK_TARGET: - { - /* - * If a read-write, read-only, primary, or standby connection - * is required, see if we have one. - */ - if (conn->target_server_type == SERVER_TYPE_READ_WRITE || - conn->target_server_type == SERVER_TYPE_READ_ONLY) - { - bool read_only_server; - - /* - * If the server didn't report - * "default_transaction_read_only" or "in_hot_standby" at - * startup, we must determine its state by sending the - * query "SHOW transaction_read_only". This GUC exists in - * all server versions that support 3.0 protocol. - */ - if (conn->default_transaction_read_only == PG_BOOL_UNKNOWN || - conn->in_hot_standby == PG_BOOL_UNKNOWN) - { - /* - * We use PQsendQueryContinue so that - * conn->errorMessage does not get cleared. We need - * to preserve any error messages related to previous - * hosts we have tried and failed to connect to. - */ - conn->status = CONNECTION_OK; - if (!PQsendQueryContinue(conn, - "SHOW transaction_read_only")) - goto error_return; - /* We'll return to this state when we have the answer */ - conn->status = CONNECTION_CHECK_WRITABLE; - return PGRES_POLLING_READING; - } - - /* OK, we can make the test */ - read_only_server = - (conn->default_transaction_read_only == PG_BOOL_YES || - conn->in_hot_standby == PG_BOOL_YES); - - if ((conn->target_server_type == SERVER_TYPE_READ_WRITE) ? - read_only_server : !read_only_server) - { - /* Wrong server state, reject and try the next host */ - if (conn->target_server_type == SERVER_TYPE_READ_WRITE) - libpq_append_conn_error(conn, "session is read-only"); - else - libpq_append_conn_error(conn, "session is not read-only"); - - /* Close connection politely. */ - conn->status = CONNECTION_OK; - sendTerminateConn(conn); - - /* - * Try next host if any, but we don't want to consider - * additional addresses for this host. - */ - conn->try_next_host = true; - goto keep_going; - } - } - else if (conn->target_server_type == SERVER_TYPE_PRIMARY || - conn->target_server_type == SERVER_TYPE_STANDBY || - conn->target_server_type == SERVER_TYPE_PREFER_STANDBY) - { - /* - * If the server didn't report "in_hot_standby" at - * startup, we must determine its state by sending the - * query "SELECT pg_catalog.pg_is_in_recovery()". Servers - * before 9.0 don't have that function, but by the same - * token they don't have any standby mode, so we may just - * assume the result. - */ - if (conn->sversion < 90000) - conn->in_hot_standby = PG_BOOL_NO; - - if (conn->in_hot_standby == PG_BOOL_UNKNOWN) - { - /* - * We use PQsendQueryContinue so that - * conn->errorMessage does not get cleared. We need - * to preserve any error messages related to previous - * hosts we have tried and failed to connect to. - */ - conn->status = CONNECTION_OK; - if (!PQsendQueryContinue(conn, - "SELECT pg_catalog.pg_is_in_recovery()")) - goto error_return; - /* We'll return to this state when we have the answer */ - conn->status = CONNECTION_CHECK_STANDBY; - return PGRES_POLLING_READING; - } - - /* OK, we can make the test */ - if ((conn->target_server_type == SERVER_TYPE_PRIMARY) ? - (conn->in_hot_standby == PG_BOOL_YES) : - (conn->in_hot_standby == PG_BOOL_NO)) - { - /* Wrong server state, reject and try the next host */ - if (conn->target_server_type == SERVER_TYPE_PRIMARY) - libpq_append_conn_error(conn, "server is in hot standby mode"); - else - libpq_append_conn_error(conn, "server is not in hot standby mode"); - - /* Close connection politely. */ - conn->status = CONNECTION_OK; - sendTerminateConn(conn); - - /* - * Try next host if any, but we don't want to consider - * additional addresses for this host. - */ - conn->try_next_host = true; - goto keep_going; - } - } - - /* We can release the address list now. */ - release_conn_addrinfo(conn); - - /* - * Contents of conn->errorMessage are no longer interesting - * (and it seems some clients expect it to be empty after a - * successful connection). - */ - pqClearConnErrorState(conn); - - /* We are open for business! */ - conn->status = CONNECTION_OK; - return PGRES_POLLING_OK; - } - - case CONNECTION_CONSUME: - { - /* - * This state just makes sure the connection is idle after - * we've obtained the result of a SHOW or SELECT query. Once - * we're clear, return to CONNECTION_CHECK_TARGET state to - * decide what to do next. We must transiently set status = - * CONNECTION_OK in order to use the result-consuming - * subroutines. - */ - conn->status = CONNECTION_OK; - if (!PQconsumeInput(conn)) - goto error_return; - - if (PQisBusy(conn)) - { - conn->status = CONNECTION_CONSUME; - return PGRES_POLLING_READING; - } - - /* Call PQgetResult() again until we get a NULL result */ - res = PQgetResult(conn); - if (res != NULL) - { - PQclear(res); - conn->status = CONNECTION_CONSUME; - return PGRES_POLLING_READING; - } - - conn->status = CONNECTION_CHECK_TARGET; - goto keep_going; - } - - case CONNECTION_CHECK_WRITABLE: - { - /* - * Waiting for result of "SHOW transaction_read_only". We - * must transiently set status = CONNECTION_OK in order to use - * the result-consuming subroutines. - */ - conn->status = CONNECTION_OK; - if (!PQconsumeInput(conn)) - goto error_return; - - if (PQisBusy(conn)) - { - conn->status = CONNECTION_CHECK_WRITABLE; - return PGRES_POLLING_READING; - } - - res = PQgetResult(conn); - if (res && PQresultStatus(res) == PGRES_TUPLES_OK && - PQntuples(res) == 1) - { - char *val = PQgetvalue(res, 0, 0); - - /* - * "transaction_read_only = on" proves that at least one - * of default_transaction_read_only and in_hot_standby is - * on, but we don't actually know which. We don't care - * though for the purpose of identifying a read-only - * session, so satisfy the CONNECTION_CHECK_TARGET code by - * claiming they are both on. On the other hand, if it's - * a read-write session, they are certainly both off. - */ - if (strncmp(val, "on", 2) == 0) - { - conn->default_transaction_read_only = PG_BOOL_YES; - conn->in_hot_standby = PG_BOOL_YES; - } - else - { - conn->default_transaction_read_only = PG_BOOL_NO; - conn->in_hot_standby = PG_BOOL_NO; - } - PQclear(res); - - /* Finish reading messages before continuing */ - conn->status = CONNECTION_CONSUME; - goto keep_going; - } - - /* Something went wrong with "SHOW transaction_read_only". */ - PQclear(res); - - /* Append error report to conn->errorMessage. */ - libpq_append_conn_error(conn, "\"%s\" failed", - "SHOW transaction_read_only"); - - /* Close connection politely. */ - conn->status = CONNECTION_OK; - sendTerminateConn(conn); - - /* Try next host. */ - conn->try_next_host = true; - goto keep_going; - } - - case CONNECTION_CHECK_STANDBY: - { - /* - * Waiting for result of "SELECT pg_is_in_recovery()". We - * must transiently set status = CONNECTION_OK in order to use - * the result-consuming subroutines. - */ - conn->status = CONNECTION_OK; - if (!PQconsumeInput(conn)) - goto error_return; - - if (PQisBusy(conn)) - { - conn->status = CONNECTION_CHECK_STANDBY; - return PGRES_POLLING_READING; - } - - res = PQgetResult(conn); - if (res && PQresultStatus(res) == PGRES_TUPLES_OK && - PQntuples(res) == 1) - { - char *val = PQgetvalue(res, 0, 0); - - if (strncmp(val, "t", 1) == 0) - conn->in_hot_standby = PG_BOOL_YES; - else - conn->in_hot_standby = PG_BOOL_NO; - PQclear(res); - - /* Finish reading messages before continuing */ - conn->status = CONNECTION_CONSUME; - goto keep_going; - } - - /* Something went wrong with "SELECT pg_is_in_recovery()". */ - PQclear(res); - - /* Append error report to conn->errorMessage. */ - libpq_append_conn_error(conn, "\"%s\" failed", - "SELECT pg_is_in_recovery()"); - - /* Close connection politely. */ - conn->status = CONNECTION_OK; - sendTerminateConn(conn); - - /* Try next host. */ - conn->try_next_host = true; - goto keep_going; - } - - default: - libpq_append_conn_error(conn, - "invalid connection state %d, probably indicative of memory corruption", - conn->status); - goto error_return; - } - - /* Unreachable */ - -error_return: - - /* - * We used to close the socket at this point, but that makes it awkward - * for those above us if they wish to remove this socket from their own - * records (an fd_set for example). We'll just have this socket closed - * when PQfinish is called (which is compulsory even after an error, since - * the connection structure must be freed). - */ - conn->status = CONNECTION_BAD; - return PGRES_POLLING_FAILED; -} - - -/* - * internal_ping - * Determine if a server is running and if we can connect to it. - * - * The argument is a connection that's been started, but not completed. - */ -static PGPing -internal_ping(PGconn *conn) -{ - /* Say "no attempt" if we never got to PQconnectPoll */ - if (!conn || !conn->options_valid) - return PQPING_NO_ATTEMPT; - - /* Attempt to complete the connection */ - if (conn->status != CONNECTION_BAD) - (void) connectDBComplete(conn); - - /* Definitely OK if we succeeded */ - if (conn->status != CONNECTION_BAD) - return PQPING_OK; - - /* - * Here begins the interesting part of "ping": determine the cause of the - * failure in sufficient detail to decide what to return. We do not want - * to report that the server is not up just because we didn't have a valid - * password, for example. In fact, any sort of authentication request - * implies the server is up. (We need this check since the libpq side of - * things might have pulled the plug on the connection before getting an - * error as such from the postmaster.) - */ - if (conn->auth_req_received) - return PQPING_OK; - - /* - * If we failed to get any ERROR response from the postmaster, report - * PQPING_NO_RESPONSE. This result could be somewhat misleading for a - * pre-7.4 server, since it won't send back a SQLSTATE, but those are long - * out of support. Another corner case where the server could return a - * failure without a SQLSTATE is fork failure, but PQPING_NO_RESPONSE - * isn't totally unreasonable for that anyway. We expect that every other - * failure case in a modern server will produce a report with a SQLSTATE. - * - * NOTE: whenever we get around to making libpq generate SQLSTATEs for - * client-side errors, we should either not store those into - * last_sqlstate, or add an extra flag so we can tell client-side errors - * apart from server-side ones. - */ - if (strlen(conn->last_sqlstate) != 5) - return PQPING_NO_RESPONSE; - - /* - * Report PQPING_REJECT if server says it's not accepting connections. - */ - if (strcmp(conn->last_sqlstate, ERRCODE_CANNOT_CONNECT_NOW) == 0) - return PQPING_REJECT; - - /* - * Any other SQLSTATE can be taken to indicate that the server is up. - * Presumably it didn't like our username, password, or database name; or - * perhaps it had some transient failure, but that should not be taken as - * meaning "it's down". - */ - return PQPING_OK; -} - - -/* - * makeEmptyPGconn - * - create a PGconn data structure with (as yet) no interesting data - */ -static PGconn * -makeEmptyPGconn(void) -{ - PGconn *conn; - -#ifdef WIN32 - - /* - * Make sure socket support is up and running in this process. - * - * Note: the Windows documentation says that we should eventually do a - * matching WSACleanup() call, but experience suggests that that is at - * least as likely to cause problems as fix them. So we don't. - */ - static bool wsastartup_done = false; - - if (!wsastartup_done) - { - WSADATA wsaData; - - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) - return NULL; - wsastartup_done = true; - } - - /* Forget any earlier error */ - WSASetLastError(0); -#endif /* WIN32 */ - - conn = (PGconn *) malloc(sizeof(PGconn)); - if (conn == NULL) - return conn; - - /* Zero all pointers and booleans */ - MemSet(conn, 0, sizeof(PGconn)); - - /* install default notice hooks */ - conn->noticeHooks.noticeRec = defaultNoticeReceiver; - conn->noticeHooks.noticeProc = defaultNoticeProcessor; - - conn->status = CONNECTION_BAD; - conn->asyncStatus = PGASYNC_IDLE; - conn->pipelineStatus = PQ_PIPELINE_OFF; - conn->xactStatus = PQTRANS_IDLE; - conn->options_valid = false; - conn->nonblocking = false; - conn->client_encoding = PG_SQL_ASCII; - conn->std_strings = false; /* unless server says differently */ - conn->default_transaction_read_only = PG_BOOL_UNKNOWN; - conn->in_hot_standby = PG_BOOL_UNKNOWN; - conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS; - conn->verbosity = PQERRORS_DEFAULT; - conn->show_context = PQSHOW_CONTEXT_ERRORS; - conn->sock = PGINVALID_SOCKET; - conn->Pfdebug = NULL; - - /* - * We try to send at least 8K at a time, which is the usual size of pipe - * buffers on Unix systems. That way, when we are sending a large amount - * of data, we avoid incurring extra kernel context swaps for partial - * bufferloads. The output buffer is initially made 16K in size, and we - * try to dump it after accumulating 8K. - * - * With the same goal of minimizing context swaps, the input buffer will - * be enlarged anytime it has less than 8K free, so we initially allocate - * twice that. - */ - conn->inBufSize = 16 * 1024; - conn->inBuffer = (char *) malloc(conn->inBufSize); - conn->outBufSize = 16 * 1024; - conn->outBuffer = (char *) malloc(conn->outBufSize); - conn->rowBufLen = 32; - conn->rowBuf = (PGdataValue *) malloc(conn->rowBufLen * sizeof(PGdataValue)); - initPQExpBuffer(&conn->errorMessage); - initPQExpBuffer(&conn->workBuffer); - - if (conn->inBuffer == NULL || - conn->outBuffer == NULL || - conn->rowBuf == NULL || - PQExpBufferBroken(&conn->errorMessage) || - PQExpBufferBroken(&conn->workBuffer)) - { - /* out of memory already :-( */ - freePGconn(conn); - conn = NULL; - } - - return conn; -} - -/* - * freePGconn - * - free an idle (closed) PGconn data structure - * - * NOTE: this should not overlap any functionality with closePGconn(). - * Clearing/resetting of transient state belongs there; what we do here is - * release data that is to be held for the life of the PGconn structure. - * If a value ought to be cleared/freed during PQreset(), do it there not here. - */ -static void -freePGconn(PGconn *conn) -{ - /* let any event procs clean up their state data */ - for (int i = 0; i < conn->nEvents; i++) - { - PGEventConnDestroy evt; - - evt.conn = conn; - (void) conn->events[i].proc(PGEVT_CONNDESTROY, &evt, - conn->events[i].passThrough); - free(conn->events[i].name); - } - - /* clean up pg_conn_host structures */ - for (int i = 0; i < conn->nconnhost; ++i) - { - free(conn->connhost[i].host); - free(conn->connhost[i].hostaddr); - free(conn->connhost[i].port); - if (conn->connhost[i].password != NULL) - { - explicit_bzero(conn->connhost[i].password, strlen(conn->connhost[i].password)); - free(conn->connhost[i].password); - } - } - free(conn->connhost); - - free(conn->client_encoding_initial); - free(conn->events); - free(conn->pghost); - free(conn->pghostaddr); - free(conn->pgport); - free(conn->connect_timeout); - free(conn->pgtcp_user_timeout); - free(conn->pgoptions); - free(conn->appname); - free(conn->fbappname); - free(conn->dbName); - free(conn->replication); - free(conn->pguser); - if (conn->pgpass) - { - explicit_bzero(conn->pgpass, strlen(conn->pgpass)); - free(conn->pgpass); - } - free(conn->pgpassfile); - free(conn->channel_binding); - free(conn->keepalives); - free(conn->keepalives_idle); - free(conn->keepalives_interval); - free(conn->keepalives_count); - free(conn->sslmode); - free(conn->sslcert); - free(conn->sslkey); - if (conn->sslpassword) - { - explicit_bzero(conn->sslpassword, strlen(conn->sslpassword)); - free(conn->sslpassword); - } - free(conn->sslcertmode); - free(conn->sslrootcert); - free(conn->sslcrl); - free(conn->sslcrldir); - free(conn->sslcompression); - free(conn->sslsni); - free(conn->requirepeer); - free(conn->require_auth); - free(conn->ssl_min_protocol_version); - free(conn->ssl_max_protocol_version); - free(conn->gssencmode); - free(conn->krbsrvname); - free(conn->gsslib); - free(conn->gssdelegation); - free(conn->connip); - /* Note that conn->Pfdebug is not ours to close or free */ - free(conn->write_err_msg); - free(conn->inBuffer); - free(conn->outBuffer); - free(conn->rowBuf); - free(conn->target_session_attrs); - free(conn->load_balance_hosts); - termPQExpBuffer(&conn->errorMessage); - termPQExpBuffer(&conn->workBuffer); - - free(conn); -} - -/* - * store_conn_addrinfo - * - copy addrinfo to PGconn object - * - * Copies the addrinfos from addrlist to the PGconn object such that the - * addrinfos can be manipulated by libpq. Returns a positive integer on - * failure, otherwise zero. - */ -static int -store_conn_addrinfo(PGconn *conn, struct addrinfo *addrlist) -{ - struct addrinfo *ai = addrlist; - - conn->whichaddr = 0; - - conn->naddr = 0; - while (ai) - { - ai = ai->ai_next; - conn->naddr++; - } - - conn->addr = calloc(conn->naddr, sizeof(AddrInfo)); - if (conn->addr == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return 1; - } - - ai = addrlist; - for (int i = 0; i < conn->naddr; i++) - { - conn->addr[i].family = ai->ai_family; - - memcpy(&conn->addr[i].addr.addr, ai->ai_addr, - ai->ai_addrlen); - conn->addr[i].addr.salen = ai->ai_addrlen; - ai = ai->ai_next; - } - - return 0; -} - -/* - * release_conn_addrinfo - * - Free any addrinfo list in the PGconn. - */ -static void -release_conn_addrinfo(PGconn *conn) -{ - if (conn->addr) - { - free(conn->addr); - conn->addr = NULL; - } -} - -/* - * sendTerminateConn - * - Send a terminate message to backend. - */ -static void -sendTerminateConn(PGconn *conn) -{ - /* - * Note that the protocol doesn't allow us to send Terminate messages - * during the startup phase. - */ - if (conn->sock != PGINVALID_SOCKET && conn->status == CONNECTION_OK) - { - /* - * Try to send "close connection" message to backend. Ignore any - * error. - */ - pqPutMsgStart('X', conn); - pqPutMsgEnd(conn); - (void) pqFlush(conn); - } -} - -/* - * closePGconn - * - properly close a connection to the backend - * - * This should reset or release all transient state, but NOT the connection - * parameters. On exit, the PGconn should be in condition to start a fresh - * connection with the same parameters (see PQreset()). - */ -static void -closePGconn(PGconn *conn) -{ - /* - * If possible, send Terminate message to close the connection politely. - */ - sendTerminateConn(conn); - - /* - * Must reset the blocking status so a possible reconnect will work. - * - * Don't call PQsetnonblocking() because it will fail if it's unable to - * flush the connection. - */ - conn->nonblocking = false; - - /* - * Close the connection, reset all transient state, flush I/O buffers. - * Note that this includes clearing conn's error state; we're no longer - * interested in any failures associated with the old connection, and we - * want a clean slate for any new connection attempt. - */ - pqDropConnection(conn, true); - conn->status = CONNECTION_BAD; /* Well, not really _bad_ - just absent */ - conn->asyncStatus = PGASYNC_IDLE; - conn->xactStatus = PQTRANS_IDLE; - conn->pipelineStatus = PQ_PIPELINE_OFF; - pqClearAsyncResult(conn); /* deallocate result */ - pqClearConnErrorState(conn); - release_conn_addrinfo(conn); - - /* Reset all state obtained from server, too */ - pqDropServerData(conn); -} - -/* - * PQfinish: properly close a connection to the backend. Also frees - * the PGconn data structure so it shouldn't be re-used after this. - */ -void -PQfinish(PGconn *conn) -{ - if (conn) - { - closePGconn(conn); - freePGconn(conn); - } -} - -/* - * PQreset: resets the connection to the backend by closing the - * existing connection and creating a new one. - */ -void -PQreset(PGconn *conn) -{ - if (conn) - { - closePGconn(conn); - - if (connectDBStart(conn) && connectDBComplete(conn)) - { - /* - * Notify event procs of successful reset. - */ - int i; - - for (i = 0; i < conn->nEvents; i++) - { - PGEventConnReset evt; - - evt.conn = conn; - (void) conn->events[i].proc(PGEVT_CONNRESET, &evt, - conn->events[i].passThrough); - } - } - } -} - - -/* - * PQresetStart: - * resets the connection to the backend - * closes the existing connection and makes a new one - * Returns 1 on success, 0 on failure. - */ -int -PQresetStart(PGconn *conn) -{ - if (conn) - { - closePGconn(conn); - - return connectDBStart(conn); - } - - return 0; -} - - -/* - * PQresetPoll: - * resets the connection to the backend - * closes the existing connection and makes a new one - */ -PostgresPollingStatusType -PQresetPoll(PGconn *conn) -{ - if (conn) - { - PostgresPollingStatusType status = PQconnectPoll(conn); - - if (status == PGRES_POLLING_OK) - { - /* - * Notify event procs of successful reset. - */ - int i; - - for (i = 0; i < conn->nEvents; i++) - { - PGEventConnReset evt; - - evt.conn = conn; - (void) conn->events[i].proc(PGEVT_CONNRESET, &evt, - conn->events[i].passThrough); - } - } - - return status; - } - - return PGRES_POLLING_FAILED; -} - -/* - * PQgetCancel: get a PGcancel structure corresponding to a connection. - * - * A copy is needed to be able to cancel a running query from a different - * thread. If the same structure is used all structure members would have - * to be individually locked (if the entire structure was locked, it would - * be impossible to cancel a synchronous query because the structure would - * have to stay locked for the duration of the query). - */ -PGcancel * -PQgetCancel(PGconn *conn) -{ - PGcancel *cancel; - - if (!conn) - return NULL; - - if (conn->sock == PGINVALID_SOCKET) - return NULL; - - cancel = malloc(sizeof(PGcancel)); - if (cancel == NULL) - return NULL; - - memcpy(&cancel->raddr, &conn->raddr, sizeof(SockAddr)); - cancel->be_pid = conn->be_pid; - cancel->be_key = conn->be_key; - /* We use -1 to indicate an unset connection option */ - cancel->pgtcp_user_timeout = -1; - cancel->keepalives = -1; - cancel->keepalives_idle = -1; - cancel->keepalives_interval = -1; - cancel->keepalives_count = -1; - if (conn->pgtcp_user_timeout != NULL) - { - if (!parse_int_param(conn->pgtcp_user_timeout, - &cancel->pgtcp_user_timeout, - conn, "tcp_user_timeout")) - goto fail; - } - if (conn->keepalives != NULL) - { - if (!parse_int_param(conn->keepalives, - &cancel->keepalives, - conn, "keepalives")) - goto fail; - } - if (conn->keepalives_idle != NULL) - { - if (!parse_int_param(conn->keepalives_idle, - &cancel->keepalives_idle, - conn, "keepalives_idle")) - goto fail; - } - if (conn->keepalives_interval != NULL) - { - if (!parse_int_param(conn->keepalives_interval, - &cancel->keepalives_interval, - conn, "keepalives_interval")) - goto fail; - } - if (conn->keepalives_count != NULL) - { - if (!parse_int_param(conn->keepalives_count, - &cancel->keepalives_count, - conn, "keepalives_count")) - goto fail; - } - - return cancel; - -fail: - free(cancel); - return NULL; -} - -/* PQfreeCancel: free a cancel structure */ -void -PQfreeCancel(PGcancel *cancel) -{ - free(cancel); -} - - -/* - * Sets an integer socket option on a TCP socket, if the provided value is - * not negative. Returns false if setsockopt fails for some reason. - * - * CAUTION: This needs to be signal safe, since it's used by PQcancel. - */ -#if defined(TCP_USER_TIMEOUT) || !defined(WIN32) -static bool -optional_setsockopt(int fd, int protoid, int optid, int value) -{ - if (value < 0) - return true; - if (setsockopt(fd, protoid, optid, (char *) &value, sizeof(value)) < 0) - return false; - return true; -} -#endif - - -/* - * PQcancel: request query cancel - * - * The return value is true if the cancel request was successfully - * dispatched, false if not (in which case an error message is available). - * Note: successful dispatch is no guarantee that there will be any effect at - * the backend. The application must read the operation result as usual. - * - * On failure, an error message is stored in *errbuf, which must be of size - * errbufsize (recommended size is 256 bytes). *errbuf is not changed on - * success return. - * - * CAUTION: we want this routine to be safely callable from a signal handler - * (for example, an application might want to call it in a SIGINT handler). - * This means we cannot use any C library routine that might be non-reentrant. - * malloc/free are often non-reentrant, and anything that might call them is - * just as dangerous. We avoid sprintf here for that reason. Building up - * error messages with strcpy/strcat is tedious but should be quite safe. - * We also save/restore errno in case the signal handler support doesn't. - */ -int -PQcancel(PGcancel *cancel, char *errbuf, int errbufsize) -{ - int save_errno = SOCK_ERRNO; - pgsocket tmpsock = PGINVALID_SOCKET; - int maxlen; - struct - { - uint32 packetlen; - CancelRequestPacket cp; - } crp; - - if (!cancel) - { - strlcpy(errbuf, "PQcancel() -- no cancel object supplied", errbufsize); - /* strlcpy probably doesn't change errno, but be paranoid */ - SOCK_ERRNO_SET(save_errno); - return false; - } - - /* - * We need to open a temporary connection to the postmaster. Do this with - * only kernel calls. - */ - if ((tmpsock = socket(cancel->raddr.addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET) - { - strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize); - goto cancel_errReturn; - } - - /* - * Since this connection will only be used to send a single packet of - * data, we don't need NODELAY. We also don't set the socket to - * nonblocking mode, because the API definition of PQcancel requires the - * cancel to be sent in a blocking way. - * - * We do set socket options related to keepalives and other TCP timeouts. - * This ensures that this function does not block indefinitely when - * reasonable keepalive and timeout settings have been provided. - */ - if (cancel->raddr.addr.ss_family != AF_UNIX && - cancel->keepalives != 0) - { -#ifndef WIN32 - if (!optional_setsockopt(tmpsock, SOL_SOCKET, SO_KEEPALIVE, 1)) - { - strlcpy(errbuf, "PQcancel() -- setsockopt(SO_KEEPALIVE) failed: ", errbufsize); - goto cancel_errReturn; - } - -#ifdef PG_TCP_KEEPALIVE_IDLE - if (!optional_setsockopt(tmpsock, IPPROTO_TCP, PG_TCP_KEEPALIVE_IDLE, - cancel->keepalives_idle)) - { - strlcpy(errbuf, "PQcancel() -- setsockopt(" PG_TCP_KEEPALIVE_IDLE_STR ") failed: ", errbufsize); - goto cancel_errReturn; - } -#endif - -#ifdef TCP_KEEPINTVL - if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPINTVL, - cancel->keepalives_interval)) - { - strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPINTVL) failed: ", errbufsize); - goto cancel_errReturn; - } -#endif - -#ifdef TCP_KEEPCNT - if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_KEEPCNT, - cancel->keepalives_count)) - { - strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_KEEPCNT) failed: ", errbufsize); - goto cancel_errReturn; - } -#endif - -#else /* WIN32 */ - -#ifdef SIO_KEEPALIVE_VALS - if (!setKeepalivesWin32(tmpsock, - cancel->keepalives_idle, - cancel->keepalives_interval)) - { - strlcpy(errbuf, "PQcancel() -- WSAIoctl(SIO_KEEPALIVE_VALS) failed: ", errbufsize); - goto cancel_errReturn; - } -#endif /* SIO_KEEPALIVE_VALS */ -#endif /* WIN32 */ - - /* TCP_USER_TIMEOUT works the same way on Unix and Windows */ -#ifdef TCP_USER_TIMEOUT - if (!optional_setsockopt(tmpsock, IPPROTO_TCP, TCP_USER_TIMEOUT, - cancel->pgtcp_user_timeout)) - { - strlcpy(errbuf, "PQcancel() -- setsockopt(TCP_USER_TIMEOUT) failed: ", errbufsize); - goto cancel_errReturn; - } -#endif - } - -retry3: - if (connect(tmpsock, (struct sockaddr *) &cancel->raddr.addr, - cancel->raddr.salen) < 0) - { - if (SOCK_ERRNO == EINTR) - /* Interrupted system call - we'll just try again */ - goto retry3; - strlcpy(errbuf, "PQcancel() -- connect() failed: ", errbufsize); - goto cancel_errReturn; - } - - /* Create and send the cancel request packet. */ - - crp.packetlen = pg_hton32((uint32) sizeof(crp)); - crp.cp.cancelRequestCode = (MsgType) pg_hton32(CANCEL_REQUEST_CODE); - crp.cp.backendPID = pg_hton32(cancel->be_pid); - crp.cp.cancelAuthCode = pg_hton32(cancel->be_key); - -retry4: - if (send(tmpsock, (char *) &crp, sizeof(crp), 0) != (int) sizeof(crp)) - { - if (SOCK_ERRNO == EINTR) - /* Interrupted system call - we'll just try again */ - goto retry4; - strlcpy(errbuf, "PQcancel() -- send() failed: ", errbufsize); - goto cancel_errReturn; - } - - /* - * Wait for the postmaster to close the connection, which indicates that - * it's processed the request. Without this delay, we might issue another - * command only to find that our cancel zaps that command instead of the - * one we thought we were canceling. Note we don't actually expect this - * read to obtain any data, we are just waiting for EOF to be signaled. - */ -retry5: - if (recv(tmpsock, (char *) &crp, 1, 0) < 0) - { - if (SOCK_ERRNO == EINTR) - /* Interrupted system call - we'll just try again */ - goto retry5; - /* we ignore other error conditions */ - } - - /* All done */ - closesocket(tmpsock); - SOCK_ERRNO_SET(save_errno); - return true; - -cancel_errReturn: - - /* - * Make sure we don't overflow the error buffer. Leave space for the \n at - * the end, and for the terminating zero. - */ - maxlen = errbufsize - strlen(errbuf) - 2; - if (maxlen >= 0) - { - /* - * We can't invoke strerror here, since it's not signal-safe. Settle - * for printing the decimal value of errno. Even that has to be done - * the hard way. - */ - int val = SOCK_ERRNO; - char buf[32]; - char *bufp; - - bufp = buf + sizeof(buf) - 1; - *bufp = '\0'; - do - { - *(--bufp) = (val % 10) + '0'; - val /= 10; - } while (val > 0); - bufp -= 6; - memcpy(bufp, "error ", 6); - strncat(errbuf, bufp, maxlen); - strcat(errbuf, "\n"); - } - if (tmpsock != PGINVALID_SOCKET) - closesocket(tmpsock); - SOCK_ERRNO_SET(save_errno); - return false; -} - - -/* - * PQrequestCancel: old, not thread-safe function for requesting query cancel - * - * Returns true if able to send the cancel request, false if not. - * - * On failure, the error message is saved in conn->errorMessage; this means - * that this can't be used when there might be other active operations on - * the connection object. - * - * NOTE: error messages will be cut off at the current size of the - * error message buffer, since we dare not try to expand conn->errorMessage! - */ -int -PQrequestCancel(PGconn *conn) -{ - int r; - PGcancel *cancel; - - /* Check we have an open connection */ - if (!conn) - return false; - - if (conn->sock == PGINVALID_SOCKET) - { - strlcpy(conn->errorMessage.data, - "PQrequestCancel() -- connection is not open\n", - conn->errorMessage.maxlen); - conn->errorMessage.len = strlen(conn->errorMessage.data); - conn->errorReported = 0; - - return false; - } - - cancel = PQgetCancel(conn); - if (cancel) - { - r = PQcancel(cancel, conn->errorMessage.data, - conn->errorMessage.maxlen); - PQfreeCancel(cancel); - } - else - { - strlcpy(conn->errorMessage.data, "out of memory", - conn->errorMessage.maxlen); - r = false; - } - - if (!r) - { - conn->errorMessage.len = strlen(conn->errorMessage.data); - conn->errorReported = 0; - } - - return r; -} - - -/* - * pqPacketSend() -- convenience routine to send a message to server. - * - * pack_type: the single-byte message type code. (Pass zero for startup - * packets, which have no message type code.) - * - * buf, buf_len: contents of message. The given length includes only what - * is in buf; the message type and message length fields are added here. - * - * RETURNS: STATUS_ERROR if the write fails, STATUS_OK otherwise. - * SIDE_EFFECTS: may block. - */ -int -pqPacketSend(PGconn *conn, char pack_type, - const void *buf, size_t buf_len) -{ - /* Start the message. */ - if (pqPutMsgStart(pack_type, conn)) - return STATUS_ERROR; - - /* Send the message body. */ - if (pqPutnchar(buf, buf_len, conn)) - return STATUS_ERROR; - - /* Finish the message. */ - if (pqPutMsgEnd(conn)) - return STATUS_ERROR; - - /* Flush to ensure backend gets it. */ - if (pqFlush(conn)) - return STATUS_ERROR; - - return STATUS_OK; -} - -#ifdef USE_LDAP - -#define LDAP_URL "ldap://" -#define LDAP_DEF_PORT 389 -#define PGLDAP_TIMEOUT 2 - -#define ld_is_sp_tab(x) ((x) == ' ' || (x) == '\t') -#define ld_is_nl_cr(x) ((x) == '\r' || (x) == '\n') - - -/* - * ldapServiceLookup - * - * Search the LDAP URL passed as first argument, treat the result as a - * string of connection options that are parsed and added to the array of - * options passed as second argument. - * - * LDAP URLs must conform to RFC 1959 without escape sequences. - * ldap://host:port/dn?attributes?scope?filter?extensions - * - * Returns - * 0 if the lookup was successful, - * 1 if the connection to the LDAP server could be established but - * the search was unsuccessful, - * 2 if a connection could not be established, and - * 3 if a fatal error occurred. - * - * An error message is appended to *errorMessage for return codes 1 and 3. - */ -static int -ldapServiceLookup(const char *purl, PQconninfoOption *options, - PQExpBuffer errorMessage) -{ - int port = LDAP_DEF_PORT, - scope, - rc, - size, - state, - oldstate, - i; -#ifndef WIN32 - int msgid; -#endif - bool found_keyword; - char *url, - *hostname, - *portstr, - *endptr, - *dn, - *scopestr, - *filter, - *result, - *p, - *p1 = NULL, - *optname = NULL, - *optval = NULL; - char *attrs[2] = {NULL, NULL}; - LDAP *ld = NULL; - LDAPMessage *res, - *entry; - struct berval **values; - LDAP_TIMEVAL time = {PGLDAP_TIMEOUT, 0}; - - if ((url = strdup(purl)) == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - return 3; - } - - /* - * Parse URL components, check for correctness. Basically, url has '\0' - * placed at component boundaries and variables are pointed at each - * component. - */ - - if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0) - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": scheme must be ldap://", purl); - free(url); - return 3; - } - - /* hostname */ - hostname = url + strlen(LDAP_URL); - if (*hostname == '/') /* no hostname? */ - hostname = DefaultHost; /* the default */ - - /* dn, "distinguished name" */ - p = strchr(url + strlen(LDAP_URL), '/'); - if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?') - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": missing distinguished name", - purl); - free(url); - return 3; - } - *p = '\0'; /* terminate hostname */ - dn = p + 1; - - /* attribute */ - if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?') - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": must have exactly one attribute", - purl); - free(url); - return 3; - } - *p = '\0'; - attrs[0] = p + 1; - - /* scope */ - if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?') - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": must have search scope (base/one/sub)", - purl); - free(url); - return 3; - } - *p = '\0'; - scopestr = p + 1; - - /* filter */ - if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?') - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": no filter", - purl); - free(url); - return 3; - } - *p = '\0'; - filter = p + 1; - if ((p = strchr(filter, '?')) != NULL) - *p = '\0'; - - /* port number? */ - if ((p1 = strchr(hostname, ':')) != NULL) - { - long lport; - - *p1 = '\0'; - portstr = p1 + 1; - errno = 0; - lport = strtol(portstr, &endptr, 10); - if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535) - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": invalid port number", - purl); - free(url); - return 3; - } - port = (int) lport; - } - - /* Allow only one attribute */ - if (strchr(attrs[0], ',') != NULL) - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": must have exactly one attribute", - purl); - free(url); - return 3; - } - - /* set scope */ - if (pg_strcasecmp(scopestr, "base") == 0) - scope = LDAP_SCOPE_BASE; - else if (pg_strcasecmp(scopestr, "one") == 0) - scope = LDAP_SCOPE_ONELEVEL; - else if (pg_strcasecmp(scopestr, "sub") == 0) - scope = LDAP_SCOPE_SUBTREE; - else - { - libpq_append_error(errorMessage, - "invalid LDAP URL \"%s\": must have search scope (base/one/sub)", - purl); - free(url); - return 3; - } - - /* initialize LDAP structure */ - if ((ld = ldap_init(hostname, port)) == NULL) - { - libpq_append_error(errorMessage, "could not create LDAP structure"); - free(url); - return 3; - } - - /* - * Perform an explicit anonymous bind. - * - * LDAP does not require that an anonymous bind is performed explicitly, - * but we want to distinguish between the case where LDAP bind does not - * succeed within PGLDAP_TIMEOUT seconds (return 2 to continue parsing the - * service control file) and the case where querying the LDAP server fails - * (return 1 to end parsing). - * - * Unfortunately there is no way of setting a timeout that works for both - * Windows and OpenLDAP. - */ -#ifdef WIN32 - /* the nonstandard ldap_connect function performs an anonymous bind */ - if (ldap_connect(ld, &time) != LDAP_SUCCESS) - { - /* error or timeout in ldap_connect */ - free(url); - ldap_unbind(ld); - return 2; - } -#else /* !WIN32 */ - /* in OpenLDAP, use the LDAP_OPT_NETWORK_TIMEOUT option */ - if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS) - { - free(url); - ldap_unbind(ld); - return 3; - } - - /* anonymous bind */ - if ((msgid = ldap_simple_bind(ld, NULL, NULL)) == -1) - { - /* error or network timeout */ - free(url); - ldap_unbind(ld); - return 2; - } - - /* wait some time for the connection to succeed */ - res = NULL; - if ((rc = ldap_result(ld, msgid, LDAP_MSG_ALL, &time, &res)) == -1 || - res == NULL) - { - /* error or timeout */ - if (res != NULL) - ldap_msgfree(res); - free(url); - ldap_unbind(ld); - return 2; - } - ldap_msgfree(res); - - /* reset timeout */ - time.tv_sec = -1; - if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &time) != LDAP_SUCCESS) - { - free(url); - ldap_unbind(ld); - return 3; - } -#endif /* WIN32 */ - - /* search */ - res = NULL; - if ((rc = ldap_search_st(ld, dn, scope, filter, attrs, 0, &time, &res)) - != LDAP_SUCCESS) - { - if (res != NULL) - ldap_msgfree(res); - libpq_append_error(errorMessage, "lookup on LDAP server failed: %s", ldap_err2string(rc)); - ldap_unbind(ld); - free(url); - return 1; - } - - /* complain if there was not exactly one result */ - if ((rc = ldap_count_entries(ld, res)) != 1) - { - if (rc > 1) - libpq_append_error(errorMessage, "more than one entry found on LDAP lookup"); - else - libpq_append_error(errorMessage, "no entry found on LDAP lookup"); - ldap_msgfree(res); - ldap_unbind(ld); - free(url); - return 1; - } - - /* get entry */ - if ((entry = ldap_first_entry(ld, res)) == NULL) - { - /* should never happen */ - libpq_append_error(errorMessage, "no entry found on LDAP lookup"); - ldap_msgfree(res); - ldap_unbind(ld); - free(url); - return 1; - } - - /* get values */ - if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL) - { - libpq_append_error(errorMessage, "attribute has no values on LDAP lookup"); - ldap_msgfree(res); - ldap_unbind(ld); - free(url); - return 1; - } - - ldap_msgfree(res); - free(url); - - if (values[0] == NULL) - { - libpq_append_error(errorMessage, "attribute has no values on LDAP lookup"); - ldap_value_free_len(values); - ldap_unbind(ld); - return 1; - } - - /* concatenate values into a single string with newline terminators */ - size = 1; /* for the trailing null */ - for (i = 0; values[i] != NULL; i++) - size += values[i]->bv_len + 1; - if ((result = malloc(size)) == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - ldap_value_free_len(values); - ldap_unbind(ld); - return 3; - } - p = result; - for (i = 0; values[i] != NULL; i++) - { - memcpy(p, values[i]->bv_val, values[i]->bv_len); - p += values[i]->bv_len; - *(p++) = '\n'; - } - *p = '\0'; - - ldap_value_free_len(values); - ldap_unbind(ld); - - /* parse result string */ - oldstate = state = 0; - for (p = result; *p != '\0'; ++p) - { - switch (state) - { - case 0: /* between entries */ - if (!ld_is_sp_tab(*p) && !ld_is_nl_cr(*p)) - { - optname = p; - state = 1; - } - break; - case 1: /* in option name */ - if (ld_is_sp_tab(*p)) - { - *p = '\0'; - state = 2; - } - else if (ld_is_nl_cr(*p)) - { - libpq_append_error(errorMessage, - "missing \"=\" after \"%s\" in connection info string", - optname); - free(result); - return 3; - } - else if (*p == '=') - { - *p = '\0'; - state = 3; - } - break; - case 2: /* after option name */ - if (*p == '=') - { - state = 3; - } - else if (!ld_is_sp_tab(*p)) - { - libpq_append_error(errorMessage, - "missing \"=\" after \"%s\" in connection info string", - optname); - free(result); - return 3; - } - break; - case 3: /* before option value */ - if (*p == '\'') - { - optval = p + 1; - p1 = p + 1; - state = 5; - } - else if (ld_is_nl_cr(*p)) - { - optval = optname + strlen(optname); /* empty */ - state = 0; - } - else if (!ld_is_sp_tab(*p)) - { - optval = p; - state = 4; - } - break; - case 4: /* in unquoted option value */ - if (ld_is_sp_tab(*p) || ld_is_nl_cr(*p)) - { - *p = '\0'; - state = 0; - } - break; - case 5: /* in quoted option value */ - if (*p == '\'') - { - *p1 = '\0'; - state = 0; - } - else if (*p == '\\') - state = 6; - else - *(p1++) = *p; - break; - case 6: /* in quoted option value after escape */ - *(p1++) = *p; - state = 5; - break; - } - - if (state == 0 && oldstate != 0) - { - found_keyword = false; - for (i = 0; options[i].keyword; i++) - { - if (strcmp(options[i].keyword, optname) == 0) - { - if (options[i].val == NULL) - { - options[i].val = strdup(optval); - if (!options[i].val) - { - libpq_append_error(errorMessage, "out of memory"); - free(result); - return 3; - } - } - found_keyword = true; - break; - } - } - if (!found_keyword) - { - libpq_append_error(errorMessage, "invalid connection option \"%s\"", optname); - free(result); - return 1; - } - optname = NULL; - optval = NULL; - } - oldstate = state; - } - - free(result); - - if (state == 5 || state == 6) - { - libpq_append_error(errorMessage, - "unterminated quoted string in connection info string"); - return 3; - } - - return 0; -} - -#endif /* USE_LDAP */ - -/* - * parseServiceInfo: if a service name has been given, look it up and absorb - * connection options from it into *options. - * - * Returns 0 on success, nonzero on failure. On failure, if errorMessage - * isn't null, also store an error message there. (Note: the only reason - * this function and related ones don't dump core on errorMessage == NULL - * is the undocumented fact that appendPQExpBuffer does nothing when passed - * a null PQExpBuffer pointer.) - */ -static int -parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage) -{ - const char *service = conninfo_getval(options, "service"); - char serviceFile[MAXPGPATH]; - char *env; - bool group_found = false; - int status; - struct stat stat_buf; - - /* - * We have to special-case the environment variable PGSERVICE here, since - * this is and should be called before inserting environment defaults for - * other connection options. - */ - if (service == NULL) - service = getenv("PGSERVICE"); - - /* If no service name given, nothing to do */ - if (service == NULL) - return 0; - - /* - * Try PGSERVICEFILE if specified, else try ~/.pg_service.conf (if that - * exists). - */ - if ((env = getenv("PGSERVICEFILE")) != NULL) - strlcpy(serviceFile, env, sizeof(serviceFile)); - else - { - char homedir[MAXPGPATH]; - - if (!pqGetHomeDirectory(homedir, sizeof(homedir))) - goto next_file; - snprintf(serviceFile, MAXPGPATH, "%s/%s", homedir, ".pg_service.conf"); - if (stat(serviceFile, &stat_buf) != 0) - goto next_file; - } - - status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found); - if (group_found || status != 0) - return status; - -next_file: - - /* - * This could be used by any application so we can't use the binary - * location to find our config files. - */ - snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf", - getenv("PGSYSCONFDIR") ? getenv("PGSYSCONFDIR") : SYSCONFDIR); - if (stat(serviceFile, &stat_buf) != 0) - goto last_file; - - status = parseServiceFile(serviceFile, service, options, errorMessage, &group_found); - if (status != 0) - return status; - -last_file: - if (!group_found) - { - libpq_append_error(errorMessage, "definition of service \"%s\" not found", service); - return 3; - } - - return 0; -} - -static int -parseServiceFile(const char *serviceFile, - const char *service, - PQconninfoOption *options, - PQExpBuffer errorMessage, - bool *group_found) -{ - int result = 0, - linenr = 0, - i; - FILE *f; - char *line; - char buf[1024]; - - *group_found = false; - - f = fopen(serviceFile, "r"); - if (f == NULL) - { - libpq_append_error(errorMessage, "service file \"%s\" not found", serviceFile); - return 1; - } - - while ((line = fgets(buf, sizeof(buf), f)) != NULL) - { - int len; - - linenr++; - - if (strlen(line) >= sizeof(buf) - 1) - { - libpq_append_error(errorMessage, - "line %d too long in service file \"%s\"", - linenr, - serviceFile); - result = 2; - goto exit; - } - - /* ignore whitespace at end of line, especially the newline */ - len = strlen(line); - while (len > 0 && isspace((unsigned char) line[len - 1])) - line[--len] = '\0'; - - /* ignore leading whitespace too */ - while (*line && isspace((unsigned char) line[0])) - line++; - - /* ignore comments and empty lines */ - if (line[0] == '\0' || line[0] == '#') - continue; - - /* Check for right groupname */ - if (line[0] == '[') - { - if (*group_found) - { - /* end of desired group reached; return success */ - goto exit; - } - - if (strncmp(line + 1, service, strlen(service)) == 0 && - line[strlen(service) + 1] == ']') - *group_found = true; - else - *group_found = false; - } - else - { - if (*group_found) - { - /* - * Finally, we are in the right group and can parse the line - */ - char *key, - *val; - bool found_keyword; - -#ifdef USE_LDAP - if (strncmp(line, "ldap", 4) == 0) - { - int rc = ldapServiceLookup(line, options, errorMessage); - - /* if rc = 2, go on reading for fallback */ - switch (rc) - { - case 0: - goto exit; - case 1: - case 3: - result = 3; - goto exit; - case 2: - continue; - } - } -#endif - - key = line; - val = strchr(line, '='); - if (val == NULL) - { - libpq_append_error(errorMessage, - "syntax error in service file \"%s\", line %d", - serviceFile, - linenr); - result = 3; - goto exit; - } - *val++ = '\0'; - - if (strcmp(key, "service") == 0) - { - libpq_append_error(errorMessage, - "nested service specifications not supported in service file \"%s\", line %d", - serviceFile, - linenr); - result = 3; - goto exit; - } - - /* - * Set the parameter --- but don't override any previous - * explicit setting. - */ - found_keyword = false; - for (i = 0; options[i].keyword; i++) - { - if (strcmp(options[i].keyword, key) == 0) - { - if (options[i].val == NULL) - options[i].val = strdup(val); - if (!options[i].val) - { - libpq_append_error(errorMessage, "out of memory"); - result = 3; - goto exit; - } - found_keyword = true; - break; - } - } - - if (!found_keyword) - { - libpq_append_error(errorMessage, - "syntax error in service file \"%s\", line %d", - serviceFile, - linenr); - result = 3; - goto exit; - } - } - } - } - -exit: - fclose(f); - - return result; -} - - -/* - * PQconninfoParse - * - * Parse a string like PQconnectdb() would do and return the - * resulting connection options array. NULL is returned on failure. - * The result contains only options specified directly in the string, - * not any possible default values. - * - * If errmsg isn't NULL, *errmsg is set to NULL on success, or a malloc'd - * string on failure (use PQfreemem to free it). In out-of-memory conditions - * both *errmsg and the result could be NULL. - * - * NOTE: the returned array is dynamically allocated and should - * be freed when no longer needed via PQconninfoFree(). - */ -PQconninfoOption * -PQconninfoParse(const char *conninfo, char **errmsg) -{ - PQExpBufferData errorBuf; - PQconninfoOption *connOptions; - - if (errmsg) - *errmsg = NULL; /* default */ - initPQExpBuffer(&errorBuf); - if (PQExpBufferDataBroken(errorBuf)) - return NULL; /* out of memory already :-( */ - connOptions = parse_connection_string(conninfo, &errorBuf, false); - if (connOptions == NULL && errmsg) - *errmsg = errorBuf.data; - else - termPQExpBuffer(&errorBuf); - return connOptions; -} - -/* - * Build a working copy of the constant PQconninfoOptions array. - */ -static PQconninfoOption * -conninfo_init(PQExpBuffer errorMessage) -{ - PQconninfoOption *options; - PQconninfoOption *opt_dest; - const internalPQconninfoOption *cur_opt; - - /* - * Get enough memory for all options in PQconninfoOptions, even if some - * end up being filtered out. - */ - options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0])); - if (options == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - return NULL; - } - opt_dest = options; - - for (cur_opt = PQconninfoOptions; cur_opt->keyword; cur_opt++) - { - /* Only copy the public part of the struct, not the full internal */ - memcpy(opt_dest, cur_opt, sizeof(PQconninfoOption)); - opt_dest++; - } - MemSet(opt_dest, 0, sizeof(PQconninfoOption)); - - return options; -} - -/* - * Connection string parser - * - * Returns a malloc'd PQconninfoOption array, if parsing is successful. - * Otherwise, NULL is returned and an error message is added to errorMessage. - * - * If use_defaults is true, default values are filled in (from a service file, - * environment variables, etc). - */ -static PQconninfoOption * -parse_connection_string(const char *connstr, PQExpBuffer errorMessage, - bool use_defaults) -{ - /* Parse as URI if connection string matches URI prefix */ - if (uri_prefix_length(connstr) != 0) - return conninfo_uri_parse(connstr, errorMessage, use_defaults); - - /* Parse as default otherwise */ - return conninfo_parse(connstr, errorMessage, use_defaults); -} - -/* - * Checks if connection string starts with either of the valid URI prefix - * designators. - * - * Returns the URI prefix length, 0 if the string doesn't contain a URI prefix. - * - * XXX this is duplicated in psql/common.c. - */ -static int -uri_prefix_length(const char *connstr) -{ - if (strncmp(connstr, uri_designator, - sizeof(uri_designator) - 1) == 0) - return sizeof(uri_designator) - 1; - - if (strncmp(connstr, short_uri_designator, - sizeof(short_uri_designator) - 1) == 0) - return sizeof(short_uri_designator) - 1; - - return 0; -} - -/* - * Recognized connection string either starts with a valid URI prefix or - * contains a "=" in it. - * - * Must be consistent with parse_connection_string: anything for which this - * returns true should at least look like it's parseable by that routine. - * - * XXX this is duplicated in psql/common.c - */ -static bool -recognized_connection_string(const char *connstr) -{ - return uri_prefix_length(connstr) != 0 || strchr(connstr, '=') != NULL; -} - -/* - * Subroutine for parse_connection_string - * - * Deal with a string containing key=value pairs. - */ -static PQconninfoOption * -conninfo_parse(const char *conninfo, PQExpBuffer errorMessage, - bool use_defaults) -{ - char *pname; - char *pval; - char *buf; - char *cp; - char *cp2; - PQconninfoOption *options; - - /* Make a working copy of PQconninfoOptions */ - options = conninfo_init(errorMessage); - if (options == NULL) - return NULL; - - /* Need a modifiable copy of the input string */ - if ((buf = strdup(conninfo)) == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - PQconninfoFree(options); - return NULL; - } - cp = buf; - - while (*cp) - { - /* Skip blanks before the parameter name */ - if (isspace((unsigned char) *cp)) - { - cp++; - continue; - } - - /* Get the parameter name */ - pname = cp; - while (*cp) - { - if (*cp == '=') - break; - if (isspace((unsigned char) *cp)) - { - *cp++ = '\0'; - while (*cp) - { - if (!isspace((unsigned char) *cp)) - break; - cp++; - } - break; - } - cp++; - } - - /* Check that there is a following '=' */ - if (*cp != '=') - { - libpq_append_error(errorMessage, - "missing \"=\" after \"%s\" in connection info string", - pname); - PQconninfoFree(options); - free(buf); - return NULL; - } - *cp++ = '\0'; - - /* Skip blanks after the '=' */ - while (*cp) - { - if (!isspace((unsigned char) *cp)) - break; - cp++; - } - - /* Get the parameter value */ - pval = cp; - - if (*cp != '\'') - { - cp2 = pval; - while (*cp) - { - if (isspace((unsigned char) *cp)) - { - *cp++ = '\0'; - break; - } - if (*cp == '\\') - { - cp++; - if (*cp != '\0') - *cp2++ = *cp++; - } - else - *cp2++ = *cp++; - } - *cp2 = '\0'; - } - else - { - cp2 = pval; - cp++; - for (;;) - { - if (*cp == '\0') - { - libpq_append_error(errorMessage, "unterminated quoted string in connection info string"); - PQconninfoFree(options); - free(buf); - return NULL; - } - if (*cp == '\\') - { - cp++; - if (*cp != '\0') - *cp2++ = *cp++; - continue; - } - if (*cp == '\'') - { - *cp2 = '\0'; - cp++; - break; - } - *cp2++ = *cp++; - } - } - - /* - * Now that we have the name and the value, store the record. - */ - if (!conninfo_storeval(options, pname, pval, errorMessage, false, false)) - { - PQconninfoFree(options); - free(buf); - return NULL; - } - } - - /* Done with the modifiable input string */ - free(buf); - - /* - * Add in defaults if the caller wants that. - */ - if (use_defaults) - { - if (!conninfo_add_defaults(options, errorMessage)) - { - PQconninfoFree(options); - return NULL; - } - } - - return options; -} - -/* - * Conninfo array parser routine - * - * If successful, a malloc'd PQconninfoOption array is returned. - * If not successful, NULL is returned and an error message is - * appended to errorMessage. - * Defaults are supplied (from a service file, environment variables, etc) - * for unspecified options, but only if use_defaults is true. - * - * If expand_dbname is non-zero, and the value passed for the first occurrence - * of "dbname" keyword is a connection string (as indicated by - * recognized_connection_string) then parse and process it, overriding any - * previously processed conflicting keywords. Subsequent keywords will take - * precedence, however. In-tree programs generally specify expand_dbname=true, - * so command-line arguments naming a database can use a connection string. - * Some code acquires arbitrary database names from known-literal sources like - * PQdb(), PQconninfoParse() and pg_database.datname. When connecting to such - * a database, in-tree code first wraps the name in a connection string. - */ -static PQconninfoOption * -conninfo_array_parse(const char *const *keywords, const char *const *values, - PQExpBuffer errorMessage, bool use_defaults, - int expand_dbname) -{ - PQconninfoOption *options; - PQconninfoOption *dbname_options = NULL; - PQconninfoOption *option; - int i = 0; - - /* - * If expand_dbname is non-zero, check keyword "dbname" to see if val is - * actually a recognized connection string. - */ - while (expand_dbname && keywords[i]) - { - const char *pname = keywords[i]; - const char *pvalue = values[i]; - - /* first find "dbname" if any */ - if (strcmp(pname, "dbname") == 0 && pvalue) - { - /* - * If value is a connection string, parse it, but do not use - * defaults here -- those get picked up later. We only want to - * override for those parameters actually passed. - */ - if (recognized_connection_string(pvalue)) - { - dbname_options = parse_connection_string(pvalue, errorMessage, false); - if (dbname_options == NULL) - return NULL; - } - break; - } - ++i; - } - - /* Make a working copy of PQconninfoOptions */ - options = conninfo_init(errorMessage); - if (options == NULL) - { - PQconninfoFree(dbname_options); - return NULL; - } - - /* Parse the keywords/values arrays */ - i = 0; - while (keywords[i]) - { - const char *pname = keywords[i]; - const char *pvalue = values[i]; - - if (pvalue != NULL && pvalue[0] != '\0') - { - /* Search for the param record */ - for (option = options; option->keyword != NULL; option++) - { - if (strcmp(option->keyword, pname) == 0) - break; - } - - /* Check for invalid connection option */ - if (option->keyword == NULL) - { - libpq_append_error(errorMessage, "invalid connection option \"%s\"", pname); - PQconninfoFree(options); - PQconninfoFree(dbname_options); - return NULL; - } - - /* - * If we are on the first dbname parameter, and we have a parsed - * connection string, copy those parameters across, overriding any - * existing previous settings. - */ - if (strcmp(pname, "dbname") == 0 && dbname_options) - { - PQconninfoOption *str_option; - - for (str_option = dbname_options; str_option->keyword != NULL; str_option++) - { - if (str_option->val != NULL) - { - int k; - - for (k = 0; options[k].keyword; k++) - { - if (strcmp(options[k].keyword, str_option->keyword) == 0) - { - free(options[k].val); - options[k].val = strdup(str_option->val); - if (!options[k].val) - { - libpq_append_error(errorMessage, "out of memory"); - PQconninfoFree(options); - PQconninfoFree(dbname_options); - return NULL; - } - break; - } - } - } - } - - /* - * Forget the parsed connection string, so that any subsequent - * dbname parameters will not be expanded. - */ - PQconninfoFree(dbname_options); - dbname_options = NULL; - } - else - { - /* - * Store the value, overriding previous settings - */ - free(option->val); - option->val = strdup(pvalue); - if (!option->val) - { - libpq_append_error(errorMessage, "out of memory"); - PQconninfoFree(options); - PQconninfoFree(dbname_options); - return NULL; - } - } - } - ++i; - } - PQconninfoFree(dbname_options); - - /* - * Add in defaults if the caller wants that. - */ - if (use_defaults) - { - if (!conninfo_add_defaults(options, errorMessage)) - { - PQconninfoFree(options); - return NULL; - } - } - - return options; -} - -/* - * Add the default values for any unspecified options to the connection - * options array. - * - * Defaults are obtained from a service file, environment variables, etc. - * - * Returns true if successful, otherwise false; errorMessage, if supplied, - * is filled in upon failure. Note that failure to locate a default value - * is not an error condition here --- we just leave the option's value as - * NULL. - */ -static bool -conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage) -{ - PQconninfoOption *option; - PQconninfoOption *sslmode_default = NULL, - *sslrootcert = NULL; - char *tmp; - - /* - * If there's a service spec, use it to obtain any not-explicitly-given - * parameters. Ignore error if no error message buffer is passed because - * there is no way to pass back the failure message. - */ - if (parseServiceInfo(options, errorMessage) != 0 && errorMessage) - return false; - - /* - * Get the fallback resources for parameters not specified in the conninfo - * string nor the service. - */ - for (option = options; option->keyword != NULL; option++) - { - if (strcmp(option->keyword, "sslrootcert") == 0) - sslrootcert = option; /* save for later */ - - if (option->val != NULL) - continue; /* Value was in conninfo or service */ - - /* - * Try to get the environment variable fallback - */ - if (option->envvar != NULL) - { - if ((tmp = getenv(option->envvar)) != NULL) - { - option->val = strdup(tmp); - if (!option->val) - { - if (errorMessage) - libpq_append_error(errorMessage, "out of memory"); - return false; - } - continue; - } - } - - /* - * Interpret the deprecated PGREQUIRESSL environment variable. Per - * tradition, translate values starting with "1" to sslmode=require, - * and ignore other values. Given both PGREQUIRESSL=1 and PGSSLMODE, - * PGSSLMODE takes precedence; the opposite was true before v9.3. - */ - if (strcmp(option->keyword, "sslmode") == 0) - { - const char *requiresslenv = getenv("PGREQUIRESSL"); - - if (requiresslenv != NULL && requiresslenv[0] == '1') - { - option->val = strdup("require"); - if (!option->val) - { - if (errorMessage) - libpq_append_error(errorMessage, "out of memory"); - return false; - } - continue; - } - - /* - * sslmode is not specified. Let it be filled in with the compiled - * default for now, but if sslrootcert=system, we'll override the - * default later before returning. - */ - sslmode_default = option; - } - - /* - * No environment variable specified or the variable isn't set - try - * compiled-in default - */ - if (option->compiled != NULL) - { - option->val = strdup(option->compiled); - if (!option->val) - { - if (errorMessage) - libpq_append_error(errorMessage, "out of memory"); - return false; - } - continue; - } - - /* - * Special handling for "user" option. Note that if pg_fe_getauthname - * fails, we just leave the value as NULL; there's no need for this to - * be an error condition if the caller provides a user name. The only - * reason we do this now at all is so that callers of PQconndefaults - * will see a correct default (barring error, of course). - */ - if (strcmp(option->keyword, "user") == 0) - { - option->val = pg_fe_getauthname(NULL); - continue; - } - } - - /* - * Special handling for sslrootcert=system with no sslmode explicitly - * defined. In this case we want to strengthen the default sslmode to - * verify-full. - */ - if (sslmode_default && sslrootcert) - { - if (sslrootcert->val && strcmp(sslrootcert->val, "system") == 0) - { - free(sslmode_default->val); - - sslmode_default->val = strdup("verify-full"); - if (!sslmode_default->val) - { - if (errorMessage) - libpq_append_error(errorMessage, "out of memory"); - return false; - } - } - } - - return true; -} - -/* - * Subroutine for parse_connection_string - * - * Deal with a URI connection string. - */ -static PQconninfoOption * -conninfo_uri_parse(const char *uri, PQExpBuffer errorMessage, - bool use_defaults) -{ - PQconninfoOption *options; - - /* Make a working copy of PQconninfoOptions */ - options = conninfo_init(errorMessage); - if (options == NULL) - return NULL; - - if (!conninfo_uri_parse_options(options, uri, errorMessage)) - { - PQconninfoFree(options); - return NULL; - } - - /* - * Add in defaults if the caller wants that. - */ - if (use_defaults) - { - if (!conninfo_add_defaults(options, errorMessage)) - { - PQconninfoFree(options); - return NULL; - } - } - - return options; -} - -/* - * conninfo_uri_parse_options - * Actual URI parser. - * - * If successful, returns true while the options array is filled with parsed - * options from the URI. - * If not successful, returns false and fills errorMessage accordingly. - * - * Parses the connection URI string in 'uri' according to the URI syntax (RFC - * 3986): - * - * postgresql://[user[:password]@][netloc][:port][/dbname][?param1=value1&...] - * - * where "netloc" is a hostname, an IPv4 address, or an IPv6 address surrounded - * by literal square brackets. As an extension, we also allow multiple - * netloc[:port] specifications, separated by commas: - * - * postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...] - * - * Any of the URI parts might use percent-encoding (%xy). - */ -static bool -conninfo_uri_parse_options(PQconninfoOption *options, const char *uri, - PQExpBuffer errorMessage) -{ - int prefix_len; - char *p; - char *buf = NULL; - char *start; - char prevchar = '\0'; - char *user = NULL; - char *host = NULL; - bool retval = false; - PQExpBufferData hostbuf; - PQExpBufferData portbuf; - - initPQExpBuffer(&hostbuf); - initPQExpBuffer(&portbuf); - if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf)) - { - libpq_append_error(errorMessage, "out of memory"); - goto cleanup; - } - - /* need a modifiable copy of the input URI */ - buf = strdup(uri); - if (buf == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - goto cleanup; - } - start = buf; - - /* Skip the URI prefix */ - prefix_len = uri_prefix_length(uri); - if (prefix_len == 0) - { - /* Should never happen */ - libpq_append_error(errorMessage, - "invalid URI propagated to internal parser routine: \"%s\"", - uri); - goto cleanup; - } - start += prefix_len; - p = start; - - /* Look ahead for possible user credentials designator */ - while (*p && *p != '@' && *p != '/') - ++p; - if (*p == '@') - { - /* - * Found username/password designator, so URI should be of the form - * "scheme://user[:password]@[netloc]". - */ - user = start; - - p = user; - while (*p != ':' && *p != '@') - ++p; - - /* Save last char and cut off at end of user name */ - prevchar = *p; - *p = '\0'; - - if (*user && - !conninfo_storeval(options, "user", user, - errorMessage, false, true)) - goto cleanup; - - if (prevchar == ':') - { - const char *password = p + 1; - - while (*p != '@') - ++p; - *p = '\0'; - - if (*password && - !conninfo_storeval(options, "password", password, - errorMessage, false, true)) - goto cleanup; - } - - /* Advance past end of parsed user name or password token */ - ++p; - } - else - { - /* - * No username/password designator found. Reset to start of URI. - */ - p = start; - } - - /* - * There may be multiple netloc[:port] pairs, each separated from the next - * by a comma. When we initially enter this loop, "p" has been - * incremented past optional URI credential information at this point and - * now points at the "netloc" part of the URI. On subsequent loop - * iterations, "p" has been incremented past the comma separator and now - * points at the start of the next "netloc". - */ - for (;;) - { - /* - * Look for IPv6 address. - */ - if (*p == '[') - { - host = ++p; - while (*p && *p != ']') - ++p; - if (!*p) - { - libpq_append_error(errorMessage, - "end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"", - uri); - goto cleanup; - } - if (p == host) - { - libpq_append_error(errorMessage, - "IPv6 host address may not be empty in URI: \"%s\"", - uri); - goto cleanup; - } - - /* Cut off the bracket and advance */ - *(p++) = '\0'; - - /* - * The address may be followed by a port specifier or a slash or a - * query or a separator comma. - */ - if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',') - { - libpq_append_error(errorMessage, - "unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"", - *p, (int) (p - buf + 1), uri); - goto cleanup; - } - } - else - { - /* not an IPv6 address: DNS-named or IPv4 netloc */ - host = p; - - /* - * Look for port specifier (colon) or end of host specifier - * (slash) or query (question mark) or host separator (comma). - */ - while (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',') - ++p; - } - - /* Save the hostname terminator before we null it */ - prevchar = *p; - *p = '\0'; - - appendPQExpBufferStr(&hostbuf, host); - - if (prevchar == ':') - { - const char *port = ++p; /* advance past host terminator */ - - while (*p && *p != '/' && *p != '?' && *p != ',') - ++p; - - prevchar = *p; - *p = '\0'; - - appendPQExpBufferStr(&portbuf, port); - } - - if (prevchar != ',') - break; - ++p; /* advance past comma separator */ - appendPQExpBufferChar(&hostbuf, ','); - appendPQExpBufferChar(&portbuf, ','); - } - - /* Save final values for host and port. */ - if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf)) - goto cleanup; - if (hostbuf.data[0] && - !conninfo_storeval(options, "host", hostbuf.data, - errorMessage, false, true)) - goto cleanup; - if (portbuf.data[0] && - !conninfo_storeval(options, "port", portbuf.data, - errorMessage, false, true)) - goto cleanup; - - if (prevchar && prevchar != '?') - { - const char *dbname = ++p; /* advance past host terminator */ - - /* Look for query parameters */ - while (*p && *p != '?') - ++p; - - prevchar = *p; - *p = '\0'; - - /* - * Avoid setting dbname to an empty string, as it forces the default - * value (username) and ignores $PGDATABASE, as opposed to not setting - * it at all. - */ - if (*dbname && - !conninfo_storeval(options, "dbname", dbname, - errorMessage, false, true)) - goto cleanup; - } - - if (prevchar) - { - ++p; /* advance past terminator */ - - if (!conninfo_uri_parse_params(p, options, errorMessage)) - goto cleanup; - } - - /* everything parsed okay */ - retval = true; - -cleanup: - termPQExpBuffer(&hostbuf); - termPQExpBuffer(&portbuf); - free(buf); - return retval; -} - -/* - * Connection URI parameters parser routine - * - * If successful, returns true while connOptions is filled with parsed - * parameters. Otherwise, returns false and fills errorMessage appropriately. - * - * Destructively modifies 'params' buffer. - */ -static bool -conninfo_uri_parse_params(char *params, - PQconninfoOption *connOptions, - PQExpBuffer errorMessage) -{ - while (*params) - { - char *keyword = params; - char *value = NULL; - char *p = params; - bool malloced = false; - int oldmsglen; - - /* - * Scan the params string for '=' and '&', marking the end of keyword - * and value respectively. - */ - for (;;) - { - if (*p == '=') - { - /* Was there '=' already? */ - if (value != NULL) - { - libpq_append_error(errorMessage, - "extra key/value separator \"=\" in URI query parameter: \"%s\"", - keyword); - return false; - } - /* Cut off keyword, advance to value */ - *p++ = '\0'; - value = p; - } - else if (*p == '&' || *p == '\0') - { - /* - * If not at the end, cut off value and advance; leave p - * pointing to start of the next parameter, if any. - */ - if (*p != '\0') - *p++ = '\0'; - /* Was there '=' at all? */ - if (value == NULL) - { - libpq_append_error(errorMessage, - "missing key/value separator \"=\" in URI query parameter: \"%s\"", - keyword); - return false; - } - /* Got keyword and value, go process them. */ - break; - } - else - ++p; /* Advance over all other bytes. */ - } - - keyword = conninfo_uri_decode(keyword, errorMessage); - if (keyword == NULL) - { - /* conninfo_uri_decode already set an error message */ - return false; - } - value = conninfo_uri_decode(value, errorMessage); - if (value == NULL) - { - /* conninfo_uri_decode already set an error message */ - free(keyword); - return false; - } - malloced = true; - - /* - * Special keyword handling for improved JDBC compatibility. - */ - if (strcmp(keyword, "ssl") == 0 && - strcmp(value, "true") == 0) - { - free(keyword); - free(value); - malloced = false; - - keyword = "sslmode"; - value = "require"; - } - - /* - * Store the value if the corresponding option exists; ignore - * otherwise. At this point both keyword and value are not - * URI-encoded. - */ - oldmsglen = errorMessage->len; - if (!conninfo_storeval(connOptions, keyword, value, - errorMessage, true, false)) - { - /* Insert generic message if conninfo_storeval didn't give one. */ - if (errorMessage->len == oldmsglen) - libpq_append_error(errorMessage, - "invalid URI query parameter: \"%s\"", - keyword); - /* And fail. */ - if (malloced) - { - free(keyword); - free(value); - } - return false; - } - - if (malloced) - { - free(keyword); - free(value); - } - - /* Proceed to next key=value pair, if any */ - params = p; - } - - return true; -} - -/* - * Connection URI decoder routine - * - * If successful, returns the malloc'd decoded string. - * If not successful, returns NULL and fills errorMessage accordingly. - * - * The string is decoded by replacing any percent-encoded tokens with - * corresponding characters, while preserving any non-encoded characters. A - * percent-encoded token is a character triplet: a percent sign, followed by a - * pair of hexadecimal digits (0-9A-F), where lower- and upper-case letters are - * treated identically. - */ -static char * -conninfo_uri_decode(const char *str, PQExpBuffer errorMessage) -{ - char *buf; - char *p; - const char *q = str; - - buf = malloc(strlen(str) + 1); - if (buf == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - return NULL; - } - p = buf; - - for (;;) - { - if (*q != '%') - { - /* copy and check for NUL terminator */ - if (!(*(p++) = *(q++))) - break; - } - else - { - int hi; - int lo; - int c; - - ++q; /* skip the percent sign itself */ - - /* - * Possible EOL will be caught by the first call to - * get_hexdigit(), so we never dereference an invalid q pointer. - */ - if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo))) - { - libpq_append_error(errorMessage, - "invalid percent-encoded token: \"%s\"", - str); - free(buf); - return NULL; - } - - c = (hi << 4) | lo; - if (c == 0) - { - libpq_append_error(errorMessage, - "forbidden value %%00 in percent-encoded value: \"%s\"", - str); - free(buf); - return NULL; - } - *(p++) = c; - } - } - - return buf; -} - -/* - * Convert hexadecimal digit character to its integer value. - * - * If successful, returns true and value is filled with digit's base 16 value. - * If not successful, returns false. - * - * Lower- and upper-case letters in the range A-F are treated identically. - */ -static bool -get_hexdigit(char digit, int *value) -{ - if ('0' <= digit && digit <= '9') - *value = digit - '0'; - else if ('A' <= digit && digit <= 'F') - *value = digit - 'A' + 10; - else if ('a' <= digit && digit <= 'f') - *value = digit - 'a' + 10; - else - return false; - - return true; -} - -/* - * Find an option value corresponding to the keyword in the connOptions array. - * - * If successful, returns a pointer to the corresponding option's value. - * If not successful, returns NULL. - */ -static const char * -conninfo_getval(PQconninfoOption *connOptions, - const char *keyword) -{ - PQconninfoOption *option; - - option = conninfo_find(connOptions, keyword); - - return option ? option->val : NULL; -} - -/* - * Store a (new) value for an option corresponding to the keyword in - * connOptions array. - * - * If uri_decode is true, the value is URI-decoded. The keyword is always - * assumed to be non URI-encoded. - * - * If successful, returns a pointer to the corresponding PQconninfoOption, - * which value is replaced with a strdup'd copy of the passed value string. - * The existing value for the option is free'd before replacing, if any. - * - * If not successful, returns NULL and fills errorMessage accordingly. - * However, if the reason of failure is an invalid keyword being passed and - * ignoreMissing is true, errorMessage will be left untouched. - */ -static PQconninfoOption * -conninfo_storeval(PQconninfoOption *connOptions, - const char *keyword, const char *value, - PQExpBuffer errorMessage, bool ignoreMissing, - bool uri_decode) -{ - PQconninfoOption *option; - char *value_copy; - - /* - * For backwards compatibility, requiressl=1 gets translated to - * sslmode=require, and requiressl=0 gets translated to sslmode=prefer - * (which is the default for sslmode). - */ - if (strcmp(keyword, "requiressl") == 0) - { - keyword = "sslmode"; - if (value[0] == '1') - value = "require"; - else - value = "prefer"; - } - - option = conninfo_find(connOptions, keyword); - if (option == NULL) - { - if (!ignoreMissing) - libpq_append_error(errorMessage, - "invalid connection option \"%s\"", - keyword); - return NULL; - } - - if (uri_decode) - { - value_copy = conninfo_uri_decode(value, errorMessage); - if (value_copy == NULL) - /* conninfo_uri_decode already set an error message */ - return NULL; - } - else - { - value_copy = strdup(value); - if (value_copy == NULL) - { - libpq_append_error(errorMessage, "out of memory"); - return NULL; - } - } - - free(option->val); - option->val = value_copy; - - return option; -} - -/* - * Find a PQconninfoOption option corresponding to the keyword in the - * connOptions array. - * - * If successful, returns a pointer to the corresponding PQconninfoOption - * structure. - * If not successful, returns NULL. - */ -static PQconninfoOption * -conninfo_find(PQconninfoOption *connOptions, const char *keyword) -{ - PQconninfoOption *option; - - for (option = connOptions; option->keyword != NULL; option++) - { - if (strcmp(option->keyword, keyword) == 0) - return option; - } - - return NULL; -} - - -/* - * Return the connection options used for the connection - */ -PQconninfoOption * -PQconninfo(PGconn *conn) -{ - PQExpBufferData errorBuf; - PQconninfoOption *connOptions; - - if (conn == NULL) - return NULL; - - /* - * We don't actually report any errors here, but callees want a buffer, - * and we prefer not to trash the conn's errorMessage. - */ - initPQExpBuffer(&errorBuf); - if (PQExpBufferDataBroken(errorBuf)) - return NULL; /* out of memory already :-( */ - - connOptions = conninfo_init(&errorBuf); - - if (connOptions != NULL) - { - const internalPQconninfoOption *option; - - for (option = PQconninfoOptions; option->keyword; option++) - { - char **connmember; - - if (option->connofs < 0) - continue; - - connmember = (char **) ((char *) conn + option->connofs); - - if (*connmember) - conninfo_storeval(connOptions, option->keyword, *connmember, - &errorBuf, true, false); - } - } - - termPQExpBuffer(&errorBuf); - - return connOptions; -} - - -void -PQconninfoFree(PQconninfoOption *connOptions) -{ - if (connOptions == NULL) - return; - - for (PQconninfoOption *option = connOptions; option->keyword != NULL; option++) - free(option->val); - free(connOptions); -} - - -/* =========== accessor functions for PGconn ========= */ -char * -PQdb(const PGconn *conn) -{ - if (!conn) - return NULL; - return conn->dbName; -} - -char * -PQuser(const PGconn *conn) -{ - if (!conn) - return NULL; - return conn->pguser; -} - -char * -PQpass(const PGconn *conn) -{ - char *password = NULL; - - if (!conn) - return NULL; - if (conn->connhost != NULL) - password = conn->connhost[conn->whichhost].password; - if (password == NULL) - password = conn->pgpass; - /* Historically we've returned "" not NULL for no password specified */ - if (password == NULL) - password = ""; - return password; -} - -char * -PQhost(const PGconn *conn) -{ - if (!conn) - return NULL; - - if (conn->connhost != NULL) - { - /* - * Return the verbatim host value provided by user, or hostaddr in its - * lack. - */ - if (conn->connhost[conn->whichhost].host != NULL && - conn->connhost[conn->whichhost].host[0] != '\0') - return conn->connhost[conn->whichhost].host; - else if (conn->connhost[conn->whichhost].hostaddr != NULL && - conn->connhost[conn->whichhost].hostaddr[0] != '\0') - return conn->connhost[conn->whichhost].hostaddr; - } - - return ""; -} - -char * -PQhostaddr(const PGconn *conn) -{ - if (!conn) - return NULL; - - /* Return the parsed IP address */ - if (conn->connhost != NULL && conn->connip != NULL) - return conn->connip; - - return ""; -} - -char * -PQport(const PGconn *conn) -{ - if (!conn) - return NULL; - - if (conn->connhost != NULL) - return conn->connhost[conn->whichhost].port; - - return ""; -} - -/* - * No longer does anything, but the function remains for API backwards - * compatibility. - */ -char * -PQtty(const PGconn *conn) -{ - if (!conn) - return NULL; - return ""; -} - -char * -PQoptions(const PGconn *conn) -{ - if (!conn) - return NULL; - return conn->pgoptions; -} - -ConnStatusType -PQstatus(const PGconn *conn) -{ - if (!conn) - return CONNECTION_BAD; - return conn->status; -} - -PGTransactionStatusType -PQtransactionStatus(const PGconn *conn) -{ - if (!conn || conn->status != CONNECTION_OK) - return PQTRANS_UNKNOWN; - if (conn->asyncStatus != PGASYNC_IDLE) - return PQTRANS_ACTIVE; - return conn->xactStatus; -} - -const char * -PQparameterStatus(const PGconn *conn, const char *paramName) -{ - const pgParameterStatus *pstatus; - - if (!conn || !paramName) - return NULL; - for (pstatus = conn->pstatus; pstatus != NULL; pstatus = pstatus->next) - { - if (strcmp(pstatus->name, paramName) == 0) - return pstatus->value; - } - return NULL; -} - -int -PQprotocolVersion(const PGconn *conn) -{ - if (!conn) - return 0; - if (conn->status == CONNECTION_BAD) - return 0; - return PG_PROTOCOL_MAJOR(conn->pversion); -} - -int -PQserverVersion(const PGconn *conn) -{ - if (!conn) - return 0; - if (conn->status == CONNECTION_BAD) - return 0; - return conn->sversion; -} - -char * -PQerrorMessage(const PGconn *conn) -{ - if (!conn) - return libpq_gettext("connection pointer is NULL\n"); - - /* - * The errorMessage buffer might be marked "broken" due to having - * previously failed to allocate enough memory for the message. In that - * case, tell the application we ran out of memory. - */ - if (PQExpBufferBroken(&conn->errorMessage)) - return libpq_gettext("out of memory\n"); - - return conn->errorMessage.data; -} - -/* - * In Windows, socket values are unsigned, and an invalid socket value - * (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler - * warning). Ideally we would return an unsigned value for PQsocket() on - * Windows, but that would cause the function's return value to differ from - * Unix, so we just return -1 for invalid sockets. - * http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx - * http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c - */ -int -PQsocket(const PGconn *conn) -{ - if (!conn) - return -1; - return (conn->sock != PGINVALID_SOCKET) ? conn->sock : -1; -} - -int -PQbackendPID(const PGconn *conn) -{ - if (!conn || conn->status != CONNECTION_OK) - return 0; - return conn->be_pid; -} - -PGpipelineStatus -PQpipelineStatus(const PGconn *conn) -{ - if (!conn) - return PQ_PIPELINE_OFF; - - return conn->pipelineStatus; -} - -int -PQconnectionNeedsPassword(const PGconn *conn) -{ - char *password; - - if (!conn) - return false; - password = PQpass(conn); - if (conn->password_needed && - (password == NULL || password[0] == '\0')) - return true; - else - return false; -} - -int -PQconnectionUsedPassword(const PGconn *conn) -{ - if (!conn) - return false; - if (conn->password_needed) - return true; - else - return false; -} - -int -PQconnectionUsedGSSAPI(const PGconn *conn) -{ - if (!conn) - return false; - if (conn->gssapi_used) - return true; - else - return false; -} - -int -PQclientEncoding(const PGconn *conn) -{ - if (!conn || conn->status != CONNECTION_OK) - return -1; - return conn->client_encoding; -} - -int -PQsetClientEncoding(PGconn *conn, const char *encoding) -{ - char qbuf[128]; - static const char query[] = "set client_encoding to '%s'"; - PGresult *res; - int status; - - if (!conn || conn->status != CONNECTION_OK) - return -1; - - if (!encoding) - return -1; - - /* Resolve special "auto" value from the locale */ - if (strcmp(encoding, "auto") == 0) - encoding = pg_encoding_to_char(pg_get_encoding_from_locale(NULL, true)); - - /* check query buffer overflow */ - if (sizeof(qbuf) < (sizeof(query) + strlen(encoding))) - return -1; - - /* ok, now send a query */ - sprintf(qbuf, query, encoding); - res = PQexec(conn, qbuf); - - if (res == NULL) - return -1; - if (res->resultStatus != PGRES_COMMAND_OK) - status = -1; - else - { - /* - * We rely on the backend to report the parameter value, and we'll - * change state at that time. - */ - status = 0; /* everything is ok */ - } - PQclear(res); - return status; -} - -PGVerbosity -PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity) -{ - PGVerbosity old; - - if (!conn) - return PQERRORS_DEFAULT; - old = conn->verbosity; - conn->verbosity = verbosity; - return old; -} - -PGContextVisibility -PQsetErrorContextVisibility(PGconn *conn, PGContextVisibility show_context) -{ - PGContextVisibility old; - - if (!conn) - return PQSHOW_CONTEXT_ERRORS; - old = conn->show_context; - conn->show_context = show_context; - return old; -} - -PQnoticeReceiver -PQsetNoticeReceiver(PGconn *conn, PQnoticeReceiver proc, void *arg) -{ - PQnoticeReceiver old; - - if (conn == NULL) - return NULL; - - old = conn->noticeHooks.noticeRec; - if (proc) - { - conn->noticeHooks.noticeRec = proc; - conn->noticeHooks.noticeRecArg = arg; - } - return old; -} - -PQnoticeProcessor -PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg) -{ - PQnoticeProcessor old; - - if (conn == NULL) - return NULL; - - old = conn->noticeHooks.noticeProc; - if (proc) - { - conn->noticeHooks.noticeProc = proc; - conn->noticeHooks.noticeProcArg = arg; - } - return old; -} - -/* - * The default notice message receiver just gets the standard notice text - * and sends it to the notice processor. This two-level setup exists - * mostly for backwards compatibility; perhaps we should deprecate use of - * PQsetNoticeProcessor? - */ -static void -defaultNoticeReceiver(void *arg, const PGresult *res) -{ - (void) arg; /* not used */ - if (res->noticeHooks.noticeProc != NULL) - res->noticeHooks.noticeProc(res->noticeHooks.noticeProcArg, - PQresultErrorMessage(res)); -} - -/* - * The default notice message processor just prints the - * message on stderr. Applications can override this if they - * want the messages to go elsewhere (a window, for example). - * Note that simply discarding notices is probably a bad idea. - */ -static void -defaultNoticeProcessor(void *arg, const char *message) -{ - (void) arg; /* not used */ - /* Note: we expect the supplied string to end with a newline already. */ - fprintf(stderr, "%s", message); -} - -/* - * returns a pointer to the next token or NULL if the current - * token doesn't match - */ -static char * -pwdfMatchesString(char *buf, const char *token) -{ - char *tbuf; - const char *ttok; - bool bslash = false; - - if (buf == NULL || token == NULL) - return NULL; - tbuf = buf; - ttok = token; - if (tbuf[0] == '*' && tbuf[1] == ':') - return tbuf + 2; - while (*tbuf != 0) - { - if (*tbuf == '\\' && !bslash) - { - tbuf++; - bslash = true; - } - if (*tbuf == ':' && *ttok == 0 && !bslash) - return tbuf + 1; - bslash = false; - if (*ttok == 0) - return NULL; - if (*tbuf == *ttok) - { - tbuf++; - ttok++; - } - else - return NULL; - } - return NULL; -} - -/* Get a password from the password file. Return value is malloc'd. */ -static char * -passwordFromFile(const char *hostname, const char *port, const char *dbname, - const char *username, const char *pgpassfile) -{ - FILE *fp; - struct stat stat_buf; - PQExpBufferData buf; - - if (dbname == NULL || dbname[0] == '\0') - return NULL; - - if (username == NULL || username[0] == '\0') - return NULL; - - /* 'localhost' matches pghost of '' or the default socket directory */ - if (hostname == NULL || hostname[0] == '\0') - hostname = DefaultHost; - else if (is_unixsock_path(hostname)) - - /* - * We should probably use canonicalize_path(), but then we have to - * bring path.c into libpq, and it doesn't seem worth it. - */ - if (strcmp(hostname, DEFAULT_PGSOCKET_DIR) == 0) - hostname = DefaultHost; - - if (port == NULL || port[0] == '\0') - port = DEF_PGPORT_STR; - - /* If password file cannot be opened, ignore it. */ - if (stat(pgpassfile, &stat_buf) != 0) - return NULL; - -#ifndef WIN32 - if (!S_ISREG(stat_buf.st_mode)) - { - fprintf(stderr, - libpq_gettext("WARNING: password file \"%s\" is not a plain file\n"), - pgpassfile); - return NULL; - } - - /* If password file is insecure, alert the user and ignore it. */ - if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) - { - fprintf(stderr, - libpq_gettext("WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"), - pgpassfile); - return NULL; - } -#else - - /* - * On Win32, the directory is protected, so we don't have to check the - * file. - */ -#endif - - fp = fopen(pgpassfile, "r"); - if (fp == NULL) - return NULL; - - /* Use an expansible buffer to accommodate any reasonable line length */ - initPQExpBuffer(&buf); - - while (!feof(fp) && !ferror(fp)) - { - /* Make sure there's a reasonable amount of room in the buffer */ - if (!enlargePQExpBuffer(&buf, 128)) - break; - - /* Read some data, appending it to what we already have */ - if (fgets(buf.data + buf.len, buf.maxlen - buf.len, fp) == NULL) - break; - buf.len += strlen(buf.data + buf.len); - - /* If we don't yet have a whole line, loop around to read more */ - if (!(buf.len > 0 && buf.data[buf.len - 1] == '\n') && !feof(fp)) - continue; - - /* ignore comments */ - if (buf.data[0] != '#') - { - char *t = buf.data; - int len; - - /* strip trailing newline and carriage return */ - len = pg_strip_crlf(t); - - if (len > 0 && - (t = pwdfMatchesString(t, hostname)) != NULL && - (t = pwdfMatchesString(t, port)) != NULL && - (t = pwdfMatchesString(t, dbname)) != NULL && - (t = pwdfMatchesString(t, username)) != NULL) - { - /* Found a match. */ - char *ret, - *p1, - *p2; - - ret = strdup(t); - - fclose(fp); - explicit_bzero(buf.data, buf.maxlen); - termPQExpBuffer(&buf); - - if (!ret) - { - /* Out of memory. XXX: an error message would be nice. */ - return NULL; - } - - /* De-escape password. */ - for (p1 = p2 = ret; *p1 != ':' && *p1 != '\0'; ++p1, ++p2) - { - if (*p1 == '\\' && p1[1] != '\0') - ++p1; - *p2 = *p1; - } - *p2 = '\0'; - - return ret; - } - } - - /* No match, reset buffer to prepare for next line. */ - buf.len = 0; - } - - fclose(fp); - explicit_bzero(buf.data, buf.maxlen); - termPQExpBuffer(&buf); - return NULL; -} - - -/* - * If the connection failed due to bad password, we should mention - * if we got the password from the pgpassfile. - */ -static void -pgpassfileWarning(PGconn *conn) -{ - /* If it was 'invalid authorization', add pgpassfile mention */ - /* only works with >= 9.0 servers */ - if (conn->password_needed && - conn->connhost[conn->whichhost].password != NULL && - conn->result) - { - const char *sqlstate = PQresultErrorField(conn->result, - PG_DIAG_SQLSTATE); - - if (sqlstate && strcmp(sqlstate, ERRCODE_INVALID_PASSWORD) == 0) - libpq_append_conn_error(conn, "password retrieved from file \"%s\"", - conn->pgpassfile); - } -} - -/* - * Check if the SSL protocol value given in input is valid or not. - * This is used as a sanity check routine for the connection parameters - * ssl_min_protocol_version and ssl_max_protocol_version. - */ -static bool -sslVerifyProtocolVersion(const char *version) -{ - /* - * An empty string and a NULL value are considered valid as it is - * equivalent to ignoring the parameter. - */ - if (!version || strlen(version) == 0) - return true; - - if (pg_strcasecmp(version, "TLSv1") == 0 || - pg_strcasecmp(version, "TLSv1.1") == 0 || - pg_strcasecmp(version, "TLSv1.2") == 0 || - pg_strcasecmp(version, "TLSv1.3") == 0) - return true; - - /* anything else is wrong */ - return false; -} - - -/* - * Ensure that the SSL protocol range given in input is correct. The check - * is performed on the input string to keep it TLS backend agnostic. Input - * to this function is expected verified with sslVerifyProtocolVersion(). - */ -static bool -sslVerifyProtocolRange(const char *min, const char *max) -{ - Assert(sslVerifyProtocolVersion(min) && - sslVerifyProtocolVersion(max)); - - /* If at least one of the bounds is not set, the range is valid */ - if (min == NULL || max == NULL || strlen(min) == 0 || strlen(max) == 0) - return true; - - /* - * If the minimum version is the lowest one we accept, then all options - * for the maximum are valid. - */ - if (pg_strcasecmp(min, "TLSv1") == 0) - return true; - - /* - * The minimum bound is valid, and cannot be TLSv1, so using TLSv1 for the - * maximum is incorrect. - */ - if (pg_strcasecmp(max, "TLSv1") == 0) - return false; - - /* - * At this point we know that we have a mix of TLSv1.1 through 1.3 - * versions. - */ - if (pg_strcasecmp(min, max) > 0) - return false; - - return true; -} - - -/* - * Obtain user's home directory, return in given buffer - * - * On Unix, this actually returns the user's home directory. On Windows - * it returns the PostgreSQL-specific application data folder. - * - * This is essentially the same as get_home_path(), but we don't use that - * because we don't want to pull path.c into libpq (it pollutes application - * namespace). - * - * Returns true on success, false on failure to obtain the directory name. - * - * CAUTION: although in most situations failure is unexpected, there are users - * who like to run applications in a home-directory-less environment. On - * failure, you almost certainly DO NOT want to report an error. Just act as - * though whatever file you were hoping to find in the home directory isn't - * there (which it isn't). - */ -bool -pqGetHomeDirectory(char *buf, int bufsize) -{ -#ifndef WIN32 - const char *home; - - home = getenv("HOME"); - if (home == NULL || home[0] == '\0') - return pg_get_user_home_dir(geteuid(), buf, bufsize); - strlcpy(buf, home, bufsize); - return true; -#else - char tmppath[MAX_PATH]; - - ZeroMemory(tmppath, sizeof(tmppath)); - if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, tmppath) != S_OK) - return false; - snprintf(buf, bufsize, "%s/postgresql", tmppath); - return true; -#endif -} - -/* - * To keep the API consistent, the locking stubs are always provided, even - * if they are not required. - * - * Since we neglected to provide any error-return convention in the - * pgthreadlock_t API, we can't do much except Assert upon failure of any - * mutex primitive. Fortunately, such failures appear to be nonexistent in - * the field. - */ - -static void -default_threadlock(int acquire) -{ -#ifdef ENABLE_THREAD_SAFETY -#ifndef WIN32 - static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER; -#else - static pthread_mutex_t singlethread_lock = NULL; - static long mutex_initlock = 0; - - if (singlethread_lock == NULL) - { - while (InterlockedExchange(&mutex_initlock, 1) == 1) - /* loop, another thread own the lock */ ; - if (singlethread_lock == NULL) - { - if (pthread_mutex_init(&singlethread_lock, NULL)) - Assert(false); - } - InterlockedExchange(&mutex_initlock, 0); - } -#endif - if (acquire) - { - if (pthread_mutex_lock(&singlethread_lock)) - Assert(false); - } - else - { - if (pthread_mutex_unlock(&singlethread_lock)) - Assert(false); - } -#endif -} - -pgthreadlock_t -PQregisterThreadLock(pgthreadlock_t newhandler) -{ - pgthreadlock_t prev = pg_g_threadlock; - - if (newhandler) - pg_g_threadlock = newhandler; - else - pg_g_threadlock = default_threadlock; - - return prev; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-exec.c b/contrib/libs/libpq/src/interfaces/libpq/fe-exec.c deleted file mode 100644 index fb11997eff..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-exec.c +++ /dev/null @@ -1,4474 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-exec.c - * functions related to sending a query down to the backend - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-exec.c - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include <ctype.h> -#include <fcntl.h> -#include <limits.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#endif - -#include "libpq-fe.h" -#include "libpq-int.h" -#include "mb/pg_wchar.h" - -/* keep this in same order as ExecStatusType in libpq-fe.h */ -char *const pgresStatus[] = { - "PGRES_EMPTY_QUERY", - "PGRES_COMMAND_OK", - "PGRES_TUPLES_OK", - "PGRES_COPY_OUT", - "PGRES_COPY_IN", - "PGRES_BAD_RESPONSE", - "PGRES_NONFATAL_ERROR", - "PGRES_FATAL_ERROR", - "PGRES_COPY_BOTH", - "PGRES_SINGLE_TUPLE", - "PGRES_PIPELINE_SYNC", - "PGRES_PIPELINE_ABORTED" -}; - -/* We return this if we're unable to make a PGresult at all */ -static const PGresult OOM_result = { - .resultStatus = PGRES_FATAL_ERROR, - .client_encoding = PG_SQL_ASCII, - .errMsg = "out of memory\n", -}; - -/* - * static state needed by PQescapeString and PQescapeBytea; initialize to - * values that result in backward-compatible behavior - */ -static int static_client_encoding = PG_SQL_ASCII; -static bool static_std_strings = false; - - -static PGEvent *dupEvents(PGEvent *events, int count, size_t *memSize); -static bool pqAddTuple(PGresult *res, PGresAttValue *tup, - const char **errmsgp); -static int PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery); -static bool PQsendQueryStart(PGconn *conn, bool newQuery); -static int PQsendQueryGuts(PGconn *conn, - const char *command, - const char *stmtName, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); -static void parseInput(PGconn *conn); -static PGresult *getCopyResult(PGconn *conn, ExecStatusType copytype); -static bool PQexecStart(PGconn *conn); -static PGresult *PQexecFinish(PGconn *conn); -static int PQsendDescribe(PGconn *conn, char desc_type, - const char *desc_target); -static int check_field_number(const PGresult *res, int field_num); -static void pqPipelineProcessQueue(PGconn *conn); -static int pqPipelineFlush(PGconn *conn); - - -/* ---------------- - * Space management for PGresult. - * - * Formerly, libpq did a separate malloc() for each field of each tuple - * returned by a query. This was remarkably expensive --- malloc/free - * consumed a sizable part of the application's runtime. And there is - * no real need to keep track of the fields separately, since they will - * all be freed together when the PGresult is released. So now, we grab - * large blocks of storage from malloc and allocate space for query data - * within these blocks, using a trivially simple allocator. This reduces - * the number of malloc/free calls dramatically, and it also avoids - * fragmentation of the malloc storage arena. - * The PGresult structure itself is still malloc'd separately. We could - * combine it with the first allocation block, but that would waste space - * for the common case that no extra storage is actually needed (that is, - * the SQL command did not return tuples). - * - * We also malloc the top-level array of tuple pointers separately, because - * we need to be able to enlarge it via realloc, and our trivial space - * allocator doesn't handle that effectively. (Too bad the FE/BE protocol - * doesn't tell us up front how many tuples will be returned.) - * All other subsidiary storage for a PGresult is kept in PGresult_data blocks - * of size PGRESULT_DATA_BLOCKSIZE. The overhead at the start of each block - * is just a link to the next one, if any. Free-space management info is - * kept in the owning PGresult. - * A query returning a small amount of data will thus require three malloc - * calls: one for the PGresult, one for the tuples pointer array, and one - * PGresult_data block. - * - * Only the most recently allocated PGresult_data block is a candidate to - * have more stuff added to it --- any extra space left over in older blocks - * is wasted. We could be smarter and search the whole chain, but the point - * here is to be simple and fast. Typical applications do not keep a PGresult - * around very long anyway, so some wasted space within one is not a problem. - * - * Tuning constants for the space allocator are: - * PGRESULT_DATA_BLOCKSIZE: size of a standard allocation block, in bytes - * PGRESULT_ALIGN_BOUNDARY: assumed alignment requirement for binary data - * PGRESULT_SEP_ALLOC_THRESHOLD: objects bigger than this are given separate - * blocks, instead of being crammed into a regular allocation block. - * Requirements for correct function are: - * PGRESULT_ALIGN_BOUNDARY must be a multiple of the alignment requirements - * of all machine data types. (Currently this is set from configure - * tests, so it should be OK automatically.) - * PGRESULT_SEP_ALLOC_THRESHOLD + PGRESULT_BLOCK_OVERHEAD <= - * PGRESULT_DATA_BLOCKSIZE - * pqResultAlloc assumes an object smaller than the threshold will fit - * in a new block. - * The amount of space wasted at the end of a block could be as much as - * PGRESULT_SEP_ALLOC_THRESHOLD, so it doesn't pay to make that too large. - * ---------------- - */ - -#define PGRESULT_DATA_BLOCKSIZE 2048 -#define PGRESULT_ALIGN_BOUNDARY MAXIMUM_ALIGNOF /* from configure */ -#define PGRESULT_BLOCK_OVERHEAD Max(sizeof(PGresult_data), PGRESULT_ALIGN_BOUNDARY) -#define PGRESULT_SEP_ALLOC_THRESHOLD (PGRESULT_DATA_BLOCKSIZE / 2) - - -/* - * PQmakeEmptyPGresult - * returns a newly allocated, initialized PGresult with given status. - * If conn is not NULL and status indicates an error, the conn's - * errorMessage is copied. Also, any PGEvents are copied from the conn. - * - * Note: the logic to copy the conn's errorMessage is now vestigial; - * no internal caller uses it. However, that behavior is documented for - * outside callers, so we'd better keep it. - */ -PGresult * -PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status) -{ - PGresult *result; - - result = (PGresult *) malloc(sizeof(PGresult)); - if (!result) - return NULL; - - result->ntups = 0; - result->numAttributes = 0; - result->attDescs = NULL; - result->tuples = NULL; - result->tupArrSize = 0; - result->numParameters = 0; - result->paramDescs = NULL; - result->resultStatus = status; - result->cmdStatus[0] = '\0'; - result->binary = 0; - result->events = NULL; - result->nEvents = 0; - result->errMsg = NULL; - result->errFields = NULL; - result->errQuery = NULL; - result->null_field[0] = '\0'; - result->curBlock = NULL; - result->curOffset = 0; - result->spaceLeft = 0; - result->memorySize = sizeof(PGresult); - - if (conn) - { - /* copy connection data we might need for operations on PGresult */ - result->noticeHooks = conn->noticeHooks; - result->client_encoding = conn->client_encoding; - - /* consider copying conn's errorMessage */ - switch (status) - { - case PGRES_EMPTY_QUERY: - case PGRES_COMMAND_OK: - case PGRES_TUPLES_OK: - case PGRES_COPY_OUT: - case PGRES_COPY_IN: - case PGRES_COPY_BOTH: - case PGRES_SINGLE_TUPLE: - /* non-error cases */ - break; - default: - /* we intentionally do not use or modify errorReported here */ - pqSetResultError(result, &conn->errorMessage, 0); - break; - } - - /* copy events last; result must be valid if we need to PQclear */ - if (conn->nEvents > 0) - { - result->events = dupEvents(conn->events, conn->nEvents, - &result->memorySize); - if (!result->events) - { - PQclear(result); - return NULL; - } - result->nEvents = conn->nEvents; - } - } - else - { - /* defaults... */ - result->noticeHooks.noticeRec = NULL; - result->noticeHooks.noticeRecArg = NULL; - result->noticeHooks.noticeProc = NULL; - result->noticeHooks.noticeProcArg = NULL; - result->client_encoding = PG_SQL_ASCII; - } - - return result; -} - -/* - * PQsetResultAttrs - * - * Set the attributes for a given result. This function fails if there are - * already attributes contained in the provided result. The call is - * ignored if numAttributes is zero or attDescs is NULL. If the - * function fails, it returns zero. If the function succeeds, it - * returns a non-zero value. - */ -int -PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs) -{ - int i; - - /* Fail if argument is NULL or OOM_result */ - if (!res || (const PGresult *) res == &OOM_result) - return false; - - /* If attrs already exist, they cannot be overwritten. */ - if (res->numAttributes > 0) - return false; - - /* ignore no-op request */ - if (numAttributes <= 0 || !attDescs) - return true; - - res->attDescs = (PGresAttDesc *) - PQresultAlloc(res, numAttributes * sizeof(PGresAttDesc)); - - if (!res->attDescs) - return false; - - res->numAttributes = numAttributes; - memcpy(res->attDescs, attDescs, numAttributes * sizeof(PGresAttDesc)); - - /* deep-copy the attribute names, and determine format */ - res->binary = 1; - for (i = 0; i < res->numAttributes; i++) - { - if (res->attDescs[i].name) - res->attDescs[i].name = pqResultStrdup(res, res->attDescs[i].name); - else - res->attDescs[i].name = res->null_field; - - if (!res->attDescs[i].name) - return false; - - if (res->attDescs[i].format == 0) - res->binary = 0; - } - - return true; -} - -/* - * PQcopyResult - * - * Returns a deep copy of the provided 'src' PGresult, which cannot be NULL. - * The 'flags' argument controls which portions of the result will or will - * NOT be copied. The created result is always put into the - * PGRES_TUPLES_OK status. The source result error message is not copied, - * although cmdStatus is. - * - * To set custom attributes, use PQsetResultAttrs. That function requires - * that there are no attrs contained in the result, so to use that - * function you cannot use the PG_COPYRES_ATTRS or PG_COPYRES_TUPLES - * options with this function. - * - * Options: - * PG_COPYRES_ATTRS - Copy the source result's attributes - * - * PG_COPYRES_TUPLES - Copy the source result's tuples. This implies - * copying the attrs, seeing how the attrs are needed by the tuples. - * - * PG_COPYRES_EVENTS - Copy the source result's events. - * - * PG_COPYRES_NOTICEHOOKS - Copy the source result's notice hooks. - */ -PGresult * -PQcopyResult(const PGresult *src, int flags) -{ - PGresult *dest; - int i; - - if (!src) - return NULL; - - dest = PQmakeEmptyPGresult(NULL, PGRES_TUPLES_OK); - if (!dest) - return NULL; - - /* Always copy these over. Is cmdStatus really useful here? */ - dest->client_encoding = src->client_encoding; - strcpy(dest->cmdStatus, src->cmdStatus); - - /* Wants attrs? */ - if (flags & (PG_COPYRES_ATTRS | PG_COPYRES_TUPLES)) - { - if (!PQsetResultAttrs(dest, src->numAttributes, src->attDescs)) - { - PQclear(dest); - return NULL; - } - } - - /* Wants to copy tuples? */ - if (flags & PG_COPYRES_TUPLES) - { - int tup, - field; - - for (tup = 0; tup < src->ntups; tup++) - { - for (field = 0; field < src->numAttributes; field++) - { - if (!PQsetvalue(dest, tup, field, - src->tuples[tup][field].value, - src->tuples[tup][field].len)) - { - PQclear(dest); - return NULL; - } - } - } - } - - /* Wants to copy notice hooks? */ - if (flags & PG_COPYRES_NOTICEHOOKS) - dest->noticeHooks = src->noticeHooks; - - /* Wants to copy PGEvents? */ - if ((flags & PG_COPYRES_EVENTS) && src->nEvents > 0) - { - dest->events = dupEvents(src->events, src->nEvents, - &dest->memorySize); - if (!dest->events) - { - PQclear(dest); - return NULL; - } - dest->nEvents = src->nEvents; - } - - /* Okay, trigger PGEVT_RESULTCOPY event */ - for (i = 0; i < dest->nEvents; i++) - { - /* We don't fire events that had some previous failure */ - if (src->events[i].resultInitialized) - { - PGEventResultCopy evt; - - evt.src = src; - evt.dest = dest; - if (dest->events[i].proc(PGEVT_RESULTCOPY, &evt, - dest->events[i].passThrough)) - dest->events[i].resultInitialized = true; - } - } - - return dest; -} - -/* - * Copy an array of PGEvents (with no extra space for more). - * Does not duplicate the event instance data, sets this to NULL. - * Also, the resultInitialized flags are all cleared. - * The total space allocated is added to *memSize. - */ -static PGEvent * -dupEvents(PGEvent *events, int count, size_t *memSize) -{ - PGEvent *newEvents; - size_t msize; - int i; - - if (!events || count <= 0) - return NULL; - - msize = count * sizeof(PGEvent); - newEvents = (PGEvent *) malloc(msize); - if (!newEvents) - return NULL; - - for (i = 0; i < count; i++) - { - newEvents[i].proc = events[i].proc; - newEvents[i].passThrough = events[i].passThrough; - newEvents[i].data = NULL; - newEvents[i].resultInitialized = false; - newEvents[i].name = strdup(events[i].name); - if (!newEvents[i].name) - { - while (--i >= 0) - free(newEvents[i].name); - free(newEvents); - return NULL; - } - msize += strlen(events[i].name) + 1; - } - - *memSize += msize; - return newEvents; -} - - -/* - * Sets the value for a tuple field. The tup_num must be less than or - * equal to PQntuples(res). If it is equal, a new tuple is created and - * added to the result. - * Returns a non-zero value for success and zero for failure. - * (On failure, we report the specific problem via pqInternalNotice.) - */ -int -PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len) -{ - PGresAttValue *attval; - const char *errmsg = NULL; - - /* Fail if argument is NULL or OOM_result */ - if (!res || (const PGresult *) res == &OOM_result) - return false; - - /* Invalid field_num? */ - if (!check_field_number(res, field_num)) - return false; - - /* Invalid tup_num, must be <= ntups */ - if (tup_num < 0 || tup_num > res->ntups) - { - pqInternalNotice(&res->noticeHooks, - "row number %d is out of range 0..%d", - tup_num, res->ntups); - return false; - } - - /* need to allocate a new tuple? */ - if (tup_num == res->ntups) - { - PGresAttValue *tup; - int i; - - tup = (PGresAttValue *) - pqResultAlloc(res, res->numAttributes * sizeof(PGresAttValue), - true); - - if (!tup) - goto fail; - - /* initialize each column to NULL */ - for (i = 0; i < res->numAttributes; i++) - { - tup[i].len = NULL_LEN; - tup[i].value = res->null_field; - } - - /* add it to the array */ - if (!pqAddTuple(res, tup, &errmsg)) - goto fail; - } - - attval = &res->tuples[tup_num][field_num]; - - /* treat either NULL_LEN or NULL value pointer as a NULL field */ - if (len == NULL_LEN || value == NULL) - { - attval->len = NULL_LEN; - attval->value = res->null_field; - } - else if (len <= 0) - { - attval->len = 0; - attval->value = res->null_field; - } - else - { - attval->value = (char *) pqResultAlloc(res, len + 1, true); - if (!attval->value) - goto fail; - attval->len = len; - memcpy(attval->value, value, len); - attval->value[len] = '\0'; - } - - return true; - - /* - * Report failure via pqInternalNotice. If preceding code didn't provide - * an error message, assume "out of memory" was meant. - */ -fail: - if (!errmsg) - errmsg = libpq_gettext("out of memory"); - pqInternalNotice(&res->noticeHooks, "%s", errmsg); - - return false; -} - -/* - * pqResultAlloc - exported routine to allocate local storage in a PGresult. - * - * We force all such allocations to be maxaligned, since we don't know - * whether the value might be binary. - */ -void * -PQresultAlloc(PGresult *res, size_t nBytes) -{ - /* Fail if argument is NULL or OOM_result */ - if (!res || (const PGresult *) res == &OOM_result) - return NULL; - - return pqResultAlloc(res, nBytes, true); -} - -/* - * pqResultAlloc - - * Allocate subsidiary storage for a PGresult. - * - * nBytes is the amount of space needed for the object. - * If isBinary is true, we assume that we need to align the object on - * a machine allocation boundary. - * If isBinary is false, we assume the object is a char string and can - * be allocated on any byte boundary. - */ -void * -pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary) -{ - char *space; - PGresult_data *block; - - if (!res) - return NULL; - - if (nBytes <= 0) - return res->null_field; - - /* - * If alignment is needed, round up the current position to an alignment - * boundary. - */ - if (isBinary) - { - int offset = res->curOffset % PGRESULT_ALIGN_BOUNDARY; - - if (offset) - { - res->curOffset += PGRESULT_ALIGN_BOUNDARY - offset; - res->spaceLeft -= PGRESULT_ALIGN_BOUNDARY - offset; - } - } - - /* If there's enough space in the current block, no problem. */ - if (nBytes <= (size_t) res->spaceLeft) - { - space = res->curBlock->space + res->curOffset; - res->curOffset += nBytes; - res->spaceLeft -= nBytes; - return space; - } - - /* - * If the requested object is very large, give it its own block; this - * avoids wasting what might be most of the current block to start a new - * block. (We'd have to special-case requests bigger than the block size - * anyway.) The object is always given binary alignment in this case. - */ - if (nBytes >= PGRESULT_SEP_ALLOC_THRESHOLD) - { - size_t alloc_size = nBytes + PGRESULT_BLOCK_OVERHEAD; - - block = (PGresult_data *) malloc(alloc_size); - if (!block) - return NULL; - res->memorySize += alloc_size; - space = block->space + PGRESULT_BLOCK_OVERHEAD; - if (res->curBlock) - { - /* - * Tuck special block below the active block, so that we don't - * have to waste the free space in the active block. - */ - block->next = res->curBlock->next; - res->curBlock->next = block; - } - else - { - /* Must set up the new block as the first active block. */ - block->next = NULL; - res->curBlock = block; - res->spaceLeft = 0; /* be sure it's marked full */ - } - return space; - } - - /* Otherwise, start a new block. */ - block = (PGresult_data *) malloc(PGRESULT_DATA_BLOCKSIZE); - if (!block) - return NULL; - res->memorySize += PGRESULT_DATA_BLOCKSIZE; - block->next = res->curBlock; - res->curBlock = block; - if (isBinary) - { - /* object needs full alignment */ - res->curOffset = PGRESULT_BLOCK_OVERHEAD; - res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - PGRESULT_BLOCK_OVERHEAD; - } - else - { - /* we can cram it right after the overhead pointer */ - res->curOffset = sizeof(PGresult_data); - res->spaceLeft = PGRESULT_DATA_BLOCKSIZE - sizeof(PGresult_data); - } - - space = block->space + res->curOffset; - res->curOffset += nBytes; - res->spaceLeft -= nBytes; - return space; -} - -/* - * PQresultMemorySize - - * Returns total space allocated for the PGresult. - */ -size_t -PQresultMemorySize(const PGresult *res) -{ - if (!res) - return 0; - return res->memorySize; -} - -/* - * pqResultStrdup - - * Like strdup, but the space is subsidiary PGresult space. - */ -char * -pqResultStrdup(PGresult *res, const char *str) -{ - char *space = (char *) pqResultAlloc(res, strlen(str) + 1, false); - - if (space) - strcpy(space, str); - return space; -} - -/* - * pqSetResultError - - * assign a new error message to a PGresult - * - * Copy text from errorMessage buffer beginning at given offset - * (it's caller's responsibility that offset is valid) - */ -void -pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset) -{ - char *msg; - - if (!res) - return; - - /* - * We handle two OOM scenarios here. The errorMessage buffer might be - * marked "broken" due to having previously failed to allocate enough - * memory for the message, or it might be fine but pqResultStrdup fails - * and returns NULL. In either case, just make res->errMsg point directly - * at a constant "out of memory" string. - */ - if (!PQExpBufferBroken(errorMessage)) - msg = pqResultStrdup(res, errorMessage->data + offset); - else - msg = NULL; - if (msg) - res->errMsg = msg; - else - res->errMsg = libpq_gettext("out of memory\n"); -} - -/* - * PQclear - - * free's the memory associated with a PGresult - */ -void -PQclear(PGresult *res) -{ - PGresult_data *block; - int i; - - /* As a convenience, do nothing for a NULL pointer */ - if (!res) - return; - /* Also, do nothing if the argument is OOM_result */ - if ((const PGresult *) res == &OOM_result) - return; - - /* Close down any events we may have */ - for (i = 0; i < res->nEvents; i++) - { - /* only send DESTROY to successfully-initialized event procs */ - if (res->events[i].resultInitialized) - { - PGEventResultDestroy evt; - - evt.result = res; - (void) res->events[i].proc(PGEVT_RESULTDESTROY, &evt, - res->events[i].passThrough); - } - free(res->events[i].name); - } - - free(res->events); - - /* Free all the subsidiary blocks */ - while ((block = res->curBlock) != NULL) - { - res->curBlock = block->next; - free(block); - } - - /* Free the top-level tuple pointer array */ - free(res->tuples); - - /* zero out the pointer fields to catch programming errors */ - res->attDescs = NULL; - res->tuples = NULL; - res->paramDescs = NULL; - res->errFields = NULL; - res->events = NULL; - res->nEvents = 0; - /* res->curBlock was zeroed out earlier */ - - /* Free the PGresult structure itself */ - free(res); -} - -/* - * Handy subroutine to deallocate any partially constructed async result. - * - * Any "next" result gets cleared too. - */ -void -pqClearAsyncResult(PGconn *conn) -{ - PQclear(conn->result); - conn->result = NULL; - conn->error_result = false; - PQclear(conn->next_result); - conn->next_result = NULL; -} - -/* - * pqSaveErrorResult - - * remember that we have an error condition - * - * In much of libpq, reporting an error just requires appending text to - * conn->errorMessage and returning a failure code to one's caller. - * Where returning a failure code is impractical, instead call this - * function to remember that an error needs to be reported. - * - * (It might seem that appending text to conn->errorMessage should be - * sufficient, but we can't rely on that working under out-of-memory - * conditions. The OOM hazard is also why we don't try to make a new - * PGresult right here.) - */ -void -pqSaveErrorResult(PGconn *conn) -{ - /* Drop any pending result ... */ - pqClearAsyncResult(conn); - /* ... and set flag to remember to make an error result later */ - conn->error_result = true; -} - -/* - * pqSaveWriteError - - * report a write failure - * - * As above, after appending conn->write_err_msg to whatever other error we - * have. This is used when we've detected a write failure and have exhausted - * our chances of reporting something else instead. - */ -static void -pqSaveWriteError(PGconn *conn) -{ - /* - * If write_err_msg is null because of previous strdup failure, do what we - * can. (It's likely our machinations here will get OOM failures as well, - * but might as well try.) - */ - if (conn->write_err_msg) - { - appendPQExpBufferStr(&conn->errorMessage, conn->write_err_msg); - /* Avoid possibly appending the same message twice */ - conn->write_err_msg[0] = '\0'; - } - else - libpq_append_conn_error(conn, "write to server failed"); - - pqSaveErrorResult(conn); -} - -/* - * pqPrepareAsyncResult - - * prepare the current async result object for return to the caller - * - * If there is not already an async result object, build an error object - * using whatever is in conn->errorMessage. In any case, clear the async - * result storage, and update our notion of how much error text has been - * returned to the application. - * - * Note that in no case (not even OOM) do we return NULL. - */ -PGresult * -pqPrepareAsyncResult(PGconn *conn) -{ - PGresult *res; - - res = conn->result; - if (res) - { - /* - * If the pre-existing result is an ERROR (presumably something - * received from the server), assume that it represents whatever is in - * conn->errorMessage, and advance errorReported. - */ - if (res->resultStatus == PGRES_FATAL_ERROR) - conn->errorReported = conn->errorMessage.len; - } - else - { - /* - * We get here after internal-to-libpq errors. We should probably - * always have error_result = true, but if we don't, gin up some error - * text. - */ - if (!conn->error_result) - libpq_append_conn_error(conn, "no error text available"); - - /* Paranoia: be sure errorReported offset is sane */ - if (conn->errorReported < 0 || - conn->errorReported >= conn->errorMessage.len) - conn->errorReported = 0; - - /* - * Make a PGresult struct for the error. We temporarily lie about the - * result status, so that PQmakeEmptyPGresult doesn't uselessly copy - * all of conn->errorMessage. - */ - res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY); - if (res) - { - /* - * Report whatever new error text we have, and advance - * errorReported. - */ - res->resultStatus = PGRES_FATAL_ERROR; - pqSetResultError(res, &conn->errorMessage, conn->errorReported); - conn->errorReported = conn->errorMessage.len; - } - else - { - /* - * Ouch, not enough memory for a PGresult. Fortunately, we have a - * card up our sleeve: we can use the static OOM_result. Casting - * away const here is a bit ugly, but it seems best to declare - * OOM_result as const, in hopes it will be allocated in read-only - * storage. - */ - res = unconstify(PGresult *, &OOM_result); - - /* - * Don't advance errorReported. Perhaps we'll be able to report - * the text later. - */ - } - } - - /* - * Replace conn->result with next_result, if any. In the normal case - * there isn't a next result and we're just dropping ownership of the - * current result. In single-row mode this restores the situation to what - * it was before we created the current single-row result. - */ - conn->result = conn->next_result; - conn->error_result = false; /* next_result is never an error */ - conn->next_result = NULL; - - return res; -} - -/* - * pqInternalNotice - produce an internally-generated notice message - * - * A format string and optional arguments can be passed. Note that we do - * libpq_gettext() here, so callers need not. - * - * The supplied text is taken as primary message (ie., it should not include - * a trailing newline, and should not be more than one line). - */ -void -pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) -{ - char msgBuf[1024]; - va_list args; - PGresult *res; - - if (hooks->noticeRec == NULL) - return; /* nobody home to receive notice? */ - - /* Format the message */ - va_start(args, fmt); - vsnprintf(msgBuf, sizeof(msgBuf), libpq_gettext(fmt), args); - va_end(args); - msgBuf[sizeof(msgBuf) - 1] = '\0'; /* make real sure it's terminated */ - - /* Make a PGresult to pass to the notice receiver */ - res = PQmakeEmptyPGresult(NULL, PGRES_NONFATAL_ERROR); - if (!res) - return; - res->noticeHooks = *hooks; - - /* - * Set up fields of notice. - */ - pqSaveMessageField(res, PG_DIAG_MESSAGE_PRIMARY, msgBuf); - pqSaveMessageField(res, PG_DIAG_SEVERITY, libpq_gettext("NOTICE")); - pqSaveMessageField(res, PG_DIAG_SEVERITY_NONLOCALIZED, "NOTICE"); - /* XXX should provide a SQLSTATE too? */ - - /* - * Result text is always just the primary message + newline. If we can't - * allocate it, substitute "out of memory", as in pqSetResultError. - */ - res->errMsg = (char *) pqResultAlloc(res, strlen(msgBuf) + 2, false); - if (res->errMsg) - sprintf(res->errMsg, "%s\n", msgBuf); - else - res->errMsg = libpq_gettext("out of memory\n"); - - /* - * Pass to receiver, then free it. - */ - res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res); - PQclear(res); -} - -/* - * pqAddTuple - * add a row pointer to the PGresult structure, growing it if necessary - * Returns true if OK, false if an error prevented adding the row - * - * On error, *errmsgp can be set to an error string to be returned. - * If it is left NULL, the error is presumed to be "out of memory". - */ -static bool -pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp) -{ - if (res->ntups >= res->tupArrSize) - { - /* - * Try to grow the array. - * - * We can use realloc because shallow copying of the structure is - * okay. Note that the first time through, res->tuples is NULL. While - * ANSI says that realloc() should act like malloc() in that case, - * some old C libraries (like SunOS 4.1.x) coredump instead. On - * failure realloc is supposed to return NULL without damaging the - * existing allocation. Note that the positions beyond res->ntups are - * garbage, not necessarily NULL. - */ - int newSize; - PGresAttValue **newTuples; - - /* - * Since we use integers for row numbers, we can't support more than - * INT_MAX rows. Make sure we allow that many, though. - */ - if (res->tupArrSize <= INT_MAX / 2) - newSize = (res->tupArrSize > 0) ? res->tupArrSize * 2 : 128; - else if (res->tupArrSize < INT_MAX) - newSize = INT_MAX; - else - { - *errmsgp = libpq_gettext("PGresult cannot support more than INT_MAX tuples"); - return false; - } - - /* - * Also, on 32-bit platforms we could, in theory, overflow size_t even - * before newSize gets to INT_MAX. (In practice we'd doubtless hit - * OOM long before that, but let's check.) - */ -#if INT_MAX >= (SIZE_MAX / 2) - if (newSize > SIZE_MAX / sizeof(PGresAttValue *)) - { - *errmsgp = libpq_gettext("size_t overflow"); - return false; - } -#endif - - if (res->tuples == NULL) - newTuples = (PGresAttValue **) - malloc(newSize * sizeof(PGresAttValue *)); - else - newTuples = (PGresAttValue **) - realloc(res->tuples, newSize * sizeof(PGresAttValue *)); - if (!newTuples) - return false; /* malloc or realloc failed */ - res->memorySize += - (newSize - res->tupArrSize) * sizeof(PGresAttValue *); - res->tupArrSize = newSize; - res->tuples = newTuples; - } - res->tuples[res->ntups] = tup; - res->ntups++; - return true; -} - -/* - * pqSaveMessageField - save one field of an error or notice message - */ -void -pqSaveMessageField(PGresult *res, char code, const char *value) -{ - PGMessageField *pfield; - - pfield = (PGMessageField *) - pqResultAlloc(res, - offsetof(PGMessageField, contents) + - strlen(value) + 1, - true); - if (!pfield) - return; /* out of memory? */ - pfield->code = code; - strcpy(pfield->contents, value); - pfield->next = res->errFields; - res->errFields = pfield; -} - -/* - * pqSaveParameterStatus - remember parameter status sent by backend - */ -void -pqSaveParameterStatus(PGconn *conn, const char *name, const char *value) -{ - pgParameterStatus *pstatus; - pgParameterStatus *prev; - - /* - * Forget any old information about the parameter - */ - for (pstatus = conn->pstatus, prev = NULL; - pstatus != NULL; - prev = pstatus, pstatus = pstatus->next) - { - if (strcmp(pstatus->name, name) == 0) - { - if (prev) - prev->next = pstatus->next; - else - conn->pstatus = pstatus->next; - free(pstatus); /* frees name and value strings too */ - break; - } - } - - /* - * Store new info as a single malloc block - */ - pstatus = (pgParameterStatus *) malloc(sizeof(pgParameterStatus) + - strlen(name) + strlen(value) + 2); - if (pstatus) - { - char *ptr; - - ptr = ((char *) pstatus) + sizeof(pgParameterStatus); - pstatus->name = ptr; - strcpy(ptr, name); - ptr += strlen(name) + 1; - pstatus->value = ptr; - strcpy(ptr, value); - pstatus->next = conn->pstatus; - conn->pstatus = pstatus; - } - - /* - * Save values of settings that are of interest to libpq in fields of the - * PGconn object. We keep client_encoding and standard_conforming_strings - * in static variables as well, so that PQescapeString and PQescapeBytea - * can behave somewhat sanely (at least in single-connection-using - * programs). - */ - if (strcmp(name, "client_encoding") == 0) - { - conn->client_encoding = pg_char_to_encoding(value); - /* if we don't recognize the encoding name, fall back to SQL_ASCII */ - if (conn->client_encoding < 0) - conn->client_encoding = PG_SQL_ASCII; - static_client_encoding = conn->client_encoding; - } - else if (strcmp(name, "standard_conforming_strings") == 0) - { - conn->std_strings = (strcmp(value, "on") == 0); - static_std_strings = conn->std_strings; - } - else if (strcmp(name, "server_version") == 0) - { - /* We convert the server version to numeric form. */ - int cnt; - int vmaj, - vmin, - vrev; - - cnt = sscanf(value, "%d.%d.%d", &vmaj, &vmin, &vrev); - - if (cnt == 3) - { - /* old style, e.g. 9.6.1 */ - conn->sversion = (100 * vmaj + vmin) * 100 + vrev; - } - else if (cnt == 2) - { - if (vmaj >= 10) - { - /* new style, e.g. 10.1 */ - conn->sversion = 100 * 100 * vmaj + vmin; - } - else - { - /* old style without minor version, e.g. 9.6devel */ - conn->sversion = (100 * vmaj + vmin) * 100; - } - } - else if (cnt == 1) - { - /* new style without minor version, e.g. 10devel */ - conn->sversion = 100 * 100 * vmaj; - } - else - conn->sversion = 0; /* unknown */ - } - else if (strcmp(name, "default_transaction_read_only") == 0) - { - conn->default_transaction_read_only = - (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO; - } - else if (strcmp(name, "in_hot_standby") == 0) - { - conn->in_hot_standby = - (strcmp(value, "on") == 0) ? PG_BOOL_YES : PG_BOOL_NO; - } - else if (strcmp(name, "scram_iterations") == 0) - { - conn->scram_sha_256_iterations = atoi(value); - } -} - - -/* - * pqRowProcessor - * Add the received row to the current async result (conn->result). - * Returns 1 if OK, 0 if error occurred. - * - * On error, *errmsgp can be set to an error string to be returned. - * (Such a string should already be translated via libpq_gettext().) - * If it is left NULL, the error is presumed to be "out of memory". - * - * In single-row mode, we create a new result holding just the current row, - * stashing the previous result in conn->next_result so that it becomes - * active again after pqPrepareAsyncResult(). This allows the result metadata - * (column descriptions) to be carried forward to each result row. - */ -int -pqRowProcessor(PGconn *conn, const char **errmsgp) -{ - PGresult *res = conn->result; - int nfields = res->numAttributes; - const PGdataValue *columns = conn->rowBuf; - PGresAttValue *tup; - int i; - - /* - * In single-row mode, make a new PGresult that will hold just this one - * row; the original conn->result is left unchanged so that it can be used - * again as the template for future rows. - */ - if (conn->singleRowMode) - { - /* Copy everything that should be in the result at this point */ - res = PQcopyResult(res, - PG_COPYRES_ATTRS | PG_COPYRES_EVENTS | - PG_COPYRES_NOTICEHOOKS); - if (!res) - return 0; - } - - /* - * Basically we just allocate space in the PGresult for each field and - * copy the data over. - * - * Note: on malloc failure, we return 0 leaving *errmsgp still NULL, which - * caller will take to mean "out of memory". This is preferable to trying - * to set up such a message here, because evidently there's not enough - * memory for gettext() to do anything. - */ - tup = (PGresAttValue *) - pqResultAlloc(res, nfields * sizeof(PGresAttValue), true); - if (tup == NULL) - goto fail; - - for (i = 0; i < nfields; i++) - { - int clen = columns[i].len; - - if (clen < 0) - { - /* null field */ - tup[i].len = NULL_LEN; - tup[i].value = res->null_field; - } - else - { - bool isbinary = (res->attDescs[i].format != 0); - char *val; - - val = (char *) pqResultAlloc(res, clen + 1, isbinary); - if (val == NULL) - goto fail; - - /* copy and zero-terminate the data (even if it's binary) */ - memcpy(val, columns[i].value, clen); - val[clen] = '\0'; - - tup[i].len = clen; - tup[i].value = val; - } - } - - /* And add the tuple to the PGresult's tuple array */ - if (!pqAddTuple(res, tup, errmsgp)) - goto fail; - - /* - * Success. In single-row mode, make the result available to the client - * immediately. - */ - if (conn->singleRowMode) - { - /* Change result status to special single-row value */ - res->resultStatus = PGRES_SINGLE_TUPLE; - /* Stash old result for re-use later */ - conn->next_result = conn->result; - conn->result = res; - /* And mark the result ready to return */ - conn->asyncStatus = PGASYNC_READY_MORE; - } - - return 1; - -fail: - /* release locally allocated PGresult, if we made one */ - if (res != conn->result) - PQclear(res); - return 0; -} - - -/* - * pqAllocCmdQueueEntry - * Get a command queue entry for caller to fill. - * - * If the recycle queue has a free element, that is returned; if not, a - * fresh one is allocated. Caller is responsible for adding it to the - * command queue (pqAppendCmdQueueEntry) once the struct is filled in, or - * releasing the memory (pqRecycleCmdQueueEntry) if an error occurs. - * - * If allocation fails, sets the error message and returns NULL. - */ -static PGcmdQueueEntry * -pqAllocCmdQueueEntry(PGconn *conn) -{ - PGcmdQueueEntry *entry; - - if (conn->cmd_queue_recycle == NULL) - { - entry = (PGcmdQueueEntry *) malloc(sizeof(PGcmdQueueEntry)); - if (entry == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return NULL; - } - } - else - { - entry = conn->cmd_queue_recycle; - conn->cmd_queue_recycle = entry->next; - } - entry->next = NULL; - entry->query = NULL; - - return entry; -} - -/* - * pqAppendCmdQueueEntry - * Append a caller-allocated entry to the command queue, and update - * conn->asyncStatus to account for it. - * - * The query itself must already have been put in the output buffer by the - * caller. - */ -static void -pqAppendCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry) -{ - Assert(entry->next == NULL); - - if (conn->cmd_queue_head == NULL) - conn->cmd_queue_head = entry; - else - conn->cmd_queue_tail->next = entry; - - conn->cmd_queue_tail = entry; - - switch (conn->pipelineStatus) - { - case PQ_PIPELINE_OFF: - case PQ_PIPELINE_ON: - - /* - * When not in pipeline aborted state, if there's a result ready - * to be consumed, let it be so (that is, don't change away from - * READY or READY_MORE); otherwise set us busy to wait for - * something to arrive from the server. - */ - if (conn->asyncStatus == PGASYNC_IDLE) - conn->asyncStatus = PGASYNC_BUSY; - break; - - case PQ_PIPELINE_ABORTED: - - /* - * In aborted pipeline state, we don't expect anything from the - * server (since we don't send any queries that are queued). - * Therefore, if IDLE then do what PQgetResult would do to let - * itself consume commands from the queue; if we're in any other - * state, we don't have to do anything. - */ - if (conn->asyncStatus == PGASYNC_IDLE || - conn->asyncStatus == PGASYNC_PIPELINE_IDLE) - pqPipelineProcessQueue(conn); - break; - } -} - -/* - * pqRecycleCmdQueueEntry - * Push a command queue entry onto the freelist. - */ -static void -pqRecycleCmdQueueEntry(PGconn *conn, PGcmdQueueEntry *entry) -{ - if (entry == NULL) - return; - - /* recyclable entries should not have a follow-on command */ - Assert(entry->next == NULL); - - if (entry->query) - { - free(entry->query); - entry->query = NULL; - } - - entry->next = conn->cmd_queue_recycle; - conn->cmd_queue_recycle = entry; -} - - -/* - * PQsendQuery - * Submit a query, but don't wait for it to finish - * - * Returns: 1 if successfully submitted - * 0 if error (conn->errorMessage is set) - * - * PQsendQueryContinue is a non-exported version that behaves identically - * except that it doesn't reset conn->errorMessage. - */ -int -PQsendQuery(PGconn *conn, const char *query) -{ - return PQsendQueryInternal(conn, query, true); -} - -int -PQsendQueryContinue(PGconn *conn, const char *query) -{ - return PQsendQueryInternal(conn, query, false); -} - -static int -PQsendQueryInternal(PGconn *conn, const char *query, bool newQuery) -{ - PGcmdQueueEntry *entry = NULL; - - if (!PQsendQueryStart(conn, newQuery)) - return 0; - - /* check the argument */ - if (!query) - { - libpq_append_conn_error(conn, "command string is a null pointer"); - return 0; - } - - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "%s not allowed in pipeline mode", - "PQsendQuery"); - return 0; - } - - entry = pqAllocCmdQueueEntry(conn); - if (entry == NULL) - return 0; /* error msg already set */ - - /* Send the query message(s) */ - /* construct the outgoing Query message */ - if (pqPutMsgStart('Q', conn) < 0 || - pqPuts(query, conn) < 0 || - pqPutMsgEnd(conn) < 0) - { - /* error message should be set up already */ - pqRecycleCmdQueueEntry(conn, entry); - return 0; - } - - /* remember we are using simple query protocol */ - entry->queryclass = PGQUERY_SIMPLE; - /* and remember the query text too, if possible */ - entry->query = strdup(query); - - /* - * Give the data a push. In nonblock mode, don't complain if we're unable - * to send it all; PQgetResult() will do any additional flushing needed. - */ - if (pqFlush(conn) < 0) - goto sendFailed; - - /* OK, it's launched! */ - pqAppendCmdQueueEntry(conn, entry); - - return 1; - -sendFailed: - pqRecycleCmdQueueEntry(conn, entry); - /* error message should be set up already */ - return 0; -} - -/* - * PQsendQueryParams - * Like PQsendQuery, but use extended query protocol so we can pass parameters - */ -int -PQsendQueryParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat) -{ - if (!PQsendQueryStart(conn, true)) - return 0; - - /* check the arguments */ - if (!command) - { - libpq_append_conn_error(conn, "command string is a null pointer"); - return 0; - } - if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT) - { - libpq_append_conn_error(conn, "number of parameters must be between 0 and %d", - PQ_QUERY_PARAM_MAX_LIMIT); - return 0; - } - - return PQsendQueryGuts(conn, - command, - "", /* use unnamed statement */ - nParams, - paramTypes, - paramValues, - paramLengths, - paramFormats, - resultFormat); -} - -/* - * PQsendPrepare - * Submit a Parse message, but don't wait for it to finish - * - * Returns: 1 if successfully submitted - * 0 if error (conn->errorMessage is set) - */ -int -PQsendPrepare(PGconn *conn, - const char *stmtName, const char *query, - int nParams, const Oid *paramTypes) -{ - PGcmdQueueEntry *entry = NULL; - - if (!PQsendQueryStart(conn, true)) - return 0; - - /* check the arguments */ - if (!stmtName) - { - libpq_append_conn_error(conn, "statement name is a null pointer"); - return 0; - } - if (!query) - { - libpq_append_conn_error(conn, "command string is a null pointer"); - return 0; - } - if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT) - { - libpq_append_conn_error(conn, "number of parameters must be between 0 and %d", - PQ_QUERY_PARAM_MAX_LIMIT); - return 0; - } - - entry = pqAllocCmdQueueEntry(conn); - if (entry == NULL) - return 0; /* error msg already set */ - - /* construct the Parse message */ - if (pqPutMsgStart('P', conn) < 0 || - pqPuts(stmtName, conn) < 0 || - pqPuts(query, conn) < 0) - goto sendFailed; - - if (nParams > 0 && paramTypes) - { - int i; - - if (pqPutInt(nParams, 2, conn) < 0) - goto sendFailed; - for (i = 0; i < nParams; i++) - { - if (pqPutInt(paramTypes[i], 4, conn) < 0) - goto sendFailed; - } - } - else - { - if (pqPutInt(0, 2, conn) < 0) - goto sendFailed; - } - if (pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* Add a Sync, unless in pipeline mode. */ - if (conn->pipelineStatus == PQ_PIPELINE_OFF) - { - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - } - - /* remember we are doing just a Parse */ - entry->queryclass = PGQUERY_PREPARE; - - /* and remember the query text too, if possible */ - /* if insufficient memory, query just winds up NULL */ - entry->query = strdup(query); - - /* - * Give the data a push (in pipeline mode, only if we're past the size - * threshold). In nonblock mode, don't complain if we're unable to send - * it all; PQgetResult() will do any additional flushing needed. - */ - if (pqPipelineFlush(conn) < 0) - goto sendFailed; - - /* OK, it's launched! */ - pqAppendCmdQueueEntry(conn, entry); - - return 1; - -sendFailed: - pqRecycleCmdQueueEntry(conn, entry); - /* error message should be set up already */ - return 0; -} - -/* - * PQsendQueryPrepared - * Like PQsendQuery, but execute a previously prepared statement, - * using extended query protocol so we can pass parameters - */ -int -PQsendQueryPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat) -{ - if (!PQsendQueryStart(conn, true)) - return 0; - - /* check the arguments */ - if (!stmtName) - { - libpq_append_conn_error(conn, "statement name is a null pointer"); - return 0; - } - if (nParams < 0 || nParams > PQ_QUERY_PARAM_MAX_LIMIT) - { - libpq_append_conn_error(conn, "number of parameters must be between 0 and %d", - PQ_QUERY_PARAM_MAX_LIMIT); - return 0; - } - - return PQsendQueryGuts(conn, - NULL, /* no command to parse */ - stmtName, - nParams, - NULL, /* no param types */ - paramValues, - paramLengths, - paramFormats, - resultFormat); -} - -/* - * PQsendQueryStart - * Common startup code for PQsendQuery and sibling routines - */ -static bool -PQsendQueryStart(PGconn *conn, bool newQuery) -{ - if (!conn) - return false; - - /* - * If this is the beginning of a query cycle, reset the error state. - * However, in pipeline mode with something already queued, the error - * buffer belongs to that command and we shouldn't clear it. - */ - if (newQuery && conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - /* Don't try to send if we know there's no live connection. */ - if (conn->status != CONNECTION_OK) - { - libpq_append_conn_error(conn, "no connection to the server"); - return false; - } - - /* Can't send while already busy, either, unless enqueuing for later */ - if (conn->asyncStatus != PGASYNC_IDLE && - conn->pipelineStatus == PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "another command is already in progress"); - return false; - } - - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - /* - * When enqueuing commands we don't change much of the connection - * state since it's already in use for the current command. The - * connection state will get updated when pqPipelineProcessQueue() - * advances to start processing the queued message. - * - * Just make sure we can safely enqueue given the current connection - * state. We can enqueue behind another queue item, or behind a - * non-queue command (one that sends its own sync), but we can't - * enqueue if the connection is in a copy state. - */ - switch (conn->asyncStatus) - { - case PGASYNC_IDLE: - case PGASYNC_PIPELINE_IDLE: - case PGASYNC_READY: - case PGASYNC_READY_MORE: - case PGASYNC_BUSY: - /* ok to queue */ - break; - - case PGASYNC_COPY_IN: - case PGASYNC_COPY_OUT: - case PGASYNC_COPY_BOTH: - libpq_append_conn_error(conn, "cannot queue commands during COPY"); - return false; - } - } - else - { - /* - * This command's results will come in immediately. Initialize async - * result-accumulation state - */ - pqClearAsyncResult(conn); - - /* reset single-row processing mode */ - conn->singleRowMode = false; - } - - /* ready to send command message */ - return true; -} - -/* - * PQsendQueryGuts - * Common code for sending a query with extended query protocol - * PQsendQueryStart should be done already - * - * command may be NULL to indicate we use an already-prepared statement - */ -static int -PQsendQueryGuts(PGconn *conn, - const char *command, - const char *stmtName, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat) -{ - int i; - PGcmdQueueEntry *entry; - - entry = pqAllocCmdQueueEntry(conn); - if (entry == NULL) - return 0; /* error msg already set */ - - /* - * We will send Parse (if needed), Bind, Describe Portal, Execute, Sync - * (if not in pipeline mode), using specified statement name and the - * unnamed portal. - */ - - if (command) - { - /* construct the Parse message */ - if (pqPutMsgStart('P', conn) < 0 || - pqPuts(stmtName, conn) < 0 || - pqPuts(command, conn) < 0) - goto sendFailed; - if (nParams > 0 && paramTypes) - { - if (pqPutInt(nParams, 2, conn) < 0) - goto sendFailed; - for (i = 0; i < nParams; i++) - { - if (pqPutInt(paramTypes[i], 4, conn) < 0) - goto sendFailed; - } - } - else - { - if (pqPutInt(0, 2, conn) < 0) - goto sendFailed; - } - if (pqPutMsgEnd(conn) < 0) - goto sendFailed; - } - - /* Construct the Bind message */ - if (pqPutMsgStart('B', conn) < 0 || - pqPuts("", conn) < 0 || - pqPuts(stmtName, conn) < 0) - goto sendFailed; - - /* Send parameter formats */ - if (nParams > 0 && paramFormats) - { - if (pqPutInt(nParams, 2, conn) < 0) - goto sendFailed; - for (i = 0; i < nParams; i++) - { - if (pqPutInt(paramFormats[i], 2, conn) < 0) - goto sendFailed; - } - } - else - { - if (pqPutInt(0, 2, conn) < 0) - goto sendFailed; - } - - if (pqPutInt(nParams, 2, conn) < 0) - goto sendFailed; - - /* Send parameters */ - for (i = 0; i < nParams; i++) - { - if (paramValues && paramValues[i]) - { - int nbytes; - - if (paramFormats && paramFormats[i] != 0) - { - /* binary parameter */ - if (paramLengths) - nbytes = paramLengths[i]; - else - { - libpq_append_conn_error(conn, "length must be given for binary parameter"); - goto sendFailed; - } - } - else - { - /* text parameter, do not use paramLengths */ - nbytes = strlen(paramValues[i]); - } - if (pqPutInt(nbytes, 4, conn) < 0 || - pqPutnchar(paramValues[i], nbytes, conn) < 0) - goto sendFailed; - } - else - { - /* take the param as NULL */ - if (pqPutInt(-1, 4, conn) < 0) - goto sendFailed; - } - } - if (pqPutInt(1, 2, conn) < 0 || - pqPutInt(resultFormat, 2, conn)) - goto sendFailed; - if (pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* construct the Describe Portal message */ - if (pqPutMsgStart('D', conn) < 0 || - pqPutc('P', conn) < 0 || - pqPuts("", conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* construct the Execute message */ - if (pqPutMsgStart('E', conn) < 0 || - pqPuts("", conn) < 0 || - pqPutInt(0, 4, conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* construct the Sync message if not in pipeline mode */ - if (conn->pipelineStatus == PQ_PIPELINE_OFF) - { - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - } - - /* remember we are using extended query protocol */ - entry->queryclass = PGQUERY_EXTENDED; - - /* and remember the query text too, if possible */ - /* if insufficient memory, query just winds up NULL */ - if (command) - entry->query = strdup(command); - - /* - * Give the data a push (in pipeline mode, only if we're past the size - * threshold). In nonblock mode, don't complain if we're unable to send - * it all; PQgetResult() will do any additional flushing needed. - */ - if (pqPipelineFlush(conn) < 0) - goto sendFailed; - - /* OK, it's launched! */ - pqAppendCmdQueueEntry(conn, entry); - - return 1; - -sendFailed: - pqRecycleCmdQueueEntry(conn, entry); - /* error message should be set up already */ - return 0; -} - -/* - * Select row-by-row processing mode - */ -int -PQsetSingleRowMode(PGconn *conn) -{ - /* - * Only allow setting the flag when we have launched a query and not yet - * received any results. - */ - if (!conn) - return 0; - if (conn->asyncStatus != PGASYNC_BUSY) - return 0; - if (!conn->cmd_queue_head || - (conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE && - conn->cmd_queue_head->queryclass != PGQUERY_EXTENDED)) - return 0; - if (pgHavePendingResult(conn)) - return 0; - - /* OK, set flag */ - conn->singleRowMode = true; - return 1; -} - -/* - * Consume any available input from the backend - * 0 return: some kind of trouble - * 1 return: no problem - */ -int -PQconsumeInput(PGconn *conn) -{ - if (!conn) - return 0; - - /* - * for non-blocking connections try to flush the send-queue, otherwise we - * may never get a response for something that may not have already been - * sent because it's in our write buffer! - */ - if (pqIsnonblocking(conn)) - { - if (pqFlush(conn) < 0) - return 0; - } - - /* - * Load more data, if available. We do this no matter what state we are - * in, since we are probably getting called because the application wants - * to get rid of a read-select condition. Note that we will NOT block - * waiting for more input. - */ - if (pqReadData(conn) < 0) - return 0; - - /* Parsing of the data waits till later. */ - return 1; -} - - -/* - * parseInput: if appropriate, parse input data from backend - * until input is exhausted or a stopping state is reached. - * Note that this function will NOT attempt to read more data from the backend. - */ -static void -parseInput(PGconn *conn) -{ - pqParseInput3(conn); -} - -/* - * PQisBusy - * Return true if PQgetResult would block waiting for input. - */ - -int -PQisBusy(PGconn *conn) -{ - if (!conn) - return false; - - /* Parse any available data, if our state permits. */ - parseInput(conn); - - /* - * PQgetResult will return immediately in all states except BUSY. Also, - * if we've detected read EOF and dropped the connection, we can expect - * that PQgetResult will fail immediately. Note that we do *not* check - * conn->write_failed here --- once that's become set, we know we have - * trouble, but we need to keep trying to read until we have a complete - * server message or detect read EOF. - */ - return conn->asyncStatus == PGASYNC_BUSY && conn->status != CONNECTION_BAD; -} - -/* - * PQgetResult - * Get the next PGresult produced by a query. Returns NULL if no - * query work remains or an error has occurred (e.g. out of - * memory). - * - * In pipeline mode, once all the result of a query have been returned, - * PQgetResult returns NULL to let the user know that the next - * query is being processed. At the end of the pipeline, returns a - * result with PQresultStatus(result) == PGRES_PIPELINE_SYNC. - */ -PGresult * -PQgetResult(PGconn *conn) -{ - PGresult *res; - - if (!conn) - return NULL; - - /* Parse any available data, if our state permits. */ - parseInput(conn); - - /* If not ready to return something, block until we are. */ - while (conn->asyncStatus == PGASYNC_BUSY) - { - int flushResult; - - /* - * If data remains unsent, send it. Else we might be waiting for the - * result of a command the backend hasn't even got yet. - */ - while ((flushResult = pqFlush(conn)) > 0) - { - if (pqWait(false, true, conn)) - { - flushResult = -1; - break; - } - } - - /* - * Wait for some more data, and load it. (Note: if the connection has - * been lost, pqWait should return immediately because the socket - * should be read-ready, either with the last server data or with an - * EOF indication. We expect therefore that this won't result in any - * undue delay in reporting a previous write failure.) - */ - if (flushResult || - pqWait(true, false, conn) || - pqReadData(conn) < 0) - { - /* Report the error saved by pqWait or pqReadData */ - pqSaveErrorResult(conn); - conn->asyncStatus = PGASYNC_IDLE; - return pqPrepareAsyncResult(conn); - } - - /* Parse it. */ - parseInput(conn); - - /* - * If we had a write error, but nothing above obtained a query result - * or detected a read error, report the write error. - */ - if (conn->write_failed && conn->asyncStatus == PGASYNC_BUSY) - { - pqSaveWriteError(conn); - conn->asyncStatus = PGASYNC_IDLE; - return pqPrepareAsyncResult(conn); - } - } - - /* Return the appropriate thing. */ - switch (conn->asyncStatus) - { - case PGASYNC_IDLE: - res = NULL; /* query is complete */ - break; - case PGASYNC_PIPELINE_IDLE: - Assert(conn->pipelineStatus != PQ_PIPELINE_OFF); - - /* - * We're about to return the NULL that terminates the round of - * results from the current query; prepare to send the results of - * the next query, if any, when we're called next. If there's no - * next element in the command queue, this gets us in IDLE state. - */ - pqPipelineProcessQueue(conn); - res = NULL; /* query is complete */ - break; - - case PGASYNC_READY: - res = pqPrepareAsyncResult(conn); - - /* Advance the queue as appropriate */ - pqCommandQueueAdvance(conn, false, - res->resultStatus == PGRES_PIPELINE_SYNC); - - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - /* - * We're about to send the results of the current query. Set - * us idle now, and ... - */ - conn->asyncStatus = PGASYNC_PIPELINE_IDLE; - - /* - * ... in cases when we're sending a pipeline-sync result, - * move queue processing forwards immediately, so that next - * time we're called, we're prepared to return the next result - * received from the server. In all other cases, leave the - * queue state change for next time, so that a terminating - * NULL result is sent. - * - * (In other words: we don't return a NULL after a pipeline - * sync.) - */ - if (res->resultStatus == PGRES_PIPELINE_SYNC) - pqPipelineProcessQueue(conn); - } - else - { - /* Set the state back to BUSY, allowing parsing to proceed. */ - conn->asyncStatus = PGASYNC_BUSY; - } - break; - case PGASYNC_READY_MORE: - res = pqPrepareAsyncResult(conn); - /* Set the state back to BUSY, allowing parsing to proceed. */ - conn->asyncStatus = PGASYNC_BUSY; - break; - case PGASYNC_COPY_IN: - res = getCopyResult(conn, PGRES_COPY_IN); - break; - case PGASYNC_COPY_OUT: - res = getCopyResult(conn, PGRES_COPY_OUT); - break; - case PGASYNC_COPY_BOTH: - res = getCopyResult(conn, PGRES_COPY_BOTH); - break; - default: - libpq_append_conn_error(conn, "unexpected asyncStatus: %d", (int) conn->asyncStatus); - pqSaveErrorResult(conn); - conn->asyncStatus = PGASYNC_IDLE; /* try to restore valid state */ - res = pqPrepareAsyncResult(conn); - break; - } - - /* Time to fire PGEVT_RESULTCREATE events, if there are any */ - if (res && res->nEvents > 0) - (void) PQfireResultCreateEvents(conn, res); - - return res; -} - -/* - * getCopyResult - * Helper for PQgetResult: generate result for COPY-in-progress cases - */ -static PGresult * -getCopyResult(PGconn *conn, ExecStatusType copytype) -{ - /* - * If the server connection has been lost, don't pretend everything is - * hunky-dory; instead return a PGRES_FATAL_ERROR result, and reset the - * asyncStatus to idle (corresponding to what we'd do if we'd detected I/O - * error in the earlier steps in PQgetResult). The text returned in the - * result is whatever is in conn->errorMessage; we hope that was filled - * with something relevant when the lost connection was detected. - */ - if (conn->status != CONNECTION_OK) - { - pqSaveErrorResult(conn); - conn->asyncStatus = PGASYNC_IDLE; - return pqPrepareAsyncResult(conn); - } - - /* If we have an async result for the COPY, return that */ - if (conn->result && conn->result->resultStatus == copytype) - return pqPrepareAsyncResult(conn); - - /* Otherwise, invent a suitable PGresult */ - return PQmakeEmptyPGresult(conn, copytype); -} - - -/* - * PQexec - * send a query to the backend and package up the result in a PGresult - * - * If the query was not even sent, return NULL; conn->errorMessage is set to - * a relevant message. - * If the query was sent, a new PGresult is returned (which could indicate - * either success or failure). - * The user is responsible for freeing the PGresult via PQclear() - * when done with it. - */ -PGresult * -PQexec(PGconn *conn, const char *query) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendQuery(conn, query)) - return NULL; - return PQexecFinish(conn); -} - -/* - * PQexecParams - * Like PQexec, but use extended query protocol so we can pass parameters - */ -PGresult * -PQexecParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendQueryParams(conn, command, - nParams, paramTypes, paramValues, paramLengths, - paramFormats, resultFormat)) - return NULL; - return PQexecFinish(conn); -} - -/* - * PQprepare - * Creates a prepared statement by issuing a Parse message. - * - * If the query was not even sent, return NULL; conn->errorMessage is set to - * a relevant message. - * If the query was sent, a new PGresult is returned (which could indicate - * either success or failure). - * The user is responsible for freeing the PGresult via PQclear() - * when done with it. - */ -PGresult * -PQprepare(PGconn *conn, - const char *stmtName, const char *query, - int nParams, const Oid *paramTypes) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendPrepare(conn, stmtName, query, nParams, paramTypes)) - return NULL; - return PQexecFinish(conn); -} - -/* - * PQexecPrepared - * Like PQexec, but execute a previously prepared statement, - * using extended query protocol so we can pass parameters - */ -PGresult * -PQexecPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendQueryPrepared(conn, stmtName, - nParams, paramValues, paramLengths, - paramFormats, resultFormat)) - return NULL; - return PQexecFinish(conn); -} - -/* - * Common code for PQexec and sibling routines: prepare to send command - */ -static bool -PQexecStart(PGconn *conn) -{ - PGresult *result; - - if (!conn) - return false; - - /* - * Since this is the beginning of a query cycle, reset the error state. - * However, in pipeline mode with something already queued, the error - * buffer belongs to that command and we shouldn't clear it. - */ - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "synchronous command execution functions are not allowed in pipeline mode"); - return false; - } - - /* - * Silently discard any prior query result that application didn't eat. - * This is probably poor design, but it's here for backward compatibility. - */ - while ((result = PQgetResult(conn)) != NULL) - { - ExecStatusType resultStatus = result->resultStatus; - - PQclear(result); /* only need its status */ - if (resultStatus == PGRES_COPY_IN) - { - /* get out of a COPY IN state */ - if (PQputCopyEnd(conn, - libpq_gettext("COPY terminated by new PQexec")) < 0) - return false; - /* keep waiting to swallow the copy's failure message */ - } - else if (resultStatus == PGRES_COPY_OUT) - { - /* - * Get out of a COPY OUT state: we just switch back to BUSY and - * allow the remaining COPY data to be dropped on the floor. - */ - conn->asyncStatus = PGASYNC_BUSY; - /* keep waiting to swallow the copy's completion message */ - } - else if (resultStatus == PGRES_COPY_BOTH) - { - /* We don't allow PQexec during COPY BOTH */ - libpq_append_conn_error(conn, "PQexec not allowed during COPY BOTH"); - return false; - } - /* check for loss of connection, too */ - if (conn->status == CONNECTION_BAD) - return false; - } - - /* OK to send a command */ - return true; -} - -/* - * Common code for PQexec and sibling routines: wait for command result - */ -static PGresult * -PQexecFinish(PGconn *conn) -{ - PGresult *result; - PGresult *lastResult; - - /* - * For backwards compatibility, return the last result if there are more - * than one. (We used to have logic here to concatenate successive error - * messages, but now that happens automatically, since conn->errorMessage - * will continue to accumulate errors throughout this loop.) - * - * We have to stop if we see copy in/out/both, however. We will resume - * parsing after application performs the data transfer. - * - * Also stop if the connection is lost (else we'll loop infinitely). - */ - lastResult = NULL; - while ((result = PQgetResult(conn)) != NULL) - { - /* The CONNECTION_BAD status could have been triggered by a previous query error */ - if (conn->status == CONNECTION_BAD && lastResult && lastResult->resultStatus == PGRES_FATAL_ERROR) { - PQclear(result); - break; - } - PQclear(lastResult); - lastResult = result; - if (result->resultStatus == PGRES_COPY_IN || - result->resultStatus == PGRES_COPY_OUT || - result->resultStatus == PGRES_COPY_BOTH || - conn->status == CONNECTION_BAD) - break; - } - - return lastResult; -} - -/* - * PQdescribePrepared - * Obtain information about a previously prepared statement - * - * If the query was not even sent, return NULL; conn->errorMessage is set to - * a relevant message. - * If the query was sent, a new PGresult is returned (which could indicate - * either success or failure). On success, the PGresult contains status - * PGRES_COMMAND_OK, and its parameter and column-heading fields describe - * the statement's inputs and outputs respectively. - * The user is responsible for freeing the PGresult via PQclear() - * when done with it. - */ -PGresult * -PQdescribePrepared(PGconn *conn, const char *stmt) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendDescribe(conn, 'S', stmt)) - return NULL; - return PQexecFinish(conn); -} - -/* - * PQdescribePortal - * Obtain information about a previously created portal - * - * This is much like PQdescribePrepared, except that no parameter info is - * returned. Note that at the moment, libpq doesn't really expose portals - * to the client; but this can be used with a portal created by a SQL - * DECLARE CURSOR command. - */ -PGresult * -PQdescribePortal(PGconn *conn, const char *portal) -{ - if (!PQexecStart(conn)) - return NULL; - if (!PQsendDescribe(conn, 'P', portal)) - return NULL; - return PQexecFinish(conn); -} - -/* - * PQsendDescribePrepared - * Submit a Describe Statement command, but don't wait for it to finish - * - * Returns: 1 if successfully submitted - * 0 if error (conn->errorMessage is set) - */ -int -PQsendDescribePrepared(PGconn *conn, const char *stmt) -{ - return PQsendDescribe(conn, 'S', stmt); -} - -/* - * PQsendDescribePortal - * Submit a Describe Portal command, but don't wait for it to finish - * - * Returns: 1 if successfully submitted - * 0 if error (conn->errorMessage is set) - */ -int -PQsendDescribePortal(PGconn *conn, const char *portal) -{ - return PQsendDescribe(conn, 'P', portal); -} - -/* - * PQsendDescribe - * Common code to send a Describe command - * - * Available options for desc_type are - * 'S' to describe a prepared statement; or - * 'P' to describe a portal. - * Returns 1 on success and 0 on failure. - */ -static int -PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target) -{ - PGcmdQueueEntry *entry = NULL; - - /* Treat null desc_target as empty string */ - if (!desc_target) - desc_target = ""; - - if (!PQsendQueryStart(conn, true)) - return 0; - - entry = pqAllocCmdQueueEntry(conn); - if (entry == NULL) - return 0; /* error msg already set */ - - /* construct the Describe message */ - if (pqPutMsgStart('D', conn) < 0 || - pqPutc(desc_type, conn) < 0 || - pqPuts(desc_target, conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* construct the Sync message */ - if (conn->pipelineStatus == PQ_PIPELINE_OFF) - { - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - } - - /* remember we are doing a Describe */ - entry->queryclass = PGQUERY_DESCRIBE; - - /* - * Give the data a push (in pipeline mode, only if we're past the size - * threshold). In nonblock mode, don't complain if we're unable to send - * it all; PQgetResult() will do any additional flushing needed. - */ - if (pqPipelineFlush(conn) < 0) - goto sendFailed; - - /* OK, it's launched! */ - pqAppendCmdQueueEntry(conn, entry); - - return 1; - -sendFailed: - pqRecycleCmdQueueEntry(conn, entry); - /* error message should be set up already */ - return 0; -} - -/* - * PQnotifies - * returns a PGnotify* structure of the latest async notification - * that has not yet been handled - * - * returns NULL, if there is currently - * no unhandled async notification from the backend - * - * the CALLER is responsible for FREE'ing the structure returned - * - * Note that this function does not read any new data from the socket; - * so usually, caller should call PQconsumeInput() first. - */ -PGnotify * -PQnotifies(PGconn *conn) -{ - PGnotify *event; - - if (!conn) - return NULL; - - /* Parse any available data to see if we can extract NOTIFY messages. */ - parseInput(conn); - - event = conn->notifyHead; - if (event) - { - conn->notifyHead = event->next; - if (!conn->notifyHead) - conn->notifyTail = NULL; - event->next = NULL; /* don't let app see the internal state */ - } - return event; -} - -/* - * PQputCopyData - send some data to the backend during COPY IN or COPY BOTH - * - * Returns 1 if successful, 0 if data could not be sent (only possible - * in nonblock mode), or -1 if an error occurs. - */ -int -PQputCopyData(PGconn *conn, const char *buffer, int nbytes) -{ - if (!conn) - return -1; - if (conn->asyncStatus != PGASYNC_COPY_IN && - conn->asyncStatus != PGASYNC_COPY_BOTH) - { - libpq_append_conn_error(conn, "no COPY in progress"); - return -1; - } - - /* - * Process any NOTICE or NOTIFY messages that might be pending in the - * input buffer. Since the server might generate many notices during the - * COPY, we want to clean those out reasonably promptly to prevent - * indefinite expansion of the input buffer. (Note: the actual read of - * input data into the input buffer happens down inside pqSendSome, but - * it's not authorized to get rid of the data again.) - */ - parseInput(conn); - - if (nbytes > 0) - { - /* - * Try to flush any previously sent data in preference to growing the - * output buffer. If we can't enlarge the buffer enough to hold the - * data, return 0 in the nonblock case, else hard error. (For - * simplicity, always assume 5 bytes of overhead.) - */ - if ((conn->outBufSize - conn->outCount - 5) < nbytes) - { - if (pqFlush(conn) < 0) - return -1; - if (pqCheckOutBufferSpace(conn->outCount + 5 + (size_t) nbytes, - conn)) - return pqIsnonblocking(conn) ? 0 : -1; - } - /* Send the data (too simple to delegate to fe-protocol files) */ - if (pqPutMsgStart('d', conn) < 0 || - pqPutnchar(buffer, nbytes, conn) < 0 || - pqPutMsgEnd(conn) < 0) - return -1; - } - return 1; -} - -/* - * PQputCopyEnd - send EOF indication to the backend during COPY IN - * - * After calling this, use PQgetResult() to check command completion status. - * - * Returns 1 if successful, 0 if data could not be sent (only possible - * in nonblock mode), or -1 if an error occurs. - */ -int -PQputCopyEnd(PGconn *conn, const char *errormsg) -{ - if (!conn) - return -1; - if (conn->asyncStatus != PGASYNC_COPY_IN && - conn->asyncStatus != PGASYNC_COPY_BOTH) - { - libpq_append_conn_error(conn, "no COPY in progress"); - return -1; - } - - /* - * Send the COPY END indicator. This is simple enough that we don't - * bother delegating it to the fe-protocol files. - */ - if (errormsg) - { - /* Send COPY FAIL */ - if (pqPutMsgStart('f', conn) < 0 || - pqPuts(errormsg, conn) < 0 || - pqPutMsgEnd(conn) < 0) - return -1; - } - else - { - /* Send COPY DONE */ - if (pqPutMsgStart('c', conn) < 0 || - pqPutMsgEnd(conn) < 0) - return -1; - } - - /* - * If we sent the COPY command in extended-query mode, we must issue a - * Sync as well. - */ - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE) - { - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - return -1; - } - - /* Return to active duty */ - if (conn->asyncStatus == PGASYNC_COPY_BOTH) - conn->asyncStatus = PGASYNC_COPY_OUT; - else - conn->asyncStatus = PGASYNC_BUSY; - - /* Try to flush data */ - if (pqFlush(conn) < 0) - return -1; - - return 1; -} - -/* - * PQgetCopyData - read a row of data from the backend during COPY OUT - * or COPY BOTH - * - * If successful, sets *buffer to point to a malloc'd row of data, and - * returns row length (always > 0) as result. - * Returns 0 if no row available yet (only possible if async is true), - * -1 if end of copy (consult PQgetResult), or -2 if error (consult - * PQerrorMessage). - */ -int -PQgetCopyData(PGconn *conn, char **buffer, int async) -{ - *buffer = NULL; /* for all failure cases */ - if (!conn) - return -2; - if (conn->asyncStatus != PGASYNC_COPY_OUT && - conn->asyncStatus != PGASYNC_COPY_BOTH) - { - libpq_append_conn_error(conn, "no COPY in progress"); - return -2; - } - return pqGetCopyData3(conn, buffer, async); -} - -/* - * PQgetline - gets a newline-terminated string from the backend. - * - * Chiefly here so that applications can use "COPY <rel> to stdout" - * and read the output string. Returns a null-terminated string in `buffer`. - * - * XXX this routine is now deprecated, because it can't handle binary data. - * If called during a COPY BINARY we return EOF. - * - * PQgetline reads up to `length`-1 characters (like fgets(3)) but strips - * the terminating \n (like gets(3)). - * - * CAUTION: the caller is responsible for detecting the end-of-copy signal - * (a line containing just "\.") when using this routine. - * - * RETURNS: - * EOF if error (eg, invalid arguments are given) - * 0 if EOL is reached (i.e., \n has been read) - * (this is required for backward-compatibility -- this - * routine used to always return EOF or 0, assuming that - * the line ended within `length` bytes.) - * 1 in other cases (i.e., the buffer was filled before \n is reached) - */ -int -PQgetline(PGconn *conn, char *buffer, int length) -{ - if (!buffer || length <= 0) - return EOF; - *buffer = '\0'; - /* length must be at least 3 to hold the \. terminator! */ - if (length < 3) - return EOF; - - if (!conn) - return EOF; - - return pqGetline3(conn, buffer, length); -} - -/* - * PQgetlineAsync - gets a COPY data row without blocking. - * - * This routine is for applications that want to do "COPY <rel> to stdout" - * asynchronously, that is without blocking. Having issued the COPY command - * and gotten a PGRES_COPY_OUT response, the app should call PQconsumeInput - * and this routine until the end-of-data signal is detected. Unlike - * PQgetline, this routine takes responsibility for detecting end-of-data. - * - * On each call, PQgetlineAsync will return data if a complete data row - * is available in libpq's input buffer. Otherwise, no data is returned - * until the rest of the row arrives. - * - * If -1 is returned, the end-of-data signal has been recognized (and removed - * from libpq's input buffer). The caller *must* next call PQendcopy and - * then return to normal processing. - * - * RETURNS: - * -1 if the end-of-copy-data marker has been recognized - * 0 if no data is available - * >0 the number of bytes returned. - * - * The data returned will not extend beyond a data-row boundary. If possible - * a whole row will be returned at one time. But if the buffer offered by - * the caller is too small to hold a row sent by the backend, then a partial - * data row will be returned. In text mode this can be detected by testing - * whether the last returned byte is '\n' or not. - * - * The returned data is *not* null-terminated. - */ - -int -PQgetlineAsync(PGconn *conn, char *buffer, int bufsize) -{ - if (!conn) - return -1; - - return pqGetlineAsync3(conn, buffer, bufsize); -} - -/* - * PQputline -- sends a string to the backend during COPY IN. - * Returns 0 if OK, EOF if not. - * - * This is deprecated primarily because the return convention doesn't allow - * caller to tell the difference between a hard error and a nonblock-mode - * send failure. - */ -int -PQputline(PGconn *conn, const char *string) -{ - return PQputnbytes(conn, string, strlen(string)); -} - -/* - * PQputnbytes -- like PQputline, but buffer need not be null-terminated. - * Returns 0 if OK, EOF if not. - */ -int -PQputnbytes(PGconn *conn, const char *buffer, int nbytes) -{ - if (PQputCopyData(conn, buffer, nbytes) > 0) - return 0; - else - return EOF; -} - -/* - * PQendcopy - * After completing the data transfer portion of a copy in/out, - * the application must call this routine to finish the command protocol. - * - * This is deprecated; it's cleaner to use PQgetResult to get the transfer - * status. - * - * RETURNS: - * 0 on success - * 1 on failure - */ -int -PQendcopy(PGconn *conn) -{ - if (!conn) - return 0; - - return pqEndcopy3(conn); -} - - -/* ---------------- - * PQfn - Send a function call to the POSTGRES backend. - * - * conn : backend connection - * fnid : OID of function to be called - * result_buf : pointer to result buffer - * result_len : actual length of result is returned here - * result_is_int : If the result is an integer, this must be 1, - * otherwise this should be 0 - * args : pointer to an array of function arguments - * (each has length, if integer, and value/pointer) - * nargs : # of arguments in args array. - * - * RETURNS - * PGresult with status = PGRES_COMMAND_OK if successful. - * *result_len is > 0 if there is a return value, 0 if not. - * PGresult with status = PGRES_FATAL_ERROR if backend returns an error. - * NULL on communications failure. conn->errorMessage will be set. - * ---------------- - */ - -PGresult * -PQfn(PGconn *conn, - int fnid, - int *result_buf, - int *result_len, - int result_is_int, - const PQArgBlock *args, - int nargs) -{ - *result_len = 0; - - if (!conn) - return NULL; - - /* - * Since this is the beginning of a query cycle, reset the error state. - * However, in pipeline mode with something already queued, the error - * buffer belongs to that command and we shouldn't clear it. - */ - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "%s not allowed in pipeline mode", "PQfn"); - return NULL; - } - - if (conn->sock == PGINVALID_SOCKET || conn->asyncStatus != PGASYNC_IDLE || - pgHavePendingResult(conn)) - { - libpq_append_conn_error(conn, "connection in wrong state"); - return NULL; - } - - return pqFunctionCall3(conn, fnid, - result_buf, result_len, - result_is_int, - args, nargs); -} - -/* ====== Pipeline mode support ======== */ - -/* - * PQenterPipelineMode - * Put an idle connection in pipeline mode. - * - * Returns 1 on success. On failure, errorMessage is set and 0 is returned. - * - * Commands submitted after this can be pipelined on the connection; - * there's no requirement to wait for one to finish before the next is - * dispatched. - * - * Queuing of a new query or syncing during COPY is not allowed. - * - * A set of commands is terminated by a PQpipelineSync. Multiple sync - * points can be established while in pipeline mode. Pipeline mode can - * be exited by calling PQexitPipelineMode() once all results are processed. - * - * This doesn't actually send anything on the wire, it just puts libpq - * into a state where it can pipeline work. - */ -int -PQenterPipelineMode(PGconn *conn) -{ - if (!conn) - return 0; - - /* succeed with no action if already in pipeline mode */ - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - return 1; - - if (conn->asyncStatus != PGASYNC_IDLE) - { - libpq_append_conn_error(conn, "cannot enter pipeline mode, connection not idle"); - return 0; - } - - conn->pipelineStatus = PQ_PIPELINE_ON; - - return 1; -} - -/* - * PQexitPipelineMode - * End pipeline mode and return to normal command mode. - * - * Returns 1 in success (pipeline mode successfully ended, or not in pipeline - * mode). - * - * Returns 0 if in pipeline mode and cannot be ended yet. Error message will - * be set. - */ -int -PQexitPipelineMode(PGconn *conn) -{ - if (!conn) - return 0; - - if (conn->pipelineStatus == PQ_PIPELINE_OFF && - (conn->asyncStatus == PGASYNC_IDLE || - conn->asyncStatus == PGASYNC_PIPELINE_IDLE) && - conn->cmd_queue_head == NULL) - return 1; - - switch (conn->asyncStatus) - { - case PGASYNC_READY: - case PGASYNC_READY_MORE: - /* there are some uncollected results */ - libpq_append_conn_error(conn, "cannot exit pipeline mode with uncollected results"); - return 0; - - case PGASYNC_BUSY: - libpq_append_conn_error(conn, "cannot exit pipeline mode while busy"); - return 0; - - case PGASYNC_IDLE: - case PGASYNC_PIPELINE_IDLE: - /* OK */ - break; - - case PGASYNC_COPY_IN: - case PGASYNC_COPY_OUT: - case PGASYNC_COPY_BOTH: - libpq_append_conn_error(conn, "cannot exit pipeline mode while in COPY"); - } - - /* still work to process */ - if (conn->cmd_queue_head != NULL) - { - libpq_append_conn_error(conn, "cannot exit pipeline mode with uncollected results"); - return 0; - } - - conn->pipelineStatus = PQ_PIPELINE_OFF; - conn->asyncStatus = PGASYNC_IDLE; - - /* Flush any pending data in out buffer */ - if (pqFlush(conn) < 0) - return 0; /* error message is setup already */ - return 1; -} - -/* - * pqCommandQueueAdvance - * Remove one query from the command queue, if appropriate. - * - * If we have received all results corresponding to the head element - * in the command queue, remove it. - * - * In simple query protocol we must not advance the command queue until the - * ReadyForQuery message has been received. This is because in simple mode a - * command can have multiple queries, and we must process result for all of - * them before moving on to the next command. - * - * Another consideration is synchronization during error processing in - * extended query protocol: we refuse to advance the queue past a SYNC queue - * element, unless the result we've received is also a SYNC. In particular - * this protects us from advancing when an error is received at an - * inappropriate moment. - */ -void -pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, bool gotSync) -{ - PGcmdQueueEntry *prevquery; - - if (conn->cmd_queue_head == NULL) - return; - - /* - * If processing a query of simple query protocol, we only advance the - * queue when we receive the ReadyForQuery message for it. - */ - if (conn->cmd_queue_head->queryclass == PGQUERY_SIMPLE && !isReadyForQuery) - return; - - /* - * If we're waiting for a SYNC, don't advance the queue until we get one. - */ - if (conn->cmd_queue_head->queryclass == PGQUERY_SYNC && !gotSync) - return; - - /* delink element from queue */ - prevquery = conn->cmd_queue_head; - conn->cmd_queue_head = conn->cmd_queue_head->next; - - /* If the queue is now empty, reset the tail too */ - if (conn->cmd_queue_head == NULL) - conn->cmd_queue_tail = NULL; - - /* and make the queue element recyclable */ - prevquery->next = NULL; - pqRecycleCmdQueueEntry(conn, prevquery); -} - -/* - * pqPipelineProcessQueue: subroutine for PQgetResult - * In pipeline mode, start processing the results of the next query in the queue. - */ -static void -pqPipelineProcessQueue(PGconn *conn) -{ - switch (conn->asyncStatus) - { - case PGASYNC_COPY_IN: - case PGASYNC_COPY_OUT: - case PGASYNC_COPY_BOTH: - case PGASYNC_READY: - case PGASYNC_READY_MORE: - case PGASYNC_BUSY: - /* client still has to process current query or results */ - return; - - case PGASYNC_IDLE: - - /* - * If we're in IDLE mode and there's some command in the queue, - * get us into PIPELINE_IDLE mode and process normally. Otherwise - * there's nothing for us to do. - */ - if (conn->cmd_queue_head != NULL) - { - conn->asyncStatus = PGASYNC_PIPELINE_IDLE; - break; - } - return; - - case PGASYNC_PIPELINE_IDLE: - Assert(conn->pipelineStatus != PQ_PIPELINE_OFF); - /* next query please */ - break; - } - - /* - * Reset single-row processing mode. (Client has to set it up for each - * query, if desired.) - */ - conn->singleRowMode = false; - - /* - * If there are no further commands to process in the queue, get us in - * "real idle" mode now. - */ - if (conn->cmd_queue_head == NULL) - { - conn->asyncStatus = PGASYNC_IDLE; - return; - } - - /* - * Reset the error state. This and the next couple of steps correspond to - * what PQsendQueryStart didn't do for this query. - */ - pqClearConnErrorState(conn); - - /* Initialize async result-accumulation state */ - pqClearAsyncResult(conn); - - if (conn->pipelineStatus == PQ_PIPELINE_ABORTED && - conn->cmd_queue_head->queryclass != PGQUERY_SYNC) - { - /* - * In an aborted pipeline we don't get anything from the server for - * each result; we're just discarding commands from the queue until we - * get to the next sync from the server. - * - * The PGRES_PIPELINE_ABORTED results tell the client that its queries - * got aborted. - */ - conn->result = PQmakeEmptyPGresult(conn, PGRES_PIPELINE_ABORTED); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - return; - } - conn->asyncStatus = PGASYNC_READY; - } - else - { - /* allow parsing to continue */ - conn->asyncStatus = PGASYNC_BUSY; - } -} - -/* - * PQpipelineSync - * Send a Sync message as part of a pipeline, and flush to server - * - * It's legal to start submitting more commands in the pipeline immediately, - * without waiting for the results of the current pipeline. There's no need to - * end pipeline mode and start it again. - * - * If a command in a pipeline fails, every subsequent command up to and including - * the result to the Sync message sent by PQpipelineSync gets set to - * PGRES_PIPELINE_ABORTED state. If the whole pipeline is processed without - * error, a PGresult with PGRES_PIPELINE_SYNC is produced. - * - * Queries can already have been sent before PQpipelineSync is called, but - * PQpipelineSync need to be called before retrieving command results. - * - * The connection will remain in pipeline mode and unavailable for new - * synchronous command execution functions until all results from the pipeline - * are processed by the client. - */ -int -PQpipelineSync(PGconn *conn) -{ - PGcmdQueueEntry *entry; - - if (!conn) - return 0; - - if (conn->pipelineStatus == PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "cannot send pipeline when not in pipeline mode"); - return 0; - } - - switch (conn->asyncStatus) - { - case PGASYNC_COPY_IN: - case PGASYNC_COPY_OUT: - case PGASYNC_COPY_BOTH: - /* should be unreachable */ - appendPQExpBufferStr(&conn->errorMessage, - "internal error: cannot send pipeline while in COPY\n"); - return 0; - case PGASYNC_READY: - case PGASYNC_READY_MORE: - case PGASYNC_BUSY: - case PGASYNC_IDLE: - case PGASYNC_PIPELINE_IDLE: - /* OK to send sync */ - break; - } - - entry = pqAllocCmdQueueEntry(conn); - if (entry == NULL) - return 0; /* error msg already set */ - - entry->queryclass = PGQUERY_SYNC; - entry->query = NULL; - - /* construct the Sync message */ - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - goto sendFailed; - - /* - * Give the data a push. In nonblock mode, don't complain if we're unable - * to send it all; PQgetResult() will do any additional flushing needed. - */ - if (PQflush(conn) < 0) - goto sendFailed; - - /* OK, it's launched! */ - pqAppendCmdQueueEntry(conn, entry); - - return 1; - -sendFailed: - pqRecycleCmdQueueEntry(conn, entry); - /* error message should be set up already */ - return 0; -} - -/* - * PQsendFlushRequest - * Send request for server to flush its buffer. Useful in pipeline - * mode when a sync point is not desired. - */ -int -PQsendFlushRequest(PGconn *conn) -{ - if (!conn) - return 0; - - /* Don't try to send if we know there's no live connection. */ - if (conn->status != CONNECTION_OK) - { - libpq_append_conn_error(conn, "no connection to the server"); - return 0; - } - - /* Can't send while already busy, either, unless enqueuing for later */ - if (conn->asyncStatus != PGASYNC_IDLE && - conn->pipelineStatus == PQ_PIPELINE_OFF) - { - libpq_append_conn_error(conn, "another command is already in progress"); - return 0; - } - - if (pqPutMsgStart('H', conn) < 0 || - pqPutMsgEnd(conn) < 0) - { - return 0; - } - - /* - * Give the data a push (in pipeline mode, only if we're past the size - * threshold). In nonblock mode, don't complain if we're unable to send - * it all; PQgetResult() will do any additional flushing needed. - */ - if (pqPipelineFlush(conn) < 0) - return 0; - - return 1; -} - -/* ====== accessor funcs for PGresult ======== */ - -ExecStatusType -PQresultStatus(const PGresult *res) -{ - if (!res) - return PGRES_FATAL_ERROR; - return res->resultStatus; -} - -char * -PQresStatus(ExecStatusType status) -{ - if ((unsigned int) status >= lengthof(pgresStatus)) - return libpq_gettext("invalid ExecStatusType code"); - return pgresStatus[status]; -} - -char * -PQresultErrorMessage(const PGresult *res) -{ - if (!res || !res->errMsg) - return ""; - return res->errMsg; -} - -char * -PQresultVerboseErrorMessage(const PGresult *res, - PGVerbosity verbosity, - PGContextVisibility show_context) -{ - PQExpBufferData workBuf; - - /* - * Because the caller is expected to free the result string, we must - * strdup any constant result. We use plain strdup and document that - * callers should expect NULL if out-of-memory. - */ - if (!res || - (res->resultStatus != PGRES_FATAL_ERROR && - res->resultStatus != PGRES_NONFATAL_ERROR)) - return strdup(libpq_gettext("PGresult is not an error result\n")); - - initPQExpBuffer(&workBuf); - - pqBuildErrorMessage3(&workBuf, res, verbosity, show_context); - - /* If insufficient memory to format the message, fail cleanly */ - if (PQExpBufferDataBroken(workBuf)) - { - termPQExpBuffer(&workBuf); - return strdup(libpq_gettext("out of memory\n")); - } - - return workBuf.data; -} - -char * -PQresultErrorField(const PGresult *res, int fieldcode) -{ - PGMessageField *pfield; - - if (!res) - return NULL; - for (pfield = res->errFields; pfield != NULL; pfield = pfield->next) - { - if (pfield->code == fieldcode) - return pfield->contents; - } - return NULL; -} - -int -PQntuples(const PGresult *res) -{ - if (!res) - return 0; - return res->ntups; -} - -int -PQnfields(const PGresult *res) -{ - if (!res) - return 0; - return res->numAttributes; -} - -int -PQbinaryTuples(const PGresult *res) -{ - if (!res) - return 0; - return res->binary; -} - -/* - * Helper routines to range-check field numbers and tuple numbers. - * Return true if OK, false if not - */ - -static int -check_field_number(const PGresult *res, int field_num) -{ - if (!res) - return false; /* no way to display error message... */ - if (field_num < 0 || field_num >= res->numAttributes) - { - pqInternalNotice(&res->noticeHooks, - "column number %d is out of range 0..%d", - field_num, res->numAttributes - 1); - return false; - } - return true; -} - -static int -check_tuple_field_number(const PGresult *res, - int tup_num, int field_num) -{ - if (!res) - return false; /* no way to display error message... */ - if (tup_num < 0 || tup_num >= res->ntups) - { - pqInternalNotice(&res->noticeHooks, - "row number %d is out of range 0..%d", - tup_num, res->ntups - 1); - return false; - } - if (field_num < 0 || field_num >= res->numAttributes) - { - pqInternalNotice(&res->noticeHooks, - "column number %d is out of range 0..%d", - field_num, res->numAttributes - 1); - return false; - } - return true; -} - -static int -check_param_number(const PGresult *res, int param_num) -{ - if (!res) - return false; /* no way to display error message... */ - if (param_num < 0 || param_num >= res->numParameters) - { - pqInternalNotice(&res->noticeHooks, - "parameter number %d is out of range 0..%d", - param_num, res->numParameters - 1); - return false; - } - - return true; -} - -/* - * returns NULL if the field_num is invalid - */ -char * -PQfname(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return NULL; - if (res->attDescs) - return res->attDescs[field_num].name; - else - return NULL; -} - -/* - * PQfnumber: find column number given column name - * - * The column name is parsed as if it were in a SQL statement, including - * case-folding and double-quote processing. But note a possible gotcha: - * downcasing in the frontend might follow different locale rules than - * downcasing in the backend... - * - * Returns -1 if no match. In the present backend it is also possible - * to have multiple matches, in which case the first one is found. - */ -int -PQfnumber(const PGresult *res, const char *field_name) -{ - char *field_case; - bool in_quotes; - bool all_lower = true; - const char *iptr; - char *optr; - int i; - - if (!res) - return -1; - - /* - * Note: it is correct to reject a zero-length input string; the proper - * input to match a zero-length field name would be "". - */ - if (field_name == NULL || - field_name[0] == '\0' || - res->attDescs == NULL) - return -1; - - /* - * Check if we can avoid the strdup() and related work because the - * passed-in string wouldn't be changed before we do the check anyway. - */ - for (iptr = field_name; *iptr; iptr++) - { - char c = *iptr; - - if (c == '"' || c != pg_tolower((unsigned char) c)) - { - all_lower = false; - break; - } - } - - if (all_lower) - for (i = 0; i < res->numAttributes; i++) - if (strcmp(field_name, res->attDescs[i].name) == 0) - return i; - - /* Fall through to the normal check if that didn't work out. */ - - /* - * Note: this code will not reject partially quoted strings, eg - * foo"BAR"foo will become fooBARfoo when it probably ought to be an error - * condition. - */ - field_case = strdup(field_name); - if (field_case == NULL) - return -1; /* grotty */ - - in_quotes = false; - optr = field_case; - for (iptr = field_case; *iptr; iptr++) - { - char c = *iptr; - - if (in_quotes) - { - if (c == '"') - { - if (iptr[1] == '"') - { - /* doubled quotes become a single quote */ - *optr++ = '"'; - iptr++; - } - else - in_quotes = false; - } - else - *optr++ = c; - } - else if (c == '"') - in_quotes = true; - else - { - c = pg_tolower((unsigned char) c); - *optr++ = c; - } - } - *optr = '\0'; - - for (i = 0; i < res->numAttributes; i++) - { - if (strcmp(field_case, res->attDescs[i].name) == 0) - { - free(field_case); - return i; - } - } - free(field_case); - return -1; -} - -Oid -PQftable(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return InvalidOid; - if (res->attDescs) - return res->attDescs[field_num].tableid; - else - return InvalidOid; -} - -int -PQftablecol(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return 0; - if (res->attDescs) - return res->attDescs[field_num].columnid; - else - return 0; -} - -int -PQfformat(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return 0; - if (res->attDescs) - return res->attDescs[field_num].format; - else - return 0; -} - -Oid -PQftype(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return InvalidOid; - if (res->attDescs) - return res->attDescs[field_num].typid; - else - return InvalidOid; -} - -int -PQfsize(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return 0; - if (res->attDescs) - return res->attDescs[field_num].typlen; - else - return 0; -} - -int -PQfmod(const PGresult *res, int field_num) -{ - if (!check_field_number(res, field_num)) - return 0; - if (res->attDescs) - return res->attDescs[field_num].atttypmod; - else - return 0; -} - -char * -PQcmdStatus(PGresult *res) -{ - if (!res) - return NULL; - return res->cmdStatus; -} - -/* - * PQoidStatus - - * if the last command was an INSERT, return the oid string - * if not, return "" - */ -char * -PQoidStatus(const PGresult *res) -{ - /* - * This must be enough to hold the result. Don't laugh, this is better - * than what this function used to do. - */ - static char buf[24]; - - size_t len; - - if (!res || strncmp(res->cmdStatus, "INSERT ", 7) != 0) - return ""; - - len = strspn(res->cmdStatus + 7, "0123456789"); - if (len > sizeof(buf) - 1) - len = sizeof(buf) - 1; - memcpy(buf, res->cmdStatus + 7, len); - buf[len] = '\0'; - - return buf; -} - -/* - * PQoidValue - - * a perhaps preferable form of the above which just returns - * an Oid type - */ -Oid -PQoidValue(const PGresult *res) -{ - char *endptr = NULL; - unsigned long result; - - if (!res || - strncmp(res->cmdStatus, "INSERT ", 7) != 0 || - res->cmdStatus[7] < '0' || - res->cmdStatus[7] > '9') - return InvalidOid; - - result = strtoul(res->cmdStatus + 7, &endptr, 10); - - if (!endptr || (*endptr != ' ' && *endptr != '\0')) - return InvalidOid; - else - return (Oid) result; -} - - -/* - * PQcmdTuples - - * If the last command was INSERT/UPDATE/DELETE/MERGE/MOVE/FETCH/COPY, - * return a string containing the number of inserted/affected tuples. - * If not, return "". - * - * XXX: this should probably return an int - */ -char * -PQcmdTuples(PGresult *res) -{ - char *p, - *c; - - if (!res) - return ""; - - if (strncmp(res->cmdStatus, "INSERT ", 7) == 0) - { - p = res->cmdStatus + 7; - /* INSERT: skip oid and space */ - while (*p && *p != ' ') - p++; - if (*p == 0) - goto interpret_error; /* no space? */ - p++; - } - else if (strncmp(res->cmdStatus, "SELECT ", 7) == 0 || - strncmp(res->cmdStatus, "DELETE ", 7) == 0 || - strncmp(res->cmdStatus, "UPDATE ", 7) == 0) - p = res->cmdStatus + 7; - else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0 || - strncmp(res->cmdStatus, "MERGE ", 6) == 0) - p = res->cmdStatus + 6; - else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 || - strncmp(res->cmdStatus, "COPY ", 5) == 0) - p = res->cmdStatus + 5; - else - return ""; - - /* check that we have an integer (at least one digit, nothing else) */ - for (c = p; *c; c++) - { - if (!isdigit((unsigned char) *c)) - goto interpret_error; - } - if (c == p) - goto interpret_error; - - return p; - -interpret_error: - pqInternalNotice(&res->noticeHooks, - "could not interpret result from server: %s", - res->cmdStatus); - return ""; -} - -/* - * PQgetvalue: - * return the value of field 'field_num' of row 'tup_num' - */ -char * -PQgetvalue(const PGresult *res, int tup_num, int field_num) -{ - if (!check_tuple_field_number(res, tup_num, field_num)) - return NULL; - return res->tuples[tup_num][field_num].value; -} - -/* PQgetlength: - * returns the actual length of a field value in bytes. - */ -int -PQgetlength(const PGresult *res, int tup_num, int field_num) -{ - if (!check_tuple_field_number(res, tup_num, field_num)) - return 0; - if (res->tuples[tup_num][field_num].len != NULL_LEN) - return res->tuples[tup_num][field_num].len; - else - return 0; -} - -/* PQgetisnull: - * returns the null status of a field value. - */ -int -PQgetisnull(const PGresult *res, int tup_num, int field_num) -{ - if (!check_tuple_field_number(res, tup_num, field_num)) - return 1; /* pretend it is null */ - if (res->tuples[tup_num][field_num].len == NULL_LEN) - return 1; - else - return 0; -} - -/* PQnparams: - * returns the number of input parameters of a prepared statement. - */ -int -PQnparams(const PGresult *res) -{ - if (!res) - return 0; - return res->numParameters; -} - -/* PQparamtype: - * returns type Oid of the specified statement parameter. - */ -Oid -PQparamtype(const PGresult *res, int param_num) -{ - if (!check_param_number(res, param_num)) - return InvalidOid; - if (res->paramDescs) - return res->paramDescs[param_num].typid; - else - return InvalidOid; -} - - -/* PQsetnonblocking: - * sets the PGconn's database connection non-blocking if the arg is true - * or makes it blocking if the arg is false, this will not protect - * you from PQexec(), you'll only be safe when using the non-blocking API. - * Needs to be called only on a connected database connection. - */ -int -PQsetnonblocking(PGconn *conn, int arg) -{ - bool barg; - - if (!conn || conn->status == CONNECTION_BAD) - return -1; - - barg = (arg ? true : false); - - /* early out if the socket is already in the state requested */ - if (barg == conn->nonblocking) - return 0; - - /* - * to guarantee constancy for flushing/query/result-polling behavior we - * need to flush the send queue at this point in order to guarantee proper - * behavior. this is ok because either they are making a transition _from_ - * or _to_ blocking mode, either way we can block them. - * - * Clear error state in case pqFlush adds to it, unless we're actively - * pipelining, in which case it seems best not to. - */ - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - /* if we are going from blocking to non-blocking flush here */ - if (pqFlush(conn)) - return -1; - - conn->nonblocking = barg; - - return 0; -} - -/* - * return the blocking status of the database connection - * true == nonblocking, false == blocking - */ -int -PQisnonblocking(const PGconn *conn) -{ - if (!conn || conn->status == CONNECTION_BAD) - return false; - return pqIsnonblocking(conn); -} - -/* libpq is thread-safe? */ -int -PQisthreadsafe(void) -{ -#ifdef ENABLE_THREAD_SAFETY - return true; -#else - return false; -#endif -} - - -/* try to force data out, really only useful for non-blocking users */ -int -PQflush(PGconn *conn) -{ - if (!conn || conn->status == CONNECTION_BAD) - return -1; - return pqFlush(conn); -} - -/* - * pqPipelineFlush - * - * In pipeline mode, data will be flushed only when the out buffer reaches the - * threshold value. In non-pipeline mode, it behaves as stock pqFlush. - * - * Returns 0 on success. - */ -static int -pqPipelineFlush(PGconn *conn) -{ - if ((conn->pipelineStatus != PQ_PIPELINE_ON) || - (conn->outCount >= OUTBUFFER_THRESHOLD)) - return pqFlush(conn); - return 0; -} - - -/* - * PQfreemem - safely frees memory allocated - * - * Needed mostly by Win32, unless multithreaded DLL (/MD in VC6) - * Used for freeing memory from PQescapeBytea()/PQunescapeBytea() - */ -void -PQfreemem(void *ptr) -{ - free(ptr); -} - -/* - * PQfreeNotify - free's the memory associated with a PGnotify - * - * This function is here only for binary backward compatibility. - * New code should use PQfreemem(). A macro will automatically map - * calls to PQfreemem. It should be removed in the future. bjm 2003-03-24 - */ - -#undef PQfreeNotify -void PQfreeNotify(PGnotify *notify); - -void -PQfreeNotify(PGnotify *notify) -{ - PQfreemem(notify); -} - - -/* - * Escaping arbitrary strings to get valid SQL literal strings. - * - * Replaces "'" with "''", and if not std_strings, replaces "\" with "\\". - * - * length is the length of the source string. (Note: if a terminating NUL - * is encountered sooner, PQescapeString stops short of "length"; the behavior - * is thus rather like strncpy.) - * - * For safety the buffer at "to" must be at least 2*length + 1 bytes long. - * A terminating NUL character is added to the output string, whether the - * input is NUL-terminated or not. - * - * Returns the actual length of the output (not counting the terminating NUL). - */ -static size_t -PQescapeStringInternal(PGconn *conn, - char *to, const char *from, size_t length, - int *error, - int encoding, bool std_strings) -{ - const char *source = from; - char *target = to; - size_t remaining = length; - - if (error) - *error = 0; - - while (remaining > 0 && *source != '\0') - { - char c = *source; - int len; - int i; - - /* Fast path for plain ASCII */ - if (!IS_HIGHBIT_SET(c)) - { - /* Apply quoting if needed */ - if (SQL_STR_DOUBLE(c, !std_strings)) - *target++ = c; - /* Copy the character */ - *target++ = c; - source++; - remaining--; - continue; - } - - /* Slow path for possible multibyte characters */ - len = pg_encoding_mblen(encoding, source); - - /* Copy the character */ - for (i = 0; i < len; i++) - { - if (remaining == 0 || *source == '\0') - break; - *target++ = *source++; - remaining--; - } - - /* - * If we hit premature end of string (ie, incomplete multibyte - * character), try to pad out to the correct length with spaces. We - * may not be able to pad completely, but we will always be able to - * insert at least one pad space (since we'd not have quoted a - * multibyte character). This should be enough to make a string that - * the server will error out on. - */ - if (i < len) - { - if (error) - *error = 1; - if (conn) - libpq_append_conn_error(conn, "incomplete multibyte character"); - for (; i < len; i++) - { - if (((size_t) (target - to)) / 2 >= length) - break; - *target++ = ' '; - } - break; - } - } - - /* Write the terminating NUL character. */ - *target = '\0'; - - return target - to; -} - -size_t -PQescapeStringConn(PGconn *conn, - char *to, const char *from, size_t length, - int *error) -{ - if (!conn) - { - /* force empty-string result */ - *to = '\0'; - if (error) - *error = 1; - return 0; - } - - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - return PQescapeStringInternal(conn, to, from, length, error, - conn->client_encoding, - conn->std_strings); -} - -size_t -PQescapeString(char *to, const char *from, size_t length) -{ - return PQescapeStringInternal(NULL, to, from, length, NULL, - static_client_encoding, - static_std_strings); -} - - -/* - * Escape arbitrary strings. If as_ident is true, we escape the result - * as an identifier; if false, as a literal. The result is returned in - * a newly allocated buffer. If we fail due to an encoding violation or out - * of memory condition, we return NULL, storing an error message into conn. - */ -static char * -PQescapeInternal(PGconn *conn, const char *str, size_t len, bool as_ident) -{ - const char *s; - char *result; - char *rp; - int num_quotes = 0; /* single or double, depending on as_ident */ - int num_backslashes = 0; - int input_len; - int result_size; - char quote_char = as_ident ? '"' : '\''; - - /* We must have a connection, else fail immediately. */ - if (!conn) - return NULL; - - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - /* Scan the string for characters that must be escaped. */ - for (s = str; (s - str) < len && *s != '\0'; ++s) - { - if (*s == quote_char) - ++num_quotes; - else if (*s == '\\') - ++num_backslashes; - else if (IS_HIGHBIT_SET(*s)) - { - int charlen; - - /* Slow path for possible multibyte characters */ - charlen = pg_encoding_mblen(conn->client_encoding, s); - - /* Multibyte character overruns allowable length. */ - if ((s - str) + charlen > len || memchr(s, 0, charlen) != NULL) - { - libpq_append_conn_error(conn, "incomplete multibyte character"); - return NULL; - } - - /* Adjust s, bearing in mind that for loop will increment it. */ - s += charlen - 1; - } - } - - /* Allocate output buffer. */ - input_len = s - str; - result_size = input_len + num_quotes + 3; /* two quotes, plus a NUL */ - if (!as_ident && num_backslashes > 0) - result_size += num_backslashes + 2; - result = rp = (char *) malloc(result_size); - if (rp == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return NULL; - } - - /* - * If we are escaping a literal that contains backslashes, we use the - * escape string syntax so that the result is correct under either value - * of standard_conforming_strings. We also emit a leading space in this - * case, to guard against the possibility that the result might be - * interpolated immediately following an identifier. - */ - if (!as_ident && num_backslashes > 0) - { - *rp++ = ' '; - *rp++ = 'E'; - } - - /* Opening quote. */ - *rp++ = quote_char; - - /* - * Use fast path if possible. - * - * We've already verified that the input string is well-formed in the - * current encoding. If it contains no quotes and, in the case of - * literal-escaping, no backslashes, then we can just copy it directly to - * the output buffer, adding the necessary quotes. - * - * If not, we must rescan the input and process each character - * individually. - */ - if (num_quotes == 0 && (num_backslashes == 0 || as_ident)) - { - memcpy(rp, str, input_len); - rp += input_len; - } - else - { - for (s = str; s - str < input_len; ++s) - { - if (*s == quote_char || (!as_ident && *s == '\\')) - { - *rp++ = *s; - *rp++ = *s; - } - else if (!IS_HIGHBIT_SET(*s)) - *rp++ = *s; - else - { - int i = pg_encoding_mblen(conn->client_encoding, s); - - while (1) - { - *rp++ = *s; - if (--i == 0) - break; - ++s; /* for loop will provide the final increment */ - } - } - } - } - - /* Closing quote and terminating NUL. */ - *rp++ = quote_char; - *rp = '\0'; - - return result; -} - -char * -PQescapeLiteral(PGconn *conn, const char *str, size_t len) -{ - return PQescapeInternal(conn, str, len, false); -} - -char * -PQescapeIdentifier(PGconn *conn, const char *str, size_t len) -{ - return PQescapeInternal(conn, str, len, true); -} - -/* HEX encoding support for bytea */ -static const char hextbl[] = "0123456789abcdef"; - -static const int8 hexlookup[128] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -}; - -static inline char -get_hex(char c) -{ - int res = -1; - - if (c > 0 && c < 127) - res = hexlookup[(unsigned char) c]; - - return (char) res; -} - - -/* - * PQescapeBytea - converts from binary string to the - * minimal encoding necessary to include the string in an SQL - * INSERT statement with a bytea type column as the target. - * - * We can use either hex or escape (traditional) encoding. - * In escape mode, the following transformations are applied: - * '\0' == ASCII 0 == \000 - * '\'' == ASCII 39 == '' - * '\\' == ASCII 92 == \\ - * anything < 0x20, or > 0x7e ---> \ooo - * (where ooo is an octal expression) - * - * If not std_strings, all backslashes sent to the output are doubled. - */ -static unsigned char * -PQescapeByteaInternal(PGconn *conn, - const unsigned char *from, size_t from_length, - size_t *to_length, bool std_strings, bool use_hex) -{ - const unsigned char *vp; - unsigned char *rp; - unsigned char *result; - size_t i; - size_t len; - size_t bslash_len = (std_strings ? 1 : 2); - - /* - * empty string has 1 char ('\0') - */ - len = 1; - - if (use_hex) - { - len += bslash_len + 1 + 2 * from_length; - } - else - { - vp = from; - for (i = from_length; i > 0; i--, vp++) - { - if (*vp < 0x20 || *vp > 0x7e) - len += bslash_len + 3; - else if (*vp == '\'') - len += 2; - else if (*vp == '\\') - len += bslash_len + bslash_len; - else - len++; - } - } - - *to_length = len; - rp = result = (unsigned char *) malloc(len); - if (rp == NULL) - { - if (conn) - libpq_append_conn_error(conn, "out of memory"); - return NULL; - } - - if (use_hex) - { - if (!std_strings) - *rp++ = '\\'; - *rp++ = '\\'; - *rp++ = 'x'; - } - - vp = from; - for (i = from_length; i > 0; i--, vp++) - { - unsigned char c = *vp; - - if (use_hex) - { - *rp++ = hextbl[(c >> 4) & 0xF]; - *rp++ = hextbl[c & 0xF]; - } - else if (c < 0x20 || c > 0x7e) - { - if (!std_strings) - *rp++ = '\\'; - *rp++ = '\\'; - *rp++ = (c >> 6) + '0'; - *rp++ = ((c >> 3) & 07) + '0'; - *rp++ = (c & 07) + '0'; - } - else if (c == '\'') - { - *rp++ = '\''; - *rp++ = '\''; - } - else if (c == '\\') - { - if (!std_strings) - { - *rp++ = '\\'; - *rp++ = '\\'; - } - *rp++ = '\\'; - *rp++ = '\\'; - } - else - *rp++ = c; - } - *rp = '\0'; - - return result; -} - -unsigned char * -PQescapeByteaConn(PGconn *conn, - const unsigned char *from, size_t from_length, - size_t *to_length) -{ - if (!conn) - return NULL; - - if (conn->cmd_queue_head == NULL) - pqClearConnErrorState(conn); - - return PQescapeByteaInternal(conn, from, from_length, to_length, - conn->std_strings, - (conn->sversion >= 90000)); -} - -unsigned char * -PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length) -{ - return PQescapeByteaInternal(NULL, from, from_length, to_length, - static_std_strings, - false /* can't use hex */ ); -} - - -#define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3') -#define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7') -#define OCTVAL(CH) ((CH) - '0') - -/* - * PQunescapeBytea - converts the null terminated string representation - * of a bytea, strtext, into binary, filling a buffer. It returns a - * pointer to the buffer (or NULL on error), and the size of the - * buffer in retbuflen. The pointer may subsequently be used as an - * argument to the function PQfreemem. - * - * The following transformations are made: - * \\ == ASCII 92 == \ - * \ooo == a byte whose value = ooo (ooo is an octal number) - * \x == x (x is any character not matched by the above transformations) - */ -unsigned char * -PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen) -{ - size_t strtextlen, - buflen; - unsigned char *buffer, - *tmpbuf; - size_t i, - j; - - if (strtext == NULL) - return NULL; - - strtextlen = strlen((const char *) strtext); - - if (strtext[0] == '\\' && strtext[1] == 'x') - { - const unsigned char *s; - unsigned char *p; - - buflen = (strtextlen - 2) / 2; - /* Avoid unportable malloc(0) */ - buffer = (unsigned char *) malloc(buflen > 0 ? buflen : 1); - if (buffer == NULL) - return NULL; - - s = strtext + 2; - p = buffer; - while (*s) - { - char v1, - v2; - - /* - * Bad input is silently ignored. Note that this includes - * whitespace between hex pairs, which is allowed by byteain. - */ - v1 = get_hex(*s++); - if (!*s || v1 == (char) -1) - continue; - v2 = get_hex(*s++); - if (v2 != (char) -1) - *p++ = (v1 << 4) | v2; - } - - buflen = p - buffer; - } - else - { - /* - * Length of input is max length of output, but add one to avoid - * unportable malloc(0) if input is zero-length. - */ - buffer = (unsigned char *) malloc(strtextlen + 1); - if (buffer == NULL) - return NULL; - - for (i = j = 0; i < strtextlen;) - { - switch (strtext[i]) - { - case '\\': - i++; - if (strtext[i] == '\\') - buffer[j++] = strtext[i++]; - else - { - if ((ISFIRSTOCTDIGIT(strtext[i])) && - (ISOCTDIGIT(strtext[i + 1])) && - (ISOCTDIGIT(strtext[i + 2]))) - { - int byte; - - byte = OCTVAL(strtext[i++]); - byte = (byte << 3) + OCTVAL(strtext[i++]); - byte = (byte << 3) + OCTVAL(strtext[i++]); - buffer[j++] = byte; - } - } - - /* - * Note: if we see '\' followed by something that isn't a - * recognized escape sequence, we loop around having done - * nothing except advance i. Therefore the something will - * be emitted as ordinary data on the next cycle. Corner - * case: '\' at end of string will just be discarded. - */ - break; - - default: - buffer[j++] = strtext[i++]; - break; - } - } - buflen = j; /* buflen is the length of the dequoted data */ - } - - /* Shrink the buffer to be no larger than necessary */ - /* +1 avoids unportable behavior when buflen==0 */ - tmpbuf = realloc(buffer, buflen + 1); - - /* It would only be a very brain-dead realloc that could fail, but... */ - if (!tmpbuf) - { - free(buffer); - return NULL; - } - - *retbuflen = buflen; - return tmpbuf; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-lobj.c b/contrib/libs/libpq/src/interfaces/libpq/fe-lobj.c deleted file mode 100644 index 206266fd04..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-lobj.c +++ /dev/null @@ -1,1064 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-lobj.c - * Front-end large object interface - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-lobj.c - * - *------------------------------------------------------------------------- - */ - -#ifdef WIN32 -/* - * As unlink/rename are #define'd in port.h (via postgres_fe.h), io.h - * must be included first on MS C. Might as well do it for all WIN32's - * here. - */ -#include <io.h> -#endif - -#include "postgres_fe.h" - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#endif - -#include <fcntl.h> -#include <limits.h> -#include <sys/stat.h> - -#include "libpq-fe.h" -#include "libpq-int.h" -#include "libpq/libpq-fs.h" /* must come after sys/stat.h */ -#include "port/pg_bswap.h" - -#define LO_BUFSIZE 8192 - -static int lo_initialize(PGconn *conn); -static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid); -static pg_int64 lo_hton64(pg_int64 host64); -static pg_int64 lo_ntoh64(pg_int64 net64); - -/* - * lo_open - * opens an existing large object - * - * returns the file descriptor for use in later lo_* calls - * return -1 upon failure. - */ -int -lo_open(PGconn *conn, Oid lobjId, int mode) -{ - int fd; - int result_len; - PQArgBlock argv[2]; - PGresult *res; - - if (lo_initialize(conn) < 0) - return -1; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = lobjId; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = mode; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_open, &fd, &result_len, 1, argv, 2); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return fd; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_close - * closes an existing large object - * - * returns 0 upon success - * returns -1 upon failure. - */ -int -lo_close(PGconn *conn, int fd) -{ - PQArgBlock argv[1]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - res = PQfn(conn, conn->lobjfuncs->fn_lo_close, - &retval, &result_len, 1, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_truncate - * truncates an existing large object to the given size - * - * returns 0 upon success - * returns -1 upon failure - */ -int -lo_truncate(PGconn *conn, int fd, size_t len) -{ - PQArgBlock argv[2]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - /* Must check this on-the-fly because it's not there pre-8.3 */ - if (conn->lobjfuncs->fn_lo_truncate == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_truncate"); - return -1; - } - - /* - * Long ago, somebody thought it'd be a good idea to declare this function - * as taking size_t ... but the underlying backend function only accepts a - * signed int32 length. So throw error if the given value overflows - * int32. (A possible alternative is to automatically redirect the call - * to lo_truncate64; but if the caller wanted to rely on that backend - * function being available, he could have called lo_truncate64 for - * himself.) - */ - if (len > (size_t) INT_MAX) - { - libpq_append_conn_error(conn, "argument of lo_truncate exceeds integer range"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = (int) len; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate, - &retval, &result_len, 1, argv, 2); - - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_truncate64 - * truncates an existing large object to the given size - * - * returns 0 upon success - * returns -1 upon failure - */ -int -lo_truncate64(PGconn *conn, int fd, pg_int64 len) -{ - PQArgBlock argv[2]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - if (conn->lobjfuncs->fn_lo_truncate64 == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_truncate64"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - len = lo_hton64(len); - argv[1].isint = 0; - argv[1].len = 8; - argv[1].u.ptr = (int *) &len; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_truncate64, - &retval, &result_len, 1, argv, 2); - - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_read - * read len bytes of the large object into buf - * - * returns the number of bytes read, or -1 on failure. - * the CALLER must have allocated enough space to hold the result returned - */ - -int -lo_read(PGconn *conn, int fd, char *buf, size_t len) -{ - PQArgBlock argv[2]; - PGresult *res; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - /* - * Long ago, somebody thought it'd be a good idea to declare this function - * as taking size_t ... but the underlying backend function only accepts a - * signed int32 length. So throw error if the given value overflows - * int32. - */ - if (len > (size_t) INT_MAX) - { - libpq_append_conn_error(conn, "argument of lo_read exceeds integer range"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = (int) len; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_read, - (void *) buf, &result_len, 0, argv, 2); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return result_len; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_write - * write len bytes of buf into the large object fd - * - * returns the number of bytes written, or -1 on failure. - */ -int -lo_write(PGconn *conn, int fd, const char *buf, size_t len) -{ - PQArgBlock argv[2]; - PGresult *res; - int result_len; - int retval; - - if (lo_initialize(conn) < 0) - return -1; - - /* - * Long ago, somebody thought it'd be a good idea to declare this function - * as taking size_t ... but the underlying backend function only accepts a - * signed int32 length. So throw error if the given value overflows - * int32. - */ - if (len > (size_t) INT_MAX) - { - libpq_append_conn_error(conn, "argument of lo_write exceeds integer range"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 0; - argv[1].len = (int) len; - argv[1].u.ptr = (int *) unconstify(char *, buf); - - res = PQfn(conn, conn->lobjfuncs->fn_lo_write, - &retval, &result_len, 1, argv, 2); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_lseek - * change the current read or write location on a large object - */ -int -lo_lseek(PGconn *conn, int fd, int offset, int whence) -{ - PQArgBlock argv[3]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - argv[1].isint = 1; - argv[1].len = 4; - argv[1].u.integer = offset; - - argv[2].isint = 1; - argv[2].len = 4; - argv[2].u.integer = whence; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek, - &retval, &result_len, 1, argv, 3); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_lseek64 - * change the current read or write location on a large object - */ -pg_int64 -lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence) -{ - PQArgBlock argv[3]; - PGresult *res; - pg_int64 retval; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - if (conn->lobjfuncs->fn_lo_lseek64 == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_lseek64"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - offset = lo_hton64(offset); - argv[1].isint = 0; - argv[1].len = 8; - argv[1].u.ptr = (int *) &offset; - - argv[2].isint = 1; - argv[2].len = 4; - argv[2].u.integer = whence; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_lseek64, - (void *) &retval, &result_len, 0, argv, 3); - if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8) - { - PQclear(res); - return lo_ntoh64(retval); - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_creat - * create a new large object - * the mode is ignored (once upon a time it had a use) - * - * returns the oid of the large object created or - * InvalidOid upon failure - */ -Oid -lo_creat(PGconn *conn, int mode) -{ - PQArgBlock argv[1]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return InvalidOid; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = mode; - res = PQfn(conn, conn->lobjfuncs->fn_lo_creat, - &retval, &result_len, 1, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return (Oid) retval; - } - else - { - PQclear(res); - return InvalidOid; - } -} - -/* - * lo_create - * create a new large object - * if lobjId isn't InvalidOid, it specifies the OID to (attempt to) create - * - * returns the oid of the large object created or - * InvalidOid upon failure - */ -Oid -lo_create(PGconn *conn, Oid lobjId) -{ - PQArgBlock argv[1]; - PGresult *res; - int retval; - int result_len; - - if (lo_initialize(conn) < 0) - return InvalidOid; - - /* Must check this on-the-fly because it's not there pre-8.1 */ - if (conn->lobjfuncs->fn_lo_create == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_create"); - return InvalidOid; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = lobjId; - res = PQfn(conn, conn->lobjfuncs->fn_lo_create, - &retval, &result_len, 1, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return (Oid) retval; - } - else - { - PQclear(res); - return InvalidOid; - } -} - - -/* - * lo_tell - * returns the current seek location of the large object - */ -int -lo_tell(PGconn *conn, int fd) -{ - int retval; - PQArgBlock argv[1]; - PGresult *res; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_tell, - &retval, &result_len, 1, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_tell64 - * returns the current seek location of the large object - */ -pg_int64 -lo_tell64(PGconn *conn, int fd) -{ - pg_int64 retval; - PQArgBlock argv[1]; - PGresult *res; - int result_len; - - if (lo_initialize(conn) < 0) - return -1; - - if (conn->lobjfuncs->fn_lo_tell64 == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_tell64"); - return -1; - } - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = fd; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_tell64, - (void *) &retval, &result_len, 0, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK && result_len == 8) - { - PQclear(res); - return lo_ntoh64(retval); - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_unlink - * delete a file - */ - -int -lo_unlink(PGconn *conn, Oid lobjId) -{ - PQArgBlock argv[1]; - PGresult *res; - int result_len; - int retval; - - if (lo_initialize(conn) < 0) - return -1; - - argv[0].isint = 1; - argv[0].len = 4; - argv[0].u.integer = lobjId; - - res = PQfn(conn, conn->lobjfuncs->fn_lo_unlink, - &retval, &result_len, 1, argv, 1); - if (PQresultStatus(res) == PGRES_COMMAND_OK) - { - PQclear(res); - return retval; - } - else - { - PQclear(res); - return -1; - } -} - -/* - * lo_import - - * imports a file as an (inversion) large object. - * - * returns the oid of that object upon success, - * returns InvalidOid upon failure - */ - -Oid -lo_import(PGconn *conn, const char *filename) -{ - return lo_import_internal(conn, filename, InvalidOid); -} - -/* - * lo_import_with_oid - - * imports a file as an (inversion) large object. - * large object id can be specified. - * - * returns the oid of that object upon success, - * returns InvalidOid upon failure - */ - -Oid -lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId) -{ - return lo_import_internal(conn, filename, lobjId); -} - -static Oid -lo_import_internal(PGconn *conn, const char *filename, Oid oid) -{ - int fd; - int nbytes, - tmp; - char buf[LO_BUFSIZE]; - Oid lobjOid; - int lobj; - char sebuf[PG_STRERROR_R_BUFLEN]; - - if (conn == NULL) - return InvalidOid; - - /* Since this is the beginning of a query cycle, reset the error state */ - pqClearConnErrorState(conn); - - /* - * open the file to be read in - */ - fd = open(filename, O_RDONLY | PG_BINARY, 0666); - if (fd < 0) - { /* error */ - libpq_append_conn_error(conn, "could not open file \"%s\": %s", - filename, strerror_r(errno, sebuf, sizeof(sebuf))); - return InvalidOid; - } - - /* - * create an inversion object - */ - if (oid == InvalidOid) - lobjOid = lo_creat(conn, INV_READ | INV_WRITE); - else - lobjOid = lo_create(conn, oid); - - if (lobjOid == InvalidOid) - { - /* we assume lo_create() already set a suitable error message */ - (void) close(fd); - return InvalidOid; - } - - lobj = lo_open(conn, lobjOid, INV_WRITE); - if (lobj == -1) - { - /* we assume lo_open() already set a suitable error message */ - (void) close(fd); - return InvalidOid; - } - - /* - * read in from the file and write to the large object - */ - while ((nbytes = read(fd, buf, LO_BUFSIZE)) > 0) - { - tmp = lo_write(conn, lobj, buf, nbytes); - if (tmp != nbytes) - { - /* - * If lo_write() failed, we are now in an aborted transaction so - * there's no need for lo_close(); furthermore, if we tried it - * we'd overwrite the useful error result with a useless one. So - * just nail the doors shut and get out of town. - */ - (void) close(fd); - return InvalidOid; - } - } - - if (nbytes < 0) - { - /* We must do lo_close before setting the errorMessage */ - int save_errno = errno; - - (void) lo_close(conn, lobj); - (void) close(fd); - /* deliberately overwrite any error from lo_close */ - pqClearConnErrorState(conn); - libpq_append_conn_error(conn, "could not read from file \"%s\": %s", - filename, - strerror_r(save_errno, sebuf, sizeof(sebuf))); - return InvalidOid; - } - - (void) close(fd); - - if (lo_close(conn, lobj) != 0) - { - /* we assume lo_close() already set a suitable error message */ - return InvalidOid; - } - - return lobjOid; -} - -/* - * lo_export - - * exports an (inversion) large object. - * returns -1 upon failure, 1 if OK - */ -int -lo_export(PGconn *conn, Oid lobjId, const char *filename) -{ - int result = 1; - int fd; - int nbytes, - tmp; - char buf[LO_BUFSIZE]; - int lobj; - char sebuf[PG_STRERROR_R_BUFLEN]; - - /* - * open the large object. - */ - lobj = lo_open(conn, lobjId, INV_READ); - if (lobj == -1) - { - /* we assume lo_open() already set a suitable error message */ - return -1; - } - - /* - * create the file to be written to - */ - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666); - if (fd < 0) - { - /* We must do lo_close before setting the errorMessage */ - int save_errno = errno; - - (void) lo_close(conn, lobj); - /* deliberately overwrite any error from lo_close */ - pqClearConnErrorState(conn); - libpq_append_conn_error(conn, "could not open file \"%s\": %s", - filename, - strerror_r(save_errno, sebuf, sizeof(sebuf))); - return -1; - } - - /* - * read in from the large object and write to the file - */ - while ((nbytes = lo_read(conn, lobj, buf, LO_BUFSIZE)) > 0) - { - tmp = write(fd, buf, nbytes); - if (tmp != nbytes) - { - /* We must do lo_close before setting the errorMessage */ - int save_errno = errno; - - (void) lo_close(conn, lobj); - (void) close(fd); - /* deliberately overwrite any error from lo_close */ - pqClearConnErrorState(conn); - libpq_append_conn_error(conn, "could not write to file \"%s\": %s", - filename, - strerror_r(save_errno, sebuf, sizeof(sebuf))); - return -1; - } - } - - /* - * If lo_read() failed, we are now in an aborted transaction so there's no - * need for lo_close(); furthermore, if we tried it we'd overwrite the - * useful error result with a useless one. So skip lo_close() if we got a - * failure result. - */ - if (nbytes < 0 || - lo_close(conn, lobj) != 0) - { - /* assume lo_read() or lo_close() left a suitable error message */ - result = -1; - } - - /* if we already failed, don't overwrite that msg with a close error */ - if (close(fd) != 0 && result >= 0) - { - libpq_append_conn_error(conn, "could not write to file \"%s\": %s", - filename, strerror_r(errno, sebuf, sizeof(sebuf))); - result = -1; - } - - return result; -} - - -/* - * lo_initialize - * - * Initialize for a new large-object operation on an existing connection. - * Return 0 if OK, -1 on failure. - * - * If we haven't previously done so, we collect the function OIDs from - * pg_proc for all functions that are required for large object operations. - */ -static int -lo_initialize(PGconn *conn) -{ - PGresult *res; - PGlobjfuncs *lobjfuncs; - int n; - const char *query; - const char *fname; - Oid foid; - - /* Nothing we can do with no connection */ - if (conn == NULL) - return -1; - - /* Since this is the beginning of a query cycle, reset the error state */ - pqClearConnErrorState(conn); - - /* Nothing else to do if we already collected info */ - if (conn->lobjfuncs != NULL) - return 0; - - /* - * Allocate the structure to hold the function OIDs. We don't store it - * into the PGconn until it's successfully filled. - */ - lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs)); - if (lobjfuncs == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return -1; - } - MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs)); - - /* - * Execute the query to get all the functions at once. (Not all of them - * may exist in older server versions.) - */ - query = "select proname, oid from pg_catalog.pg_proc " - "where proname in (" - "'lo_open', " - "'lo_close', " - "'lo_creat', " - "'lo_create', " - "'lo_unlink', " - "'lo_lseek', " - "'lo_lseek64', " - "'lo_tell', " - "'lo_tell64', " - "'lo_truncate', " - "'lo_truncate64', " - "'loread', " - "'lowrite') " - "and pronamespace = (select oid from pg_catalog.pg_namespace " - "where nspname = 'pg_catalog')"; - - res = PQexec(conn, query); - if (res == NULL) - { - free(lobjfuncs); - return -1; - } - - if (res->resultStatus != PGRES_TUPLES_OK) - { - free(lobjfuncs); - PQclear(res); - libpq_append_conn_error(conn, "query to initialize large object functions did not return data"); - return -1; - } - - /* - * Examine the result and put the OID's into the struct - */ - for (n = 0; n < PQntuples(res); n++) - { - fname = PQgetvalue(res, n, 0); - foid = (Oid) atoi(PQgetvalue(res, n, 1)); - if (strcmp(fname, "lo_open") == 0) - lobjfuncs->fn_lo_open = foid; - else if (strcmp(fname, "lo_close") == 0) - lobjfuncs->fn_lo_close = foid; - else if (strcmp(fname, "lo_creat") == 0) - lobjfuncs->fn_lo_creat = foid; - else if (strcmp(fname, "lo_create") == 0) - lobjfuncs->fn_lo_create = foid; - else if (strcmp(fname, "lo_unlink") == 0) - lobjfuncs->fn_lo_unlink = foid; - else if (strcmp(fname, "lo_lseek") == 0) - lobjfuncs->fn_lo_lseek = foid; - else if (strcmp(fname, "lo_lseek64") == 0) - lobjfuncs->fn_lo_lseek64 = foid; - else if (strcmp(fname, "lo_tell") == 0) - lobjfuncs->fn_lo_tell = foid; - else if (strcmp(fname, "lo_tell64") == 0) - lobjfuncs->fn_lo_tell64 = foid; - else if (strcmp(fname, "lo_truncate") == 0) - lobjfuncs->fn_lo_truncate = foid; - else if (strcmp(fname, "lo_truncate64") == 0) - lobjfuncs->fn_lo_truncate64 = foid; - else if (strcmp(fname, "loread") == 0) - lobjfuncs->fn_lo_read = foid; - else if (strcmp(fname, "lowrite") == 0) - lobjfuncs->fn_lo_write = foid; - } - - PQclear(res); - - /* - * Finally check that we got all required large object interface functions - * (ones that have been added later than the stone age are instead checked - * only if used) - */ - if (lobjfuncs->fn_lo_open == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_open"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_close == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_close"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_creat == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_creat"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_unlink == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_unlink"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_lseek == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_lseek"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_tell == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lo_tell"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_read == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "loread"); - free(lobjfuncs); - return -1; - } - if (lobjfuncs->fn_lo_write == 0) - { - libpq_append_conn_error(conn, "cannot determine OID of function %s", - "lowrite"); - free(lobjfuncs); - return -1; - } - - /* - * Put the structure into the connection control - */ - conn->lobjfuncs = lobjfuncs; - return 0; -} - -/* - * lo_hton64 - * converts a 64-bit integer from host byte order to network byte order - */ -static pg_int64 -lo_hton64(pg_int64 host64) -{ - union - { - pg_int64 i64; - uint32 i32[2]; - } swap; - uint32 t; - - /* High order half first, since we're doing MSB-first */ - t = (uint32) (host64 >> 32); - swap.i32[0] = pg_hton32(t); - - /* Now the low order half */ - t = (uint32) host64; - swap.i32[1] = pg_hton32(t); - - return swap.i64; -} - -/* - * lo_ntoh64 - * converts a 64-bit integer from network byte order to host byte order - */ -static pg_int64 -lo_ntoh64(pg_int64 net64) -{ - union - { - pg_int64 i64; - uint32 i32[2]; - } swap; - pg_int64 result; - - swap.i64 = net64; - - result = (uint32) pg_ntoh32(swap.i32[0]); - result <<= 32; - result |= (uint32) pg_ntoh32(swap.i32[1]); - - return result; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-misc.c b/contrib/libs/libpq/src/interfaces/libpq/fe-misc.c deleted file mode 100644 index 660cdec93c..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-misc.c +++ /dev/null @@ -1,1333 +0,0 @@ -/*------------------------------------------------------------------------- - * - * FILE - * fe-misc.c - * - * DESCRIPTION - * miscellaneous useful functions - * - * The communication routines here are analogous to the ones in - * backend/libpq/pqcomm.c and backend/libpq/pqformat.c, but operate - * in the considerably different environment of the frontend libpq. - * In particular, we work with a bare nonblock-mode socket, rather than - * a stdio stream, so that we can avoid unwanted blocking of the application. - * - * XXX: MOVE DEBUG PRINTOUT TO HIGHER LEVEL. As is, block and restart - * will cause repeat printouts. - * - * We must speak the same transmitted data representations as the backend - * routines. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-misc.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <signal.h> -#include <time.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#include <sys/select.h> -#include <sys/time.h> -#endif - -#ifdef HAVE_POLL_H -#include <poll.h> -#endif - -#include "libpq-fe.h" -#include "libpq-int.h" -#include "mb/pg_wchar.h" -#include "pg_config_paths.h" -#include "port/pg_bswap.h" - -static int pqPutMsgBytes(const void *buf, size_t len, PGconn *conn); -static int pqSendSome(PGconn *conn, int len); -static int pqSocketCheck(PGconn *conn, int forRead, int forWrite, - time_t end_time); -static int pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time); - -/* - * PQlibVersion: return the libpq version number - */ -int -PQlibVersion(void) -{ - return PG_VERSION_NUM; -} - - -/* - * pqGetc: get 1 character from the connection - * - * All these routines return 0 on success, EOF on error. - * Note that for the Get routines, EOF only means there is not enough - * data in the buffer, not that there is necessarily a hard error. - */ -int -pqGetc(char *result, PGconn *conn) -{ - if (conn->inCursor >= conn->inEnd) - return EOF; - - *result = conn->inBuffer[conn->inCursor++]; - - return 0; -} - - -/* - * pqPutc: write 1 char to the current message - */ -int -pqPutc(char c, PGconn *conn) -{ - if (pqPutMsgBytes(&c, 1, conn)) - return EOF; - - return 0; -} - - -/* - * pqGets[_append]: - * get a null-terminated string from the connection, - * and store it in an expansible PQExpBuffer. - * If we run out of memory, all of the string is still read, - * but the excess characters are silently discarded. - */ -static int -pqGets_internal(PQExpBuffer buf, PGconn *conn, bool resetbuffer) -{ - /* Copy conn data to locals for faster search loop */ - char *inBuffer = conn->inBuffer; - int inCursor = conn->inCursor; - int inEnd = conn->inEnd; - int slen; - - while (inCursor < inEnd && inBuffer[inCursor]) - inCursor++; - - if (inCursor >= inEnd) - return EOF; - - slen = inCursor - conn->inCursor; - - if (resetbuffer) - resetPQExpBuffer(buf); - - appendBinaryPQExpBuffer(buf, inBuffer + conn->inCursor, slen); - - conn->inCursor = ++inCursor; - - return 0; -} - -int -pqGets(PQExpBuffer buf, PGconn *conn) -{ - return pqGets_internal(buf, conn, true); -} - -int -pqGets_append(PQExpBuffer buf, PGconn *conn) -{ - return pqGets_internal(buf, conn, false); -} - - -/* - * pqPuts: write a null-terminated string to the current message - */ -int -pqPuts(const char *s, PGconn *conn) -{ - if (pqPutMsgBytes(s, strlen(s) + 1, conn)) - return EOF; - - return 0; -} - -/* - * pqGetnchar: - * get a string of exactly len bytes in buffer s, no null termination - */ -int -pqGetnchar(char *s, size_t len, PGconn *conn) -{ - if (len > (size_t) (conn->inEnd - conn->inCursor)) - return EOF; - - memcpy(s, conn->inBuffer + conn->inCursor, len); - /* no terminating null */ - - conn->inCursor += len; - - return 0; -} - -/* - * pqSkipnchar: - * skip over len bytes in input buffer. - * - * Note: this is primarily useful for its debug output, which should - * be exactly the same as for pqGetnchar. We assume the data in question - * will actually be used, but just isn't getting copied anywhere as yet. - */ -int -pqSkipnchar(size_t len, PGconn *conn) -{ - if (len > (size_t) (conn->inEnd - conn->inCursor)) - return EOF; - - conn->inCursor += len; - - return 0; -} - -/* - * pqPutnchar: - * write exactly len bytes to the current message - */ -int -pqPutnchar(const char *s, size_t len, PGconn *conn) -{ - if (pqPutMsgBytes(s, len, conn)) - return EOF; - - return 0; -} - -/* - * pqGetInt - * read a 2 or 4 byte integer and convert from network byte order - * to local byte order - */ -int -pqGetInt(int *result, size_t bytes, PGconn *conn) -{ - uint16 tmp2; - uint32 tmp4; - - switch (bytes) - { - case 2: - if (conn->inCursor + 2 > conn->inEnd) - return EOF; - memcpy(&tmp2, conn->inBuffer + conn->inCursor, 2); - conn->inCursor += 2; - *result = (int) pg_ntoh16(tmp2); - break; - case 4: - if (conn->inCursor + 4 > conn->inEnd) - return EOF; - memcpy(&tmp4, conn->inBuffer + conn->inCursor, 4); - conn->inCursor += 4; - *result = (int) pg_ntoh32(tmp4); - break; - default: - pqInternalNotice(&conn->noticeHooks, - "integer of size %lu not supported by pqGetInt", - (unsigned long) bytes); - return EOF; - } - - return 0; -} - -/* - * pqPutInt - * write an integer of 2 or 4 bytes, converting from host byte order - * to network byte order. - */ -int -pqPutInt(int value, size_t bytes, PGconn *conn) -{ - uint16 tmp2; - uint32 tmp4; - - switch (bytes) - { - case 2: - tmp2 = pg_hton16((uint16) value); - if (pqPutMsgBytes((const char *) &tmp2, 2, conn)) - return EOF; - break; - case 4: - tmp4 = pg_hton32((uint32) value); - if (pqPutMsgBytes((const char *) &tmp4, 4, conn)) - return EOF; - break; - default: - pqInternalNotice(&conn->noticeHooks, - "integer of size %lu not supported by pqPutInt", - (unsigned long) bytes); - return EOF; - } - - return 0; -} - -/* - * Make sure conn's output buffer can hold bytes_needed bytes (caller must - * include already-stored data into the value!) - * - * Returns 0 on success, EOF if failed to enlarge buffer - */ -int -pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn) -{ - int newsize = conn->outBufSize; - char *newbuf; - - /* Quick exit if we have enough space */ - if (bytes_needed <= (size_t) newsize) - return 0; - - /* - * If we need to enlarge the buffer, we first try to double it in size; if - * that doesn't work, enlarge in multiples of 8K. This avoids thrashing - * the malloc pool by repeated small enlargements. - * - * Note: tests for newsize > 0 are to catch integer overflow. - */ - do - { - newsize *= 2; - } while (newsize > 0 && bytes_needed > (size_t) newsize); - - if (newsize > 0 && bytes_needed <= (size_t) newsize) - { - newbuf = realloc(conn->outBuffer, newsize); - if (newbuf) - { - /* realloc succeeded */ - conn->outBuffer = newbuf; - conn->outBufSize = newsize; - return 0; - } - } - - newsize = conn->outBufSize; - do - { - newsize += 8192; - } while (newsize > 0 && bytes_needed > (size_t) newsize); - - if (newsize > 0 && bytes_needed <= (size_t) newsize) - { - newbuf = realloc(conn->outBuffer, newsize); - if (newbuf) - { - /* realloc succeeded */ - conn->outBuffer = newbuf; - conn->outBufSize = newsize; - return 0; - } - } - - /* realloc failed. Probably out of memory */ - appendPQExpBufferStr(&conn->errorMessage, - "cannot allocate memory for output buffer\n"); - return EOF; -} - -/* - * Make sure conn's input buffer can hold bytes_needed bytes (caller must - * include already-stored data into the value!) - * - * Returns 0 on success, EOF if failed to enlarge buffer - */ -int -pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn) -{ - int newsize = conn->inBufSize; - char *newbuf; - - /* Quick exit if we have enough space */ - if (bytes_needed <= (size_t) newsize) - return 0; - - /* - * Before concluding that we need to enlarge the buffer, left-justify - * whatever is in it and recheck. The caller's value of bytes_needed - * includes any data to the left of inStart, but we can delete that in - * preference to enlarging the buffer. It's slightly ugly to have this - * function do this, but it's better than making callers worry about it. - */ - bytes_needed -= conn->inStart; - - if (conn->inStart < conn->inEnd) - { - if (conn->inStart > 0) - { - memmove(conn->inBuffer, conn->inBuffer + conn->inStart, - conn->inEnd - conn->inStart); - conn->inEnd -= conn->inStart; - conn->inCursor -= conn->inStart; - conn->inStart = 0; - } - } - else - { - /* buffer is logically empty, reset it */ - conn->inStart = conn->inCursor = conn->inEnd = 0; - } - - /* Recheck whether we have enough space */ - if (bytes_needed <= (size_t) newsize) - return 0; - - /* - * If we need to enlarge the buffer, we first try to double it in size; if - * that doesn't work, enlarge in multiples of 8K. This avoids thrashing - * the malloc pool by repeated small enlargements. - * - * Note: tests for newsize > 0 are to catch integer overflow. - */ - do - { - newsize *= 2; - } while (newsize > 0 && bytes_needed > (size_t) newsize); - - if (newsize > 0 && bytes_needed <= (size_t) newsize) - { - newbuf = realloc(conn->inBuffer, newsize); - if (newbuf) - { - /* realloc succeeded */ - conn->inBuffer = newbuf; - conn->inBufSize = newsize; - return 0; - } - } - - newsize = conn->inBufSize; - do - { - newsize += 8192; - } while (newsize > 0 && bytes_needed > (size_t) newsize); - - if (newsize > 0 && bytes_needed <= (size_t) newsize) - { - newbuf = realloc(conn->inBuffer, newsize); - if (newbuf) - { - /* realloc succeeded */ - conn->inBuffer = newbuf; - conn->inBufSize = newsize; - return 0; - } - } - - /* realloc failed. Probably out of memory */ - appendPQExpBufferStr(&conn->errorMessage, - "cannot allocate memory for input buffer\n"); - return EOF; -} - -/* - * pqPutMsgStart: begin construction of a message to the server - * - * msg_type is the message type byte, or 0 for a message without type byte - * (only startup messages have no type byte) - * - * Returns 0 on success, EOF on error - * - * The idea here is that we construct the message in conn->outBuffer, - * beginning just past any data already in outBuffer (ie, at - * outBuffer+outCount). We enlarge the buffer as needed to hold the message. - * When the message is complete, we fill in the length word (if needed) and - * then advance outCount past the message, making it eligible to send. - * - * The state variable conn->outMsgStart points to the incomplete message's - * length word: it is either outCount or outCount+1 depending on whether - * there is a type byte. The state variable conn->outMsgEnd is the end of - * the data collected so far. - */ -int -pqPutMsgStart(char msg_type, PGconn *conn) -{ - int lenPos; - int endPos; - - /* allow room for message type byte */ - if (msg_type) - endPos = conn->outCount + 1; - else - endPos = conn->outCount; - - /* do we want a length word? */ - lenPos = endPos; - /* allow room for message length */ - endPos += 4; - - /* make sure there is room for message header */ - if (pqCheckOutBufferSpace(endPos, conn)) - return EOF; - /* okay, save the message type byte if any */ - if (msg_type) - conn->outBuffer[conn->outCount] = msg_type; - /* set up the message pointers */ - conn->outMsgStart = lenPos; - conn->outMsgEnd = endPos; - /* length word, if needed, will be filled in by pqPutMsgEnd */ - - return 0; -} - -/* - * pqPutMsgBytes: add bytes to a partially-constructed message - * - * Returns 0 on success, EOF on error - */ -static int -pqPutMsgBytes(const void *buf, size_t len, PGconn *conn) -{ - /* make sure there is room for it */ - if (pqCheckOutBufferSpace(conn->outMsgEnd + len, conn)) - return EOF; - /* okay, save the data */ - memcpy(conn->outBuffer + conn->outMsgEnd, buf, len); - conn->outMsgEnd += len; - /* no Pfdebug call here, caller should do it */ - return 0; -} - -/* - * pqPutMsgEnd: finish constructing a message and possibly send it - * - * Returns 0 on success, EOF on error - * - * We don't actually send anything here unless we've accumulated at least - * 8K worth of data (the typical size of a pipe buffer on Unix systems). - * This avoids sending small partial packets. The caller must use pqFlush - * when it's important to flush all the data out to the server. - */ -int -pqPutMsgEnd(PGconn *conn) -{ - /* Fill in length word if needed */ - if (conn->outMsgStart >= 0) - { - uint32 msgLen = conn->outMsgEnd - conn->outMsgStart; - - msgLen = pg_hton32(msgLen); - memcpy(conn->outBuffer + conn->outMsgStart, &msgLen, 4); - } - - /* trace client-to-server message */ - if (conn->Pfdebug) - { - if (conn->outCount < conn->outMsgStart) - pqTraceOutputMessage(conn, conn->outBuffer + conn->outCount, true); - else - pqTraceOutputNoTypeByteMessage(conn, - conn->outBuffer + conn->outMsgStart); - } - - /* Make message eligible to send */ - conn->outCount = conn->outMsgEnd; - - if (conn->outCount >= 8192) - { - int toSend = conn->outCount - (conn->outCount % 8192); - - if (pqSendSome(conn, toSend) < 0) - return EOF; - /* in nonblock mode, don't complain if unable to send it all */ - } - - return 0; -} - -/* ---------- - * pqReadData: read more data, if any is available - * Possible return values: - * 1: successfully loaded at least one more byte - * 0: no data is presently available, but no error detected - * -1: error detected (including EOF = connection closure); - * conn->errorMessage set - * NOTE: callers must not assume that pointers or indexes into conn->inBuffer - * remain valid across this call! - * ---------- - */ -int -pqReadData(PGconn *conn) -{ - int someread = 0; - int nread; - - if (conn->sock == PGINVALID_SOCKET) - { - libpq_append_conn_error(conn, "connection not open"); - return -1; - } - - /* Left-justify any data in the buffer to make room */ - if (conn->inStart < conn->inEnd) - { - if (conn->inStart > 0) - { - memmove(conn->inBuffer, conn->inBuffer + conn->inStart, - conn->inEnd - conn->inStart); - conn->inEnd -= conn->inStart; - conn->inCursor -= conn->inStart; - conn->inStart = 0; - } - } - else - { - /* buffer is logically empty, reset it */ - conn->inStart = conn->inCursor = conn->inEnd = 0; - } - - /* - * If the buffer is fairly full, enlarge it. We need to be able to enlarge - * the buffer in case a single message exceeds the initial buffer size. We - * enlarge before filling the buffer entirely so as to avoid asking the - * kernel for a partial packet. The magic constant here should be large - * enough for a TCP packet or Unix pipe bufferload. 8K is the usual pipe - * buffer size, so... - */ - if (conn->inBufSize - conn->inEnd < 8192) - { - if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn)) - { - /* - * We don't insist that the enlarge worked, but we need some room - */ - if (conn->inBufSize - conn->inEnd < 100) - return -1; /* errorMessage already set */ - } - } - - /* OK, try to read some data */ -retry3: - nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd, - conn->inBufSize - conn->inEnd); - if (nread < 0) - { - switch (SOCK_ERRNO) - { - case EINTR: - goto retry3; - - /* Some systems return EAGAIN/EWOULDBLOCK for no data */ -#ifdef EAGAIN - case EAGAIN: - return someread; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: - return someread; -#endif - - /* We might get ECONNRESET etc here if connection failed */ - case ALL_CONNECTION_FAILURE_ERRNOS: - goto definitelyFailed; - - default: - /* pqsecure_read set the error message for us */ - return -1; - } - } - if (nread > 0) - { - conn->inEnd += nread; - - /* - * Hack to deal with the fact that some kernels will only give us back - * 1 packet per recv() call, even if we asked for more and there is - * more available. If it looks like we are reading a long message, - * loop back to recv() again immediately, until we run out of data or - * buffer space. Without this, the block-and-restart behavior of - * libpq's higher levels leads to O(N^2) performance on long messages. - * - * Since we left-justified the data above, conn->inEnd gives the - * amount of data already read in the current message. We consider - * the message "long" once we have acquired 32k ... - */ - if (conn->inEnd > 32768 && - (conn->inBufSize - conn->inEnd) >= 8192) - { - someread = 1; - goto retry3; - } - return 1; - } - - if (someread) - return 1; /* got a zero read after successful tries */ - - /* - * A return value of 0 could mean just that no data is now available, or - * it could mean EOF --- that is, the server has closed the connection. - * Since we have the socket in nonblock mode, the only way to tell the - * difference is to see if select() is saying that the file is ready. - * Grumble. Fortunately, we don't expect this path to be taken much, - * since in normal practice we should not be trying to read data unless - * the file selected for reading already. - * - * In SSL mode it's even worse: SSL_read() could say WANT_READ and then - * data could arrive before we make the pqReadReady() test, but the second - * SSL_read() could still say WANT_READ because the data received was not - * a complete SSL record. So we must play dumb and assume there is more - * data, relying on the SSL layer to detect true EOF. - */ - -#ifdef USE_SSL - if (conn->ssl_in_use) - return 0; -#endif - - switch (pqReadReady(conn)) - { - case 0: - /* definitely no data available */ - return 0; - case 1: - /* ready for read */ - break; - default: - /* we override pqReadReady's message with something more useful */ - goto definitelyEOF; - } - - /* - * Still not sure that it's EOF, because some data could have just - * arrived. - */ -retry4: - nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd, - conn->inBufSize - conn->inEnd); - if (nread < 0) - { - switch (SOCK_ERRNO) - { - case EINTR: - goto retry4; - - /* Some systems return EAGAIN/EWOULDBLOCK for no data */ -#ifdef EAGAIN - case EAGAIN: - return 0; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: - return 0; -#endif - - /* We might get ECONNRESET etc here if connection failed */ - case ALL_CONNECTION_FAILURE_ERRNOS: - goto definitelyFailed; - - default: - /* pqsecure_read set the error message for us */ - return -1; - } - } - if (nread > 0) - { - conn->inEnd += nread; - return 1; - } - - /* - * OK, we are getting a zero read even though select() says ready. This - * means the connection has been closed. Cope. - */ -definitelyEOF: - libpq_append_conn_error(conn, "server closed the connection unexpectedly\n" - "\tThis probably means the server terminated abnormally\n" - "\tbefore or while processing the request."); - - /* Come here if lower-level code already set a suitable errorMessage */ -definitelyFailed: - /* Do *not* drop any already-read data; caller still wants it */ - pqDropConnection(conn, false); - conn->status = CONNECTION_BAD; /* No more connection to backend */ - return -1; -} - -/* - * pqSendSome: send data waiting in the output buffer. - * - * len is how much to try to send (typically equal to outCount, but may - * be less). - * - * Return 0 on success, -1 on failure and 1 when not all data could be sent - * because the socket would block and the connection is non-blocking. - * - * Note that this is also responsible for consuming data from the socket - * (putting it in conn->inBuffer) in any situation where we can't send - * all the specified data immediately. - * - * If a socket-level write failure occurs, conn->write_failed is set and the - * error message is saved in conn->write_err_msg, but we clear the output - * buffer and return zero anyway; this is because callers should soldier on - * until we have read what we can from the server and checked for an error - * message. write_err_msg should be reported only when we are unable to - * obtain a server error first. Much of that behavior is implemented at - * lower levels, but this function deals with some edge cases. - */ -static int -pqSendSome(PGconn *conn, int len) -{ - char *ptr = conn->outBuffer; - int remaining = conn->outCount; - int result = 0; - - /* - * If we already had a write failure, we will never again try to send data - * on that connection. Even if the kernel would let us, we've probably - * lost message boundary sync with the server. conn->write_failed - * therefore persists until the connection is reset, and we just discard - * all data presented to be written. However, as long as we still have a - * valid socket, we should continue to absorb data from the backend, so - * that we can collect any final error messages. - */ - if (conn->write_failed) - { - /* conn->write_err_msg should be set up already */ - conn->outCount = 0; - /* Absorb input data if any, and detect socket closure */ - if (conn->sock != PGINVALID_SOCKET) - { - if (pqReadData(conn) < 0) - return -1; - } - return 0; - } - - if (conn->sock == PGINVALID_SOCKET) - { - conn->write_failed = true; - /* Store error message in conn->write_err_msg, if possible */ - /* (strdup failure is OK, we'll cope later) */ - conn->write_err_msg = strdup(libpq_gettext("connection not open\n")); - /* Discard queued data; no chance it'll ever be sent */ - conn->outCount = 0; - return 0; - } - - /* while there's still data to send */ - while (len > 0) - { - int sent; - -#ifndef WIN32 - sent = pqsecure_write(conn, ptr, len); -#else - - /* - * Windows can fail on large sends, per KB article Q201213. The - * failure-point appears to be different in different versions of - * Windows, but 64k should always be safe. - */ - sent = pqsecure_write(conn, ptr, Min(len, 65536)); -#endif - - if (sent < 0) - { - /* Anything except EAGAIN/EWOULDBLOCK/EINTR is trouble */ - switch (SOCK_ERRNO) - { -#ifdef EAGAIN - case EAGAIN: - break; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: - break; -#endif - case EINTR: - continue; - - default: - /* Discard queued data; no chance it'll ever be sent */ - conn->outCount = 0; - - /* Absorb input data if any, and detect socket closure */ - if (conn->sock != PGINVALID_SOCKET) - { - if (pqReadData(conn) < 0) - return -1; - } - - /* - * Lower-level code should already have filled - * conn->write_err_msg (and set conn->write_failed) or - * conn->errorMessage. In the former case, we pretend - * there's no problem; the write_failed condition will be - * dealt with later. Otherwise, report the error now. - */ - if (conn->write_failed) - return 0; - else - return -1; - } - } - else - { - ptr += sent; - len -= sent; - remaining -= sent; - } - - if (len > 0) - { - /* - * We didn't send it all, wait till we can send more. - * - * There are scenarios in which we can't send data because the - * communications channel is full, but we cannot expect the server - * to clear the channel eventually because it's blocked trying to - * send data to us. (This can happen when we are sending a large - * amount of COPY data, and the server has generated lots of - * NOTICE responses.) To avoid a deadlock situation, we must be - * prepared to accept and buffer incoming data before we try - * again. Furthermore, it is possible that such incoming data - * might not arrive until after we've gone to sleep. Therefore, - * we wait for either read ready or write ready. - * - * In non-blocking mode, we don't wait here directly, but return 1 - * to indicate that data is still pending. The caller should wait - * for both read and write ready conditions, and call - * PQconsumeInput() on read ready, but just in case it doesn't, we - * call pqReadData() ourselves before returning. That's not - * enough if the data has not arrived yet, but it's the best we - * can do, and works pretty well in practice. (The documentation - * used to say that you only need to wait for write-ready, so - * there are still plenty of applications like that out there.) - * - * Note that errors here don't result in write_failed becoming - * set. - */ - if (pqReadData(conn) < 0) - { - result = -1; /* error message already set up */ - break; - } - - if (pqIsnonblocking(conn)) - { - result = 1; - break; - } - - if (pqWait(true, true, conn)) - { - result = -1; - break; - } - } - } - - /* shift the remaining contents of the buffer */ - if (remaining > 0) - memmove(conn->outBuffer, ptr, remaining); - conn->outCount = remaining; - - return result; -} - - -/* - * pqFlush: send any data waiting in the output buffer - * - * Return 0 on success, -1 on failure and 1 when not all data could be sent - * because the socket would block and the connection is non-blocking. - * (See pqSendSome comments about how failure should be handled.) - */ -int -pqFlush(PGconn *conn) -{ - if (conn->outCount > 0) - { - if (conn->Pfdebug) - fflush(conn->Pfdebug); - - return pqSendSome(conn, conn->outCount); - } - - return 0; -} - - -/* - * pqWait: wait until we can read or write the connection socket - * - * JAB: If SSL enabled and used and forRead, buffered bytes short-circuit the - * call to select(). - * - * We also stop waiting and return if the kernel flags an exception condition - * on the socket. The actual error condition will be detected and reported - * when the caller tries to read or write the socket. - */ -int -pqWait(int forRead, int forWrite, PGconn *conn) -{ - return pqWaitTimed(forRead, forWrite, conn, (time_t) -1); -} - -/* - * pqWaitTimed: wait, but not past finish_time. - * - * finish_time = ((time_t) -1) disables the wait limit. - * - * Returns -1 on failure, 0 if the socket is readable/writable, 1 if it timed out. - */ -int -pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time) -{ - int result; - - result = pqSocketCheck(conn, forRead, forWrite, finish_time); - - if (result < 0) - return -1; /* errorMessage is already set */ - - if (result == 0) - { - libpq_append_conn_error(conn, "timeout expired"); - return 1; - } - - return 0; -} - -/* - * pqReadReady: is select() saying the file is ready to read? - * Returns -1 on failure, 0 if not ready, 1 if ready. - */ -int -pqReadReady(PGconn *conn) -{ - return pqSocketCheck(conn, 1, 0, (time_t) 0); -} - -/* - * pqWriteReady: is select() saying the file is ready to write? - * Returns -1 on failure, 0 if not ready, 1 if ready. - */ -int -pqWriteReady(PGconn *conn) -{ - return pqSocketCheck(conn, 0, 1, (time_t) 0); -} - -/* - * Checks a socket, using poll or select, for data to be read, written, - * or both. Returns >0 if one or more conditions are met, 0 if it timed - * out, -1 if an error occurred. - * - * If SSL is in use, the SSL buffer is checked prior to checking the socket - * for read data directly. - */ -static int -pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time) -{ - int result; - - if (!conn) - return -1; - if (conn->sock == PGINVALID_SOCKET) - { - libpq_append_conn_error(conn, "invalid socket"); - return -1; - } - -#ifdef USE_SSL - /* Check for SSL library buffering read bytes */ - if (forRead && conn->ssl_in_use && pgtls_read_pending(conn)) - { - /* short-circuit the select */ - return 1; - } -#endif - - /* We will retry as long as we get EINTR */ - do - result = pqSocketPoll(conn->sock, forRead, forWrite, end_time); - while (result < 0 && SOCK_ERRNO == EINTR); - - if (result < 0) - { - char sebuf[PG_STRERROR_R_BUFLEN]; - - libpq_append_conn_error(conn, "%s() failed: %s", "select", - SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf))); - } - - return result; -} - - -/* - * Check a file descriptor for read and/or write data, possibly waiting. - * If neither forRead nor forWrite are set, immediately return a timeout - * condition (without waiting). Return >0 if condition is met, 0 - * if a timeout occurred, -1 if an error or interrupt occurred. - * - * Timeout is infinite if end_time is -1. Timeout is immediate (no blocking) - * if end_time is 0 (or indeed, any time before now). - */ -static int -pqSocketPoll(int sock, int forRead, int forWrite, time_t end_time) -{ - /* We use poll(2) if available, otherwise select(2) */ -#ifdef HAVE_POLL - struct pollfd input_fd; - int timeout_ms; - - if (!forRead && !forWrite) - return 0; - - input_fd.fd = sock; - input_fd.events = POLLERR; - input_fd.revents = 0; - - if (forRead) - input_fd.events |= POLLIN; - if (forWrite) - input_fd.events |= POLLOUT; - - /* Compute appropriate timeout interval */ - if (end_time == ((time_t) -1)) - timeout_ms = -1; - else - { - time_t now = time(NULL); - - if (end_time > now) - timeout_ms = (end_time - now) * 1000; - else - timeout_ms = 0; - } - - return poll(&input_fd, 1, timeout_ms); -#else /* !HAVE_POLL */ - - fd_set input_mask; - fd_set output_mask; - fd_set except_mask; - struct timeval timeout; - struct timeval *ptr_timeout; - - if (!forRead && !forWrite) - return 0; - - FD_ZERO(&input_mask); - FD_ZERO(&output_mask); - FD_ZERO(&except_mask); - if (forRead) - FD_SET(sock, &input_mask); - - if (forWrite) - FD_SET(sock, &output_mask); - FD_SET(sock, &except_mask); - - /* Compute appropriate timeout interval */ - if (end_time == ((time_t) -1)) - ptr_timeout = NULL; - else - { - time_t now = time(NULL); - - if (end_time > now) - timeout.tv_sec = end_time - now; - else - timeout.tv_sec = 0; - timeout.tv_usec = 0; - ptr_timeout = &timeout; - } - - return select(sock + 1, &input_mask, &output_mask, - &except_mask, ptr_timeout); -#endif /* HAVE_POLL */ -} - - -/* - * A couple of "miscellaneous" multibyte related functions. They used - * to be in fe-print.c but that file is doomed. - */ - -/* - * Returns the byte length of the character beginning at s, using the - * specified encoding. - * - * Caution: when dealing with text that is not certainly valid in the - * specified encoding, the result may exceed the actual remaining - * string length. Callers that are not prepared to deal with that - * should use PQmblenBounded() instead. - */ -int -PQmblen(const char *s, int encoding) -{ - return pg_encoding_mblen(encoding, s); -} - -/* - * Returns the byte length of the character beginning at s, using the - * specified encoding; but not more than the distance to end of string. - */ -int -PQmblenBounded(const char *s, int encoding) -{ - return strnlen(s, pg_encoding_mblen(encoding, s)); -} - -/* - * Returns the display length of the character beginning at s, using the - * specified encoding. - */ -int -PQdsplen(const char *s, int encoding) -{ - return pg_encoding_dsplen(encoding, s); -} - -/* - * Get encoding id from environment variable PGCLIENTENCODING. - */ -int -PQenv2encoding(void) -{ - char *str; - int encoding = PG_SQL_ASCII; - - str = getenv("PGCLIENTENCODING"); - if (str && *str != '\0') - { - encoding = pg_char_to_encoding(str); - if (encoding < 0) - encoding = PG_SQL_ASCII; - } - return encoding; -} - - -#ifdef ENABLE_NLS - -static void -libpq_binddomain(void) -{ - /* - * If multiple threads come through here at about the same time, it's okay - * for more than one of them to call bindtextdomain(). But it's not okay - * for any of them to return to caller before bindtextdomain() is - * complete, so don't set the flag till that's done. Use "volatile" just - * to be sure the compiler doesn't try to get cute. - */ - static volatile bool already_bound = false; - - if (!already_bound) - { - /* bindtextdomain() does not preserve errno */ -#ifdef WIN32 - int save_errno = GetLastError(); -#else - int save_errno = errno; -#endif - const char *ldir; - - /* No relocatable lookup here because the binary could be anywhere */ - ldir = getenv("PGLOCALEDIR"); - if (!ldir) - ldir = LOCALEDIR; - bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir); - already_bound = true; -#ifdef WIN32 - SetLastError(save_errno); -#else - errno = save_errno; -#endif - } -} - -char * -libpq_gettext(const char *msgid) -{ - libpq_binddomain(); - return dgettext(PG_TEXTDOMAIN("libpq"), msgid); -} - -char * -libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) -{ - libpq_binddomain(); - return dngettext(PG_TEXTDOMAIN("libpq"), msgid, msgid_plural, n); -} - -#endif /* ENABLE_NLS */ - - -/* - * Append a formatted string to the given buffer, after translating it. A - * newline is automatically appended; the format should not end with a - * newline. - */ -void -libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...) -{ - int save_errno = errno; - bool done; - va_list args; - - Assert(fmt[strlen(fmt) - 1] != '\n'); - - if (PQExpBufferBroken(errorMessage)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - errno = save_errno; - va_start(args, fmt); - done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args); - va_end(args); - } while (!done); - - appendPQExpBufferChar(errorMessage, '\n'); -} - -/* - * Append a formatted string to the error message buffer of the given - * connection, after translating it. A newline is automatically appended; the - * format should not end with a newline. - */ -void -libpq_append_conn_error(PGconn *conn, const char *fmt,...) -{ - int save_errno = errno; - bool done; - va_list args; - - Assert(fmt[strlen(fmt) - 1] != '\n'); - - if (PQExpBufferBroken(&conn->errorMessage)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - errno = save_errno; - va_start(args, fmt); - done = appendPQExpBufferVA(&conn->errorMessage, libpq_gettext(fmt), args); - va_end(args); - } while (!done); - - appendPQExpBufferChar(&conn->errorMessage, '\n'); -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-print.c b/contrib/libs/libpq/src/interfaces/libpq/fe-print.c deleted file mode 100644 index 40620b47e9..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-print.c +++ /dev/null @@ -1,773 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-print.c - * functions for pretty-printing query results - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * These functions were formerly part of fe-exec.c, but they - * didn't really belong there. - * - * IDENTIFICATION - * src/interfaces/libpq/fe-print.c - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include <signal.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#include <sys/ioctl.h> -#endif - -#ifdef HAVE_TERMIOS_H -#include <termios.h> -#else -#ifndef WIN32 -#include <sys/termios.h> -#endif -#endif - -#include "libpq-fe.h" -#include "libpq-int.h" - - -static bool do_field(const PQprintOpt *po, const PGresult *res, - const int i, const int j, const int fs_len, - char **fields, - const int nFields, const char **fieldNames, - unsigned char *fieldNotNum, int *fieldMax, - const int fieldMaxLen, FILE *fout); -static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields, - int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum, - const int fs_len, const PGresult *res); -static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields, - unsigned char *fieldNotNum, int *fieldMax, char *border, - const int row_index); -static void fill(int length, int max, char filler, FILE *fp); - -/* - * PQprint() - * - * Format results of a query for printing. - * - * PQprintOpt is a typedef (structure) that contains - * various flags and options. consult libpq-fe.h for - * details - * - * This function should probably be removed sometime since psql - * doesn't use it anymore. It is unclear to what extent this is used - * by external clients, however. - */ -void -PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po) -{ - int nFields; - - nFields = PQnfields(res); - - if (nFields > 0) - { /* only print rows with at least 1 field. */ - int i, - j; - int nTups; - int *fieldMax = NULL; /* in case we don't use them */ - unsigned char *fieldNotNum = NULL; - char *border = NULL; - char **fields = NULL; - const char **fieldNames = NULL; - int fieldMaxLen = 0; - int numFieldName; - int fs_len = strlen(po->fieldSep); - int total_line_length = 0; - bool usePipe = false; - char *pagerenv; - -#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) - sigset_t osigset; - bool sigpipe_masked = false; - bool sigpipe_pending; -#endif -#if !defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) - pqsigfunc oldsigpipehandler = NULL; -#endif - -#ifdef TIOCGWINSZ - struct winsize screen_size; -#else - struct winsize - { - int ws_row; - int ws_col; - } screen_size; -#endif - - nTups = PQntuples(res); - fieldNames = (const char **) calloc(nFields, sizeof(char *)); - fieldNotNum = (unsigned char *) calloc(nFields, 1); - fieldMax = (int *) calloc(nFields, sizeof(int)); - if (!fieldNames || !fieldNotNum || !fieldMax) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - goto exit; - } - for (numFieldName = 0; - po->fieldName && po->fieldName[numFieldName]; - numFieldName++) - ; - for (j = 0; j < nFields; j++) - { - int len; - const char *s = (j < numFieldName && po->fieldName[j][0]) ? - po->fieldName[j] : PQfname(res, j); - - fieldNames[j] = s; - len = s ? strlen(s) : 0; - fieldMax[j] = len; - len += fs_len; - if (len > fieldMaxLen) - fieldMaxLen = len; - total_line_length += len; - } - - total_line_length += nFields * strlen(po->fieldSep) + 1; - - if (fout == NULL) - fout = stdout; - if (po->pager && fout == stdout && isatty(fileno(stdin)) && - isatty(fileno(stdout))) - { - /* - * If we think there'll be more than one screen of output, try to - * pipe to the pager program. - */ -#ifdef TIOCGWINSZ - if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 || - screen_size.ws_col == 0 || - screen_size.ws_row == 0) - { - screen_size.ws_row = 24; - screen_size.ws_col = 80; - } -#else - screen_size.ws_row = 24; - screen_size.ws_col = 80; -#endif - - /* - * Since this function is no longer used by psql, we don't examine - * PSQL_PAGER. It's possible that the hypothetical external users - * of the function would like that to happen, but in the name of - * backwards compatibility, we'll stick to just examining PAGER. - */ - pagerenv = getenv("PAGER"); - /* if PAGER is unset, empty or all-white-space, don't use pager */ - if (pagerenv != NULL && - strspn(pagerenv, " \t\r\n") != strlen(pagerenv) && - !po->html3 && - ((po->expanded && - nTups * (nFields + 1) >= screen_size.ws_row) || - (!po->expanded && - nTups * (total_line_length / screen_size.ws_col + 1) * - (1 + (po->standard != 0)) >= screen_size.ws_row - - (po->header != 0) * - (total_line_length / screen_size.ws_col + 1) * 2 - - (po->header != 0) * 2 /* row count and newline */ - ))) - { - fflush(NULL); - fout = popen(pagerenv, "w"); - if (fout) - { - usePipe = true; -#ifndef WIN32 -#ifdef ENABLE_THREAD_SAFETY - if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0) - sigpipe_masked = true; -#else - oldsigpipehandler = pqsignal(SIGPIPE, SIG_IGN); -#endif /* ENABLE_THREAD_SAFETY */ -#endif /* WIN32 */ - } - else - fout = stdout; - } - } - - if (!po->expanded && (po->align || po->html3)) - { - fields = (char **) calloc((size_t) nTups + 1, - nFields * sizeof(char *)); - if (!fields) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - goto exit; - } - } - else if (po->header && !po->html3) - { - if (po->expanded) - { - if (po->align) - fprintf(fout, libpq_gettext("%-*s%s Value\n"), - fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep); - else - fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep); - } - else - { - int len = 0; - - for (j = 0; j < nFields; j++) - { - const char *s = fieldNames[j]; - - fputs(s, fout); - len += strlen(s) + fs_len; - if ((j + 1) < nFields) - fputs(po->fieldSep, fout); - } - fputc('\n', fout); - for (len -= fs_len; len--; fputc('-', fout)); - fputc('\n', fout); - } - } - if (po->expanded && po->html3) - { - if (po->caption) - fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption); - else - fprintf(fout, - "<center><h2>" - "Query retrieved %d rows * %d fields" - "</h2></center>\n", - nTups, nFields); - } - for (i = 0; i < nTups; i++) - { - if (po->expanded) - { - if (po->html3) - fprintf(fout, - "<table %s><caption align=\"top\">%d</caption>\n", - po->tableOpt ? po->tableOpt : "", i); - else - fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i); - } - for (j = 0; j < nFields; j++) - { - if (!do_field(po, res, i, j, fs_len, fields, nFields, - fieldNames, fieldNotNum, - fieldMax, fieldMaxLen, fout)) - goto exit; - } - if (po->html3 && po->expanded) - fputs("</table>\n", fout); - } - if (!po->expanded && (po->align || po->html3)) - { - if (po->html3) - { - if (po->header) - { - if (po->caption) - fprintf(fout, - "<table %s><caption align=\"top\">%s</caption>\n", - po->tableOpt ? po->tableOpt : "", - po->caption); - else - fprintf(fout, - "<table %s><caption align=\"top\">" - "Retrieved %d rows * %d fields" - "</caption>\n", - po->tableOpt ? po->tableOpt : "", nTups, nFields); - } - else - fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : ""); - } - if (po->header) - border = do_header(fout, po, nFields, fieldMax, fieldNames, - fieldNotNum, fs_len, res); - for (i = 0; i < nTups; i++) - output_row(fout, po, nFields, fields, - fieldNotNum, fieldMax, border, i); - } - if (po->header && !po->html3) - fprintf(fout, "(%d row%s)\n\n", PQntuples(res), - (PQntuples(res) == 1) ? "" : "s"); - if (po->html3 && !po->expanded) - fputs("</table>\n", fout); - -exit: - free(fieldMax); - free(fieldNotNum); - free(border); - if (fields) - { - /* if calloc succeeded, this shouldn't overflow size_t */ - size_t numfields = ((size_t) nTups + 1) * (size_t) nFields; - - while (numfields-- > 0) - free(fields[numfields]); - free(fields); - } - free(fieldNames); - if (usePipe) - { -#ifdef WIN32 - _pclose(fout); -#else - pclose(fout); - -#ifdef ENABLE_THREAD_SAFETY - /* we can't easily verify if EPIPE occurred, so say it did */ - if (sigpipe_masked) - pq_reset_sigpipe(&osigset, sigpipe_pending, true); -#else - pqsignal(SIGPIPE, oldsigpipehandler); -#endif /* ENABLE_THREAD_SAFETY */ -#endif /* WIN32 */ - } - } -} - - -static bool -do_field(const PQprintOpt *po, const PGresult *res, - const int i, const int j, const int fs_len, - char **fields, - const int nFields, char const **fieldNames, - unsigned char *fieldNotNum, int *fieldMax, - const int fieldMaxLen, FILE *fout) -{ - const char *pval, - *p; - int plen; - bool skipit; - - plen = PQgetlength(res, i, j); - pval = PQgetvalue(res, i, j); - - if (plen < 1 || !pval || !*pval) - { - if (po->align || po->expanded) - skipit = true; - else - { - skipit = false; - goto efield; - } - } - else - skipit = false; - - if (!skipit) - { - if (po->align && !fieldNotNum[j]) - { - /* Detect whether field contains non-numeric data */ - char ch = '0'; - - for (p = pval; *p; p += PQmblenBounded(p, res->client_encoding)) - { - ch = *p; - if (!((ch >= '0' && ch <= '9') || - ch == '.' || - ch == 'E' || - ch == 'e' || - ch == ' ' || - ch == '-')) - { - fieldNotNum[j] = 1; - break; - } - } - - /* - * Above loop will believe E in first column is numeric; also, we - * insist on a digit in the last column for a numeric. This test - * is still not bulletproof but it handles most cases. - */ - if (*pval == 'E' || *pval == 'e' || - !(ch >= '0' && ch <= '9')) - fieldNotNum[j] = 1; - } - - if (!po->expanded && (po->align || po->html3)) - { - if (plen > fieldMax[j]) - fieldMax[j] = plen; - if (!(fields[i * nFields + j] = (char *) malloc(plen + 1))) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - return false; - } - strcpy(fields[i * nFields + j], pval); - } - else - { - if (po->expanded) - { - if (po->html3) - fprintf(fout, - "<tr><td align=\"left\"><b>%s</b></td>" - "<td align=\"%s\">%s</td></tr>\n", - fieldNames[j], - fieldNotNum[j] ? "left" : "right", - pval); - else - { - if (po->align) - fprintf(fout, - "%-*s%s %s\n", - fieldMaxLen - fs_len, fieldNames[j], - po->fieldSep, - pval); - else - fprintf(fout, - "%s%s%s\n", - fieldNames[j], po->fieldSep, pval); - } - } - else - { - if (!po->html3) - { - fputs(pval, fout); - efield: - if ((j + 1) < nFields) - fputs(po->fieldSep, fout); - else - fputc('\n', fout); - } - } - } - } - return true; -} - - -static char * -do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax, - const char **fieldNames, unsigned char *fieldNotNum, - const int fs_len, const PGresult *res) -{ - int j; /* for loop index */ - char *border = NULL; - - if (po->html3) - fputs("<tr>", fout); - else - { - int tot = 0; - int n = 0; - char *p = NULL; - - for (; n < nFields; n++) - tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0); - if (po->standard) - tot += fs_len * 2 + 2; - border = malloc(tot + 1); - if (!border) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - return NULL; - } - p = border; - if (po->standard) - { - char *fs = po->fieldSep; - - while (*fs++) - *p++ = '+'; - } - for (j = 0; j < nFields; j++) - { - int len; - - for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-'); - if (po->standard || (j + 1) < nFields) - { - char *fs = po->fieldSep; - - while (*fs++) - *p++ = '+'; - } - } - *p = '\0'; - if (po->standard) - fprintf(fout, "%s\n", border); - } - if (po->standard) - fputs(po->fieldSep, fout); - for (j = 0; j < nFields; j++) - { - const char *s = PQfname(res, j); - - if (po->html3) - { - fprintf(fout, "<th align=\"%s\">%s</th>", - fieldNotNum[j] ? "left" : "right", fieldNames[j]); - } - else - { - int n = strlen(s); - - if (n > fieldMax[j]) - fieldMax[j] = n; - if (po->standard) - fprintf(fout, - fieldNotNum[j] ? " %-*s " : " %*s ", - fieldMax[j], s); - else - fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s); - if (po->standard || (j + 1) < nFields) - fputs(po->fieldSep, fout); - } - } - if (po->html3) - fputs("</tr>\n", fout); - else - fprintf(fout, "\n%s\n", border); - return border; -} - - -static void -output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields, - unsigned char *fieldNotNum, int *fieldMax, char *border, - const int row_index) -{ - int field_index; /* for loop index */ - - if (po->html3) - fputs("<tr>", fout); - else if (po->standard) - fputs(po->fieldSep, fout); - for (field_index = 0; field_index < nFields; field_index++) - { - char *p = fields[row_index * nFields + field_index]; - - if (po->html3) - fprintf(fout, "<td align=\"%s\">%s</td>", - fieldNotNum[field_index] ? "left" : "right", p ? p : ""); - else - { - fprintf(fout, - fieldNotNum[field_index] ? - (po->standard ? " %-*s " : "%-*s") : - (po->standard ? " %*s " : "%*s"), - fieldMax[field_index], - p ? p : ""); - if (po->standard || field_index + 1 < nFields) - fputs(po->fieldSep, fout); - } - } - if (po->html3) - fputs("</tr>", fout); - else if (po->standard) - fprintf(fout, "\n%s", border); - fputc('\n', fout); -} - - - -/* - * really old printing routines - */ - -void -PQdisplayTuples(const PGresult *res, - FILE *fp, /* where to send the output */ - int fillAlign, /* pad the fields with spaces */ - const char *fieldSep, /* field separator */ - int printHeader, /* display headers? */ - int quiet -) -{ -#define DEFAULT_FIELD_SEP " " - - int i, - j; - int nFields; - int nTuples; - int *fLength = NULL; - - if (fieldSep == NULL) - fieldSep = DEFAULT_FIELD_SEP; - - /* Get some useful info about the results */ - nFields = PQnfields(res); - nTuples = PQntuples(res); - - if (fp == NULL) - fp = stdout; - - /* Figure the field lengths to align to */ - /* will be somewhat time consuming for very large results */ - if (fillAlign) - { - fLength = (int *) malloc(nFields * sizeof(int)); - if (!fLength) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - return; - } - - for (j = 0; j < nFields; j++) - { - fLength[j] = strlen(PQfname(res, j)); - for (i = 0; i < nTuples; i++) - { - int flen = PQgetlength(res, i, j); - - if (flen > fLength[j]) - fLength[j] = flen; - } - } - } - - if (printHeader) - { - /* first, print out the attribute names */ - for (i = 0; i < nFields; i++) - { - fputs(PQfname(res, i), fp); - if (fillAlign) - fill(strlen(PQfname(res, i)), fLength[i], ' ', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - - /* Underline the attribute names */ - for (i = 0; i < nFields; i++) - { - if (fillAlign) - fill(0, fLength[i], '-', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - } - - /* next, print out the instances */ - for (i = 0; i < nTuples; i++) - { - for (j = 0; j < nFields; j++) - { - fprintf(fp, "%s", PQgetvalue(res, i, j)); - if (fillAlign) - fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp); - fputs(fieldSep, fp); - } - fprintf(fp, "\n"); - } - - if (!quiet) - fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res), - (PQntuples(res) == 1) ? "" : "s"); - - fflush(fp); - - free(fLength); -} - - - -void -PQprintTuples(const PGresult *res, - FILE *fout, /* output stream */ - int PrintAttNames, /* print attribute names or not */ - int TerseOutput, /* delimiter bars or not? */ - int colWidth /* width of column, if 0, use variable width */ -) -{ - int nFields; - int nTups; - int i, - j; - char formatString[80]; - char *tborder = NULL; - - nFields = PQnfields(res); - nTups = PQntuples(res); - - if (colWidth > 0) - sprintf(formatString, "%%s %%-%ds", colWidth); - else - sprintf(formatString, "%%s %%s"); - - if (nFields > 0) - { /* only print rows with at least 1 field. */ - - if (!TerseOutput) - { - int width; - - width = nFields * 14; - tborder = (char *) malloc(width + 1); - if (!tborder) - { - fprintf(stderr, libpq_gettext("out of memory\n")); - return; - } - for (i = 0; i < width; i++) - tborder[i] = '-'; - tborder[width] = '\0'; - fprintf(fout, "%s\n", tborder); - } - - for (i = 0; i < nFields; i++) - { - if (PrintAttNames) - { - fprintf(fout, formatString, - TerseOutput ? "" : "|", - PQfname(res, i)); - } - } - - if (PrintAttNames) - { - if (TerseOutput) - fprintf(fout, "\n"); - else - fprintf(fout, "|\n%s\n", tborder); - } - - for (i = 0; i < nTups; i++) - { - for (j = 0; j < nFields; j++) - { - const char *pval = PQgetvalue(res, i, j); - - fprintf(fout, formatString, - TerseOutput ? "" : "|", - pval ? pval : ""); - } - if (TerseOutput) - fprintf(fout, "\n"); - else - fprintf(fout, "|\n%s\n", tborder); - } - } - - free(tborder); -} - - -/* simply send out max-length number of filler characters to fp */ - -static void -fill(int length, int max, char filler, FILE *fp) -{ - int count; - - count = max - length; - while (count-- >= 0) - putc(filler, fp); -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-protocol3.c b/contrib/libs/libpq/src/interfaces/libpq/fe-protocol3.c deleted file mode 100644 index 9c4aa7e2c7..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-protocol3.c +++ /dev/null @@ -1,2301 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-protocol3.c - * functions that are specific to frontend/backend protocol version 3 - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-protocol3.c - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include <ctype.h> -#include <fcntl.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#include <netinet/tcp.h> -#endif - -#include "libpq-fe.h" -#include "libpq-int.h" -#include "mb/pg_wchar.h" -#include "port/pg_bswap.h" - -/* - * This macro lists the backend message types that could be "long" (more - * than a couple of kilobytes). - */ -#define VALID_LONG_MESSAGE_TYPE(id) \ - ((id) == 'T' || (id) == 'D' || (id) == 'd' || (id) == 'V' || \ - (id) == 'E' || (id) == 'N' || (id) == 'A') - - -static void handleSyncLoss(PGconn *conn, char id, int msgLength); -static int getRowDescriptions(PGconn *conn, int msgLength); -static int getParamDescriptions(PGconn *conn, int msgLength); -static int getAnotherTuple(PGconn *conn, int msgLength); -static int getParameterStatus(PGconn *conn); -static int getNotify(PGconn *conn); -static int getCopyStart(PGconn *conn, ExecStatusType copytype); -static int getReadyForQuery(PGconn *conn); -static void reportErrorPosition(PQExpBuffer msg, const char *query, - int loc, int encoding); -static int build_startup_packet(const PGconn *conn, char *packet, - const PQEnvironmentOption *options); - - -/* - * parseInput: if appropriate, parse input data from backend - * until input is exhausted or a stopping state is reached. - * Note that this function will NOT attempt to read more data from the backend. - */ -void -pqParseInput3(PGconn *conn) -{ - char id; - int msgLength; - int avail; - - /* - * Loop to parse successive complete messages available in the buffer. - */ - for (;;) - { - /* - * Try to read a message. First get the type code and length. Return - * if not enough data. - */ - conn->inCursor = conn->inStart; - if (pqGetc(&id, conn)) - return; - if (pqGetInt(&msgLength, 4, conn)) - return; - - /* - * Try to validate message type/length here. A length less than 4 is - * definitely broken. Large lengths should only be believed for a few - * message types. - */ - if (msgLength < 4) - { - handleSyncLoss(conn, id, msgLength); - return; - } - if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id)) - { - handleSyncLoss(conn, id, msgLength); - return; - } - - /* - * Can't process if message body isn't all here yet. - */ - msgLength -= 4; - avail = conn->inEnd - conn->inCursor; - if (avail < msgLength) - { - /* - * Before returning, enlarge the input buffer if needed to hold - * the whole message. This is better than leaving it to - * pqReadData because we can avoid multiple cycles of realloc() - * when the message is large; also, we can implement a reasonable - * recovery strategy if we are unable to make the buffer big - * enough. - */ - if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength, - conn)) - { - /* - * XXX add some better recovery code... plan is to skip over - * the message using its length, then report an error. For the - * moment, just treat this like loss of sync (which indeed it - * might be!) - */ - handleSyncLoss(conn, id, msgLength); - } - return; - } - - /* - * NOTIFY and NOTICE messages can happen in any state; always process - * them right away. - * - * Most other messages should only be processed while in BUSY state. - * (In particular, in READY state we hold off further parsing until - * the application collects the current PGresult.) - * - * However, if the state is IDLE then we got trouble; we need to deal - * with the unexpected message somehow. - * - * ParameterStatus ('S') messages are a special case: in IDLE state we - * must process 'em (this case could happen if a new value was adopted - * from config file due to SIGHUP), but otherwise we hold off until - * BUSY state. - */ - if (id == 'A') - { - if (getNotify(conn)) - return; - } - else if (id == 'N') - { - if (pqGetErrorNotice3(conn, false)) - return; - } - else if (conn->asyncStatus != PGASYNC_BUSY) - { - /* If not IDLE state, just wait ... */ - if (conn->asyncStatus != PGASYNC_IDLE) - return; - - /* - * Unexpected message in IDLE state; need to recover somehow. - * ERROR messages are handled using the notice processor; - * ParameterStatus is handled normally; anything else is just - * dropped on the floor after displaying a suitable warning - * notice. (An ERROR is very possibly the backend telling us why - * it is about to close the connection, so we don't want to just - * discard it...) - */ - if (id == 'E') - { - if (pqGetErrorNotice3(conn, false /* treat as notice */ )) - return; - } - else if (id == 'S') - { - if (getParameterStatus(conn)) - return; - } - else - { - /* Any other case is unexpected and we summarily skip it */ - pqInternalNotice(&conn->noticeHooks, - "message type 0x%02x arrived from server while idle", - id); - /* Discard the unexpected message */ - conn->inCursor += msgLength; - } - } - else - { - /* - * In BUSY state, we can process everything. - */ - switch (id) - { - case 'C': /* command complete */ - if (pqGets(&conn->workBuffer, conn)) - return; - if (!pgHavePendingResult(conn)) - { - conn->result = PQmakeEmptyPGresult(conn, - PGRES_COMMAND_OK); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - } - if (conn->result) - strlcpy(conn->result->cmdStatus, conn->workBuffer.data, - CMDSTATUS_LEN); - conn->asyncStatus = PGASYNC_READY; - break; - case 'E': /* error return */ - if (pqGetErrorNotice3(conn, true)) - return; - conn->asyncStatus = PGASYNC_READY; - break; - case 'Z': /* sync response, backend is ready for new - * query */ - if (getReadyForQuery(conn)) - return; - if (conn->pipelineStatus != PQ_PIPELINE_OFF) - { - conn->result = PQmakeEmptyPGresult(conn, - PGRES_PIPELINE_SYNC); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - else - { - conn->pipelineStatus = PQ_PIPELINE_ON; - conn->asyncStatus = PGASYNC_READY; - } - } - else - { - /* Advance the command queue and set us idle */ - pqCommandQueueAdvance(conn, true, false); - conn->asyncStatus = PGASYNC_IDLE; - } - break; - case 'I': /* empty query */ - if (!pgHavePendingResult(conn)) - { - conn->result = PQmakeEmptyPGresult(conn, - PGRES_EMPTY_QUERY); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - } - conn->asyncStatus = PGASYNC_READY; - break; - case '1': /* Parse Complete */ - /* If we're doing PQprepare, we're done; else ignore */ - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_PREPARE) - { - if (!pgHavePendingResult(conn)) - { - conn->result = PQmakeEmptyPGresult(conn, - PGRES_COMMAND_OK); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - } - conn->asyncStatus = PGASYNC_READY; - } - break; - case '2': /* Bind Complete */ - case '3': /* Close Complete */ - /* Nothing to do for these message types */ - break; - case 'S': /* parameter status */ - if (getParameterStatus(conn)) - return; - break; - case 'K': /* secret key data from the backend */ - - /* - * This is expected only during backend startup, but it's - * just as easy to handle it as part of the main loop. - * Save the data and continue processing. - */ - if (pqGetInt(&(conn->be_pid), 4, conn)) - return; - if (pqGetInt(&(conn->be_key), 4, conn)) - return; - break; - case 'T': /* Row Description */ - if (conn->error_result || - (conn->result != NULL && - conn->result->resultStatus == PGRES_FATAL_ERROR)) - { - /* - * We've already choked for some reason. Just discard - * the data till we get to the end of the query. - */ - conn->inCursor += msgLength; - } - else if (conn->result == NULL || - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) - { - /* First 'T' in a query sequence */ - if (getRowDescriptions(conn, msgLength)) - return; - } - else - { - /* - * A new 'T' message is treated as the start of - * another PGresult. (It is not clear that this is - * really possible with the current backend.) We stop - * parsing until the application accepts the current - * result. - */ - conn->asyncStatus = PGASYNC_READY; - return; - } - break; - case 'n': /* No Data */ - - /* - * NoData indicates that we will not be seeing a - * RowDescription message because the statement or portal - * inquired about doesn't return rows. - * - * If we're doing a Describe, we have to pass something - * back to the client, so set up a COMMAND_OK result, - * instead of PGRES_TUPLES_OK. Otherwise we can just - * ignore this message. - */ - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE) - { - if (!pgHavePendingResult(conn)) - { - conn->result = PQmakeEmptyPGresult(conn, - PGRES_COMMAND_OK); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - } - conn->asyncStatus = PGASYNC_READY; - } - break; - case 't': /* Parameter Description */ - if (getParamDescriptions(conn, msgLength)) - return; - break; - case 'D': /* Data Row */ - if (conn->result != NULL && - conn->result->resultStatus == PGRES_TUPLES_OK) - { - /* Read another tuple of a normal query response */ - if (getAnotherTuple(conn, msgLength)) - return; - } - else if (conn->error_result || - (conn->result != NULL && - conn->result->resultStatus == PGRES_FATAL_ERROR)) - { - /* - * We've already choked for some reason. Just discard - * tuples till we get to the end of the query. - */ - conn->inCursor += msgLength; - } - else - { - /* Set up to report error at end of query */ - libpq_append_conn_error(conn, "server sent data (\"D\" message) without prior row description (\"T\" message)"); - pqSaveErrorResult(conn); - /* Discard the unexpected message */ - conn->inCursor += msgLength; - } - break; - case 'G': /* Start Copy In */ - if (getCopyStart(conn, PGRES_COPY_IN)) - return; - conn->asyncStatus = PGASYNC_COPY_IN; - break; - case 'H': /* Start Copy Out */ - if (getCopyStart(conn, PGRES_COPY_OUT)) - return; - conn->asyncStatus = PGASYNC_COPY_OUT; - conn->copy_already_done = 0; - break; - case 'W': /* Start Copy Both */ - if (getCopyStart(conn, PGRES_COPY_BOTH)) - return; - conn->asyncStatus = PGASYNC_COPY_BOTH; - conn->copy_already_done = 0; - break; - case 'd': /* Copy Data */ - - /* - * If we see Copy Data, just silently drop it. This would - * only occur if application exits COPY OUT mode too - * early. - */ - conn->inCursor += msgLength; - break; - case 'c': /* Copy Done */ - - /* - * If we see Copy Done, just silently drop it. This is - * the normal case during PQendcopy. We will keep - * swallowing data, expecting to see command-complete for - * the COPY command. - */ - break; - default: - libpq_append_conn_error(conn, "unexpected response from server; first received character was \"%c\"", id); - /* build an error result holding the error message */ - pqSaveErrorResult(conn); - /* not sure if we will see more, so go to ready state */ - conn->asyncStatus = PGASYNC_READY; - /* Discard the unexpected message */ - conn->inCursor += msgLength; - break; - } /* switch on protocol character */ - } - /* Successfully consumed this message */ - if (conn->inCursor == conn->inStart + 5 + msgLength) - { - /* trace server-to-client message */ - if (conn->Pfdebug) - pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false); - - /* Normal case: parsing agrees with specified length */ - conn->inStart = conn->inCursor; - } - else - { - /* Trouble --- report it */ - libpq_append_conn_error(conn, "message contents do not agree with length in message type \"%c\"", id); - /* build an error result holding the error message */ - pqSaveErrorResult(conn); - conn->asyncStatus = PGASYNC_READY; - /* trust the specified message length as what to skip */ - conn->inStart += 5 + msgLength; - } - } -} - -/* - * handleSyncLoss: clean up after loss of message-boundary sync - * - * There isn't really a lot we can do here except abandon the connection. - */ -static void -handleSyncLoss(PGconn *conn, char id, int msgLength) -{ - libpq_append_conn_error(conn, "lost synchronization with server: got message type \"%c\", length %d", - id, msgLength); - /* build an error result holding the error message */ - pqSaveErrorResult(conn); - conn->asyncStatus = PGASYNC_READY; /* drop out of PQgetResult wait loop */ - /* flush input data since we're giving up on processing it */ - pqDropConnection(conn, true); - conn->status = CONNECTION_BAD; /* No more connection to backend */ -} - -/* - * parseInput subroutine to read a 'T' (row descriptions) message. - * We'll build a new PGresult structure (unless called for a Describe - * command for a prepared statement) containing the attribute data. - * Returns: 0 if processed message successfully, EOF to suspend parsing - * (the latter case is not actually used currently). - */ -static int -getRowDescriptions(PGconn *conn, int msgLength) -{ - PGresult *result; - int nfields; - const char *errmsg; - int i; - - /* - * When doing Describe for a prepared statement, there'll already be a - * PGresult created by getParamDescriptions, and we should fill data into - * that. Otherwise, create a new, empty PGresult. - */ - if (!conn->cmd_queue_head || - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) - { - if (conn->result) - result = conn->result; - else - result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK); - } - else - result = PQmakeEmptyPGresult(conn, PGRES_TUPLES_OK); - if (!result) - { - errmsg = NULL; /* means "out of memory", see below */ - goto advance_and_error; - } - - /* parseInput already read the 'T' label and message length. */ - /* the next two bytes are the number of fields */ - if (pqGetInt(&(result->numAttributes), 2, conn)) - { - /* We should not run out of data here, so complain */ - errmsg = libpq_gettext("insufficient data in \"T\" message"); - goto advance_and_error; - } - nfields = result->numAttributes; - - /* allocate space for the attribute descriptors */ - if (nfields > 0) - { - result->attDescs = (PGresAttDesc *) - pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true); - if (!result->attDescs) - { - errmsg = NULL; /* means "out of memory", see below */ - goto advance_and_error; - } - MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc)); - } - - /* result->binary is true only if ALL columns are binary */ - result->binary = (nfields > 0) ? 1 : 0; - - /* get type info */ - for (i = 0; i < nfields; i++) - { - int tableid; - int columnid; - int typid; - int typlen; - int atttypmod; - int format; - - if (pqGets(&conn->workBuffer, conn) || - pqGetInt(&tableid, 4, conn) || - pqGetInt(&columnid, 2, conn) || - pqGetInt(&typid, 4, conn) || - pqGetInt(&typlen, 2, conn) || - pqGetInt(&atttypmod, 4, conn) || - pqGetInt(&format, 2, conn)) - { - /* We should not run out of data here, so complain */ - errmsg = libpq_gettext("insufficient data in \"T\" message"); - goto advance_and_error; - } - - /* - * Since pqGetInt treats 2-byte integers as unsigned, we need to - * coerce these results to signed form. - */ - columnid = (int) ((int16) columnid); - typlen = (int) ((int16) typlen); - format = (int) ((int16) format); - - result->attDescs[i].name = pqResultStrdup(result, - conn->workBuffer.data); - if (!result->attDescs[i].name) - { - errmsg = NULL; /* means "out of memory", see below */ - goto advance_and_error; - } - result->attDescs[i].tableid = tableid; - result->attDescs[i].columnid = columnid; - result->attDescs[i].format = format; - result->attDescs[i].typid = typid; - result->attDescs[i].typlen = typlen; - result->attDescs[i].atttypmod = atttypmod; - - if (format != 1) - result->binary = 0; - } - - /* Success! */ - conn->result = result; - - /* - * If we're doing a Describe, we're done, and ready to pass the result - * back to the client. - */ - if ((!conn->cmd_queue_head) || - (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass == PGQUERY_DESCRIBE)) - { - conn->asyncStatus = PGASYNC_READY; - return 0; - } - - /* - * We could perform additional setup for the new result set here, but for - * now there's nothing else to do. - */ - - /* And we're done. */ - return 0; - -advance_and_error: - /* Discard unsaved result, if any */ - if (result && result != conn->result) - PQclear(result); - - /* - * Replace partially constructed result with an error result. First - * discard the old result to try to win back some memory. - */ - pqClearAsyncResult(conn); - - /* - * If preceding code didn't provide an error message, assume "out of - * memory" was meant. The advantage of having this special case is that - * freeing the old result first greatly improves the odds that gettext() - * will succeed in providing a translation. - */ - if (!errmsg) - errmsg = libpq_gettext("out of memory for query result"); - - appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg); - pqSaveErrorResult(conn); - - /* - * Show the message as fully consumed, else pqParseInput3 will overwrite - * our error with a complaint about that. - */ - conn->inCursor = conn->inStart + 5 + msgLength; - - /* - * Return zero to allow input parsing to continue. Subsequent "D" - * messages will be ignored until we get to end of data, since an error - * result is already set up. - */ - return 0; -} - -/* - * parseInput subroutine to read a 't' (ParameterDescription) message. - * We'll build a new PGresult structure containing the parameter data. - * Returns: 0 if processed message successfully, EOF to suspend parsing - * (the latter case is not actually used currently). - */ -static int -getParamDescriptions(PGconn *conn, int msgLength) -{ - PGresult *result; - const char *errmsg = NULL; /* means "out of memory", see below */ - int nparams; - int i; - - result = PQmakeEmptyPGresult(conn, PGRES_COMMAND_OK); - if (!result) - goto advance_and_error; - - /* parseInput already read the 't' label and message length. */ - /* the next two bytes are the number of parameters */ - if (pqGetInt(&(result->numParameters), 2, conn)) - goto not_enough_data; - nparams = result->numParameters; - - /* allocate space for the parameter descriptors */ - if (nparams > 0) - { - result->paramDescs = (PGresParamDesc *) - pqResultAlloc(result, nparams * sizeof(PGresParamDesc), true); - if (!result->paramDescs) - goto advance_and_error; - MemSet(result->paramDescs, 0, nparams * sizeof(PGresParamDesc)); - } - - /* get parameter info */ - for (i = 0; i < nparams; i++) - { - int typid; - - if (pqGetInt(&typid, 4, conn)) - goto not_enough_data; - result->paramDescs[i].typid = typid; - } - - /* Success! */ - conn->result = result; - - return 0; - -not_enough_data: - errmsg = libpq_gettext("insufficient data in \"t\" message"); - -advance_and_error: - /* Discard unsaved result, if any */ - if (result && result != conn->result) - PQclear(result); - - /* - * Replace partially constructed result with an error result. First - * discard the old result to try to win back some memory. - */ - pqClearAsyncResult(conn); - - /* - * If preceding code didn't provide an error message, assume "out of - * memory" was meant. The advantage of having this special case is that - * freeing the old result first greatly improves the odds that gettext() - * will succeed in providing a translation. - */ - if (!errmsg) - errmsg = libpq_gettext("out of memory"); - appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg); - pqSaveErrorResult(conn); - - /* - * Show the message as fully consumed, else pqParseInput3 will overwrite - * our error with a complaint about that. - */ - conn->inCursor = conn->inStart + 5 + msgLength; - - /* - * Return zero to allow input parsing to continue. Essentially, we've - * replaced the COMMAND_OK result with an error result, but since this - * doesn't affect the protocol state, it's fine. - */ - return 0; -} - -/* - * parseInput subroutine to read a 'D' (row data) message. - * We fill rowbuf with column pointers and then call the row processor. - * Returns: 0 if processed message successfully, EOF to suspend parsing - * (the latter case is not actually used currently). - */ -static int -getAnotherTuple(PGconn *conn, int msgLength) -{ - PGresult *result = conn->result; - int nfields = result->numAttributes; - const char *errmsg; - PGdataValue *rowbuf; - int tupnfields; /* # fields from tuple */ - int vlen; /* length of the current field value */ - int i; - - /* Get the field count and make sure it's what we expect */ - if (pqGetInt(&tupnfields, 2, conn)) - { - /* We should not run out of data here, so complain */ - errmsg = libpq_gettext("insufficient data in \"D\" message"); - goto advance_and_error; - } - - if (tupnfields != nfields) - { - errmsg = libpq_gettext("unexpected field count in \"D\" message"); - goto advance_and_error; - } - - /* Resize row buffer if needed */ - rowbuf = conn->rowBuf; - if (nfields > conn->rowBufLen) - { - rowbuf = (PGdataValue *) realloc(rowbuf, - nfields * sizeof(PGdataValue)); - if (!rowbuf) - { - errmsg = NULL; /* means "out of memory", see below */ - goto advance_and_error; - } - conn->rowBuf = rowbuf; - conn->rowBufLen = nfields; - } - - /* Scan the fields */ - for (i = 0; i < nfields; i++) - { - /* get the value length */ - if (pqGetInt(&vlen, 4, conn)) - { - /* We should not run out of data here, so complain */ - errmsg = libpq_gettext("insufficient data in \"D\" message"); - goto advance_and_error; - } - rowbuf[i].len = vlen; - - /* - * rowbuf[i].value always points to the next address in the data - * buffer even if the value is NULL. This allows row processors to - * estimate data sizes more easily. - */ - rowbuf[i].value = conn->inBuffer + conn->inCursor; - - /* Skip over the data value */ - if (vlen > 0) - { - if (pqSkipnchar(vlen, conn)) - { - /* We should not run out of data here, so complain */ - errmsg = libpq_gettext("insufficient data in \"D\" message"); - goto advance_and_error; - } - } - } - - /* Process the collected row */ - errmsg = NULL; - if (pqRowProcessor(conn, &errmsg)) - return 0; /* normal, successful exit */ - - /* pqRowProcessor failed, fall through to report it */ - -advance_and_error: - - /* - * Replace partially constructed result with an error result. First - * discard the old result to try to win back some memory. - */ - pqClearAsyncResult(conn); - - /* - * If preceding code didn't provide an error message, assume "out of - * memory" was meant. The advantage of having this special case is that - * freeing the old result first greatly improves the odds that gettext() - * will succeed in providing a translation. - */ - if (!errmsg) - errmsg = libpq_gettext("out of memory for query result"); - - appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg); - pqSaveErrorResult(conn); - - /* - * Show the message as fully consumed, else pqParseInput3 will overwrite - * our error with a complaint about that. - */ - conn->inCursor = conn->inStart + 5 + msgLength; - - /* - * Return zero to allow input parsing to continue. Subsequent "D" - * messages will be ignored until we get to end of data, since an error - * result is already set up. - */ - return 0; -} - - -/* - * Attempt to read an Error or Notice response message. - * This is possible in several places, so we break it out as a subroutine. - * Entry: 'E' or 'N' message type and length have already been consumed. - * Exit: returns 0 if successfully consumed message. - * returns EOF if not enough data. - */ -int -pqGetErrorNotice3(PGconn *conn, bool isError) -{ - PGresult *res = NULL; - bool have_position = false; - PQExpBufferData workBuf; - char id; - - /* If in pipeline mode, set error indicator for it */ - if (isError && conn->pipelineStatus != PQ_PIPELINE_OFF) - conn->pipelineStatus = PQ_PIPELINE_ABORTED; - - /* - * If this is an error message, pre-emptively clear any incomplete query - * result we may have. We'd just throw it away below anyway, and - * releasing it before collecting the error might avoid out-of-memory. - */ - if (isError) - pqClearAsyncResult(conn); - - /* - * Since the fields might be pretty long, we create a temporary - * PQExpBuffer rather than using conn->workBuffer. workBuffer is intended - * for stuff that is expected to be short. We shouldn't use - * conn->errorMessage either, since this might be only a notice. - */ - initPQExpBuffer(&workBuf); - - /* - * Make a PGresult to hold the accumulated fields. We temporarily lie - * about the result status, so that PQmakeEmptyPGresult doesn't uselessly - * copy conn->errorMessage. - * - * NB: This allocation can fail, if you run out of memory. The rest of the - * function handles that gracefully, and we still try to set the error - * message as the connection's error message. - */ - res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY); - if (res) - res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR; - - /* - * Read the fields and save into res. - * - * While at it, save the SQLSTATE in conn->last_sqlstate, and note whether - * we saw a PG_DIAG_STATEMENT_POSITION field. - */ - for (;;) - { - if (pqGetc(&id, conn)) - goto fail; - if (id == '\0') - break; /* terminator found */ - if (pqGets(&workBuf, conn)) - goto fail; - pqSaveMessageField(res, id, workBuf.data); - if (id == PG_DIAG_SQLSTATE) - strlcpy(conn->last_sqlstate, workBuf.data, - sizeof(conn->last_sqlstate)); - else if (id == PG_DIAG_STATEMENT_POSITION) - have_position = true; - } - - /* - * Save the active query text, if any, into res as well; but only if we - * might need it for an error cursor display, which is only true if there - * is a PG_DIAG_STATEMENT_POSITION field. - */ - if (have_position && res && conn->cmd_queue_head && conn->cmd_queue_head->query) - res->errQuery = pqResultStrdup(res, conn->cmd_queue_head->query); - - /* - * Now build the "overall" error message for PQresultErrorMessage. - */ - resetPQExpBuffer(&workBuf); - pqBuildErrorMessage3(&workBuf, res, conn->verbosity, conn->show_context); - - /* - * Either save error as current async result, or just emit the notice. - */ - if (isError) - { - pqClearAsyncResult(conn); /* redundant, but be safe */ - if (res) - { - pqSetResultError(res, &workBuf, 0); - conn->result = res; - } - else - { - /* Fall back to using the internal-error processing paths */ - conn->error_result = true; - } - - if (PQExpBufferDataBroken(workBuf)) - libpq_append_conn_error(conn, "out of memory"); - else - appendPQExpBufferStr(&conn->errorMessage, workBuf.data); - } - else - { - /* if we couldn't allocate the result set, just discard the NOTICE */ - if (res) - { - /* - * We can cheat a little here and not copy the message. But if we - * were unlucky enough to run out of memory while filling workBuf, - * insert "out of memory", as in pqSetResultError. - */ - if (PQExpBufferDataBroken(workBuf)) - res->errMsg = libpq_gettext("out of memory\n"); - else - res->errMsg = workBuf.data; - if (res->noticeHooks.noticeRec != NULL) - res->noticeHooks.noticeRec(res->noticeHooks.noticeRecArg, res); - PQclear(res); - } - } - - termPQExpBuffer(&workBuf); - return 0; - -fail: - PQclear(res); - termPQExpBuffer(&workBuf); - return EOF; -} - -/* - * Construct an error message from the fields in the given PGresult, - * appending it to the contents of "msg". - */ -void -pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, - PGVerbosity verbosity, PGContextVisibility show_context) -{ - const char *val; - const char *querytext = NULL; - int querypos = 0; - - /* If we couldn't allocate a PGresult, just say "out of memory" */ - if (res == NULL) - { - appendPQExpBufferStr(msg, libpq_gettext("out of memory\n")); - return; - } - - /* - * If we don't have any broken-down fields, just return the base message. - * This mainly applies if we're given a libpq-generated error result. - */ - if (res->errFields == NULL) - { - if (res->errMsg && res->errMsg[0]) - appendPQExpBufferStr(msg, res->errMsg); - else - appendPQExpBufferStr(msg, libpq_gettext("no error message available\n")); - return; - } - - /* Else build error message from relevant fields */ - val = PQresultErrorField(res, PG_DIAG_SEVERITY); - if (val) - appendPQExpBuffer(msg, "%s: ", val); - - if (verbosity == PQERRORS_SQLSTATE) - { - /* - * If we have a SQLSTATE, print that and nothing else. If not (which - * shouldn't happen for server-generated errors, but might possibly - * happen for libpq-generated ones), fall back to TERSE format, as - * that seems better than printing nothing at all. - */ - val = PQresultErrorField(res, PG_DIAG_SQLSTATE); - if (val) - { - appendPQExpBuffer(msg, "%s\n", val); - return; - } - verbosity = PQERRORS_TERSE; - } - - if (verbosity == PQERRORS_VERBOSE) - { - val = PQresultErrorField(res, PG_DIAG_SQLSTATE); - if (val) - appendPQExpBuffer(msg, "%s: ", val); - } - val = PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY); - if (val) - appendPQExpBufferStr(msg, val); - val = PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION); - if (val) - { - if (verbosity != PQERRORS_TERSE && res->errQuery != NULL) - { - /* emit position as a syntax cursor display */ - querytext = res->errQuery; - querypos = atoi(val); - } - else - { - /* emit position as text addition to primary message */ - /* translator: %s represents a digit string */ - appendPQExpBuffer(msg, libpq_gettext(" at character %s"), - val); - } - } - else - { - val = PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION); - if (val) - { - querytext = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY); - if (verbosity != PQERRORS_TERSE && querytext != NULL) - { - /* emit position as a syntax cursor display */ - querypos = atoi(val); - } - else - { - /* emit position as text addition to primary message */ - /* translator: %s represents a digit string */ - appendPQExpBuffer(msg, libpq_gettext(" at character %s"), - val); - } - } - } - appendPQExpBufferChar(msg, '\n'); - if (verbosity != PQERRORS_TERSE) - { - if (querytext && querypos > 0) - reportErrorPosition(msg, querytext, querypos, - res->client_encoding); - val = PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL); - if (val) - appendPQExpBuffer(msg, libpq_gettext("DETAIL: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_MESSAGE_HINT); - if (val) - appendPQExpBuffer(msg, libpq_gettext("HINT: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY); - if (val) - appendPQExpBuffer(msg, libpq_gettext("QUERY: %s\n"), val); - if (show_context == PQSHOW_CONTEXT_ALWAYS || - (show_context == PQSHOW_CONTEXT_ERRORS && - res->resultStatus == PGRES_FATAL_ERROR)) - { - val = PQresultErrorField(res, PG_DIAG_CONTEXT); - if (val) - appendPQExpBuffer(msg, libpq_gettext("CONTEXT: %s\n"), - val); - } - } - if (verbosity == PQERRORS_VERBOSE) - { - val = PQresultErrorField(res, PG_DIAG_SCHEMA_NAME); - if (val) - appendPQExpBuffer(msg, - libpq_gettext("SCHEMA NAME: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_TABLE_NAME); - if (val) - appendPQExpBuffer(msg, - libpq_gettext("TABLE NAME: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_COLUMN_NAME); - if (val) - appendPQExpBuffer(msg, - libpq_gettext("COLUMN NAME: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_DATATYPE_NAME); - if (val) - appendPQExpBuffer(msg, - libpq_gettext("DATATYPE NAME: %s\n"), val); - val = PQresultErrorField(res, PG_DIAG_CONSTRAINT_NAME); - if (val) - appendPQExpBuffer(msg, - libpq_gettext("CONSTRAINT NAME: %s\n"), val); - } - if (verbosity == PQERRORS_VERBOSE) - { - const char *valf; - const char *vall; - - valf = PQresultErrorField(res, PG_DIAG_SOURCE_FILE); - vall = PQresultErrorField(res, PG_DIAG_SOURCE_LINE); - val = PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION); - if (val || valf || vall) - { - appendPQExpBufferStr(msg, libpq_gettext("LOCATION: ")); - if (val) - appendPQExpBuffer(msg, libpq_gettext("%s, "), val); - if (valf && vall) /* unlikely we'd have just one */ - appendPQExpBuffer(msg, libpq_gettext("%s:%s"), - valf, vall); - appendPQExpBufferChar(msg, '\n'); - } - } -} - -/* - * Add an error-location display to the error message under construction. - * - * The cursor location is measured in logical characters; the query string - * is presumed to be in the specified encoding. - */ -static void -reportErrorPosition(PQExpBuffer msg, const char *query, int loc, int encoding) -{ -#define DISPLAY_SIZE 60 /* screen width limit, in screen cols */ -#define MIN_RIGHT_CUT 10 /* try to keep this far away from EOL */ - - char *wquery; - int slen, - cno, - i, - *qidx, - *scridx, - qoffset, - scroffset, - ibeg, - iend, - loc_line; - bool mb_encoding, - beg_trunc, - end_trunc; - - /* Convert loc from 1-based to 0-based; no-op if out of range */ - loc--; - if (loc < 0) - return; - - /* Need a writable copy of the query */ - wquery = strdup(query); - if (wquery == NULL) - return; /* fail silently if out of memory */ - - /* - * Each character might occupy multiple physical bytes in the string, and - * in some Far Eastern character sets it might take more than one screen - * column as well. We compute the starting byte offset and starting - * screen column of each logical character, and store these in qidx[] and - * scridx[] respectively. - */ - - /* we need a safe allocation size... */ - slen = strlen(wquery) + 1; - - qidx = (int *) malloc(slen * sizeof(int)); - if (qidx == NULL) - { - free(wquery); - return; - } - scridx = (int *) malloc(slen * sizeof(int)); - if (scridx == NULL) - { - free(qidx); - free(wquery); - return; - } - - /* We can optimize a bit if it's a single-byte encoding */ - mb_encoding = (pg_encoding_max_length(encoding) != 1); - - /* - * Within the scanning loop, cno is the current character's logical - * number, qoffset is its offset in wquery, and scroffset is its starting - * logical screen column (all indexed from 0). "loc" is the logical - * character number of the error location. We scan to determine loc_line - * (the 1-based line number containing loc) and ibeg/iend (first character - * number and last+1 character number of the line containing loc). Note - * that qidx[] and scridx[] are filled only as far as iend. - */ - qoffset = 0; - scroffset = 0; - loc_line = 1; - ibeg = 0; - iend = -1; /* -1 means not set yet */ - - for (cno = 0; wquery[qoffset] != '\0'; cno++) - { - char ch = wquery[qoffset]; - - qidx[cno] = qoffset; - scridx[cno] = scroffset; - - /* - * Replace tabs with spaces in the writable copy. (Later we might - * want to think about coping with their variable screen width, but - * not today.) - */ - if (ch == '\t') - wquery[qoffset] = ' '; - - /* - * If end-of-line, count lines and mark positions. Each \r or \n - * counts as a line except when \r \n appear together. - */ - else if (ch == '\r' || ch == '\n') - { - if (cno < loc) - { - if (ch == '\r' || - cno == 0 || - wquery[qidx[cno - 1]] != '\r') - loc_line++; - /* extract beginning = last line start before loc. */ - ibeg = cno + 1; - } - else - { - /* set extract end. */ - iend = cno; - /* done scanning. */ - break; - } - } - - /* Advance */ - if (mb_encoding) - { - int w; - - w = pg_encoding_dsplen(encoding, &wquery[qoffset]); - /* treat any non-tab control chars as width 1 */ - if (w <= 0) - w = 1; - scroffset += w; - qoffset += PQmblenBounded(&wquery[qoffset], encoding); - } - else - { - /* We assume wide chars only exist in multibyte encodings */ - scroffset++; - qoffset++; - } - } - /* Fix up if we didn't find an end-of-line after loc */ - if (iend < 0) - { - iend = cno; /* query length in chars, +1 */ - qidx[iend] = qoffset; - scridx[iend] = scroffset; - } - - /* Print only if loc is within computed query length */ - if (loc <= cno) - { - /* If the line extracted is too long, we truncate it. */ - beg_trunc = false; - end_trunc = false; - if (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE) - { - /* - * We first truncate right if it is enough. This code might be - * off a space or so on enforcing MIN_RIGHT_CUT if there's a wide - * character right there, but that should be okay. - */ - if (scridx[ibeg] + DISPLAY_SIZE >= scridx[loc] + MIN_RIGHT_CUT) - { - while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE) - iend--; - end_trunc = true; - } - else - { - /* Truncate right if not too close to loc. */ - while (scridx[loc] + MIN_RIGHT_CUT < scridx[iend]) - { - iend--; - end_trunc = true; - } - - /* Truncate left if still too long. */ - while (scridx[iend] - scridx[ibeg] > DISPLAY_SIZE) - { - ibeg++; - beg_trunc = true; - } - } - } - - /* truncate working copy at desired endpoint */ - wquery[qidx[iend]] = '\0'; - - /* Begin building the finished message. */ - i = msg->len; - appendPQExpBuffer(msg, libpq_gettext("LINE %d: "), loc_line); - if (beg_trunc) - appendPQExpBufferStr(msg, "..."); - - /* - * While we have the prefix in the msg buffer, compute its screen - * width. - */ - scroffset = 0; - for (; i < msg->len; i += PQmblenBounded(&msg->data[i], encoding)) - { - int w = pg_encoding_dsplen(encoding, &msg->data[i]); - - if (w <= 0) - w = 1; - scroffset += w; - } - - /* Finish up the LINE message line. */ - appendPQExpBufferStr(msg, &wquery[qidx[ibeg]]); - if (end_trunc) - appendPQExpBufferStr(msg, "..."); - appendPQExpBufferChar(msg, '\n'); - - /* Now emit the cursor marker line. */ - scroffset += scridx[loc] - scridx[ibeg]; - for (i = 0; i < scroffset; i++) - appendPQExpBufferChar(msg, ' '); - appendPQExpBufferChar(msg, '^'); - appendPQExpBufferChar(msg, '\n'); - } - - /* Clean up. */ - free(scridx); - free(qidx); - free(wquery); -} - - -/* - * Attempt to read a NegotiateProtocolVersion message. - * Entry: 'v' message type and length have already been consumed. - * Exit: returns 0 if successfully consumed message. - * returns EOF if not enough data. - */ -int -pqGetNegotiateProtocolVersion3(PGconn *conn) -{ - int tmp; - ProtocolVersion their_version; - int num; - PQExpBufferData buf; - - if (pqGetInt(&tmp, 4, conn) != 0) - return EOF; - their_version = tmp; - - if (pqGetInt(&num, 4, conn) != 0) - return EOF; - - initPQExpBuffer(&buf); - for (int i = 0; i < num; i++) - { - if (pqGets(&conn->workBuffer, conn)) - { - termPQExpBuffer(&buf); - return EOF; - } - if (buf.len > 0) - appendPQExpBufferChar(&buf, ' '); - appendPQExpBufferStr(&buf, conn->workBuffer.data); - } - - if (their_version < conn->pversion) - libpq_append_conn_error(conn, "protocol version not supported by server: client uses %u.%u, server supports up to %u.%u", - PG_PROTOCOL_MAJOR(conn->pversion), PG_PROTOCOL_MINOR(conn->pversion), - PG_PROTOCOL_MAJOR(their_version), PG_PROTOCOL_MINOR(their_version)); - if (num > 0) - { - appendPQExpBuffer(&conn->errorMessage, - libpq_ngettext("protocol extension not supported by server: %s", - "protocol extensions not supported by server: %s", num), - buf.data); - appendPQExpBufferChar(&conn->errorMessage, '\n'); - } - - /* neither -- server shouldn't have sent it */ - if (!(their_version < conn->pversion) && !(num > 0)) - libpq_append_conn_error(conn, "invalid %s message", "NegotiateProtocolVersion"); - - termPQExpBuffer(&buf); - return 0; -} - - -/* - * Attempt to read a ParameterStatus message. - * This is possible in several places, so we break it out as a subroutine. - * Entry: 'S' message type and length have already been consumed. - * Exit: returns 0 if successfully consumed message. - * returns EOF if not enough data. - */ -static int -getParameterStatus(PGconn *conn) -{ - PQExpBufferData valueBuf; - - /* Get the parameter name */ - if (pqGets(&conn->workBuffer, conn)) - return EOF; - /* Get the parameter value (could be large) */ - initPQExpBuffer(&valueBuf); - if (pqGets(&valueBuf, conn)) - { - termPQExpBuffer(&valueBuf); - return EOF; - } - /* And save it */ - pqSaveParameterStatus(conn, conn->workBuffer.data, valueBuf.data); - termPQExpBuffer(&valueBuf); - return 0; -} - - -/* - * Attempt to read a Notify response message. - * This is possible in several places, so we break it out as a subroutine. - * Entry: 'A' message type and length have already been consumed. - * Exit: returns 0 if successfully consumed Notify message. - * returns EOF if not enough data. - */ -static int -getNotify(PGconn *conn) -{ - int be_pid; - char *svname; - int nmlen; - int extralen; - PGnotify *newNotify; - - if (pqGetInt(&be_pid, 4, conn)) - return EOF; - if (pqGets(&conn->workBuffer, conn)) - return EOF; - /* must save name while getting extra string */ - svname = strdup(conn->workBuffer.data); - if (!svname) - return EOF; - if (pqGets(&conn->workBuffer, conn)) - { - free(svname); - return EOF; - } - - /* - * Store the strings right after the PGnotify structure so it can all be - * freed at once. We don't use NAMEDATALEN because we don't want to tie - * this interface to a specific server name length. - */ - nmlen = strlen(svname); - extralen = strlen(conn->workBuffer.data); - newNotify = (PGnotify *) malloc(sizeof(PGnotify) + nmlen + extralen + 2); - if (newNotify) - { - newNotify->relname = (char *) newNotify + sizeof(PGnotify); - strcpy(newNotify->relname, svname); - newNotify->extra = newNotify->relname + nmlen + 1; - strcpy(newNotify->extra, conn->workBuffer.data); - newNotify->be_pid = be_pid; - newNotify->next = NULL; - if (conn->notifyTail) - conn->notifyTail->next = newNotify; - else - conn->notifyHead = newNotify; - conn->notifyTail = newNotify; - } - - free(svname); - return 0; -} - -/* - * getCopyStart - process CopyInResponse, CopyOutResponse or - * CopyBothResponse message - * - * parseInput already read the message type and length. - */ -static int -getCopyStart(PGconn *conn, ExecStatusType copytype) -{ - PGresult *result; - int nfields; - int i; - - result = PQmakeEmptyPGresult(conn, copytype); - if (!result) - goto failure; - - if (pqGetc(&conn->copy_is_binary, conn)) - goto failure; - result->binary = conn->copy_is_binary; - /* the next two bytes are the number of fields */ - if (pqGetInt(&(result->numAttributes), 2, conn)) - goto failure; - nfields = result->numAttributes; - - /* allocate space for the attribute descriptors */ - if (nfields > 0) - { - result->attDescs = (PGresAttDesc *) - pqResultAlloc(result, nfields * sizeof(PGresAttDesc), true); - if (!result->attDescs) - goto failure; - MemSet(result->attDescs, 0, nfields * sizeof(PGresAttDesc)); - } - - for (i = 0; i < nfields; i++) - { - int format; - - if (pqGetInt(&format, 2, conn)) - goto failure; - - /* - * Since pqGetInt treats 2-byte integers as unsigned, we need to - * coerce these results to signed form. - */ - format = (int) ((int16) format); - result->attDescs[i].format = format; - } - - /* Success! */ - conn->result = result; - return 0; - -failure: - PQclear(result); - return EOF; -} - -/* - * getReadyForQuery - process ReadyForQuery message - */ -static int -getReadyForQuery(PGconn *conn) -{ - char xact_status; - - if (pqGetc(&xact_status, conn)) - return EOF; - switch (xact_status) - { - case 'I': - conn->xactStatus = PQTRANS_IDLE; - break; - case 'T': - conn->xactStatus = PQTRANS_INTRANS; - break; - case 'E': - conn->xactStatus = PQTRANS_INERROR; - break; - default: - conn->xactStatus = PQTRANS_UNKNOWN; - break; - } - - return 0; -} - -/* - * getCopyDataMessage - fetch next CopyData message, process async messages - * - * Returns length word of CopyData message (> 0), or 0 if no complete - * message available, -1 if end of copy, -2 if error. - */ -static int -getCopyDataMessage(PGconn *conn) -{ - char id; - int msgLength; - int avail; - - for (;;) - { - /* - * Do we have the next input message? To make life simpler for async - * callers, we keep returning 0 until the next message is fully - * available, even if it is not Copy Data. - */ - conn->inCursor = conn->inStart; - if (pqGetc(&id, conn)) - return 0; - if (pqGetInt(&msgLength, 4, conn)) - return 0; - if (msgLength < 4) - { - handleSyncLoss(conn, id, msgLength); - return -2; - } - avail = conn->inEnd - conn->inCursor; - if (avail < msgLength - 4) - { - /* - * Before returning, enlarge the input buffer if needed to hold - * the whole message. See notes in parseInput. - */ - if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength - 4, - conn)) - { - /* - * XXX add some better recovery code... plan is to skip over - * the message using its length, then report an error. For the - * moment, just treat this like loss of sync (which indeed it - * might be!) - */ - handleSyncLoss(conn, id, msgLength); - return -2; - } - return 0; - } - - /* - * If it's a legitimate async message type, process it. (NOTIFY - * messages are not currently possible here, but we handle them for - * completeness.) Otherwise, if it's anything except Copy Data, - * report end-of-copy. - */ - switch (id) - { - case 'A': /* NOTIFY */ - if (getNotify(conn)) - return 0; - break; - case 'N': /* NOTICE */ - if (pqGetErrorNotice3(conn, false)) - return 0; - break; - case 'S': /* ParameterStatus */ - if (getParameterStatus(conn)) - return 0; - break; - case 'd': /* Copy Data, pass it back to caller */ - return msgLength; - case 'c': - - /* - * If this is a CopyDone message, exit COPY_OUT mode and let - * caller read status with PQgetResult(). If we're in - * COPY_BOTH mode, return to COPY_IN mode. - */ - if (conn->asyncStatus == PGASYNC_COPY_BOTH) - conn->asyncStatus = PGASYNC_COPY_IN; - else - conn->asyncStatus = PGASYNC_BUSY; - return -1; - default: /* treat as end of copy */ - - /* - * Any other message terminates either COPY_IN or COPY_BOTH - * mode. - */ - conn->asyncStatus = PGASYNC_BUSY; - return -1; - } - - /* trace server-to-client message */ - if (conn->Pfdebug) - pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false); - - /* Drop the processed message and loop around for another */ - conn->inStart = conn->inCursor; - } -} - -/* - * PQgetCopyData - read a row of data from the backend during COPY OUT - * or COPY BOTH - * - * If successful, sets *buffer to point to a malloc'd row of data, and - * returns row length (always > 0) as result. - * Returns 0 if no row available yet (only possible if async is true), - * -1 if end of copy (consult PQgetResult), or -2 if error (consult - * PQerrorMessage). - */ -int -pqGetCopyData3(PGconn *conn, char **buffer, int async) -{ - int msgLength; - - for (;;) - { - /* - * Collect the next input message. To make life simpler for async - * callers, we keep returning 0 until the next message is fully - * available, even if it is not Copy Data. - */ - msgLength = getCopyDataMessage(conn); - if (msgLength < 0) - return msgLength; /* end-of-copy or error */ - if (msgLength == 0) - { - /* Don't block if async read requested */ - if (async) - return 0; - /* Need to load more data */ - if (pqWait(true, false, conn) || - pqReadData(conn) < 0) - return -2; - continue; - } - - /* - * Drop zero-length messages (shouldn't happen anyway). Otherwise - * pass the data back to the caller. - */ - msgLength -= 4; - if (msgLength > 0) - { - *buffer = (char *) malloc(msgLength + 1); - if (*buffer == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return -2; - } - memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength); - (*buffer)[msgLength] = '\0'; /* Add terminating null */ - - /* Mark message consumed */ - conn->inStart = conn->inCursor + msgLength; - - return msgLength; - } - - /* Empty, so drop it and loop around for another */ - conn->inStart = conn->inCursor; - } -} - -/* - * PQgetline - gets a newline-terminated string from the backend. - * - * See fe-exec.c for documentation. - */ -int -pqGetline3(PGconn *conn, char *s, int maxlen) -{ - int status; - - if (conn->sock == PGINVALID_SOCKET || - (conn->asyncStatus != PGASYNC_COPY_OUT && - conn->asyncStatus != PGASYNC_COPY_BOTH) || - conn->copy_is_binary) - { - libpq_append_conn_error(conn, "PQgetline: not doing text COPY OUT"); - *s = '\0'; - return EOF; - } - - while ((status = PQgetlineAsync(conn, s, maxlen - 1)) == 0) - { - /* need to load more data */ - if (pqWait(true, false, conn) || - pqReadData(conn) < 0) - { - *s = '\0'; - return EOF; - } - } - - if (status < 0) - { - /* End of copy detected; gin up old-style terminator */ - strcpy(s, "\\."); - return 0; - } - - /* Add null terminator, and strip trailing \n if present */ - if (s[status - 1] == '\n') - { - s[status - 1] = '\0'; - return 0; - } - else - { - s[status] = '\0'; - return 1; - } -} - -/* - * PQgetlineAsync - gets a COPY data row without blocking. - * - * See fe-exec.c for documentation. - */ -int -pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize) -{ - int msgLength; - int avail; - - if (conn->asyncStatus != PGASYNC_COPY_OUT - && conn->asyncStatus != PGASYNC_COPY_BOTH) - return -1; /* we are not doing a copy... */ - - /* - * Recognize the next input message. To make life simpler for async - * callers, we keep returning 0 until the next message is fully available - * even if it is not Copy Data. This should keep PQendcopy from blocking. - * (Note: unlike pqGetCopyData3, we do not change asyncStatus here.) - */ - msgLength = getCopyDataMessage(conn); - if (msgLength < 0) - return -1; /* end-of-copy or error */ - if (msgLength == 0) - return 0; /* no data yet */ - - /* - * Move data from libpq's buffer to the caller's. In the case where a - * prior call found the caller's buffer too small, we use - * conn->copy_already_done to remember how much of the row was already - * returned to the caller. - */ - conn->inCursor += conn->copy_already_done; - avail = msgLength - 4 - conn->copy_already_done; - if (avail <= bufsize) - { - /* Able to consume the whole message */ - memcpy(buffer, &conn->inBuffer[conn->inCursor], avail); - /* Mark message consumed */ - conn->inStart = conn->inCursor + avail; - /* Reset state for next time */ - conn->copy_already_done = 0; - return avail; - } - else - { - /* We must return a partial message */ - memcpy(buffer, &conn->inBuffer[conn->inCursor], bufsize); - /* The message is NOT consumed from libpq's buffer */ - conn->copy_already_done += bufsize; - return bufsize; - } -} - -/* - * PQendcopy - * - * See fe-exec.c for documentation. - */ -int -pqEndcopy3(PGconn *conn) -{ - PGresult *result; - - if (conn->asyncStatus != PGASYNC_COPY_IN && - conn->asyncStatus != PGASYNC_COPY_OUT && - conn->asyncStatus != PGASYNC_COPY_BOTH) - { - libpq_append_conn_error(conn, "no COPY in progress"); - return 1; - } - - /* Send the CopyDone message if needed */ - if (conn->asyncStatus == PGASYNC_COPY_IN || - conn->asyncStatus == PGASYNC_COPY_BOTH) - { - if (pqPutMsgStart('c', conn) < 0 || - pqPutMsgEnd(conn) < 0) - return 1; - - /* - * If we sent the COPY command in extended-query mode, we must issue a - * Sync as well. - */ - if (conn->cmd_queue_head && - conn->cmd_queue_head->queryclass != PGQUERY_SIMPLE) - { - if (pqPutMsgStart('S', conn) < 0 || - pqPutMsgEnd(conn) < 0) - return 1; - } - } - - /* - * make sure no data is waiting to be sent, abort if we are non-blocking - * and the flush fails - */ - if (pqFlush(conn) && pqIsnonblocking(conn)) - return 1; - - /* Return to active duty */ - conn->asyncStatus = PGASYNC_BUSY; - - /* - * Non blocking connections may have to abort at this point. If everyone - * played the game there should be no problem, but in error scenarios the - * expected messages may not have arrived yet. (We are assuming that the - * backend's packetizing will ensure that CommandComplete arrives along - * with the CopyDone; are there corner cases where that doesn't happen?) - */ - if (pqIsnonblocking(conn) && PQisBusy(conn)) - return 1; - - /* Wait for the completion response */ - result = PQgetResult(conn); - - /* Expecting a successful result */ - if (result && result->resultStatus == PGRES_COMMAND_OK) - { - PQclear(result); - return 0; - } - - /* - * Trouble. For backwards-compatibility reasons, we issue the error - * message as if it were a notice (would be nice to get rid of this - * silliness, but too many apps probably don't handle errors from - * PQendcopy reasonably). Note that the app can still obtain the error - * status from the PGconn object. - */ - if (conn->errorMessage.len > 0) - { - /* We have to strip the trailing newline ... pain in neck... */ - char svLast = conn->errorMessage.data[conn->errorMessage.len - 1]; - - if (svLast == '\n') - conn->errorMessage.data[conn->errorMessage.len - 1] = '\0'; - pqInternalNotice(&conn->noticeHooks, "%s", conn->errorMessage.data); - conn->errorMessage.data[conn->errorMessage.len - 1] = svLast; - } - - PQclear(result); - - return 1; -} - - -/* - * PQfn - Send a function call to the POSTGRES backend. - * - * See fe-exec.c for documentation. - */ -PGresult * -pqFunctionCall3(PGconn *conn, Oid fnid, - int *result_buf, int *actual_result_len, - int result_is_int, - const PQArgBlock *args, int nargs) -{ - bool needInput = false; - ExecStatusType status = PGRES_FATAL_ERROR; - char id; - int msgLength; - int avail; - int i; - - /* already validated by PQfn */ - Assert(conn->pipelineStatus == PQ_PIPELINE_OFF); - - /* PQfn already validated connection state */ - - if (pqPutMsgStart('F', conn) < 0 || /* function call msg */ - pqPutInt(fnid, 4, conn) < 0 || /* function id */ - pqPutInt(1, 2, conn) < 0 || /* # of format codes */ - pqPutInt(1, 2, conn) < 0 || /* format code: BINARY */ - pqPutInt(nargs, 2, conn) < 0) /* # of args */ - { - /* error message should be set up already */ - return NULL; - } - - for (i = 0; i < nargs; ++i) - { /* len.int4 + contents */ - if (pqPutInt(args[i].len, 4, conn)) - return NULL; - if (args[i].len == -1) - continue; /* it's NULL */ - - if (args[i].isint) - { - if (pqPutInt(args[i].u.integer, args[i].len, conn)) - return NULL; - } - else - { - if (pqPutnchar((char *) args[i].u.ptr, args[i].len, conn)) - return NULL; - } - } - - if (pqPutInt(1, 2, conn) < 0) /* result format code: BINARY */ - return NULL; - - if (pqPutMsgEnd(conn) < 0 || - pqFlush(conn)) - return NULL; - - for (;;) - { - if (needInput) - { - /* Wait for some data to arrive (or for the channel to close) */ - if (pqWait(true, false, conn) || - pqReadData(conn) < 0) - break; - } - - /* - * Scan the message. If we run out of data, loop around to try again. - */ - needInput = true; - - conn->inCursor = conn->inStart; - if (pqGetc(&id, conn)) - continue; - if (pqGetInt(&msgLength, 4, conn)) - continue; - - /* - * Try to validate message type/length here. A length less than 4 is - * definitely broken. Large lengths should only be believed for a few - * message types. - */ - if (msgLength < 4) - { - handleSyncLoss(conn, id, msgLength); - break; - } - if (msgLength > 30000 && !VALID_LONG_MESSAGE_TYPE(id)) - { - handleSyncLoss(conn, id, msgLength); - break; - } - - /* - * Can't process if message body isn't all here yet. - */ - msgLength -= 4; - avail = conn->inEnd - conn->inCursor; - if (avail < msgLength) - { - /* - * Before looping, enlarge the input buffer if needed to hold the - * whole message. See notes in parseInput. - */ - if (pqCheckInBufferSpace(conn->inCursor + (size_t) msgLength, - conn)) - { - /* - * XXX add some better recovery code... plan is to skip over - * the message using its length, then report an error. For the - * moment, just treat this like loss of sync (which indeed it - * might be!) - */ - handleSyncLoss(conn, id, msgLength); - break; - } - continue; - } - - /* - * We should see V or E response to the command, but might get N - * and/or A notices first. We also need to swallow the final Z before - * returning. - */ - switch (id) - { - case 'V': /* function result */ - if (pqGetInt(actual_result_len, 4, conn)) - continue; - if (*actual_result_len != -1) - { - if (result_is_int) - { - if (pqGetInt(result_buf, *actual_result_len, conn)) - continue; - } - else - { - if (pqGetnchar((char *) result_buf, - *actual_result_len, - conn)) - continue; - } - } - /* correctly finished function result message */ - status = PGRES_COMMAND_OK; - break; - case 'E': /* error return */ - if (pqGetErrorNotice3(conn, true)) - continue; - status = PGRES_FATAL_ERROR; - break; - case 'A': /* notify message */ - /* handle notify and go back to processing return values */ - if (getNotify(conn)) - continue; - break; - case 'N': /* notice */ - /* handle notice and go back to processing return values */ - if (pqGetErrorNotice3(conn, false)) - continue; - break; - case 'Z': /* backend is ready for new query */ - if (getReadyForQuery(conn)) - continue; - /* consume the message and exit */ - conn->inStart += 5 + msgLength; - - /* - * If we already have a result object (probably an error), use - * that. Otherwise, if we saw a function result message, - * report COMMAND_OK. Otherwise, the backend violated the - * protocol, so complain. - */ - if (!pgHavePendingResult(conn)) - { - if (status == PGRES_COMMAND_OK) - { - conn->result = PQmakeEmptyPGresult(conn, status); - if (!conn->result) - { - libpq_append_conn_error(conn, "out of memory"); - pqSaveErrorResult(conn); - } - } - else - { - libpq_append_conn_error(conn, "protocol error: no function result"); - pqSaveErrorResult(conn); - } - } - return pqPrepareAsyncResult(conn); - case 'S': /* parameter status */ - if (getParameterStatus(conn)) - continue; - break; - default: - /* The backend violates the protocol. */ - libpq_append_conn_error(conn, "protocol error: id=0x%x", id); - pqSaveErrorResult(conn); - /* trust the specified message length as what to skip */ - conn->inStart += 5 + msgLength; - return pqPrepareAsyncResult(conn); - } - - /* trace server-to-client message */ - if (conn->Pfdebug) - pqTraceOutputMessage(conn, conn->inBuffer + conn->inStart, false); - - /* Completed this message, keep going */ - /* trust the specified message length as what to skip */ - conn->inStart += 5 + msgLength; - needInput = false; - } - - /* - * We fall out of the loop only upon failing to read data. - * conn->errorMessage has been set by pqWait or pqReadData. We want to - * append it to any already-received error message. - */ - pqSaveErrorResult(conn); - return pqPrepareAsyncResult(conn); -} - - -/* - * Construct startup packet - * - * Returns a malloc'd packet buffer, or NULL if out of memory - */ -char * -pqBuildStartupPacket3(PGconn *conn, int *packetlen, - const PQEnvironmentOption *options) -{ - char *startpacket; - - *packetlen = build_startup_packet(conn, NULL, options); - startpacket = (char *) malloc(*packetlen); - if (!startpacket) - return NULL; - *packetlen = build_startup_packet(conn, startpacket, options); - return startpacket; -} - -/* - * Build a startup packet given a filled-in PGconn structure. - * - * We need to figure out how much space is needed, then fill it in. - * To avoid duplicate logic, this routine is called twice: the first time - * (with packet == NULL) just counts the space needed, the second time - * (with packet == allocated space) fills it in. Return value is the number - * of bytes used. - */ -static int -build_startup_packet(const PGconn *conn, char *packet, - const PQEnvironmentOption *options) -{ - int packet_len = 0; - const PQEnvironmentOption *next_eo; - const char *val; - - /* Protocol version comes first. */ - if (packet) - { - ProtocolVersion pv = pg_hton32(conn->pversion); - - memcpy(packet + packet_len, &pv, sizeof(ProtocolVersion)); - } - packet_len += sizeof(ProtocolVersion); - - /* Add user name, database name, options */ - -#define ADD_STARTUP_OPTION(optname, optval) \ - do { \ - if (packet) \ - strcpy(packet + packet_len, optname); \ - packet_len += strlen(optname) + 1; \ - if (packet) \ - strcpy(packet + packet_len, optval); \ - packet_len += strlen(optval) + 1; \ - } while(0) - - if (conn->pguser && conn->pguser[0]) - ADD_STARTUP_OPTION("user", conn->pguser); - if (conn->dbName && conn->dbName[0]) - ADD_STARTUP_OPTION("database", conn->dbName); - if (conn->replication && conn->replication[0]) - ADD_STARTUP_OPTION("replication", conn->replication); - if (conn->pgoptions && conn->pgoptions[0]) - ADD_STARTUP_OPTION("options", conn->pgoptions); - if (conn->send_appname) - { - /* Use appname if present, otherwise use fallback */ - val = conn->appname ? conn->appname : conn->fbappname; - if (val && val[0]) - ADD_STARTUP_OPTION("application_name", val); - } - - if (conn->client_encoding_initial && conn->client_encoding_initial[0]) - ADD_STARTUP_OPTION("client_encoding", conn->client_encoding_initial); - - /* Add any environment-driven GUC settings needed */ - for (next_eo = options; next_eo->envName; next_eo++) - { - if ((val = getenv(next_eo->envName)) != NULL) - { - if (pg_strcasecmp(val, "default") != 0) - ADD_STARTUP_OPTION(next_eo->pgName, val); - } - } - - /* Add trailing terminator */ - if (packet) - packet[packet_len] = '\0'; - packet_len++; - - return packet_len; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.c b/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.c deleted file mode 100644 index 3ecc7bf615..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.c +++ /dev/null @@ -1,307 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-secure-common.c - * - * common implementation-independent SSL support code - * - * While fe-secure.c contains the interfaces that the rest of libpq call, this - * file contains support routines that are used by the library-specific - * implementations such as fe-secure-openssl.c. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-secure-common.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <arpa/inet.h> - -#include "fe-secure-common.h" - -#include "libpq-int.h" -#include "pqexpbuffer.h" - -/* - * Check if a wildcard certificate matches the server hostname. - * - * The rule for this is: - * 1. We only match the '*' character as wildcard - * 2. We match only wildcards at the start of the string - * 3. The '*' character does *not* match '.', meaning that we match only - * a single pathname component. - * 4. We don't support more than one '*' in a single pattern. - * - * This is roughly in line with RFC2818, but contrary to what most browsers - * appear to be implementing (point 3 being the difference) - * - * Matching is always case-insensitive, since DNS is case insensitive. - */ -static bool -wildcard_certificate_match(const char *pattern, const char *string) -{ - int lenpat = strlen(pattern); - int lenstr = strlen(string); - - /* If we don't start with a wildcard, it's not a match (rule 1 & 2) */ - if (lenpat < 3 || - pattern[0] != '*' || - pattern[1] != '.') - return false; - - /* If pattern is longer than the string, we can never match */ - if (lenpat > lenstr) - return false; - - /* - * If string does not end in pattern (minus the wildcard), we don't match - */ - if (pg_strcasecmp(pattern + 1, string + lenstr - lenpat + 1) != 0) - return false; - - /* - * If there is a dot left of where the pattern started to match, we don't - * match (rule 3) - */ - if (strchr(string, '.') < string + lenstr - lenpat) - return false; - - /* String ended with pattern, and didn't have a dot before, so we match */ - return true; -} - -/* - * Check if a name from a server's certificate matches the peer's hostname. - * - * Returns 1 if the name matches, and 0 if it does not. On error, returns - * -1, and sets the libpq error message. - * - * The name extracted from the certificate is returned in *store_name. The - * caller is responsible for freeing it. - */ -int -pq_verify_peer_name_matches_certificate_name(PGconn *conn, - const char *namedata, size_t namelen, - char **store_name) -{ - char *name; - int result; - char *host = conn->connhost[conn->whichhost].host; - - *store_name = NULL; - - if (!(host && host[0] != '\0')) - { - libpq_append_conn_error(conn, "host name must be specified"); - return -1; - } - - /* - * There is no guarantee the string returned from the certificate is - * NULL-terminated, so make a copy that is. - */ - name = malloc(namelen + 1); - if (name == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return -1; - } - memcpy(name, namedata, namelen); - name[namelen] = '\0'; - - /* - * Reject embedded NULLs in certificate common or alternative name to - * prevent attacks like CVE-2009-4034. - */ - if (namelen != strlen(name)) - { - free(name); - libpq_append_conn_error(conn, "SSL certificate's name contains embedded null"); - return -1; - } - - if (pg_strcasecmp(name, host) == 0) - { - /* Exact name match */ - result = 1; - } - else if (wildcard_certificate_match(name, host)) - { - /* Matched wildcard name */ - result = 1; - } - else - { - result = 0; - } - - *store_name = name; - return result; -} - -/* - * Check if an IP address from a server's certificate matches the peer's - * hostname (which must itself be an IPv4/6 address). - * - * Returns 1 if the address matches, and 0 if it does not. On error, returns - * -1, and sets the libpq error message. - * - * A string representation of the certificate's IP address is returned in - * *store_name. The caller is responsible for freeing it. - */ -int -pq_verify_peer_name_matches_certificate_ip(PGconn *conn, - const unsigned char *ipdata, - size_t iplen, - char **store_name) -{ - char *addrstr; - int match = 0; - char *host = conn->connhost[conn->whichhost].host; - int family; - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - char sebuf[PG_STRERROR_R_BUFLEN]; - - *store_name = NULL; - - if (!(host && host[0] != '\0')) - { - libpq_append_conn_error(conn, "host name must be specified"); - return -1; - } - - /* - * The data from the certificate is in network byte order. Convert our - * host string to network-ordered bytes as well, for comparison. (The host - * string isn't guaranteed to actually be an IP address, so if this - * conversion fails we need to consider it a mismatch rather than an - * error.) - */ - if (iplen == 4) - { - /* IPv4 */ - struct in_addr addr; - - family = AF_INET; - - /* - * The use of inet_aton() is deliberate; we accept alternative IPv4 - * address notations that are accepted by inet_aton() but not - * inet_pton() as server addresses. - */ - if (inet_aton(host, &addr)) - { - if (memcmp(ipdata, &addr.s_addr, iplen) == 0) - match = 1; - } - } - - /* - * If they don't have inet_pton(), skip this. Then, an IPv6 address in a - * certificate will cause an error. - */ -#ifdef HAVE_INET_PTON - else if (iplen == 16) - { - /* IPv6 */ - struct in6_addr addr; - - family = AF_INET6; - - if (inet_pton(AF_INET6, host, &addr) == 1) - { - if (memcmp(ipdata, &addr.s6_addr, iplen) == 0) - match = 1; - } - } -#endif - else - { - /* - * Not IPv4 or IPv6. We could ignore the field, but leniency seems - * wrong given the subject matter. - */ - libpq_append_conn_error(conn, "certificate contains IP address with invalid length %zu", - iplen); - return -1; - } - - /* Generate a human-readable representation of the certificate's IP. */ - addrstr = pg_inet_net_ntop(family, ipdata, 8 * iplen, tmp, sizeof(tmp)); - if (!addrstr) - { - libpq_append_conn_error(conn, "could not convert certificate's IP address to string: %s", - strerror_r(errno, sebuf, sizeof(sebuf))); - return -1; - } - - *store_name = strdup(addrstr); - return match; -} - -/* - * Verify that the server certificate matches the hostname we connected to. - * - * The certificate's Common Name and Subject Alternative Names are considered. - */ -bool -pq_verify_peer_name_matches_certificate(PGconn *conn) -{ - char *host = conn->connhost[conn->whichhost].host; - int rc; - int names_examined = 0; - char *first_name = NULL; - - /* - * If told not to verify the peer name, don't do it. Return true - * indicating that the verification was successful. - */ - if (strcmp(conn->sslmode, "verify-full") != 0) - return true; - - /* Check that we have a hostname to compare with. */ - if (!(host && host[0] != '\0')) - { - libpq_append_conn_error(conn, "host name must be specified for a verified SSL connection"); - return false; - } - - rc = pgtls_verify_peer_name_matches_certificate_guts(conn, &names_examined, &first_name); - - if (rc == 0) - { - /* - * No match. Include the name from the server certificate in the error - * message, to aid debugging broken configurations. If there are - * multiple names, only print the first one to avoid an overly long - * error message. - */ - if (names_examined > 1) - { - appendPQExpBuffer(&conn->errorMessage, - libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"", - "server certificate for \"%s\" (and %d other names) does not match host name \"%s\"", - names_examined - 1), - first_name, names_examined - 1, host); - appendPQExpBufferChar(&conn->errorMessage, '\n'); - } - else if (names_examined == 1) - { - libpq_append_conn_error(conn, "server certificate for \"%s\" does not match host name \"%s\"", - first_name, host); - } - else - { - libpq_append_conn_error(conn, "could not get server's host name from server certificate"); - } - } - - /* clean up */ - free(first_name); - - return (rc == 1); -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.h b/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.h deleted file mode 100644 index e048f97b01..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-common.h +++ /dev/null @@ -1,30 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-secure-common.h - * - * common implementation-independent SSL support code - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-secure-common.h - * - *------------------------------------------------------------------------- - */ - -#ifndef FE_SECURE_COMMON_H -#define FE_SECURE_COMMON_H - -#include "libpq-fe.h" - -extern int pq_verify_peer_name_matches_certificate_name(PGconn *conn, - const char *namedata, size_t namelen, - char **store_name); -extern int pq_verify_peer_name_matches_certificate_ip(PGconn *conn, - const unsigned char *ipdata, - size_t iplen, - char **store_name); -extern bool pq_verify_peer_name_matches_certificate(PGconn *conn); - -#endif /* FE_SECURE_COMMON_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-openssl.c b/contrib/libs/libpq/src/interfaces/libpq/fe-secure-openssl.c deleted file mode 100644 index 8b845994a1..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-secure-openssl.c +++ /dev/null @@ -1,2093 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-secure-openssl.c - * OpenSSL support - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-secure-openssl.c - * - * NOTES - * - * We don't provide informational callbacks here (like - * info_cb() in be-secure-openssl.c), since there's no good mechanism to - * display such information to the user. - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <signal.h> -#include <fcntl.h> -#include <ctype.h> - -#include "libpq-fe.h" -#include "fe-auth.h" -#include "fe-secure-common.h" -#include "libpq-int.h" - -#ifdef WIN32 -#include "win32.h" -#else -#include <sys/socket.h> -#include <unistd.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#endif - -#include <sys/stat.h> - -#ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 -#include "pthread-win32.h" -#else -#include <pthread.h> -#endif -#endif - -/* - * These SSL-related #includes must come after all system-provided headers. - * This ensures that OpenSSL can take care of conflicts with Windows' - * <wincrypt.h> by #undef'ing the conflicting macros. (We don't directly - * include <wincrypt.h>, but some other Windows headers do.) - */ -#include "common/openssl.h" -#include <openssl/conf.h> -#ifdef USE_SSL_ENGINE -#include <openssl/engine.h> -#endif -#include <openssl/x509v3.h> - - -static int verify_cb(int ok, X509_STORE_CTX *ctx); -static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, - ASN1_STRING *name_entry, - char **store_name); -static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, - ASN1_OCTET_STRING *addr_entry, - char **store_name); -static void destroy_ssl_system(void); -static int initialize_SSL(PGconn *conn); -static PostgresPollingStatusType open_client_SSL(PGconn *conn); -static char *SSLerrmessage(unsigned long ecode); -static void SSLerrfree(char *buf); -static int PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata); - -static int my_sock_read(BIO *h, char *buf, int size); -static int my_sock_write(BIO *h, const char *buf, int size); -static BIO_METHOD *my_BIO_s_socket(void); -static int my_SSL_set_fd(PGconn *conn, int fd); - - -static bool pq_init_ssl_lib = true; -static bool pq_init_crypto_lib = true; - -static bool ssl_lib_initialized = false; - -#ifdef ENABLE_THREAD_SAFETY -static long crypto_open_connections = 0; - -#ifndef WIN32 -static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER; -#else -static pthread_mutex_t ssl_config_mutex = NULL; -static long win32_ssl_create_mutex = 0; -#endif -#endif /* ENABLE_THREAD_SAFETY */ - -static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL; -static int ssl_protocol_version_to_openssl(const char *protocol); - -/* ------------------------------------------------------------ */ -/* Procedures common to all secure sessions */ -/* ------------------------------------------------------------ */ - -void -pgtls_init_library(bool do_ssl, int do_crypto) -{ -#ifdef ENABLE_THREAD_SAFETY - - /* - * Disallow changing the flags while we have open connections, else we'd - * get completely confused. - */ - if (crypto_open_connections != 0) - return; -#endif - - pq_init_ssl_lib = do_ssl; - pq_init_crypto_lib = do_crypto; -} - -PostgresPollingStatusType -pgtls_open_client(PGconn *conn) -{ - /* First time through? */ - if (conn->ssl == NULL) - { - /* - * Create a connection-specific SSL object, and load client - * certificate, private key, and trusted CA certs. - */ - if (initialize_SSL(conn) != 0) - { - /* initialize_SSL already put a message in conn->errorMessage */ - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - } - - /* Begin or continue the actual handshake */ - return open_client_SSL(conn); -} - -ssize_t -pgtls_read(PGconn *conn, void *ptr, size_t len) -{ - ssize_t n; - int result_errno = 0; - char sebuf[PG_STRERROR_R_BUFLEN]; - int err; - unsigned long ecode; - -rloop: - - /* - * Prepare to call SSL_get_error() by clearing thread's OpenSSL error - * queue. In general, the current thread's error queue must be empty - * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will - * not work reliably. Since the possibility exists that other OpenSSL - * clients running in the same thread but not under our control will fail - * to call ERR_get_error() themselves (after their own I/O operations), - * pro-actively clear the per-thread error queue now. - */ - SOCK_ERRNO_SET(0); - ERR_clear_error(); - n = SSL_read(conn->ssl, ptr, len); - err = SSL_get_error(conn->ssl, n); - - /* - * Other clients of OpenSSL may fail to call ERR_get_error(), but we - * always do, so as to not cause problems for OpenSSL clients that don't - * call ERR_clear_error() defensively. Be sure that this happens by - * calling now. SSL_get_error() relies on the OpenSSL per-thread error - * queue being intact, so this is the earliest possible point - * ERR_get_error() may be called. - */ - ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0; - switch (err) - { - case SSL_ERROR_NONE: - if (n < 0) - { - /* Not supposed to happen, so we don't translate the msg */ - appendPQExpBufferStr(&conn->errorMessage, - "SSL_read failed but did not provide error information\n"); - /* assume the connection is broken */ - result_errno = ECONNRESET; - } - break; - case SSL_ERROR_WANT_READ: - n = 0; - break; - case SSL_ERROR_WANT_WRITE: - - /* - * Returning 0 here would cause caller to wait for read-ready, - * which is not correct since what SSL wants is wait for - * write-ready. The former could get us stuck in an infinite - * wait, so don't risk it; busy-loop instead. - */ - goto rloop; - case SSL_ERROR_SYSCALL: - if (n < 0 && SOCK_ERRNO != 0) - { - result_errno = SOCK_ERRNO; - if (result_errno == EPIPE || - result_errno == ECONNRESET) - libpq_append_conn_error(conn, "server closed the connection unexpectedly\n" - "\tThis probably means the server terminated abnormally\n" - "\tbefore or while processing the request."); - else - libpq_append_conn_error(conn, "SSL SYSCALL error: %s", - SOCK_STRERROR(result_errno, - sebuf, sizeof(sebuf))); - } - else - { - libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected"); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - } - break; - case SSL_ERROR_SSL: - { - char *errm = SSLerrmessage(ecode); - - libpq_append_conn_error(conn, "SSL error: %s", errm); - SSLerrfree(errm); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - break; - } - case SSL_ERROR_ZERO_RETURN: - - /* - * Per OpenSSL documentation, this error code is only returned for - * a clean connection closure, so we should not report it as a - * server crash. - */ - libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly"); - result_errno = ECONNRESET; - n = -1; - break; - default: - libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - break; - } - - /* ensure we return the intended errno to caller */ - SOCK_ERRNO_SET(result_errno); - - return n; -} - -bool -pgtls_read_pending(PGconn *conn) -{ - return SSL_pending(conn->ssl) > 0; -} - -ssize_t -pgtls_write(PGconn *conn, const void *ptr, size_t len) -{ - ssize_t n; - int result_errno = 0; - char sebuf[PG_STRERROR_R_BUFLEN]; - int err; - unsigned long ecode; - - SOCK_ERRNO_SET(0); - ERR_clear_error(); - n = SSL_write(conn->ssl, ptr, len); - err = SSL_get_error(conn->ssl, n); - ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0; - switch (err) - { - case SSL_ERROR_NONE: - if (n < 0) - { - /* Not supposed to happen, so we don't translate the msg */ - appendPQExpBufferStr(&conn->errorMessage, - "SSL_write failed but did not provide error information\n"); - /* assume the connection is broken */ - result_errno = ECONNRESET; - } - break; - case SSL_ERROR_WANT_READ: - - /* - * Returning 0 here causes caller to wait for write-ready, which - * is not really the right thing, but it's the best we can do. - */ - n = 0; - break; - case SSL_ERROR_WANT_WRITE: - n = 0; - break; - case SSL_ERROR_SYSCALL: - - /* - * If errno is still zero then assume it's a read EOF situation, - * and report EOF. (This seems possible because SSL_write can - * also do reads.) - */ - if (n < 0 && SOCK_ERRNO != 0) - { - result_errno = SOCK_ERRNO; - if (result_errno == EPIPE || result_errno == ECONNRESET) - libpq_append_conn_error(conn, "server closed the connection unexpectedly\n" - "\tThis probably means the server terminated abnormally\n" - "\tbefore or while processing the request."); - else - libpq_append_conn_error(conn, "SSL SYSCALL error: %s", - SOCK_STRERROR(result_errno, - sebuf, sizeof(sebuf))); - } - else - { - libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected"); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - } - break; - case SSL_ERROR_SSL: - { - char *errm = SSLerrmessage(ecode); - - libpq_append_conn_error(conn, "SSL error: %s", errm); - SSLerrfree(errm); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - break; - } - case SSL_ERROR_ZERO_RETURN: - - /* - * Per OpenSSL documentation, this error code is only returned for - * a clean connection closure, so we should not report it as a - * server crash. - */ - libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly"); - result_errno = ECONNRESET; - n = -1; - break; - default: - libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err); - /* assume the connection is broken */ - result_errno = ECONNRESET; - n = -1; - break; - } - - /* ensure we return the intended errno to caller */ - SOCK_ERRNO_SET(result_errno); - - return n; -} - -#if defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO) -char * -pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len) -{ - X509 *peer_cert; - const EVP_MD *algo_type; - unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */ - unsigned int hash_size; - int algo_nid; - char *cert_hash; - - *len = 0; - - if (!conn->peer) - return NULL; - - peer_cert = conn->peer; - - /* - * Get the signature algorithm of the certificate to determine the hash - * algorithm to use for the result. Prefer X509_get_signature_info(), - * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures. - */ -#if HAVE_X509_GET_SIGNATURE_INFO - if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL)) -#else - if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert), - &algo_nid, NULL)) -#endif - { - libpq_append_conn_error(conn, "could not determine server certificate signature algorithm"); - return NULL; - } - - /* - * The TLS server's certificate bytes need to be hashed with SHA-256 if - * its signature algorithm is MD5 or SHA-1 as per RFC 5929 - * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else - * is used, the same hash as the signature algorithm is used. - */ - switch (algo_nid) - { - case NID_md5: - case NID_sha1: - algo_type = EVP_sha256(); - break; - default: - algo_type = EVP_get_digestbynid(algo_nid); - if (algo_type == NULL) - { - libpq_append_conn_error(conn, "could not find digest for NID %s", - OBJ_nid2sn(algo_nid)); - return NULL; - } - break; - } - - if (!X509_digest(peer_cert, algo_type, hash, &hash_size)) - { - libpq_append_conn_error(conn, "could not generate peer certificate hash"); - return NULL; - } - - /* save result */ - cert_hash = malloc(hash_size); - if (cert_hash == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return NULL; - } - memcpy(cert_hash, hash, hash_size); - *len = hash_size; - - return cert_hash; -} -#endif /* HAVE_X509_GET_SIGNATURE_NID */ - -/* ------------------------------------------------------------ */ -/* OpenSSL specific code */ -/* ------------------------------------------------------------ */ - -/* - * Certificate verification callback - * - * This callback allows us to log intermediate problems during - * verification, but there doesn't seem to be a clean way to get - * our PGconn * structure. So we can't log anything! - * - * This callback also allows us to override the default acceptance - * criteria (e.g., accepting self-signed or expired certs), but - * for now we accept the default checks. - */ -static int -verify_cb(int ok, X509_STORE_CTX *ctx) -{ - return ok; -} - -#ifdef HAVE_SSL_CTX_SET_CERT_CB -/* - * Certificate selection callback - * - * This callback lets us choose the client certificate we send to the server - * after seeing its CertificateRequest. We only support sending a single - * hard-coded certificate via sslcert, so we don't actually set any certificates - * here; we just use it to record whether or not the server has actually asked - * for one and whether we have one to send. - */ -static int -cert_cb(SSL *ssl, void *arg) -{ - PGconn *conn = arg; - - conn->ssl_cert_requested = true; - - /* Do we have a certificate loaded to send back? */ - if (SSL_get_certificate(ssl)) - conn->ssl_cert_sent = true; - - /* - * Tell OpenSSL that the callback succeeded; we're not required to - * actually make any changes to the SSL handle. - */ - return 1; -} -#endif - -/* - * OpenSSL-specific wrapper around - * pq_verify_peer_name_matches_certificate_name(), converting the ASN1_STRING - * into a plain C string. - */ -static int -openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry, - char **store_name) -{ - int len; - const unsigned char *namedata; - - /* Should not happen... */ - if (name_entry == NULL) - { - libpq_append_conn_error(conn, "SSL certificate's name entry is missing"); - return -1; - } - - /* - * GEN_DNS can be only IA5String, equivalent to US ASCII. - */ -#ifdef HAVE_ASN1_STRING_GET0_DATA - namedata = ASN1_STRING_get0_data(name_entry); -#else - namedata = ASN1_STRING_data(name_entry); -#endif - len = ASN1_STRING_length(name_entry); - - /* OK to cast from unsigned to plain char, since it's all ASCII. */ - return pq_verify_peer_name_matches_certificate_name(conn, (const char *) namedata, len, store_name); -} - -/* - * OpenSSL-specific wrapper around - * pq_verify_peer_name_matches_certificate_ip(), converting the - * ASN1_OCTET_STRING into a plain C string. - */ -static int -openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, - ASN1_OCTET_STRING *addr_entry, - char **store_name) -{ - int len; - const unsigned char *addrdata; - - /* Should not happen... */ - if (addr_entry == NULL) - { - libpq_append_conn_error(conn, "SSL certificate's address entry is missing"); - return -1; - } - - /* - * GEN_IPADD is an OCTET STRING containing an IP address in network byte - * order. - */ -#ifdef HAVE_ASN1_STRING_GET0_DATA - addrdata = ASN1_STRING_get0_data(addr_entry); -#else - addrdata = ASN1_STRING_data(addr_entry); -#endif - len = ASN1_STRING_length(addr_entry); - - return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name); -} - -static bool -is_ip_address(const char *host) -{ - struct in_addr dummy4; -#ifdef HAVE_INET_PTON - struct in6_addr dummy6; -#endif - - return inet_aton(host, &dummy4) -#ifdef HAVE_INET_PTON - || (inet_pton(AF_INET6, host, &dummy6) == 1) -#endif - ; -} - -/* - * Verify that the server certificate matches the hostname we connected to. - * - * The certificate's Common Name and Subject Alternative Names are considered. - */ -int -pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, - int *names_examined, - char **first_name) -{ - STACK_OF(GENERAL_NAME) * peer_san; - int i; - int rc = 0; - char *host = conn->connhost[conn->whichhost].host; - int host_type; - bool check_cn = true; - - Assert(host && host[0]); /* should be guaranteed by caller */ - - /* - * We try to match the NSS behavior here, which is a slight departure from - * the spec but seems to make more intuitive sense: - * - * If connhost contains a DNS name, and the certificate's SANs contain any - * dNSName entries, then we'll ignore the Subject Common Name entirely; - * otherwise, we fall back to checking the CN. (This behavior matches the - * RFC.) - * - * If connhost contains an IP address, and the SANs contain iPAddress - * entries, we again ignore the CN. Otherwise, we allow the CN to match, - * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A - * client MUST NOT seek a match for a reference identifier of CN-ID if the - * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any - * application-specific identifier types supported by the client.") - * - * NOTE: Prior versions of libpq did not consider iPAddress entries at - * all, so this new behavior might break a certificate that has different - * IP addresses in the Subject CN and the SANs. - */ - if (is_ip_address(host)) - host_type = GEN_IPADD; - else - host_type = GEN_DNS; - - /* - * First, get the Subject Alternative Names (SANs) from the certificate, - * and compare them against the originally given hostname. - */ - peer_san = (STACK_OF(GENERAL_NAME) *) - X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL); - - if (peer_san) - { - int san_len = sk_GENERAL_NAME_num(peer_san); - - for (i = 0; i < san_len; i++) - { - const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i); - char *alt_name = NULL; - - if (name->type == host_type) - { - /* - * This SAN is of the same type (IP or DNS) as our host name, - * so don't allow a fallback check of the CN. - */ - check_cn = false; - } - - if (name->type == GEN_DNS) - { - (*names_examined)++; - rc = openssl_verify_peer_name_matches_certificate_name(conn, - name->d.dNSName, - &alt_name); - } - else if (name->type == GEN_IPADD) - { - (*names_examined)++; - rc = openssl_verify_peer_name_matches_certificate_ip(conn, - name->d.iPAddress, - &alt_name); - } - - if (alt_name) - { - if (!*first_name) - *first_name = alt_name; - else - free(alt_name); - } - - if (rc != 0) - { - /* - * Either we hit an error or a match, and either way we should - * not fall back to the CN. - */ - check_cn = false; - break; - } - } - sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free); - } - - /* - * If there is no subjectAltName extension of the matching type, check the - * Common Name. - * - * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type - * dNSName is present, the CN must be ignored. We break this rule if host - * is an IP address; see the comment above.) - */ - if (check_cn) - { - X509_NAME *subject_name; - - subject_name = X509_get_subject_name(conn->peer); - if (subject_name != NULL) - { - int cn_index; - - cn_index = X509_NAME_get_index_by_NID(subject_name, - NID_commonName, -1); - if (cn_index >= 0) - { - char *common_name = NULL; - - (*names_examined)++; - rc = openssl_verify_peer_name_matches_certificate_name(conn, - X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)), - &common_name); - - if (common_name) - { - if (!*first_name) - *first_name = common_name; - else - free(common_name); - } - } - } - } - - return rc; -} - -#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) -/* - * Callback functions for OpenSSL internal locking. (OpenSSL 1.1.0 - * does its own locking, and doesn't need these anymore. The - * CRYPTO_lock() function was removed in 1.1.0, when the callbacks - * were made obsolete, so we assume that if CRYPTO_lock() exists, - * the callbacks are still required.) - */ - -static unsigned long -pq_threadidcallback(void) -{ - /* - * This is not standards-compliant. pthread_self() returns pthread_t, and - * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires - * it, so we have to do it. - */ - return (unsigned long) pthread_self(); -} - -static pthread_mutex_t *pq_lockarray; - -static void -pq_lockingcallback(int mode, int n, const char *file, int line) -{ - /* - * There's no way to report a mutex-primitive failure, so we just Assert - * in development builds, and ignore any errors otherwise. Fortunately - * this is all obsolete in modern OpenSSL. - */ - if (mode & CRYPTO_LOCK) - { - if (pthread_mutex_lock(&pq_lockarray[n])) - Assert(false); - } - else - { - if (pthread_mutex_unlock(&pq_lockarray[n])) - Assert(false); - } -} -#endif /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */ - -/* - * Initialize SSL library. - * - * In threadsafe mode, this includes setting up libcrypto callback functions - * to do thread locking. - * - * If the caller has told us (through PQinitOpenSSL) that he's taking care - * of libcrypto, we expect that callbacks are already set, and won't try to - * override it. - */ -int -pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto) -{ -#ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 - /* Also see similar code in fe-connect.c, default_threadlock() */ - if (ssl_config_mutex == NULL) - { - while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1) - /* loop, another thread own the lock */ ; - if (ssl_config_mutex == NULL) - { - if (pthread_mutex_init(&ssl_config_mutex, NULL)) - return -1; - } - InterlockedExchange(&win32_ssl_create_mutex, 0); - } -#endif - if (pthread_mutex_lock(&ssl_config_mutex)) - return -1; - -#ifdef HAVE_CRYPTO_LOCK - if (pq_init_crypto_lib) - { - /* - * If necessary, set up an array to hold locks for libcrypto. - * libcrypto will tell us how big to make this array. - */ - if (pq_lockarray == NULL) - { - int i; - - pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks()); - if (!pq_lockarray) - { - pthread_mutex_unlock(&ssl_config_mutex); - return -1; - } - for (i = 0; i < CRYPTO_num_locks(); i++) - { - if (pthread_mutex_init(&pq_lockarray[i], NULL)) - { - free(pq_lockarray); - pq_lockarray = NULL; - pthread_mutex_unlock(&ssl_config_mutex); - return -1; - } - } - } - - if (do_crypto && !conn->crypto_loaded) - { - if (crypto_open_connections++ == 0) - { - /* - * These are only required for threaded libcrypto - * applications, but make sure we don't stomp on them if - * they're already set. - */ - if (CRYPTO_get_id_callback() == NULL) - CRYPTO_set_id_callback(pq_threadidcallback); - if (CRYPTO_get_locking_callback() == NULL) - CRYPTO_set_locking_callback(pq_lockingcallback); - } - - conn->crypto_loaded = true; - } - } -#endif /* HAVE_CRYPTO_LOCK */ -#endif /* ENABLE_THREAD_SAFETY */ - - if (!ssl_lib_initialized && do_ssl) - { - if (pq_init_ssl_lib) - { -#ifdef HAVE_OPENSSL_INIT_SSL - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); -#else - OPENSSL_config(NULL); - SSL_library_init(); - SSL_load_error_strings(); -#endif - } - ssl_lib_initialized = true; - } - -#ifdef ENABLE_THREAD_SAFETY - pthread_mutex_unlock(&ssl_config_mutex); -#endif - return 0; -} - -/* - * This function is needed because if the libpq library is unloaded - * from the application, the callback functions will no longer exist when - * libcrypto is used by other parts of the system. For this reason, - * we unregister the callback functions when the last libpq - * connection is closed. (The same would apply for OpenSSL callbacks - * if we had any.) - * - * Callbacks are only set when we're compiled in threadsafe mode, so - * we only need to remove them in this case. They are also not needed - * with OpenSSL 1.1.0 anymore. - */ -static void -destroy_ssl_system(void) -{ -#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK) - /* Mutex is created in pgtls_init() */ - if (pthread_mutex_lock(&ssl_config_mutex)) - return; - - if (pq_init_crypto_lib && crypto_open_connections > 0) - --crypto_open_connections; - - if (pq_init_crypto_lib && crypto_open_connections == 0) - { - /* - * No connections left, unregister libcrypto callbacks, if no one - * registered different ones in the meantime. - */ - if (CRYPTO_get_locking_callback() == pq_lockingcallback) - CRYPTO_set_locking_callback(NULL); - if (CRYPTO_get_id_callback() == pq_threadidcallback) - CRYPTO_set_id_callback(NULL); - - /* - * We don't free the lock array. If we get another connection in this - * process, we will just re-use them with the existing mutexes. - * - * This means we leak a little memory on repeated load/unload of the - * library. - */ - } - - pthread_mutex_unlock(&ssl_config_mutex); -#endif -} - -/* - * Create per-connection SSL object, and load the client certificate, - * private key, and trusted CA certs. - * - * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage). - */ -static int -initialize_SSL(PGconn *conn) -{ - SSL_CTX *SSL_context; - struct stat buf; - char homedir[MAXPGPATH]; - char fnbuf[MAXPGPATH]; - char sebuf[PG_STRERROR_R_BUFLEN]; - bool have_homedir; - bool have_cert; - bool have_rootcert; - EVP_PKEY *pkey = NULL; - - /* - * We'll need the home directory if any of the relevant parameters are - * defaulted. If pqGetHomeDirectory fails, act as though none of the - * files could be found. - */ - if (!(conn->sslcert && strlen(conn->sslcert) > 0) || - !(conn->sslkey && strlen(conn->sslkey) > 0) || - !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) || - !((conn->sslcrl && strlen(conn->sslcrl) > 0) || - (conn->sslcrldir && strlen(conn->sslcrldir) > 0))) - have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir)); - else /* won't need it */ - have_homedir = false; - - /* - * Create a new SSL_CTX object. - * - * We used to share a single SSL_CTX between all connections, but it was - * complicated if connections used different certificates. So now we - * create a separate context for each connection, and accept the overhead. - */ - SSL_context = SSL_CTX_new(SSLv23_method()); - if (!SSL_context) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not create SSL context: %s", err); - SSLerrfree(err); - return -1; - } - - /* - * Delegate the client cert password prompt to the libpq wrapper callback - * if any is defined. - * - * If the application hasn't installed its own and the sslpassword - * parameter is non-null, we install ours now to make sure we supply - * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin. - * - * This will replace OpenSSL's default PEM_def_callback (which prompts on - * stdin), but we're only setting it for this SSL context so it's - * harmless. - */ - if (PQsslKeyPassHook - || (conn->sslpassword && strlen(conn->sslpassword) > 0)) - { - SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn); - } - -#ifdef HAVE_SSL_CTX_SET_CERT_CB - /* Set up a certificate selection callback. */ - SSL_CTX_set_cert_cb(SSL_context, cert_cb, conn); -#endif - - /* Disable old protocol versions */ - SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - - /* Set the minimum and maximum protocol versions if necessary */ - if (conn->ssl_min_protocol_version && - strlen(conn->ssl_min_protocol_version) != 0) - { - int ssl_min_ver; - - ssl_min_ver = ssl_protocol_version_to_openssl(conn->ssl_min_protocol_version); - - if (ssl_min_ver == -1) - { - libpq_append_conn_error(conn, "invalid value \"%s\" for minimum SSL protocol version", - conn->ssl_min_protocol_version); - SSL_CTX_free(SSL_context); - return -1; - } - - if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver)) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not set minimum SSL protocol version: %s", err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - } - - if (conn->ssl_max_protocol_version && - strlen(conn->ssl_max_protocol_version) != 0) - { - int ssl_max_ver; - - ssl_max_ver = ssl_protocol_version_to_openssl(conn->ssl_max_protocol_version); - - if (ssl_max_ver == -1) - { - libpq_append_conn_error(conn, "invalid value \"%s\" for maximum SSL protocol version", - conn->ssl_max_protocol_version); - SSL_CTX_free(SSL_context); - return -1; - } - - if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver)) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not set maximum SSL protocol version: %s", err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - } - - /* - * Disable OpenSSL's moving-write-buffer sanity check, because it causes - * unnecessary failures in nonblocking send cases. - */ - SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - - /* - * If the root cert file exists, load it so we can perform certificate - * verification. If sslmode is "verify-full" we will also do further - * verification after the connection has been completed. - */ - if (conn->sslrootcert && strlen(conn->sslrootcert) > 0) - strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf)); - else if (have_homedir) - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE); - else - fnbuf[0] = '\0'; - - if (strcmp(fnbuf, "system") == 0) - { - /* - * The "system" sentinel value indicates that we should load whatever - * root certificates are installed for use by OpenSSL; these locations - * differ by platform. Note that the default system locations may be - * further overridden by the SSL_CERT_DIR and SSL_CERT_FILE - * environment variables. - */ - if (SSL_CTX_set_default_verify_paths(SSL_context) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not load system root certificate paths: %s", - err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - have_rootcert = true; - } - else if (fnbuf[0] != '\0' && - stat(fnbuf, &buf) == 0) - { - X509_STORE *cvstore; - - if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not read root certificate file \"%s\": %s", - fnbuf, err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - - if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL) - { - char *fname = NULL; - char *dname = NULL; - - if (conn->sslcrl && strlen(conn->sslcrl) > 0) - fname = conn->sslcrl; - if (conn->sslcrldir && strlen(conn->sslcrldir) > 0) - dname = conn->sslcrldir; - - /* defaults to use the default CRL file */ - if (!fname && !dname && have_homedir) - { - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE); - fname = fnbuf; - } - - /* Set the flags to check against the complete CRL chain */ - if ((fname || dname) && - X509_STORE_load_locations(cvstore, fname, dname) == 1) - { - X509_STORE_set_flags(cvstore, - X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); - } - - /* if not found, silently ignore; we do not require CRL */ - ERR_clear_error(); - } - have_rootcert = true; - } - else - { - /* - * stat() failed; assume root file doesn't exist. If sslmode is - * verify-ca or verify-full, this is an error. Otherwise, continue - * without performing any server cert verification. - */ - if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */ - { - /* - * The only way to reach here with an empty filename is if - * pqGetHomeDirectory failed. That's a sufficiently unusual case - * that it seems worth having a specialized error message for it. - */ - if (fnbuf[0] == '\0') - libpq_append_conn_error(conn, "could not get home directory to locate root certificate file\n" - "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification."); - else - libpq_append_conn_error(conn, "root certificate file \"%s\" does not exist\n" - "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.", fnbuf); - SSL_CTX_free(SSL_context); - return -1; - } - have_rootcert = false; - } - - /* Read the client certificate file */ - if (conn->sslcert && strlen(conn->sslcert) > 0) - strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf)); - else if (have_homedir) - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE); - else - fnbuf[0] = '\0'; - - if (conn->sslcertmode[0] == 'd') /* disable */ - { - /* don't send a client cert even if we have one */ - have_cert = false; - } - else if (fnbuf[0] == '\0') - { - /* no home directory, proceed without a client cert */ - have_cert = false; - } - else if (stat(fnbuf, &buf) != 0) - { - /* - * If file is not present, just go on without a client cert; server - * might or might not accept the connection. Any other error, - * however, is grounds for complaint. - */ - if (errno != ENOENT && errno != ENOTDIR) - { - libpq_append_conn_error(conn, "could not open certificate file \"%s\": %s", - fnbuf, strerror_r(errno, sebuf, sizeof(sebuf))); - SSL_CTX_free(SSL_context); - return -1; - } - have_cert = false; - } - else - { - /* - * Cert file exists, so load it. Since OpenSSL doesn't provide the - * equivalent of "SSL_use_certificate_chain_file", we have to load it - * into the SSL context, rather than the SSL object. - */ - if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not read certificate file \"%s\": %s", - fnbuf, err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - - /* need to load the associated private key, too */ - have_cert = true; - } - - /* - * The SSL context is now loaded with the correct root and client - * certificates. Create a connection-specific SSL object. The private key - * is loaded directly into the SSL object. (We could load the private key - * into the context, too, but we have done it this way historically, and - * it doesn't really matter.) - */ - if (!(conn->ssl = SSL_new(SSL_context)) || - !SSL_set_app_data(conn->ssl, conn) || - !my_SSL_set_fd(conn, conn->sock)) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not establish SSL connection: %s", err); - SSLerrfree(err); - SSL_CTX_free(SSL_context); - return -1; - } - conn->ssl_in_use = true; - - /* - * SSL contexts are reference counted by OpenSSL. We can free it as soon - * as we have created the SSL object, and it will stick around for as long - * as it's actually needed. - */ - SSL_CTX_free(SSL_context); - SSL_context = NULL; - - /* - * Set Server Name Indication (SNI), if enabled by connection parameters. - * Per RFC 6066, do not set it if the host is a literal IP address (IPv4 - * or IPv6). - */ - if (conn->sslsni && conn->sslsni[0] == '1') - { - const char *host = conn->connhost[conn->whichhost].host; - - if (host && host[0] && - !(strspn(host, "0123456789.") == strlen(host) || - strchr(host, ':'))) - { - if (SSL_set_tlsext_host_name(conn->ssl, host) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not set SSL Server Name Indication (SNI): %s", err); - SSLerrfree(err); - return -1; - } - } - } - - /* - * Read the SSL key. If a key is specified, treat it as an engine:key - * combination if there is colon present - we don't support files with - * colon in the name. The exception is if the second character is a colon, - * in which case it can be a Windows filename with drive specification. - */ - if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0) - { -#ifdef USE_SSL_ENGINE - if (strchr(conn->sslkey, ':') -#ifdef WIN32 - && conn->sslkey[1] != ':' -#endif - ) - { - /* Colon, but not in second character, treat as engine:key */ - char *engine_str = strdup(conn->sslkey); - char *engine_colon; - - if (engine_str == NULL) - { - libpq_append_conn_error(conn, "out of memory"); - return -1; - } - - /* cannot return NULL because we already checked before strdup */ - engine_colon = strchr(engine_str, ':'); - - *engine_colon = '\0'; /* engine_str now has engine name */ - engine_colon++; /* engine_colon now has key name */ - - conn->engine = ENGINE_by_id(engine_str); - if (conn->engine == NULL) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not load SSL engine \"%s\": %s", - engine_str, err); - SSLerrfree(err); - free(engine_str); - return -1; - } - - if (ENGINE_init(conn->engine) == 0) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not initialize SSL engine \"%s\": %s", - engine_str, err); - SSLerrfree(err); - ENGINE_free(conn->engine); - conn->engine = NULL; - free(engine_str); - return -1; - } - - pkey = ENGINE_load_private_key(conn->engine, engine_colon, - NULL, NULL); - if (pkey == NULL) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not read private SSL key \"%s\" from engine \"%s\": %s", - engine_colon, engine_str, err); - SSLerrfree(err); - ENGINE_finish(conn->engine); - ENGINE_free(conn->engine); - conn->engine = NULL; - free(engine_str); - return -1; - } - if (SSL_use_PrivateKey(conn->ssl, pkey) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "could not load private SSL key \"%s\" from engine \"%s\": %s", - engine_colon, engine_str, err); - SSLerrfree(err); - ENGINE_finish(conn->engine); - ENGINE_free(conn->engine); - conn->engine = NULL; - free(engine_str); - return -1; - } - - free(engine_str); - - fnbuf[0] = '\0'; /* indicate we're not going to load from a - * file */ - } - else -#endif /* USE_SSL_ENGINE */ - { - /* PGSSLKEY is not an engine, treat it as a filename */ - strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf)); - } - } - else if (have_homedir) - { - /* No PGSSLKEY specified, load default file */ - snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE); - } - else - fnbuf[0] = '\0'; - - if (have_cert && fnbuf[0] != '\0') - { - /* read the client key from file */ - - if (stat(fnbuf, &buf) != 0) - { - if (errno == ENOENT) - libpq_append_conn_error(conn, "certificate present, but not private key file \"%s\"", - fnbuf); - else - libpq_append_conn_error(conn, "could not stat private key file \"%s\": %m", - fnbuf); - return -1; - } - - /* Key file must be a regular file */ - if (!S_ISREG(buf.st_mode)) - { - libpq_append_conn_error(conn, "private key file \"%s\" is not a regular file", - fnbuf); - return -1; - } - - /* - * Refuse to load world-readable key files. We accept root-owned - * files with mode 0640 or less, so that we can access system-wide - * certificates if we have a supplementary group membership that - * allows us to read 'em. For files with non-root ownership, require - * mode 0600 or less. We need not check the file's ownership exactly; - * if we're able to read it despite it having such restrictive - * permissions, it must have the right ownership. - * - * Note: be very careful about tightening these rules. Some people - * expect, for example, that a client process running as root should - * be able to use a non-root-owned key file. - * - * Note that roughly similar checks are performed in - * src/backend/libpq/be-secure-common.c so any changes here may need - * to be made there as well. However, this code caters for the case - * of current user == root, while that code does not. - * - * Ideally we would do similar permissions checks on Windows, but it - * is not clear how that would work since Unix-style permissions may - * not be available. - */ -#if !defined(WIN32) && !defined(__CYGWIN__) - if (buf.st_uid == 0 ? - buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO) : - buf.st_mode & (S_IRWXG | S_IRWXO)) - { - libpq_append_conn_error(conn, - "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root", - fnbuf); - return -1; - } -#endif - - if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - /* - * We'll try to load the file in DER (binary ASN.1) format, and if - * that fails too, report the original error. This could mask - * issues where there's something wrong with a DER-format cert, - * but we'd have to duplicate openssl's format detection to be - * smarter than this. We can't just probe for a leading -----BEGIN - * because PEM can have leading non-matching lines and blanks. - * OpenSSL doesn't expose its get_name(...) and its PEM routines - * don't differentiate between failure modes in enough detail to - * let us tell the difference between "not PEM, try DER" and - * "wrong password". - */ - if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1) - { - libpq_append_conn_error(conn, "could not load private key file \"%s\": %s", - fnbuf, err); - SSLerrfree(err); - return -1; - } - - SSLerrfree(err); - } - } - - /* verify that the cert and key go together */ - if (have_cert && - SSL_check_private_key(conn->ssl) != 1) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "certificate does not match private key file \"%s\": %s", - fnbuf, err); - SSLerrfree(err); - return -1; - } - - /* - * If a root cert was loaded, also set our certificate verification - * callback. - */ - if (have_rootcert) - SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb); - - /* - * Set compression option if necessary. - */ - if (conn->sslcompression && conn->sslcompression[0] == '0') - SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION); - else - SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION); - - return 0; -} - -/* - * Attempt to negotiate SSL connection. - */ -static PostgresPollingStatusType -open_client_SSL(PGconn *conn) -{ - int r; - - SOCK_ERRNO_SET(0); - ERR_clear_error(); - r = SSL_connect(conn->ssl); - if (r <= 0) - { - int save_errno = SOCK_ERRNO; - int err = SSL_get_error(conn->ssl, r); - unsigned long ecode; - - ecode = ERR_get_error(); - switch (err) - { - case SSL_ERROR_WANT_READ: - return PGRES_POLLING_READING; - - case SSL_ERROR_WANT_WRITE: - return PGRES_POLLING_WRITING; - - case SSL_ERROR_SYSCALL: - { - char sebuf[PG_STRERROR_R_BUFLEN]; - unsigned long vcode; - - vcode = SSL_get_verify_result(conn->ssl); - - /* - * If we get an X509 error here for failing to load the - * local issuer cert, without an error in the socket layer - * it means that verification failed due to a missing - * system CA pool without it being a protocol error. We - * inspect the sslrootcert setting to ensure that the user - * was using the system CA pool. For other errors, log - * them using the normal SYSCALL logging. - */ - if (save_errno == 0 && - vcode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY && - strcmp(conn->sslrootcert, "system") == 0) - libpq_append_conn_error(conn, "SSL error: certificate verify failed: %s", - X509_verify_cert_error_string(vcode)); - else if (r == -1 && save_errno != 0) - libpq_append_conn_error(conn, "SSL SYSCALL error: %s", - SOCK_STRERROR(save_errno, sebuf, sizeof(sebuf))); - else - libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected"); - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - case SSL_ERROR_SSL: - { - char *err = SSLerrmessage(ecode); - - libpq_append_conn_error(conn, "SSL error: %s", err); - SSLerrfree(err); - switch (ERR_GET_REASON(ecode)) - { - /* - * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and - * TLSV1_ALERT_PROTOCOL_VERSION have been observed - * when trying to communicate with an old OpenSSL - * library, or when the client and server specify - * disjoint protocol ranges. - * NO_PROTOCOLS_AVAILABLE occurs if there's a - * local misconfiguration (which can happen - * despite our checks, if openssl.cnf injects a - * limit we didn't account for). It's not very - * clear what would make OpenSSL return the other - * codes listed here, but a hint about protocol - * versions seems like it's appropriate for all. - */ - case SSL_R_NO_PROTOCOLS_AVAILABLE: - case SSL_R_UNSUPPORTED_PROTOCOL: - case SSL_R_BAD_PROTOCOL_VERSION_NUMBER: - case SSL_R_UNKNOWN_PROTOCOL: - case SSL_R_UNKNOWN_SSL_VERSION: - case SSL_R_UNSUPPORTED_SSL_VERSION: - case SSL_R_WRONG_SSL_VERSION: - case SSL_R_WRONG_VERSION_NUMBER: - case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION: -#ifdef SSL_R_VERSION_TOO_HIGH - case SSL_R_VERSION_TOO_HIGH: - case SSL_R_VERSION_TOO_LOW: -#endif - libpq_append_conn_error(conn, "This may indicate that the server does not support any SSL protocol version between %s and %s.", - conn->ssl_min_protocol_version ? - conn->ssl_min_protocol_version : - MIN_OPENSSL_TLS_VERSION, - conn->ssl_max_protocol_version ? - conn->ssl_max_protocol_version : - MAX_OPENSSL_TLS_VERSION); - break; - default: - break; - } - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - - default: - libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err); - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - } - - /* - * We already checked the server certificate in initialize_SSL() using - * SSL_CTX_set_verify(), if root.crt exists. - */ - - /* get server certificate */ - conn->peer = SSL_get_peer_certificate(conn->ssl); - if (conn->peer == NULL) - { - char *err = SSLerrmessage(ERR_get_error()); - - libpq_append_conn_error(conn, "certificate could not be obtained: %s", err); - SSLerrfree(err); - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - - if (!pq_verify_peer_name_matches_certificate(conn)) - { - pgtls_close(conn); - return PGRES_POLLING_FAILED; - } - - /* SSL handshake is complete */ - return PGRES_POLLING_OK; -} - -void -pgtls_close(PGconn *conn) -{ - bool destroy_needed = false; - - if (conn->ssl_in_use) - { - if (conn->ssl) - { - /* - * We can't destroy everything SSL-related here due to the - * possible later calls to OpenSSL routines which may need our - * thread callbacks, so set a flag here and check at the end. - */ - - if (SSL_shutdown(conn->ssl) < 0) { - // Pop an error and ignore it. We might have already printed one - // and SSL_shutdown just yields logic warnings as errors. - ERR_get_error(); - } - SSL_free(conn->ssl); - conn->ssl = NULL; - conn->ssl_in_use = false; - - destroy_needed = true; - } - - if (conn->peer) - { - X509_free(conn->peer); - conn->peer = NULL; - } - -#ifdef USE_SSL_ENGINE - if (conn->engine) - { - ENGINE_finish(conn->engine); - ENGINE_free(conn->engine); - conn->engine = NULL; - } -#endif - } - else - { - /* - * In the non-SSL case, just remove the crypto callbacks if the - * connection has then loaded. This code path has no dependency on - * any pending SSL calls. - */ - if (conn->crypto_loaded) - destroy_needed = true; - } - - /* - * This will remove our crypto locking hooks if this is the last - * connection using libcrypto which means we must wait to call it until - * after all the potential SSL calls have been made, otherwise we can end - * up with a race condition and possible deadlocks. - * - * See comments above destroy_ssl_system(). - */ - if (destroy_needed) - { - destroy_ssl_system(); - conn->crypto_loaded = false; - } -} - - -/* - * Obtain reason string for passed SSL errcode - * - * ERR_get_error() is used by caller to get errcode to pass here. - * - * Some caution is needed here since ERR_reason_error_string will - * return NULL if it doesn't recognize the error code. We don't - * want to return NULL ever. - */ -static char ssl_nomem[] = "out of memory allocating error description"; - -#define SSL_ERR_LEN 128 - -static char * -SSLerrmessage(unsigned long ecode) -{ - const char *errreason; - char *errbuf; - - errbuf = malloc(SSL_ERR_LEN); - if (!errbuf) - return ssl_nomem; - if (ecode == 0) - { - snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported")); - return errbuf; - } - errreason = ERR_reason_error_string(ecode); - if (errreason != NULL) - { - strlcpy(errbuf, errreason, SSL_ERR_LEN); - return errbuf; - } - snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode); - return errbuf; -} - -static void -SSLerrfree(char *buf) -{ - if (buf != ssl_nomem) - free(buf); -} - -/* ------------------------------------------------------------ */ -/* SSL information functions */ -/* ------------------------------------------------------------ */ - -/* - * Return pointer to OpenSSL object. - */ -void * -PQgetssl(PGconn *conn) -{ - if (!conn) - return NULL; - return conn->ssl; -} - -void * -PQsslStruct(PGconn *conn, const char *struct_name) -{ - if (!conn) - return NULL; - if (strcmp(struct_name, "OpenSSL") == 0) - return conn->ssl; - return NULL; -} - -const char *const * -PQsslAttributeNames(PGconn *conn) -{ - static const char *const openssl_attrs[] = { - "library", - "key_bits", - "cipher", - "compression", - "protocol", - NULL - }; - static const char *const empty_attrs[] = {NULL}; - - if (!conn) - { - /* Return attributes of default SSL library */ - return openssl_attrs; - } - - /* No attrs for unencrypted connection */ - if (conn->ssl == NULL) - return empty_attrs; - - return openssl_attrs; -} - -const char * -PQsslAttribute(PGconn *conn, const char *attribute_name) -{ - if (!conn) - { - /* PQsslAttribute(NULL, "library") reports the default SSL library */ - if (strcmp(attribute_name, "library") == 0) - return "OpenSSL"; - return NULL; - } - - /* All attributes read as NULL for a non-encrypted connection */ - if (conn->ssl == NULL) - return NULL; - - if (strcmp(attribute_name, "library") == 0) - return "OpenSSL"; - - if (strcmp(attribute_name, "key_bits") == 0) - { - static char sslbits_str[12]; - int sslbits; - - SSL_get_cipher_bits(conn->ssl, &sslbits); - snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits); - return sslbits_str; - } - - if (strcmp(attribute_name, "cipher") == 0) - return SSL_get_cipher(conn->ssl); - - if (strcmp(attribute_name, "compression") == 0) - return SSL_get_current_compression(conn->ssl) ? "on" : "off"; - - if (strcmp(attribute_name, "protocol") == 0) - return SSL_get_version(conn->ssl); - - return NULL; /* unknown attribute */ -} - -/* - * Private substitute BIO: this does the sending and receiving using - * pqsecure_raw_write() and pqsecure_raw_read() instead, to allow those - * functions to disable SIGPIPE and give better error messages on I/O errors. - * - * These functions are closely modelled on the standard socket BIO in OpenSSL; - * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c. - * XXX OpenSSL 1.0.1e considers many more errcodes than just EINTR as reasons - * to retry; do we need to adopt their logic for that? - */ - -/* protected by ssl_config_mutex */ -static BIO_METHOD *my_bio_methods; - -static int -my_sock_read(BIO *h, char *buf, int size) -{ - int res; - - res = pqsecure_raw_read((PGconn *) BIO_get_app_data(h), buf, size); - BIO_clear_retry_flags(h); - if (res < 0) - { - /* If we were interrupted, tell caller to retry */ - switch (SOCK_ERRNO) - { -#ifdef EAGAIN - case EAGAIN: -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: -#endif - case EINTR: - BIO_set_retry_read(h); - break; - - default: - break; - } - } - - return res; -} - -static int -my_sock_write(BIO *h, const char *buf, int size) -{ - int res; - - res = pqsecure_raw_write((PGconn *) BIO_get_app_data(h), buf, size); - BIO_clear_retry_flags(h); - if (res < 0) - { - /* If we were interrupted, tell caller to retry */ - switch (SOCK_ERRNO) - { -#ifdef EAGAIN - case EAGAIN: -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: -#endif - case EINTR: - BIO_set_retry_write(h); - break; - - default: - break; - } - } - - return res; -} - -static BIO_METHOD * -my_BIO_s_socket(void) -{ - BIO_METHOD *res; - -#ifdef ENABLE_THREAD_SAFETY - if (pthread_mutex_lock(&ssl_config_mutex)) - return NULL; -#endif - - res = my_bio_methods; - - if (!my_bio_methods) - { - BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket(); -#ifdef HAVE_BIO_METH_NEW - int my_bio_index; - - my_bio_index = BIO_get_new_index(); - if (my_bio_index == -1) - goto err; - my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK); - res = BIO_meth_new(my_bio_index, "libpq socket"); - if (!res) - goto err; - - /* - * As of this writing, these functions never fail. But check anyway, - * like OpenSSL's own examples do. - */ - if (!BIO_meth_set_write(res, my_sock_write) || - !BIO_meth_set_read(res, my_sock_read) || - !BIO_meth_set_gets(res, BIO_meth_get_gets(biom)) || - !BIO_meth_set_puts(res, BIO_meth_get_puts(biom)) || - !BIO_meth_set_ctrl(res, BIO_meth_get_ctrl(biom)) || - !BIO_meth_set_create(res, BIO_meth_get_create(biom)) || - !BIO_meth_set_destroy(res, BIO_meth_get_destroy(biom)) || - !BIO_meth_set_callback_ctrl(res, BIO_meth_get_callback_ctrl(biom))) - { - goto err; - } -#else - res = malloc(sizeof(BIO_METHOD)); - if (!res) - goto err; - memcpy(res, biom, sizeof(BIO_METHOD)); - res->bread = my_sock_read; - res->bwrite = my_sock_write; -#endif - } - - my_bio_methods = res; - -#ifdef ENABLE_THREAD_SAFETY - pthread_mutex_unlock(&ssl_config_mutex); -#endif - - return res; - -err: -#ifdef HAVE_BIO_METH_NEW - if (res) - BIO_meth_free(res); -#else - if (res) - free(res); -#endif - -#ifdef ENABLE_THREAD_SAFETY - pthread_mutex_unlock(&ssl_config_mutex); -#endif - return NULL; -} - -/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */ -static int -my_SSL_set_fd(PGconn *conn, int fd) -{ - int ret = 0; - BIO *bio; - BIO_METHOD *bio_method; - - bio_method = my_BIO_s_socket(); - if (bio_method == NULL) - { - SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); - goto err; - } - bio = BIO_new(bio_method); - if (bio == NULL) - { - SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_app_data(bio, conn); - - SSL_set_bio(conn->ssl, bio, bio); - BIO_set_fd(bio, fd, BIO_NOCLOSE); - ret = 1; -err: - return ret; -} - -/* - * This is the default handler to return a client cert password from - * conn->sslpassword. Apps may install it explicitly if they want to - * prevent openssl from ever prompting on stdin. - */ -int -PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn) -{ - if (conn && conn->sslpassword) - { - if (strlen(conn->sslpassword) + 1 > size) - fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n")); - strncpy(buf, conn->sslpassword, size); - buf[size - 1] = '\0'; - return strlen(buf); - } - else - { - buf[0] = '\0'; - return 0; - } -} - -PQsslKeyPassHook_OpenSSL_type -PQgetSSLKeyPassHook_OpenSSL(void) -{ - return PQsslKeyPassHook; -} - -void -PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook) -{ - PQsslKeyPassHook = hook; -} - -/* - * Supply a password to decrypt a client certificate. - * - * This must match OpenSSL type pem_password_cb. - */ -static int -PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata) -{ - PGconn *conn = userdata; - - if (PQsslKeyPassHook) - return PQsslKeyPassHook(buf, size, conn); - else - return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn); -} - -/* - * Convert TLS protocol version string to OpenSSL values - * - * If a version is passed that is not supported by the current OpenSSL version, - * then we return -1. If a non-negative value is returned, subsequent code can - * assume it is working with a supported version. - * - * Note: this is rather similar to the backend routine in be-secure-openssl.c, - * so make sure to update both routines if changing this one. - */ -static int -ssl_protocol_version_to_openssl(const char *protocol) -{ - if (pg_strcasecmp("TLSv1", protocol) == 0) - return TLS1_VERSION; - -#ifdef TLS1_1_VERSION - if (pg_strcasecmp("TLSv1.1", protocol) == 0) - return TLS1_1_VERSION; -#endif - -#ifdef TLS1_2_VERSION - if (pg_strcasecmp("TLSv1.2", protocol) == 0) - return TLS1_2_VERSION; -#endif - -#ifdef TLS1_3_VERSION - if (pg_strcasecmp("TLSv1.3", protocol) == 0) - return TLS1_3_VERSION; -#endif - - return -1; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-secure.c b/contrib/libs/libpq/src/interfaces/libpq/fe-secure.c deleted file mode 100644 index 8444f19f08..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-secure.c +++ /dev/null @@ -1,618 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-secure.c - * functions related to setting up a secure connection to the backend. - * Secure connections are expected to provide confidentiality, - * message integrity and endpoint authentication. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/fe-secure.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <signal.h> -#include <fcntl.h> -#include <ctype.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <sys/socket.h> -#include <unistd.h> -#include <netdb.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <arpa/inet.h> -#endif - -#include <sys/stat.h> - -#ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 -#include "pthread-win32.h" -#else -#include <pthread.h> -#endif -#endif - -#include "fe-auth.h" -#include "libpq-fe.h" -#include "libpq-int.h" - -/* - * Macros to handle disabling and then restoring the state of SIGPIPE handling. - * On Windows, these are all no-ops since there's no SIGPIPEs. - */ - -#ifndef WIN32 - -#define SIGPIPE_MASKED(conn) ((conn)->sigpipe_so || (conn)->sigpipe_flag) - -#ifdef ENABLE_THREAD_SAFETY - -struct sigpipe_info -{ - sigset_t oldsigmask; - bool sigpipe_pending; - bool got_epipe; -}; - -#define DECLARE_SIGPIPE_INFO(spinfo) struct sigpipe_info spinfo - -#define DISABLE_SIGPIPE(conn, spinfo, failaction) \ - do { \ - (spinfo).got_epipe = false; \ - if (!SIGPIPE_MASKED(conn)) \ - { \ - if (pq_block_sigpipe(&(spinfo).oldsigmask, \ - &(spinfo).sigpipe_pending) < 0) \ - failaction; \ - } \ - } while (0) - -#define REMEMBER_EPIPE(spinfo, cond) \ - do { \ - if (cond) \ - (spinfo).got_epipe = true; \ - } while (0) - -#define RESTORE_SIGPIPE(conn, spinfo) \ - do { \ - if (!SIGPIPE_MASKED(conn)) \ - pq_reset_sigpipe(&(spinfo).oldsigmask, (spinfo).sigpipe_pending, \ - (spinfo).got_epipe); \ - } while (0) -#else /* !ENABLE_THREAD_SAFETY */ - -#define DECLARE_SIGPIPE_INFO(spinfo) pqsigfunc spinfo = NULL - -#define DISABLE_SIGPIPE(conn, spinfo, failaction) \ - do { \ - if (!SIGPIPE_MASKED(conn)) \ - spinfo = pqsignal(SIGPIPE, SIG_IGN); \ - } while (0) - -#define REMEMBER_EPIPE(spinfo, cond) - -#define RESTORE_SIGPIPE(conn, spinfo) \ - do { \ - if (!SIGPIPE_MASKED(conn)) \ - pqsignal(SIGPIPE, spinfo); \ - } while (0) -#endif /* ENABLE_THREAD_SAFETY */ -#else /* WIN32 */ - -#define DECLARE_SIGPIPE_INFO(spinfo) -#define DISABLE_SIGPIPE(conn, spinfo, failaction) -#define REMEMBER_EPIPE(spinfo, cond) -#define RESTORE_SIGPIPE(conn, spinfo) -#endif /* WIN32 */ - -/* ------------------------------------------------------------ */ -/* Procedures common to all secure sessions */ -/* ------------------------------------------------------------ */ - - -int -PQsslInUse(PGconn *conn) -{ - if (!conn) - return 0; - return conn->ssl_in_use; -} - -/* - * Exported function to allow application to tell us it's already - * initialized OpenSSL. - */ -void -PQinitSSL(int do_init) -{ -#ifdef USE_SSL - pgtls_init_library(do_init, do_init); -#endif -} - -/* - * Exported function to allow application to tell us it's already - * initialized OpenSSL and/or libcrypto. - */ -void -PQinitOpenSSL(int do_ssl, int do_crypto) -{ -#ifdef USE_SSL - pgtls_init_library(do_ssl, do_crypto); -#endif -} - -/* - * Initialize global SSL context - */ -int -pqsecure_initialize(PGconn *conn, bool do_ssl, bool do_crypto) -{ - int r = 0; - -#ifdef USE_SSL - r = pgtls_init(conn, do_ssl, do_crypto); -#endif - - return r; -} - -/* - * Begin or continue negotiating a secure session. - */ -PostgresPollingStatusType -pqsecure_open_client(PGconn *conn) -{ -#ifdef USE_SSL - return pgtls_open_client(conn); -#else - /* shouldn't get here */ - return PGRES_POLLING_FAILED; -#endif -} - -/* - * Close secure session. - */ -void -pqsecure_close(PGconn *conn) -{ -#ifdef USE_SSL - pgtls_close(conn); -#endif -} - -/* - * Read data from a secure connection. - * - * On failure, this function is responsible for appending a suitable message - * to conn->errorMessage. The caller must still inspect errno, but only - * to determine whether to continue/retry after error. - */ -ssize_t -pqsecure_read(PGconn *conn, void *ptr, size_t len) -{ - ssize_t n; - -#ifdef USE_SSL - if (conn->ssl_in_use) - { - n = pgtls_read(conn, ptr, len); - } - else -#endif -#ifdef ENABLE_GSS - if (conn->gssenc) - { - n = pg_GSS_read(conn, ptr, len); - } - else -#endif - { - n = pqsecure_raw_read(conn, ptr, len); - } - - return n; -} - -ssize_t -pqsecure_raw_read(PGconn *conn, void *ptr, size_t len) -{ - ssize_t n; - int result_errno = 0; - char sebuf[PG_STRERROR_R_BUFLEN]; - - SOCK_ERRNO_SET(0); - - n = recv(conn->sock, ptr, len, 0); - - if (n < 0) - { - result_errno = SOCK_ERRNO; - - /* Set error message if appropriate */ - switch (result_errno) - { -#ifdef EAGAIN - case EAGAIN: -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: -#endif - case EINTR: - /* no error message, caller is expected to retry */ - break; - - case EPIPE: - case ECONNRESET: - libpq_append_conn_error(conn, "server closed the connection unexpectedly\n" - "\tThis probably means the server terminated abnormally\n" - "\tbefore or while processing the request."); - break; - - case 0: - /* If errno didn't get set, treat it as regular EOF */ - n = 0; - break; - - default: - libpq_append_conn_error(conn, "could not receive data from server: %s", - SOCK_STRERROR(result_errno, - sebuf, sizeof(sebuf))); - break; - } - } - - /* ensure we return the intended errno to caller */ - SOCK_ERRNO_SET(result_errno); - - return n; -} - -/* - * Write data to a secure connection. - * - * Returns the number of bytes written, or a negative value (with errno - * set) upon failure. The write count could be less than requested. - * - * Note that socket-level hard failures are masked from the caller, - * instead setting conn->write_failed and storing an error message - * in conn->write_err_msg; see pqsecure_raw_write. This allows us to - * postpone reporting of write failures until we're sure no error - * message is available from the server. - * - * However, errors detected in the SSL or GSS management level are reported - * via a negative result, with message appended to conn->errorMessage. - * It's frequently unclear whether such errors should be considered read or - * write errors, so we don't attempt to postpone reporting them. - * - * The caller must still inspect errno upon failure, but only to determine - * whether to continue/retry; a message has been saved someplace in any case. - */ -ssize_t -pqsecure_write(PGconn *conn, const void *ptr, size_t len) -{ - ssize_t n; - -#ifdef USE_SSL - if (conn->ssl_in_use) - { - n = pgtls_write(conn, ptr, len); - } - else -#endif -#ifdef ENABLE_GSS - if (conn->gssenc) - { - n = pg_GSS_write(conn, ptr, len); - } - else -#endif - { - n = pqsecure_raw_write(conn, ptr, len); - } - - return n; -} - -/* - * Low-level implementation of pqsecure_write. - * - * This is used directly for an unencrypted connection. For encrypted - * connections, this does the physical I/O on behalf of pgtls_write or - * pg_GSS_write. - * - * This function reports failure (i.e., returns a negative result) only - * for retryable errors such as EINTR. Looping for such cases is to be - * handled at some outer level, maybe all the way up to the application. - * For hard failures, we set conn->write_failed and store an error message - * in conn->write_err_msg, but then claim to have written the data anyway. - * This is because we don't want to report write failures so long as there - * is a possibility of reading from the server and getting an error message - * that could explain why the connection dropped. Many TCP stacks have - * race conditions such that a write failure may or may not be reported - * before all incoming data has been read. - * - * Note that this error behavior happens below the SSL management level when - * we are using SSL. That's because at least some versions of OpenSSL are - * too quick to report a write failure when there's still a possibility to - * get a more useful error from the server. - */ -ssize_t -pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len) -{ - ssize_t n; - int flags = 0; - int result_errno = 0; - char msgbuf[1024]; - char sebuf[PG_STRERROR_R_BUFLEN]; - - DECLARE_SIGPIPE_INFO(spinfo); - - /* - * If we already had a write failure, we will never again try to send data - * on that connection. Even if the kernel would let us, we've probably - * lost message boundary sync with the server. conn->write_failed - * therefore persists until the connection is reset, and we just discard - * all data presented to be written. - */ - if (conn->write_failed) - return len; - -#ifdef MSG_NOSIGNAL - if (conn->sigpipe_flag) - flags |= MSG_NOSIGNAL; - -retry_masked: -#endif /* MSG_NOSIGNAL */ - - DISABLE_SIGPIPE(conn, spinfo, return -1); - - n = send(conn->sock, ptr, len, flags); - - if (n < 0) - { - result_errno = SOCK_ERRNO; - - /* - * If we see an EINVAL, it may be because MSG_NOSIGNAL isn't available - * on this machine. So, clear sigpipe_flag so we don't try the flag - * again, and retry the send(). - */ -#ifdef MSG_NOSIGNAL - if (flags != 0 && result_errno == EINVAL) - { - conn->sigpipe_flag = false; - flags = 0; - goto retry_masked; - } -#endif /* MSG_NOSIGNAL */ - - /* Set error message if appropriate */ - switch (result_errno) - { -#ifdef EAGAIN - case EAGAIN: -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: -#endif - case EINTR: - /* no error message, caller is expected to retry */ - break; - - case EPIPE: - /* Set flag for EPIPE */ - REMEMBER_EPIPE(spinfo, true); - - /* FALL THRU */ - - case ECONNRESET: - conn->write_failed = true; - /* Store error message in conn->write_err_msg, if possible */ - /* (strdup failure is OK, we'll cope later) */ - snprintf(msgbuf, sizeof(msgbuf), - libpq_gettext("server closed the connection unexpectedly\n" - "\tThis probably means the server terminated abnormally\n" - "\tbefore or while processing the request.")); - /* keep newline out of translated string */ - strlcat(msgbuf, "\n", sizeof(msgbuf)); - conn->write_err_msg = strdup(msgbuf); - /* Now claim the write succeeded */ - n = len; - break; - - default: - conn->write_failed = true; - /* Store error message in conn->write_err_msg, if possible */ - /* (strdup failure is OK, we'll cope later) */ - snprintf(msgbuf, sizeof(msgbuf), - libpq_gettext("could not send data to server: %s"), - SOCK_STRERROR(result_errno, - sebuf, sizeof(sebuf))); - /* keep newline out of translated string */ - strlcat(msgbuf, "\n", sizeof(msgbuf)); - conn->write_err_msg = strdup(msgbuf); - /* Now claim the write succeeded */ - n = len; - break; - } - } - - RESTORE_SIGPIPE(conn, spinfo); - - /* ensure we return the intended errno to caller */ - SOCK_ERRNO_SET(result_errno); - - return n; -} - -/* Dummy versions of SSL info functions, when built without SSL support */ -#ifndef USE_SSL - -void * -PQgetssl(PGconn *conn) -{ - return NULL; -} - -void * -PQsslStruct(PGconn *conn, const char *struct_name) -{ - return NULL; -} - -const char * -PQsslAttribute(PGconn *conn, const char *attribute_name) -{ - return NULL; -} - -const char *const * -PQsslAttributeNames(PGconn *conn) -{ - static const char *const result[] = {NULL}; - - return result; -} -#endif /* USE_SSL */ - -/* - * Dummy versions of OpenSSL key password hook functions, when built without - * OpenSSL. - */ -#ifndef USE_OPENSSL - -PQsslKeyPassHook_OpenSSL_type -PQgetSSLKeyPassHook_OpenSSL(void) -{ - return NULL; -} - -void -PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook) -{ - return; -} - -int -PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn) -{ - return 0; -} -#endif /* USE_OPENSSL */ - -/* Dummy version of GSSAPI information functions, when built without GSS support */ -#ifndef ENABLE_GSS - -void * -PQgetgssctx(PGconn *conn) -{ - return NULL; -} - -int -PQgssEncInUse(PGconn *conn) -{ - return 0; -} - -#endif /* ENABLE_GSS */ - - -#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) - -/* - * Block SIGPIPE for this thread. This prevents send()/write() from exiting - * the application. - */ -int -pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending) -{ - sigset_t sigpipe_sigset; - sigset_t sigset; - - sigemptyset(&sigpipe_sigset); - sigaddset(&sigpipe_sigset, SIGPIPE); - - /* Block SIGPIPE and save previous mask for later reset */ - SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset)); - if (SOCK_ERRNO) - return -1; - - /* We can have a pending SIGPIPE only if it was blocked before */ - if (sigismember(osigset, SIGPIPE)) - { - /* Is there a pending SIGPIPE? */ - if (sigpending(&sigset) != 0) - return -1; - - if (sigismember(&sigset, SIGPIPE)) - *sigpipe_pending = true; - else - *sigpipe_pending = false; - } - else - *sigpipe_pending = false; - - return 0; -} - -/* - * Discard any pending SIGPIPE and reset the signal mask. - * - * Note: we are effectively assuming here that the C library doesn't queue - * up multiple SIGPIPE events. If it did, then we'd accidentally leave - * ours in the queue when an event was already pending and we got another. - * As long as it doesn't queue multiple events, we're OK because the caller - * can't tell the difference. - * - * The caller should say got_epipe = false if it is certain that it - * didn't get an EPIPE error; in that case we'll skip the clear operation - * and things are definitely OK, queuing or no. If it got one or might have - * gotten one, pass got_epipe = true. - * - * We do not want this to change errno, since if it did that could lose - * the error code from a preceding send(). We essentially assume that if - * we were able to do pq_block_sigpipe(), this can't fail. - */ -void -pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe) -{ - int save_errno = SOCK_ERRNO; - int signo; - sigset_t sigset; - - /* Clear SIGPIPE only if none was pending */ - if (got_epipe && !sigpipe_pending) - { - if (sigpending(&sigset) == 0 && - sigismember(&sigset, SIGPIPE)) - { - sigset_t sigpipe_sigset; - - sigemptyset(&sigpipe_sigset); - sigaddset(&sigpipe_sigset, SIGPIPE); - - sigwait(&sigpipe_sigset, &signo); - } - } - - /* Restore saved block mask */ - pthread_sigmask(SIG_SETMASK, osigset, NULL); - - SOCK_ERRNO_SET(save_errno); -} - -#endif /* ENABLE_THREAD_SAFETY && !WIN32 */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/fe-trace.c b/contrib/libs/libpq/src/interfaces/libpq/fe-trace.c deleted file mode 100644 index 402784f40e..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/fe-trace.c +++ /dev/null @@ -1,729 +0,0 @@ -/*------------------------------------------------------------------------- - * - * fe-trace.c - * functions for libpq protocol tracing - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/interfaces/libpq/fe-trace.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <ctype.h> -#include <limits.h> -#include <sys/time.h> -#include <time.h> - -#ifdef WIN32 -#include "win32.h" -#else -#include <unistd.h> -#endif - -#include "libpq-fe.h" -#include "libpq-int.h" -#include "port/pg_bswap.h" - - -/* Enable tracing */ -void -PQtrace(PGconn *conn, FILE *debug_port) -{ - if (conn == NULL) - return; - PQuntrace(conn); - if (debug_port == NULL) - return; - - conn->Pfdebug = debug_port; - conn->traceFlags = 0; -} - -/* Disable tracing */ -void -PQuntrace(PGconn *conn) -{ - if (conn == NULL) - return; - if (conn->Pfdebug) - { - fflush(conn->Pfdebug); - conn->Pfdebug = NULL; - } - - conn->traceFlags = 0; -} - -/* Set flags for current tracing session */ -void -PQsetTraceFlags(PGconn *conn, int flags) -{ - if (conn == NULL) - return; - /* If PQtrace() failed, do nothing. */ - if (conn->Pfdebug == NULL) - return; - conn->traceFlags = flags; -} - -/* - * Print the current time, with microseconds, into a caller-supplied - * buffer. - * Cribbed from get_formatted_log_time, but much simpler. - */ -static void -pqTraceFormatTimestamp(char *timestr, size_t ts_len) -{ - struct timeval tval; - time_t now; - - gettimeofday(&tval, NULL); - - /* - * MSVC's implementation of timeval uses a long for tv_sec, however, - * localtime() expects a time_t pointer. Here we'll assign tv_sec to a - * local time_t variable so that we pass localtime() the correct pointer - * type. - */ - now = tval.tv_sec; - strftime(timestr, ts_len, - "%Y-%m-%d %H:%M:%S", - localtime(&now)); - /* append microseconds */ - snprintf(timestr + strlen(timestr), ts_len - strlen(timestr), - ".%06u", (unsigned int) (tval.tv_usec)); -} - -/* - * pqTraceOutputByte1: output a 1-char message to the log - */ -static void -pqTraceOutputByte1(FILE *pfdebug, const char *data, int *cursor) -{ - const char *v = data + *cursor; - - /* - * Show non-printable data in hex format, including the terminating \0 - * that completes ErrorResponse and NoticeResponse messages. - */ - if (!isprint((unsigned char) *v)) - fprintf(pfdebug, " \\x%02x", *v); - else - fprintf(pfdebug, " %c", *v); - *cursor += 1; -} - -/* - * pqTraceOutputInt16: output a 2-byte integer message to the log - */ -static int -pqTraceOutputInt16(FILE *pfdebug, const char *data, int *cursor) -{ - uint16 tmp; - int result; - - memcpy(&tmp, data + *cursor, 2); - *cursor += 2; - result = (int) pg_ntoh16(tmp); - fprintf(pfdebug, " %d", result); - - return result; -} - -/* - * pqTraceOutputInt32: output a 4-byte integer message to the log - * - * If 'suppress' is true, print a literal NNNN instead of the actual number. - */ -static int -pqTraceOutputInt32(FILE *pfdebug, const char *data, int *cursor, bool suppress) -{ - int result; - - memcpy(&result, data + *cursor, 4); - *cursor += 4; - result = (int) pg_ntoh32(result); - if (suppress) - fprintf(pfdebug, " NNNN"); - else - fprintf(pfdebug, " %d", result); - - return result; -} - -/* - * pqTraceOutputString: output a string message to the log - */ -static void -pqTraceOutputString(FILE *pfdebug, const char *data, int *cursor, bool suppress) -{ - int len; - - if (suppress) - { - fprintf(pfdebug, " \"SSSS\""); - *cursor += strlen(data + *cursor) + 1; - } - else - { - len = fprintf(pfdebug, " \"%s\"", data + *cursor); - - /* - * This is a null-terminated string. So add 1 after subtracting 3 - * which is the double quotes and space length from len. - */ - *cursor += (len - 3 + 1); - } -} - -/* - * pqTraceOutputNchar: output a string of exactly len bytes message to the log - */ -static void -pqTraceOutputNchar(FILE *pfdebug, int len, const char *data, int *cursor) -{ - int i, - next; /* first char not yet printed */ - const char *v = data + *cursor; - - fprintf(pfdebug, " \'"); - - for (next = i = 0; i < len; ++i) - { - if (isprint((unsigned char) v[i])) - continue; - else - { - fwrite(v + next, 1, i - next, pfdebug); - fprintf(pfdebug, "\\x%02x", v[i]); - next = i + 1; - } - } - if (next < len) - fwrite(v + next, 1, len - next, pfdebug); - - fprintf(pfdebug, "\'"); - *cursor += len; -} - -/* - * Output functions by protocol message type - */ - -/* NotificationResponse */ -static void -pqTraceOutputA(FILE *f, const char *message, int *cursor, bool regress) -{ - fprintf(f, "NotificationResponse\t"); - pqTraceOutputInt32(f, message, cursor, regress); - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputString(f, message, cursor, false); -} - -/* Bind */ -static void -pqTraceOutputB(FILE *f, const char *message, int *cursor) -{ - int nparams; - - fprintf(f, "Bind\t"); - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputString(f, message, cursor, false); - nparams = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nparams; i++) - pqTraceOutputInt16(f, message, cursor); - - nparams = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nparams; i++) - { - int nbytes; - - nbytes = pqTraceOutputInt32(f, message, cursor, false); - if (nbytes == -1) - continue; - pqTraceOutputNchar(f, nbytes, message, cursor); - } - - nparams = pqTraceOutputInt16(f, message, cursor); - for (int i = 0; i < nparams; i++) - pqTraceOutputInt16(f, message, cursor); -} - -/* Close(F) or CommandComplete(B) */ -static void -pqTraceOutputC(FILE *f, bool toServer, const char *message, int *cursor) -{ - if (toServer) - { - fprintf(f, "Close\t"); - pqTraceOutputByte1(f, message, cursor); - pqTraceOutputString(f, message, cursor, false); - } - else - { - fprintf(f, "CommandComplete\t"); - pqTraceOutputString(f, message, cursor, false); - } -} - -/* Describe(F) or DataRow(B) */ -static void -pqTraceOutputD(FILE *f, bool toServer, const char *message, int *cursor) -{ - if (toServer) - { - fprintf(f, "Describe\t"); - pqTraceOutputByte1(f, message, cursor); - pqTraceOutputString(f, message, cursor, false); - } - else - { - int nfields; - int len; - int i; - - fprintf(f, "DataRow\t"); - nfields = pqTraceOutputInt16(f, message, cursor); - for (i = 0; i < nfields; i++) - { - len = pqTraceOutputInt32(f, message, cursor, false); - if (len == -1) - continue; - pqTraceOutputNchar(f, len, message, cursor); - } - } -} - -/* NoticeResponse / ErrorResponse */ -static void -pqTraceOutputNR(FILE *f, const char *type, const char *message, int *cursor, - bool regress) -{ - fprintf(f, "%s\t", type); - for (;;) - { - char field; - bool suppress; - - pqTraceOutputByte1(f, message, cursor); - field = message[*cursor - 1]; - if (field == '\0') - break; - - suppress = regress && (field == 'L' || field == 'F' || field == 'R'); - pqTraceOutputString(f, message, cursor, suppress); - } -} - -/* Execute(F) or ErrorResponse(B) */ -static void -pqTraceOutputE(FILE *f, bool toServer, const char *message, int *cursor, bool regress) -{ - if (toServer) - { - fprintf(f, "Execute\t"); - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputInt32(f, message, cursor, false); - } - else - pqTraceOutputNR(f, "ErrorResponse", message, cursor, regress); -} - -/* CopyFail */ -static void -pqTraceOutputf(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "CopyFail\t"); - pqTraceOutputString(f, message, cursor, false); -} - -/* FunctionCall */ -static void -pqTraceOutputF(FILE *f, const char *message, int *cursor, bool regress) -{ - int nfields; - int nbytes; - - fprintf(f, "FunctionCall\t"); - pqTraceOutputInt32(f, message, cursor, regress); - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, cursor); - - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - { - nbytes = pqTraceOutputInt32(f, message, cursor, false); - if (nbytes == -1) - continue; - pqTraceOutputNchar(f, nbytes, message, cursor); - } - - pqTraceOutputInt16(f, message, cursor); -} - -/* CopyInResponse */ -static void -pqTraceOutputG(FILE *f, const char *message, int *cursor) -{ - int nfields; - - fprintf(f, "CopyInResponse\t"); - pqTraceOutputByte1(f, message, cursor); - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, cursor); -} - -/* CopyOutResponse */ -static void -pqTraceOutputH(FILE *f, const char *message, int *cursor) -{ - int nfields; - - fprintf(f, "CopyOutResponse\t"); - pqTraceOutputByte1(f, message, cursor); - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - pqTraceOutputInt16(f, message, cursor); -} - -/* BackendKeyData */ -static void -pqTraceOutputK(FILE *f, const char *message, int *cursor, bool regress) -{ - fprintf(f, "BackendKeyData\t"); - pqTraceOutputInt32(f, message, cursor, regress); - pqTraceOutputInt32(f, message, cursor, regress); -} - -/* Parse */ -static void -pqTraceOutputP(FILE *f, const char *message, int *cursor, bool regress) -{ - int nparams; - - fprintf(f, "Parse\t"); - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputString(f, message, cursor, false); - nparams = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nparams; i++) - pqTraceOutputInt32(f, message, cursor, regress); -} - -/* Query */ -static void -pqTraceOutputQ(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "Query\t"); - pqTraceOutputString(f, message, cursor, false); -} - -/* Authentication */ -static void -pqTraceOutputR(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "Authentication\t"); - pqTraceOutputInt32(f, message, cursor, false); -} - -/* ParameterStatus */ -static void -pqTraceOutputS(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "ParameterStatus\t"); - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputString(f, message, cursor, false); -} - -/* ParameterDescription */ -static void -pqTraceOutputt(FILE *f, const char *message, int *cursor, bool regress) -{ - int nfields; - - fprintf(f, "ParameterDescription\t"); - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - pqTraceOutputInt32(f, message, cursor, regress); -} - -/* RowDescription */ -static void -pqTraceOutputT(FILE *f, const char *message, int *cursor, bool regress) -{ - int nfields; - - fprintf(f, "RowDescription\t"); - nfields = pqTraceOutputInt16(f, message, cursor); - - for (int i = 0; i < nfields; i++) - { - pqTraceOutputString(f, message, cursor, false); - pqTraceOutputInt32(f, message, cursor, regress); - pqTraceOutputInt16(f, message, cursor); - pqTraceOutputInt32(f, message, cursor, regress); - pqTraceOutputInt16(f, message, cursor); - pqTraceOutputInt32(f, message, cursor, false); - pqTraceOutputInt16(f, message, cursor); - } -} - -/* NegotiateProtocolVersion */ -static void -pqTraceOutputv(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "NegotiateProtocolVersion\t"); - pqTraceOutputInt32(f, message, cursor, false); - pqTraceOutputInt32(f, message, cursor, false); -} - -/* FunctionCallResponse */ -static void -pqTraceOutputV(FILE *f, const char *message, int *cursor) -{ - int len; - - fprintf(f, "FunctionCallResponse\t"); - len = pqTraceOutputInt32(f, message, cursor, false); - if (len != -1) - pqTraceOutputNchar(f, len, message, cursor); -} - -/* CopyBothResponse */ -static void -pqTraceOutputW(FILE *f, const char *message, int *cursor, int length) -{ - fprintf(f, "CopyBothResponse\t"); - pqTraceOutputByte1(f, message, cursor); - - while (length > *cursor) - pqTraceOutputInt16(f, message, cursor); -} - -/* ReadyForQuery */ -static void -pqTraceOutputZ(FILE *f, const char *message, int *cursor) -{ - fprintf(f, "ReadyForQuery\t"); - pqTraceOutputByte1(f, message, cursor); -} - -/* - * Print the given message to the trace output stream. - */ -void -pqTraceOutputMessage(PGconn *conn, const char *message, bool toServer) -{ - char id; - int length; - char *prefix = toServer ? "F" : "B"; - int logCursor = 0; - bool regress; - - if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0) - { - char timestr[128]; - - pqTraceFormatTimestamp(timestr, sizeof(timestr)); - fprintf(conn->Pfdebug, "%s\t", timestr); - } - regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0; - - id = message[logCursor++]; - - memcpy(&length, message + logCursor, 4); - length = (int) pg_ntoh32(length); - logCursor += 4; - - /* - * In regress mode, suppress the length of ErrorResponse and - * NoticeResponse. The F (file name), L (line number) and R (routine - * name) fields can change as server code is modified, and if their - * lengths differ from the originals, that would break tests. - */ - if (regress && !toServer && (id == 'E' || id == 'N')) - fprintf(conn->Pfdebug, "%s\tNN\t", prefix); - else - fprintf(conn->Pfdebug, "%s\t%d\t", prefix, length); - - switch (id) - { - case '1': - fprintf(conn->Pfdebug, "ParseComplete"); - /* No message content */ - break; - case '2': - fprintf(conn->Pfdebug, "BindComplete"); - /* No message content */ - break; - case '3': - fprintf(conn->Pfdebug, "CloseComplete"); - /* No message content */ - break; - case 'A': /* Notification Response */ - pqTraceOutputA(conn->Pfdebug, message, &logCursor, regress); - break; - case 'B': /* Bind */ - pqTraceOutputB(conn->Pfdebug, message, &logCursor); - break; - case 'c': - fprintf(conn->Pfdebug, "CopyDone"); - /* No message content */ - break; - case 'C': /* Close(F) or Command Complete(B) */ - pqTraceOutputC(conn->Pfdebug, toServer, message, &logCursor); - break; - case 'd': /* Copy Data */ - /* Drop COPY data to reduce the overhead of logging. */ - break; - case 'D': /* Describe(F) or Data Row(B) */ - pqTraceOutputD(conn->Pfdebug, toServer, message, &logCursor); - break; - case 'E': /* Execute(F) or Error Response(B) */ - pqTraceOutputE(conn->Pfdebug, toServer, message, &logCursor, - regress); - break; - case 'f': /* Copy Fail */ - pqTraceOutputf(conn->Pfdebug, message, &logCursor); - break; - case 'F': /* Function Call */ - pqTraceOutputF(conn->Pfdebug, message, &logCursor, regress); - break; - case 'G': /* Start Copy In */ - pqTraceOutputG(conn->Pfdebug, message, &logCursor); - break; - case 'H': /* Flush(F) or Start Copy Out(B) */ - if (!toServer) - pqTraceOutputH(conn->Pfdebug, message, &logCursor); - else - fprintf(conn->Pfdebug, "Flush"); /* no message content */ - break; - case 'I': - fprintf(conn->Pfdebug, "EmptyQueryResponse"); - /* No message content */ - break; - case 'K': /* secret key data from the backend */ - pqTraceOutputK(conn->Pfdebug, message, &logCursor, regress); - break; - case 'n': - fprintf(conn->Pfdebug, "NoData"); - /* No message content */ - break; - case 'N': - pqTraceOutputNR(conn->Pfdebug, "NoticeResponse", message, - &logCursor, regress); - break; - case 'P': /* Parse */ - pqTraceOutputP(conn->Pfdebug, message, &logCursor, regress); - break; - case 'Q': /* Query */ - pqTraceOutputQ(conn->Pfdebug, message, &logCursor); - break; - case 'R': /* Authentication */ - pqTraceOutputR(conn->Pfdebug, message, &logCursor); - break; - case 's': - fprintf(conn->Pfdebug, "PortalSuspended"); - /* No message content */ - break; - case 'S': /* Parameter Status(B) or Sync(F) */ - if (!toServer) - pqTraceOutputS(conn->Pfdebug, message, &logCursor); - else - fprintf(conn->Pfdebug, "Sync"); /* no message content */ - break; - case 't': /* Parameter Description */ - pqTraceOutputt(conn->Pfdebug, message, &logCursor, regress); - break; - case 'T': /* Row Description */ - pqTraceOutputT(conn->Pfdebug, message, &logCursor, regress); - break; - case 'v': /* Negotiate Protocol Version */ - pqTraceOutputv(conn->Pfdebug, message, &logCursor); - break; - case 'V': /* Function Call response */ - pqTraceOutputV(conn->Pfdebug, message, &logCursor); - break; - case 'W': /* Start Copy Both */ - pqTraceOutputW(conn->Pfdebug, message, &logCursor, length); - break; - case 'X': - fprintf(conn->Pfdebug, "Terminate"); - /* No message content */ - break; - case 'Z': /* Ready For Query */ - pqTraceOutputZ(conn->Pfdebug, message, &logCursor); - break; - default: - fprintf(conn->Pfdebug, "Unknown message: %02x", id); - break; - } - - fputc('\n', conn->Pfdebug); - - /* - * Verify the printing routine did it right. Note that the one-byte - * message identifier is not included in the length, but our cursor does - * include it. - */ - if (logCursor - 1 != length) - fprintf(conn->Pfdebug, - "mismatched message length: consumed %d, expected %d\n", - logCursor - 1, length); -} - -/* - * Print special messages (those containing no type byte) to the trace output - * stream. - */ -void -pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message) -{ - int length; - int logCursor = 0; - - if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0) - { - char timestr[128]; - - pqTraceFormatTimestamp(timestr, sizeof(timestr)); - fprintf(conn->Pfdebug, "%s\t", timestr); - } - - memcpy(&length, message + logCursor, 4); - length = (int) pg_ntoh32(length); - logCursor += 4; - - fprintf(conn->Pfdebug, "F\t%d\t", length); - - switch (length) - { - case 16: /* CancelRequest */ - fprintf(conn->Pfdebug, "CancelRequest\t"); - pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false); - pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false); - pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false); - break; - case 8: /* GSSENCRequest or SSLRequest */ - /* These messages do not reach here. */ - default: - fprintf(conn->Pfdebug, "Unknown message: length is %d", length); - break; - } - - fputc('\n', conn->Pfdebug); -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/libpq-events.c b/contrib/libs/libpq/src/interfaces/libpq/libpq-events.c deleted file mode 100644 index 229bed910f..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/libpq-events.c +++ /dev/null @@ -1,211 +0,0 @@ -/*------------------------------------------------------------------------- - * - * libpq-events.c - * functions for supporting the libpq "events" API - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/interfaces/libpq/libpq-events.c - * - *------------------------------------------------------------------------- - */ -#include "postgres_fe.h" - -#include "libpq-fe.h" -#include "libpq-int.h" - - -/* - * Registers an event proc with the given PGconn. - * - * The same proc can't be registered more than once in a PGconn. This - * restriction is required because we use the proc address to identify - * the event for purposes such as PQinstanceData(). - * - * The name argument is used within error messages to aid in debugging. - * A name must be supplied, but it needn't be unique. The string is - * copied, so the passed value needn't be long-lived. - * - * The passThrough argument is an application specific pointer and can be set - * to NULL if not required. It is passed through to the event proc whenever - * the event proc is called, and is not otherwise touched by libpq. - * - * The function returns a non-zero if successful. If the function fails, - * zero is returned. - */ -int -PQregisterEventProc(PGconn *conn, PGEventProc proc, - const char *name, void *passThrough) -{ - int i; - PGEventRegister regevt; - - if (!proc || !conn || !name || !*name) - return false; /* bad arguments */ - - for (i = 0; i < conn->nEvents; i++) - { - if (conn->events[i].proc == proc) - return false; /* already registered */ - } - - if (conn->nEvents >= conn->eventArraySize) - { - PGEvent *e; - int newSize; - - newSize = conn->eventArraySize ? conn->eventArraySize * 2 : 8; - if (conn->events) - e = (PGEvent *) realloc(conn->events, newSize * sizeof(PGEvent)); - else - e = (PGEvent *) malloc(newSize * sizeof(PGEvent)); - - if (!e) - return false; - - conn->eventArraySize = newSize; - conn->events = e; - } - - conn->events[conn->nEvents].proc = proc; - conn->events[conn->nEvents].name = strdup(name); - if (!conn->events[conn->nEvents].name) - return false; - conn->events[conn->nEvents].passThrough = passThrough; - conn->events[conn->nEvents].data = NULL; - conn->events[conn->nEvents].resultInitialized = false; - conn->nEvents++; - - regevt.conn = conn; - if (!proc(PGEVT_REGISTER, ®evt, passThrough)) - { - conn->nEvents--; - free(conn->events[conn->nEvents].name); - return false; - } - - return true; -} - -/* - * Set some "instance data" for an event within a PGconn. - * Returns nonzero on success, zero on failure. - */ -int -PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data) -{ - int i; - - if (!conn || !proc) - return false; - - for (i = 0; i < conn->nEvents; i++) - { - if (conn->events[i].proc == proc) - { - conn->events[i].data = data; - return true; - } - } - - return false; -} - -/* - * Obtain the "instance data", if any, for the event. - */ -void * -PQinstanceData(const PGconn *conn, PGEventProc proc) -{ - int i; - - if (!conn || !proc) - return NULL; - - for (i = 0; i < conn->nEvents; i++) - { - if (conn->events[i].proc == proc) - return conn->events[i].data; - } - - return NULL; -} - -/* - * Set some "instance data" for an event within a PGresult. - * Returns nonzero on success, zero on failure. - */ -int -PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data) -{ - int i; - - if (!result || !proc) - return false; - - for (i = 0; i < result->nEvents; i++) - { - if (result->events[i].proc == proc) - { - result->events[i].data = data; - return true; - } - } - - return false; -} - -/* - * Obtain the "instance data", if any, for the event. - */ -void * -PQresultInstanceData(const PGresult *result, PGEventProc proc) -{ - int i; - - if (!result || !proc) - return NULL; - - for (i = 0; i < result->nEvents; i++) - if (result->events[i].proc == proc) - return result->events[i].data; - - return NULL; -} - -/* - * Fire RESULTCREATE events for an application-created PGresult. - * - * The conn argument can be NULL if event procedures won't use it. - */ -int -PQfireResultCreateEvents(PGconn *conn, PGresult *res) -{ - int result = true; - int i; - - if (!res) - return false; - - for (i = 0; i < res->nEvents; i++) - { - /* It's possible event was already fired, if so don't repeat it */ - if (!res->events[i].resultInitialized) - { - PGEventResultCreate evt; - - evt.conn = conn; - evt.result = res; - if (res->events[i].proc(PGEVT_RESULTCREATE, &evt, - res->events[i].passThrough)) - res->events[i].resultInitialized = true; - else - result = false; - } - } - - return result; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/libpq-events.h b/contrib/libs/libpq/src/interfaces/libpq/libpq-events.h deleted file mode 100644 index b9d5137634..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/libpq-events.h +++ /dev/null @@ -1,94 +0,0 @@ -/*------------------------------------------------------------------------- - * - * libpq-events.h - * This file contains definitions that are useful to applications - * that invoke the libpq "events" API, but are not interesting to - * ordinary users of libpq. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/libpq-events.h - * - *------------------------------------------------------------------------- - */ - -#ifndef LIBPQ_EVENTS_H -#define LIBPQ_EVENTS_H - -#include "libpq-fe.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Callback Event Ids */ -typedef enum -{ - PGEVT_REGISTER, - PGEVT_CONNRESET, - PGEVT_CONNDESTROY, - PGEVT_RESULTCREATE, - PGEVT_RESULTCOPY, - PGEVT_RESULTDESTROY -} PGEventId; - -typedef struct -{ - PGconn *conn; -} PGEventRegister; - -typedef struct -{ - PGconn *conn; -} PGEventConnReset; - -typedef struct -{ - PGconn *conn; -} PGEventConnDestroy; - -typedef struct -{ - PGconn *conn; - PGresult *result; -} PGEventResultCreate; - -typedef struct -{ - const PGresult *src; - PGresult *dest; -} PGEventResultCopy; - -typedef struct -{ - PGresult *result; -} PGEventResultDestroy; - -typedef int (*PGEventProc) (PGEventId evtId, void *evtInfo, void *passThrough); - -/* Registers an event proc with the given PGconn. */ -extern int PQregisterEventProc(PGconn *conn, PGEventProc proc, - const char *name, void *passThrough); - -/* Sets the PGconn instance data for the provided proc to data. */ -extern int PQsetInstanceData(PGconn *conn, PGEventProc proc, void *data); - -/* Gets the PGconn instance data for the provided proc. */ -extern void *PQinstanceData(const PGconn *conn, PGEventProc proc); - -/* Sets the PGresult instance data for the provided proc to data. */ -extern int PQresultSetInstanceData(PGresult *result, PGEventProc proc, void *data); - -/* Gets the PGresult instance data for the provided proc. */ -extern void *PQresultInstanceData(const PGresult *result, PGEventProc proc); - -/* Fires RESULTCREATE events for an application-created PGresult. */ -extern int PQfireResultCreateEvents(PGconn *conn, PGresult *res); - -#ifdef __cplusplus -} -#endif - -#endif /* LIBPQ_EVENTS_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/libpq-fe.h b/contrib/libs/libpq/src/interfaces/libpq/libpq-fe.h deleted file mode 100644 index 7476dbe0e9..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/libpq-fe.h +++ /dev/null @@ -1,675 +0,0 @@ -/*------------------------------------------------------------------------- - * - * libpq-fe.h - * This file contains definitions for structures and - * externs for functions used by frontend postgres applications. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/libpq-fe.h - * - *------------------------------------------------------------------------- - */ - -#ifndef LIBPQ_FE_H -#define LIBPQ_FE_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdio.h> - -/* - * postgres_ext.h defines the backend's externally visible types, - * such as Oid. - */ -#include "postgres_ext.h" - -/* - * These symbols may be used in compile-time #ifdef tests for the availability - * of newer libpq features. - */ -/* Indicates presence of PQenterPipelineMode and friends */ -#define LIBPQ_HAS_PIPELINING 1 -/* Indicates presence of PQsetTraceFlags; also new PQtrace output format */ -#define LIBPQ_HAS_TRACE_FLAGS 1 -/* Indicates that PQsslAttribute(NULL, "library") is useful */ -#define LIBPQ_HAS_SSL_LIBRARY_DETECTION 1 - -/* - * Option flags for PQcopyResult - */ -#define PG_COPYRES_ATTRS 0x01 -#define PG_COPYRES_TUPLES 0x02 /* Implies PG_COPYRES_ATTRS */ -#define PG_COPYRES_EVENTS 0x04 -#define PG_COPYRES_NOTICEHOOKS 0x08 - -/* Application-visible enum types */ - -/* - * Although it is okay to add to these lists, values which become unused - * should never be removed, nor should constants be redefined - that would - * break compatibility with existing code. - */ - -typedef enum -{ - CONNECTION_OK, - CONNECTION_BAD, - /* Non-blocking mode only below here */ - - /* - * The existence of these should never be relied upon - they should only - * be used for user feedback or similar purposes. - */ - CONNECTION_STARTED, /* Waiting for connection to be made. */ - CONNECTION_MADE, /* Connection OK; waiting to send. */ - CONNECTION_AWAITING_RESPONSE, /* Waiting for a response from the - * postmaster. */ - CONNECTION_AUTH_OK, /* Received authentication; waiting for - * backend startup. */ - CONNECTION_SETENV, /* This state is no longer used. */ - CONNECTION_SSL_STARTUP, /* Negotiating SSL. */ - CONNECTION_NEEDED, /* Internal state: connect() needed */ - CONNECTION_CHECK_WRITABLE, /* Checking if session is read-write. */ - CONNECTION_CONSUME, /* Consuming any extra messages. */ - CONNECTION_GSS_STARTUP, /* Negotiating GSSAPI. */ - CONNECTION_CHECK_TARGET, /* Checking target server properties. */ - CONNECTION_CHECK_STANDBY /* Checking if server is in standby mode. */ -} ConnStatusType; - -typedef enum -{ - PGRES_POLLING_FAILED = 0, - PGRES_POLLING_READING, /* These two indicate that one may */ - PGRES_POLLING_WRITING, /* use select before polling again. */ - PGRES_POLLING_OK, - PGRES_POLLING_ACTIVE /* unused; keep for awhile for backwards - * compatibility */ -} PostgresPollingStatusType; - -typedef enum -{ - PGRES_EMPTY_QUERY = 0, /* empty query string was executed */ - PGRES_COMMAND_OK, /* a query command that doesn't return - * anything was executed properly by the - * backend */ - PGRES_TUPLES_OK, /* a query command that returns tuples was - * executed properly by the backend, PGresult - * contains the result tuples */ - PGRES_COPY_OUT, /* Copy Out data transfer in progress */ - PGRES_COPY_IN, /* Copy In data transfer in progress */ - PGRES_BAD_RESPONSE, /* an unexpected response was recv'd from the - * backend */ - PGRES_NONFATAL_ERROR, /* notice or warning message */ - PGRES_FATAL_ERROR, /* query failed */ - PGRES_COPY_BOTH, /* Copy In/Out data transfer in progress */ - PGRES_SINGLE_TUPLE, /* single tuple from larger resultset */ - PGRES_PIPELINE_SYNC, /* pipeline synchronization point */ - PGRES_PIPELINE_ABORTED /* Command didn't run because of an abort - * earlier in a pipeline */ -} ExecStatusType; - -typedef enum -{ - PQTRANS_IDLE, /* connection idle */ - PQTRANS_ACTIVE, /* command in progress */ - PQTRANS_INTRANS, /* idle, within transaction block */ - PQTRANS_INERROR, /* idle, within failed transaction */ - PQTRANS_UNKNOWN /* cannot determine status */ -} PGTransactionStatusType; - -typedef enum -{ - PQERRORS_TERSE, /* single-line error messages */ - PQERRORS_DEFAULT, /* recommended style */ - PQERRORS_VERBOSE, /* all the facts, ma'am */ - PQERRORS_SQLSTATE /* only error severity and SQLSTATE code */ -} PGVerbosity; - -typedef enum -{ - PQSHOW_CONTEXT_NEVER, /* never show CONTEXT field */ - PQSHOW_CONTEXT_ERRORS, /* show CONTEXT for errors only (default) */ - PQSHOW_CONTEXT_ALWAYS /* always show CONTEXT field */ -} PGContextVisibility; - -/* - * PGPing - The ordering of this enum should not be altered because the - * values are exposed externally via pg_isready. - */ - -typedef enum -{ - PQPING_OK, /* server is accepting connections */ - PQPING_REJECT, /* server is alive but rejecting connections */ - PQPING_NO_RESPONSE, /* could not establish connection */ - PQPING_NO_ATTEMPT /* connection not attempted (bad params) */ -} PGPing; - -/* - * PGpipelineStatus - Current status of pipeline mode - */ -typedef enum -{ - PQ_PIPELINE_OFF, - PQ_PIPELINE_ON, - PQ_PIPELINE_ABORTED -} PGpipelineStatus; - -/* PGconn encapsulates a connection to the backend. - * The contents of this struct are not supposed to be known to applications. - */ -typedef struct pg_conn PGconn; - -/* PGresult encapsulates the result of a query (or more precisely, of a single - * SQL command --- a query string given to PQsendQuery can contain multiple - * commands and thus return multiple PGresult objects). - * The contents of this struct are not supposed to be known to applications. - */ -typedef struct pg_result PGresult; - -/* PGcancel encapsulates the information needed to cancel a running - * query on an existing connection. - * The contents of this struct are not supposed to be known to applications. - */ -typedef struct pg_cancel PGcancel; - -/* PGnotify represents the occurrence of a NOTIFY message. - * Ideally this would be an opaque typedef, but it's so simple that it's - * unlikely to change. - * NOTE: in Postgres 6.4 and later, the be_pid is the notifying backend's, - * whereas in earlier versions it was always your own backend's PID. - */ -typedef struct pgNotify -{ - char *relname; /* notification condition name */ - int be_pid; /* process ID of notifying server process */ - char *extra; /* notification parameter */ - /* Fields below here are private to libpq; apps should not use 'em */ - struct pgNotify *next; /* list link */ -} PGnotify; - -/* Function types for notice-handling callbacks */ -typedef void (*PQnoticeReceiver) (void *arg, const PGresult *res); -typedef void (*PQnoticeProcessor) (void *arg, const char *message); - -/* Print options for PQprint() */ -typedef char pqbool; - -typedef struct _PQprintOpt -{ - pqbool header; /* print output field headings and row count */ - pqbool align; /* fill align the fields */ - pqbool standard; /* old brain dead format */ - pqbool html3; /* output html tables */ - pqbool expanded; /* expand tables */ - pqbool pager; /* use pager for output if needed */ - char *fieldSep; /* field separator */ - char *tableOpt; /* insert to HTML <table ...> */ - char *caption; /* HTML <caption> */ - char **fieldName; /* null terminated array of replacement field - * names */ -} PQprintOpt; - -/* ---------------- - * Structure for the conninfo parameter definitions returned by PQconndefaults - * or PQconninfoParse. - * - * All fields except "val" point at static strings which must not be altered. - * "val" is either NULL or a malloc'd current-value string. PQconninfoFree() - * will release both the val strings and the PQconninfoOption array itself. - * ---------------- - */ -typedef struct _PQconninfoOption -{ - char *keyword; /* The keyword of the option */ - char *envvar; /* Fallback environment variable name */ - char *compiled; /* Fallback compiled in default value */ - char *val; /* Option's current value, or NULL */ - char *label; /* Label for field in connect dialog */ - char *dispchar; /* Indicates how to display this field in a - * connect dialog. Values are: "" Display - * entered value as is "*" Password field - - * hide value "D" Debug option - don't show - * by default */ - int dispsize; /* Field size in characters for dialog */ -} PQconninfoOption; - -/* ---------------- - * PQArgBlock -- structure for PQfn() arguments - * ---------------- - */ -typedef struct -{ - int len; - int isint; - union - { - int *ptr; /* can't use void (dec compiler barfs) */ - int integer; - } u; -} PQArgBlock; - -/* ---------------- - * PGresAttDesc -- Data about a single attribute (column) of a query result - * ---------------- - */ -typedef struct pgresAttDesc -{ - char *name; /* column name */ - Oid tableid; /* source table, if known */ - int columnid; /* source column, if known */ - int format; /* format code for value (text/binary) */ - Oid typid; /* type id */ - int typlen; /* type size */ - int atttypmod; /* type-specific modifier info */ -} PGresAttDesc; - -/* ---------------- - * Exported functions of libpq - * ---------------- - */ - -/* === in fe-connect.c === */ - -/* make a new client connection to the backend */ -/* Asynchronous (non-blocking) */ -extern PGconn *PQconnectStart(const char *conninfo); -extern PGconn *PQconnectStartParams(const char *const *keywords, - const char *const *values, int expand_dbname); -extern PostgresPollingStatusType PQconnectPoll(PGconn *conn); - -/* Synchronous (blocking) */ -extern PGconn *PQconnectdb(const char *conninfo); -extern PGconn *PQconnectdbParams(const char *const *keywords, - const char *const *values, int expand_dbname); -extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport, - const char *pgoptions, const char *pgtty, - const char *dbName, - const char *login, const char *pwd); - -#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \ - PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL) - -/* close the current connection and free the PGconn data structure */ -extern void PQfinish(PGconn *conn); - -/* get info about connection options known to PQconnectdb */ -extern PQconninfoOption *PQconndefaults(void); - -/* parse connection options in same way as PQconnectdb */ -extern PQconninfoOption *PQconninfoParse(const char *conninfo, char **errmsg); - -/* return the connection options used by a live connection */ -extern PQconninfoOption *PQconninfo(PGconn *conn); - -/* free the data structure returned by PQconndefaults() or PQconninfoParse() */ -extern void PQconninfoFree(PQconninfoOption *connOptions); - -/* - * close the current connection and reestablish a new one with the same - * parameters - */ -/* Asynchronous (non-blocking) */ -extern int PQresetStart(PGconn *conn); -extern PostgresPollingStatusType PQresetPoll(PGconn *conn); - -/* Synchronous (blocking) */ -extern void PQreset(PGconn *conn); - -/* request a cancel structure */ -extern PGcancel *PQgetCancel(PGconn *conn); - -/* free a cancel structure */ -extern void PQfreeCancel(PGcancel *cancel); - -/* issue a cancel request */ -extern int PQcancel(PGcancel *cancel, char *errbuf, int errbufsize); - -/* backwards compatible version of PQcancel; not thread-safe */ -extern int PQrequestCancel(PGconn *conn); - -/* Accessor functions for PGconn objects */ -extern char *PQdb(const PGconn *conn); -extern char *PQuser(const PGconn *conn); -extern char *PQpass(const PGconn *conn); -extern char *PQhost(const PGconn *conn); -extern char *PQhostaddr(const PGconn *conn); -extern char *PQport(const PGconn *conn); -extern char *PQtty(const PGconn *conn); -extern char *PQoptions(const PGconn *conn); -extern ConnStatusType PQstatus(const PGconn *conn); -extern PGTransactionStatusType PQtransactionStatus(const PGconn *conn); -extern const char *PQparameterStatus(const PGconn *conn, - const char *paramName); -extern int PQprotocolVersion(const PGconn *conn); -extern int PQserverVersion(const PGconn *conn); -extern char *PQerrorMessage(const PGconn *conn); -extern int PQsocket(const PGconn *conn); -extern int PQbackendPID(const PGconn *conn); -extern PGpipelineStatus PQpipelineStatus(const PGconn *conn); -extern int PQconnectionNeedsPassword(const PGconn *conn); -extern int PQconnectionUsedPassword(const PGconn *conn); -extern int PQconnectionUsedGSSAPI(const PGconn *conn); -extern int PQclientEncoding(const PGconn *conn); -extern int PQsetClientEncoding(PGconn *conn, const char *encoding); - -/* SSL information functions */ -extern int PQsslInUse(PGconn *conn); -extern void *PQsslStruct(PGconn *conn, const char *struct_name); -extern const char *PQsslAttribute(PGconn *conn, const char *attribute_name); -extern const char *const *PQsslAttributeNames(PGconn *conn); - -/* Get the OpenSSL structure associated with a connection. Returns NULL for - * unencrypted connections or if any other TLS library is in use. */ -extern void *PQgetssl(PGconn *conn); - -/* Tell libpq whether it needs to initialize OpenSSL */ -extern void PQinitSSL(int do_init); - -/* More detailed way to tell libpq whether it needs to initialize OpenSSL */ -extern void PQinitOpenSSL(int do_ssl, int do_crypto); - -/* Return true if GSSAPI encryption is in use */ -extern int PQgssEncInUse(PGconn *conn); - -/* Returns GSSAPI context if GSSAPI is in use */ -extern void *PQgetgssctx(PGconn *conn); - -/* Set verbosity for PQerrorMessage and PQresultErrorMessage */ -extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity); - -/* Set CONTEXT visibility for PQerrorMessage and PQresultErrorMessage */ -extern PGContextVisibility PQsetErrorContextVisibility(PGconn *conn, - PGContextVisibility show_context); - -/* Override default notice handling routines */ -extern PQnoticeReceiver PQsetNoticeReceiver(PGconn *conn, - PQnoticeReceiver proc, - void *arg); -extern PQnoticeProcessor PQsetNoticeProcessor(PGconn *conn, - PQnoticeProcessor proc, - void *arg); - -/* - * Used to set callback that prevents concurrent access to - * non-thread safe functions that libpq needs. - * The default implementation uses a libpq internal mutex. - * Only required for multithreaded apps that use kerberos - * both within their app and for postgresql connections. - */ -typedef void (*pgthreadlock_t) (int acquire); - -extern pgthreadlock_t PQregisterThreadLock(pgthreadlock_t newhandler); - -/* === in fe-trace.c === */ -extern void PQtrace(PGconn *conn, FILE *debug_port); -extern void PQuntrace(PGconn *conn); - -/* flags controlling trace output: */ -/* omit timestamps from each line */ -#define PQTRACE_SUPPRESS_TIMESTAMPS (1<<0) -/* redact portions of some messages, for testing frameworks */ -#define PQTRACE_REGRESS_MODE (1<<1) -extern void PQsetTraceFlags(PGconn *conn, int flags); - -/* === in fe-exec.c === */ - -/* Simple synchronous query */ -extern PGresult *PQexec(PGconn *conn, const char *query); -extern PGresult *PQexecParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); -extern PGresult *PQprepare(PGconn *conn, const char *stmtName, - const char *query, int nParams, - const Oid *paramTypes); -extern PGresult *PQexecPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); - -/* Interface for multiple-result or asynchronous queries */ -#define PQ_QUERY_PARAM_MAX_LIMIT 65535 - -extern int PQsendQuery(PGconn *conn, const char *query); -extern int PQsendQueryParams(PGconn *conn, - const char *command, - int nParams, - const Oid *paramTypes, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); -extern int PQsendPrepare(PGconn *conn, const char *stmtName, - const char *query, int nParams, - const Oid *paramTypes); -extern int PQsendQueryPrepared(PGconn *conn, - const char *stmtName, - int nParams, - const char *const *paramValues, - const int *paramLengths, - const int *paramFormats, - int resultFormat); -extern int PQsetSingleRowMode(PGconn *conn); -extern PGresult *PQgetResult(PGconn *conn); - -/* Routines for managing an asynchronous query */ -extern int PQisBusy(PGconn *conn); -extern int PQconsumeInput(PGconn *conn); - -/* Routines for pipeline mode management */ -extern int PQenterPipelineMode(PGconn *conn); -extern int PQexitPipelineMode(PGconn *conn); -extern int PQpipelineSync(PGconn *conn); -extern int PQsendFlushRequest(PGconn *conn); - -/* LISTEN/NOTIFY support */ -extern PGnotify *PQnotifies(PGconn *conn); - -/* Routines for copy in/out */ -extern int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); -extern int PQputCopyEnd(PGconn *conn, const char *errormsg); -extern int PQgetCopyData(PGconn *conn, char **buffer, int async); - -/* Deprecated routines for copy in/out */ -extern int PQgetline(PGconn *conn, char *buffer, int length); -extern int PQputline(PGconn *conn, const char *string); -extern int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); -extern int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); -extern int PQendcopy(PGconn *conn); - -/* Set blocking/nonblocking connection to the backend */ -extern int PQsetnonblocking(PGconn *conn, int arg); -extern int PQisnonblocking(const PGconn *conn); -extern int PQisthreadsafe(void); -extern PGPing PQping(const char *conninfo); -extern PGPing PQpingParams(const char *const *keywords, - const char *const *values, int expand_dbname); - -/* Force the write buffer to be written (or at least try) */ -extern int PQflush(PGconn *conn); - -/* - * "Fast path" interface --- not really recommended for application - * use - */ -extern PGresult *PQfn(PGconn *conn, - int fnid, - int *result_buf, - int *result_len, - int result_is_int, - const PQArgBlock *args, - int nargs); - -/* Accessor functions for PGresult objects */ -extern ExecStatusType PQresultStatus(const PGresult *res); -extern char *PQresStatus(ExecStatusType status); -extern char *PQresultErrorMessage(const PGresult *res); -extern char *PQresultVerboseErrorMessage(const PGresult *res, - PGVerbosity verbosity, - PGContextVisibility show_context); -extern char *PQresultErrorField(const PGresult *res, int fieldcode); -extern int PQntuples(const PGresult *res); -extern int PQnfields(const PGresult *res); -extern int PQbinaryTuples(const PGresult *res); -extern char *PQfname(const PGresult *res, int field_num); -extern int PQfnumber(const PGresult *res, const char *field_name); -extern Oid PQftable(const PGresult *res, int field_num); -extern int PQftablecol(const PGresult *res, int field_num); -extern int PQfformat(const PGresult *res, int field_num); -extern Oid PQftype(const PGresult *res, int field_num); -extern int PQfsize(const PGresult *res, int field_num); -extern int PQfmod(const PGresult *res, int field_num); -extern char *PQcmdStatus(PGresult *res); -extern char *PQoidStatus(const PGresult *res); /* old and ugly */ -extern Oid PQoidValue(const PGresult *res); /* new and improved */ -extern char *PQcmdTuples(PGresult *res); -extern char *PQgetvalue(const PGresult *res, int tup_num, int field_num); -extern int PQgetlength(const PGresult *res, int tup_num, int field_num); -extern int PQgetisnull(const PGresult *res, int tup_num, int field_num); -extern int PQnparams(const PGresult *res); -extern Oid PQparamtype(const PGresult *res, int param_num); - -/* Describe prepared statements and portals */ -extern PGresult *PQdescribePrepared(PGconn *conn, const char *stmt); -extern PGresult *PQdescribePortal(PGconn *conn, const char *portal); -extern int PQsendDescribePrepared(PGconn *conn, const char *stmt); -extern int PQsendDescribePortal(PGconn *conn, const char *portal); - -/* Delete a PGresult */ -extern void PQclear(PGresult *res); - -/* For freeing other alloc'd results, such as PGnotify structs */ -extern void PQfreemem(void *ptr); - -/* Exists for backward compatibility. bjm 2003-03-24 */ -#define PQfreeNotify(ptr) PQfreemem(ptr) - -/* Error when no password was given. */ -/* Note: depending on this is deprecated; use PQconnectionNeedsPassword(). */ -#define PQnoPasswordSupplied "fe_sendauth: no password supplied\n" - -/* Create and manipulate PGresults */ -extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status); -extern PGresult *PQcopyResult(const PGresult *src, int flags); -extern int PQsetResultAttrs(PGresult *res, int numAttributes, PGresAttDesc *attDescs); -extern void *PQresultAlloc(PGresult *res, size_t nBytes); -extern size_t PQresultMemorySize(const PGresult *res); -extern int PQsetvalue(PGresult *res, int tup_num, int field_num, char *value, int len); - -/* Quoting strings before inclusion in queries. */ -extern size_t PQescapeStringConn(PGconn *conn, - char *to, const char *from, size_t length, - int *error); -extern char *PQescapeLiteral(PGconn *conn, const char *str, size_t len); -extern char *PQescapeIdentifier(PGconn *conn, const char *str, size_t len); -extern unsigned char *PQescapeByteaConn(PGconn *conn, - const unsigned char *from, size_t from_length, - size_t *to_length); -extern unsigned char *PQunescapeBytea(const unsigned char *strtext, - size_t *retbuflen); - -/* These forms are deprecated! */ -extern size_t PQescapeString(char *to, const char *from, size_t length); -extern unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, - size_t *to_length); - - - -/* === in fe-print.c === */ - -extern void PQprint(FILE *fout, /* output stream */ - const PGresult *res, - const PQprintOpt *po); /* option structure */ - -/* - * really old printing routines - */ -extern void PQdisplayTuples(const PGresult *res, - FILE *fp, /* where to send the output */ - int fillAlign, /* pad the fields with spaces */ - const char *fieldSep, /* field separator */ - int printHeader, /* display headers? */ - int quiet); - -extern void PQprintTuples(const PGresult *res, - FILE *fout, /* output stream */ - int PrintAttNames, /* print attribute names */ - int TerseOutput, /* delimiter bars */ - int colWidth); /* width of column, if 0, use - * variable width */ - - -/* === in fe-lobj.c === */ - -/* Large-object access routines */ -extern int lo_open(PGconn *conn, Oid lobjId, int mode); -extern int lo_close(PGconn *conn, int fd); -extern int lo_read(PGconn *conn, int fd, char *buf, size_t len); -extern int lo_write(PGconn *conn, int fd, const char *buf, size_t len); -extern int lo_lseek(PGconn *conn, int fd, int offset, int whence); -extern pg_int64 lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence); -extern Oid lo_creat(PGconn *conn, int mode); -extern Oid lo_create(PGconn *conn, Oid lobjId); -extern int lo_tell(PGconn *conn, int fd); -extern pg_int64 lo_tell64(PGconn *conn, int fd); -extern int lo_truncate(PGconn *conn, int fd, size_t len); -extern int lo_truncate64(PGconn *conn, int fd, pg_int64 len); -extern int lo_unlink(PGconn *conn, Oid lobjId); -extern Oid lo_import(PGconn *conn, const char *filename); -extern Oid lo_import_with_oid(PGconn *conn, const char *filename, Oid lobjId); -extern int lo_export(PGconn *conn, Oid lobjId, const char *filename); - -/* === in fe-misc.c === */ - -/* Get the version of the libpq library in use */ -extern int PQlibVersion(void); - -/* Determine length of multibyte encoded char at *s */ -extern int PQmblen(const char *s, int encoding); - -/* Same, but not more than the distance to the end of string s */ -extern int PQmblenBounded(const char *s, int encoding); - -/* Determine display length of multibyte encoded char at *s */ -extern int PQdsplen(const char *s, int encoding); - -/* Get encoding id from environment variable PGCLIENTENCODING */ -extern int PQenv2encoding(void); - -/* === in fe-auth.c === */ - -extern char *PQencryptPassword(const char *passwd, const char *user); -extern char *PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user, const char *algorithm); - -/* === in encnames.c === */ - -extern int pg_char_to_encoding(const char *name); -extern const char *pg_encoding_to_char(int encoding); -extern int pg_valid_server_encoding_id(int encoding); - -/* === in fe-secure-openssl.c === */ - -/* Support for overriding sslpassword handling with a callback */ -typedef int (*PQsslKeyPassHook_OpenSSL_type) (char *buf, int size, PGconn *conn); -extern PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL(void); -extern void PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook); -extern int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn); - -#ifdef __cplusplus -} -#endif - -#endif /* LIBPQ_FE_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/libpq-int.h b/contrib/libs/libpq/src/interfaces/libpq/libpq-int.h deleted file mode 100644 index a951f4992b..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/libpq-int.h +++ /dev/null @@ -1,940 +0,0 @@ -/*------------------------------------------------------------------------- - * - * libpq-int.h - * This file contains internal definitions meant to be used only by - * the frontend libpq library, not by applications that call it. - * - * An application can include this file if it wants to bypass the - * official API defined by libpq-fe.h, but code that does so is much - * more likely to break across PostgreSQL releases than code that uses - * only the official API. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/libpq-int.h - * - *------------------------------------------------------------------------- - */ - -#ifndef LIBPQ_INT_H -#define LIBPQ_INT_H - -/* We assume libpq-fe.h has already been included. */ -#include "libpq-events.h" - -#include <netdb.h> -#include <sys/socket.h> -#include <time.h> -/* MinGW has sys/time.h, but MSVC doesn't */ -#ifndef _MSC_VER -#include <sys/time.h> -#endif - -#ifdef ENABLE_THREAD_SAFETY -#ifdef WIN32 -#include "pthread-win32.h" -#else -#include <pthread.h> -#endif -#include <signal.h> -#endif - -/* include stuff common to fe and be */ -#include "libpq/pqcomm.h" -/* include stuff found in fe only */ -#include "fe-auth-sasl.h" -#include "pqexpbuffer.h" - -#ifdef ENABLE_GSS -#if defined(HAVE_GSSAPI_H) -#include <gssapi.h> -#else -#include <gssapi/gssapi.h> -#endif -#endif - -#ifdef ENABLE_SSPI -#define SECURITY_WIN32 -#if defined(WIN32) && !defined(_MSC_VER) -#include <ntsecapi.h> -#endif -#include <security.h> -#undef SECURITY_WIN32 - -#ifndef ENABLE_GSS -/* - * Define a fake structure compatible with GSSAPI on Unix. - */ -typedef struct -{ - void *value; - int length; -} gss_buffer_desc; -#endif -#endif /* ENABLE_SSPI */ - -#ifdef USE_OPENSSL -#include <openssl/ssl.h> -#include <openssl/err.h> - -#ifndef OPENSSL_NO_ENGINE -#define USE_SSL_ENGINE -#endif -#endif /* USE_OPENSSL */ - -#include "common/pg_prng.h" - -/* - * POSTGRES backend dependent Constants. - */ -#define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */ - -/* - * PGresult and the subsidiary types PGresAttDesc, PGresAttValue - * represent the result of a query (or more precisely, of a single SQL - * command --- a query string given to PQexec can contain multiple commands). - * Note we assume that a single command can return at most one tuple group, - * hence there is no need for multiple descriptor sets. - */ - -/* Subsidiary-storage management structure for PGresult. - * See space management routines in fe-exec.c for details. - * Note that space[k] refers to the k'th byte starting from the physical - * head of the block --- it's a union, not a struct! - */ -typedef union pgresult_data PGresult_data; - -union pgresult_data -{ - PGresult_data *next; /* link to next block, or NULL */ - char space[1]; /* dummy for accessing block as bytes */ -}; - -/* Data about a single parameter of a prepared statement */ -typedef struct pgresParamDesc -{ - Oid typid; /* type id */ -} PGresParamDesc; - -/* - * Data for a single attribute of a single tuple - * - * We use char* for Attribute values. - * - * The value pointer always points to a null-terminated area; we add a - * null (zero) byte after whatever the backend sends us. This is only - * particularly useful for text values ... with a binary value, the - * value might have embedded nulls, so the application can't use C string - * operators on it. But we add a null anyway for consistency. - * Note that the value itself does not contain a length word. - * - * A NULL attribute is a special case in two ways: its len field is NULL_LEN - * and its value field points to null_field in the owning PGresult. All the - * NULL attributes in a query result point to the same place (there's no need - * to store a null string separately for each one). - */ - -#define NULL_LEN (-1) /* pg_result len for NULL value */ - -typedef struct pgresAttValue -{ - int len; /* length in bytes of the value */ - char *value; /* actual value, plus terminating zero byte */ -} PGresAttValue; - -/* Typedef for message-field list entries */ -typedef struct pgMessageField -{ - struct pgMessageField *next; /* list link */ - char code; /* field code */ - char contents[FLEXIBLE_ARRAY_MEMBER]; /* value, nul-terminated */ -} PGMessageField; - -/* Fields needed for notice handling */ -typedef struct -{ - PQnoticeReceiver noticeRec; /* notice message receiver */ - void *noticeRecArg; - PQnoticeProcessor noticeProc; /* notice message processor */ - void *noticeProcArg; -} PGNoticeHooks; - -typedef struct PGEvent -{ - PGEventProc proc; /* the function to call on events */ - char *name; /* used only for error messages */ - void *passThrough; /* pointer supplied at registration time */ - void *data; /* optional state (instance) data */ - bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */ -} PGEvent; - -struct pg_result -{ - int ntups; - int numAttributes; - PGresAttDesc *attDescs; - PGresAttValue **tuples; /* each PGresult tuple is an array of - * PGresAttValue's */ - int tupArrSize; /* allocated size of tuples array */ - int numParameters; - PGresParamDesc *paramDescs; - ExecStatusType resultStatus; - char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */ - int binary; /* binary tuple values if binary == 1, - * otherwise text */ - - /* - * These fields are copied from the originating PGconn, so that operations - * on the PGresult don't have to reference the PGconn. - */ - PGNoticeHooks noticeHooks; - PGEvent *events; - int nEvents; - int client_encoding; /* encoding id */ - - /* - * Error information (all NULL if not an error result). errMsg is the - * "overall" error message returned by PQresultErrorMessage. If we have - * per-field info then it is stored in a linked list. - */ - char *errMsg; /* error message, or NULL if no error */ - PGMessageField *errFields; /* message broken into fields */ - char *errQuery; /* text of triggering query, if available */ - - /* All NULL attributes in the query result point to this null string */ - char null_field[1]; - - /* - * Space management information. Note that attDescs and error stuff, if - * not null, point into allocated blocks. But tuples points to a - * separately malloc'd block, so that we can realloc it. - */ - PGresult_data *curBlock; /* most recently allocated block */ - int curOffset; /* start offset of free space in block */ - int spaceLeft; /* number of free bytes remaining in block */ - - size_t memorySize; /* total space allocated for this PGresult */ -}; - -/* PGAsyncStatusType defines the state of the query-execution state machine */ -typedef enum -{ - PGASYNC_IDLE, /* nothing's happening, dude */ - PGASYNC_BUSY, /* query in progress */ - PGASYNC_READY, /* query done, waiting for client to fetch - * result */ - PGASYNC_READY_MORE, /* query done, waiting for client to fetch - * result, more results expected from this - * query */ - PGASYNC_COPY_IN, /* Copy In data transfer in progress */ - PGASYNC_COPY_OUT, /* Copy Out data transfer in progress */ - PGASYNC_COPY_BOTH, /* Copy In/Out data transfer in progress */ - PGASYNC_PIPELINE_IDLE, /* "Idle" between commands in pipeline mode */ -} PGAsyncStatusType; - -/* Target server type (decoded value of target_session_attrs) */ -typedef enum -{ - SERVER_TYPE_ANY = 0, /* Any server (default) */ - SERVER_TYPE_READ_WRITE, /* Read-write server */ - SERVER_TYPE_READ_ONLY, /* Read-only server */ - SERVER_TYPE_PRIMARY, /* Primary server */ - SERVER_TYPE_STANDBY, /* Standby server */ - SERVER_TYPE_PREFER_STANDBY, /* Prefer standby server */ - SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */ -} PGTargetServerType; - -/* Target server type (decoded value of load_balance_hosts) */ -typedef enum -{ - LOAD_BALANCE_DISABLE = 0, /* Use the existing host order (default) */ - LOAD_BALANCE_RANDOM, /* Randomly shuffle the hosts */ -} PGLoadBalanceType; - -/* Boolean value plus a not-known state, for GUCs we might have to fetch */ -typedef enum -{ - PG_BOOL_UNKNOWN = 0, /* Currently unknown */ - PG_BOOL_YES, /* Yes (true) */ - PG_BOOL_NO /* No (false) */ -} PGTernaryBool; - -/* Typedef for the EnvironmentOptions[] array */ -typedef struct PQEnvironmentOption -{ - const char *envName, /* name of an environment variable */ - *pgName; /* name of corresponding SET variable */ -} PQEnvironmentOption; - -/* Typedef for parameter-status list entries */ -typedef struct pgParameterStatus -{ - struct pgParameterStatus *next; /* list link */ - char *name; /* parameter name */ - char *value; /* parameter value */ - /* Note: name and value are stored in same malloc block as struct is */ -} pgParameterStatus; - -/* large-object-access data ... allocated only if large-object code is used. */ -typedef struct pgLobjfuncs -{ - Oid fn_lo_open; /* OID of backend function lo_open */ - Oid fn_lo_close; /* OID of backend function lo_close */ - Oid fn_lo_creat; /* OID of backend function lo_creat */ - Oid fn_lo_create; /* OID of backend function lo_create */ - Oid fn_lo_unlink; /* OID of backend function lo_unlink */ - Oid fn_lo_lseek; /* OID of backend function lo_lseek */ - Oid fn_lo_lseek64; /* OID of backend function lo_lseek64 */ - Oid fn_lo_tell; /* OID of backend function lo_tell */ - Oid fn_lo_tell64; /* OID of backend function lo_tell64 */ - Oid fn_lo_truncate; /* OID of backend function lo_truncate */ - Oid fn_lo_truncate64; /* OID of function lo_truncate64 */ - Oid fn_lo_read; /* OID of backend function LOread */ - Oid fn_lo_write; /* OID of backend function LOwrite */ -} PGlobjfuncs; - -/* PGdataValue represents a data field value being passed to a row processor. - * It could be either text or binary data; text data is not zero-terminated. - * A SQL NULL is represented by len < 0; then value is still valid but there - * are no data bytes there. - */ -typedef struct pgDataValue -{ - int len; /* data length in bytes, or <0 if NULL */ - const char *value; /* data value, without zero-termination */ -} PGdataValue; - -/* Host address type enum for struct pg_conn_host */ -typedef enum pg_conn_host_type -{ - CHT_HOST_NAME, - CHT_HOST_ADDRESS, - CHT_UNIX_SOCKET -} pg_conn_host_type; - -/* - * PGQueryClass tracks which query protocol is in use for each command queue - * entry, or special operation in execution - */ -typedef enum -{ - PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */ - PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */ - PGQUERY_PREPARE, /* Parse only (PQprepare) */ - PGQUERY_DESCRIBE, /* Describe Statement or Portal */ - PGQUERY_SYNC, /* Sync (at end of a pipeline) */ - PGQUERY_CLOSE -} PGQueryClass; - -/* - * An entry in the pending command queue. - */ -typedef struct PGcmdQueueEntry -{ - PGQueryClass queryclass; /* Query type */ - char *query; /* SQL command, or NULL if none/unknown/OOM */ - struct PGcmdQueueEntry *next; /* list link */ -} PGcmdQueueEntry; - -/* - * pg_conn_host stores all information about each of possibly several hosts - * mentioned in the connection string. Most fields are derived by splitting - * the relevant connection parameter (e.g., pghost) at commas. - */ -typedef struct pg_conn_host -{ - pg_conn_host_type type; /* type of host address */ - char *host; /* host name or socket path */ - char *hostaddr; /* host numeric IP address */ - char *port; /* port number (always provided) */ - char *password; /* password for this host, read from the - * password file; NULL if not sought or not - * found in password file. */ -} pg_conn_host; - -/* - * PGconn stores all the state data associated with a single connection - * to a backend. - */ -struct pg_conn -{ - /* Saved values of connection options */ - char *pghost; /* the machine on which the server is running, - * or a path to a UNIX-domain socket, or a - * comma-separated list of machines and/or - * paths; if NULL, use DEFAULT_PGSOCKET_DIR */ - char *pghostaddr; /* the numeric IP address of the machine on - * which the server is running, or a - * comma-separated list of same. Takes - * precedence over pghost. */ - char *pgport; /* the server's communication port number, or - * a comma-separated list of ports */ - char *connect_timeout; /* connection timeout (numeric string) */ - char *pgtcp_user_timeout; /* tcp user timeout (numeric string) */ - char *client_encoding_initial; /* encoding to use */ - char *pgoptions; /* options to start the backend with */ - char *appname; /* application name */ - char *fbappname; /* fallback application name */ - char *dbName; /* database name */ - char *replication; /* connect as the replication standby? */ - char *pguser; /* Postgres username and password, if any */ - char *pgpass; - char *pgpassfile; /* path to a file containing password(s) */ - char *channel_binding; /* channel binding mode - * (require,prefer,disable) */ - char *keepalives; /* use TCP keepalives? */ - char *keepalives_idle; /* time between TCP keepalives */ - char *keepalives_interval; /* time between TCP keepalive - * retransmits */ - char *keepalives_count; /* maximum number of TCP keepalive - * retransmits */ - char *sslmode; /* SSL mode (require,prefer,allow,disable) */ - char *sslcompression; /* SSL compression (0 or 1) */ - char *sslkey; /* client key filename */ - char *sslcert; /* client certificate filename */ - char *sslpassword; /* client key file password */ - char *sslcertmode; /* client cert mode (require,allow,disable) */ - char *sslrootcert; /* root certificate filename */ - char *sslcrl; /* certificate revocation list filename */ - char *sslcrldir; /* certificate revocation list directory name */ - char *sslsni; /* use SSL SNI extension (0 or 1) */ - char *requirepeer; /* required peer credentials for local sockets */ - char *gssencmode; /* GSS mode (require,prefer,disable) */ - char *krbsrvname; /* Kerberos service name */ - char *gsslib; /* What GSS library to use ("gssapi" or - * "sspi") */ - char *gssdelegation; /* Try to delegate GSS credentials? (0 or 1) */ - char *ssl_min_protocol_version; /* minimum TLS protocol version */ - char *ssl_max_protocol_version; /* maximum TLS protocol version */ - char *target_session_attrs; /* desired session properties */ - char *require_auth; /* name of the expected auth method */ - char *load_balance_hosts; /* load balance over hosts */ - - /* Optional file to write trace info to */ - FILE *Pfdebug; - int traceFlags; - - /* Callback procedures for notice message processing */ - PGNoticeHooks noticeHooks; - - /* Event procs registered via PQregisterEventProc */ - PGEvent *events; /* expandable array of event data */ - int nEvents; /* number of active events */ - int eventArraySize; /* allocated array size */ - - /* Status indicators */ - ConnStatusType status; - PGAsyncStatusType asyncStatus; - PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ - char last_sqlstate[6]; /* last reported SQLSTATE */ - bool options_valid; /* true if OK to attempt connection */ - bool nonblocking; /* whether this connection is using nonblock - * sending semantics */ - PGpipelineStatus pipelineStatus; /* status of pipeline mode */ - bool singleRowMode; /* return current query result row-by-row? */ - char copy_is_binary; /* 1 = copy binary, 0 = copy text */ - int copy_already_done; /* # bytes already returned in COPY OUT */ - PGnotify *notifyHead; /* oldest unreported Notify msg */ - PGnotify *notifyTail; /* newest unreported Notify msg */ - - /* Support for multiple hosts in connection string */ - int nconnhost; /* # of hosts named in conn string */ - int whichhost; /* host we're currently trying/connected to */ - pg_conn_host *connhost; /* details about each named host */ - char *connip; /* IP address for current network connection */ - - /* - * The pending command queue as a singly-linked list. Head is the command - * currently in execution, tail is where new commands are added. - */ - PGcmdQueueEntry *cmd_queue_head; - PGcmdQueueEntry *cmd_queue_tail; - - /* - * To save malloc traffic, we don't free entries right away; instead we - * save them in this list for possible reuse. - */ - PGcmdQueueEntry *cmd_queue_recycle; - - /* Connection data */ - pgsocket sock; /* FD for socket, PGINVALID_SOCKET if - * unconnected */ - SockAddr laddr; /* Local address */ - SockAddr raddr; /* Remote address */ - ProtocolVersion pversion; /* FE/BE protocol version in use */ - int sversion; /* server version, e.g. 70401 for 7.4.1 */ - bool auth_req_received; /* true if any type of auth req received */ - bool password_needed; /* true if server demanded a password */ - bool gssapi_used; /* true if authenticated via gssapi */ - bool sigpipe_so; /* have we masked SIGPIPE via SO_NOSIGPIPE? */ - bool sigpipe_flag; /* can we mask SIGPIPE via MSG_NOSIGNAL? */ - bool write_failed; /* have we had a write failure on sock? */ - char *write_err_msg; /* write error message, or NULL if OOM */ - - bool auth_required; /* require an authentication challenge from - * the server? */ - uint32 allowed_auth_methods; /* bitmask of acceptable AuthRequest - * codes */ - bool client_finished_auth; /* have we finished our half of the - * authentication exchange? */ - - - /* Transient state needed while establishing connection */ - PGTargetServerType target_server_type; /* desired session properties */ - PGLoadBalanceType load_balance_type; /* desired load balancing - * algorithm */ - bool try_next_addr; /* time to advance to next address/host? */ - bool try_next_host; /* time to advance to next connhost[]? */ - int naddr; /* number of addresses returned by getaddrinfo */ - int whichaddr; /* the address currently being tried */ - AddrInfo *addr; /* the array of addresses for the currently - * tried host */ - bool send_appname; /* okay to send application_name? */ - - /* Miscellaneous stuff */ - int be_pid; /* PID of backend --- needed for cancels */ - int be_key; /* key of backend --- needed for cancels */ - pgParameterStatus *pstatus; /* ParameterStatus data */ - int client_encoding; /* encoding id */ - bool std_strings; /* standard_conforming_strings */ - PGTernaryBool default_transaction_read_only; /* default_transaction_read_only */ - PGTernaryBool in_hot_standby; /* in_hot_standby */ - PGVerbosity verbosity; /* error/notice message verbosity */ - PGContextVisibility show_context; /* whether to show CONTEXT field */ - PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ - pg_prng_state prng_state; /* prng state for load balancing connections */ - - - /* Buffer for data received from backend and not yet processed */ - char *inBuffer; /* currently allocated buffer */ - int inBufSize; /* allocated size of buffer */ - int inStart; /* offset to first unconsumed data in buffer */ - int inCursor; /* next byte to tentatively consume */ - int inEnd; /* offset to first position after avail data */ - - /* Buffer for data not yet sent to backend */ - char *outBuffer; /* currently allocated buffer */ - int outBufSize; /* allocated size of buffer */ - int outCount; /* number of chars waiting in buffer */ - - /* State for constructing messages in outBuffer */ - int outMsgStart; /* offset to msg start (length word); if -1, - * msg has no length word */ - int outMsgEnd; /* offset to msg end (so far) */ - - /* Row processor interface workspace */ - PGdataValue *rowBuf; /* array for passing values to rowProcessor */ - int rowBufLen; /* number of entries allocated in rowBuf */ - - /* - * Status for asynchronous result construction. If result isn't NULL, it - * is a result being constructed or ready to return. If result is NULL - * and error_result is true, then we need to return a PGRES_FATAL_ERROR - * result, but haven't yet constructed it; text for the error has been - * appended to conn->errorMessage. (Delaying construction simplifies - * dealing with out-of-memory cases.) If next_result isn't NULL, it is a - * PGresult that will replace "result" after we return that one. - */ - PGresult *result; /* result being constructed */ - bool error_result; /* do we need to make an ERROR result? */ - PGresult *next_result; /* next result (used in single-row mode) */ - - /* Assorted state for SASL, SSL, GSS, etc */ - const pg_fe_sasl_mech *sasl; - void *sasl_state; - int scram_sha_256_iterations; - - /* SSL structures */ - bool ssl_in_use; - bool ssl_cert_requested; /* Did the server ask us for a cert? */ - bool ssl_cert_sent; /* Did we send one in reply? */ - -#ifdef USE_SSL - bool allow_ssl_try; /* Allowed to try SSL negotiation */ - bool wait_ssl_try; /* Delay SSL negotiation until after - * attempting normal connection */ -#ifdef USE_OPENSSL - SSL *ssl; /* SSL status, if have SSL connection */ - X509 *peer; /* X509 cert of server */ -#ifdef USE_SSL_ENGINE - ENGINE *engine; /* SSL engine, if any */ -#else - void *engine; /* dummy field to keep struct the same if - * OpenSSL version changes */ -#endif - bool crypto_loaded; /* Track if libcrypto locking callbacks have - * been done for this connection. This can be - * removed once support for OpenSSL 1.0.2 is - * removed as this locking is handled - * internally in OpenSSL >= 1.1.0. */ -#endif /* USE_OPENSSL */ -#endif /* USE_SSL */ - -#ifdef ENABLE_GSS - gss_ctx_id_t gctx; /* GSS context */ - gss_name_t gtarg_nam; /* GSS target name */ - - /* The following are encryption-only */ - bool try_gss; /* GSS attempting permitted */ - bool gssenc; /* GSS encryption is usable */ - gss_cred_id_t gcred; /* GSS credential temp storage. */ - - /* GSS encryption I/O state --- see fe-secure-gssapi.c */ - char *gss_SendBuffer; /* Encrypted data waiting to be sent */ - int gss_SendLength; /* End of data available in gss_SendBuffer */ - int gss_SendNext; /* Next index to send a byte from - * gss_SendBuffer */ - int gss_SendConsumed; /* Number of source bytes encrypted but - * not yet reported as sent */ - char *gss_RecvBuffer; /* Received, encrypted data */ - int gss_RecvLength; /* End of data available in gss_RecvBuffer */ - char *gss_ResultBuffer; /* Decryption of data in gss_RecvBuffer */ - int gss_ResultLength; /* End of data available in - * gss_ResultBuffer */ - int gss_ResultNext; /* Next index to read a byte from - * gss_ResultBuffer */ - uint32 gss_MaxPktSize; /* Maximum size we can encrypt and fit the - * results into our output buffer */ -#endif - -#ifdef ENABLE_SSPI - CredHandle *sspicred; /* SSPI credentials handle */ - CtxtHandle *sspictx; /* SSPI context */ - char *sspitarget; /* SSPI target name */ - int usesspi; /* Indicate if SSPI is in use on the - * connection */ -#endif - - /* - * Buffer for current error message. This is cleared at the start of any - * connection attempt or query cycle; after that, all code should append - * messages to it, never overwrite. - * - * In some situations we might report an error more than once in a query - * cycle. If so, errorMessage accumulates text from all the errors, and - * errorReported tracks how much we've already reported, so that the - * individual error PGresult objects don't contain duplicative text. - */ - PQExpBufferData errorMessage; /* expansible string */ - int errorReported; /* # bytes of string already reported */ - - /* Buffer for receiving various parts of messages */ - PQExpBufferData workBuffer; /* expansible string */ -}; - -/* PGcancel stores all data necessary to cancel a connection. A copy of this - * data is required to safely cancel a connection running on a different - * thread. - */ -struct pg_cancel -{ - SockAddr raddr; /* Remote address */ - int be_pid; /* PID of backend --- needed for cancels */ - int be_key; /* key of backend --- needed for cancels */ - int pgtcp_user_timeout; /* tcp user timeout */ - int keepalives; /* use TCP keepalives? */ - int keepalives_idle; /* time between TCP keepalives */ - int keepalives_interval; /* time between TCP keepalive - * retransmits */ - int keepalives_count; /* maximum number of TCP keepalive - * retransmits */ -}; - - -/* String descriptions of the ExecStatusTypes. - * direct use of this array is deprecated; call PQresStatus() instead. - */ -extern char *const pgresStatus[]; - - -#ifdef USE_SSL - -#ifndef WIN32 -#define USER_CERT_FILE ".postgresql/postgresql.crt" -#define USER_KEY_FILE ".postgresql/postgresql.key" -#define ROOT_CERT_FILE ".postgresql/root.crt" -#define ROOT_CRL_FILE ".postgresql/root.crl" -#else -/* On Windows, the "home" directory is already PostgreSQL-specific */ -#define USER_CERT_FILE "postgresql.crt" -#define USER_KEY_FILE "postgresql.key" -#define ROOT_CERT_FILE "root.crt" -#define ROOT_CRL_FILE "root.crl" -#endif - -#endif /* USE_SSL */ - -/* ---------------- - * Internal functions of libpq - * Functions declared here need to be visible across files of libpq, - * but are not intended to be called by applications. We use the - * convention "pqXXX" for internal functions, vs. the "PQxxx" names - * used for application-visible routines. - * ---------------- - */ - -/* === in fe-connect.c === */ - -extern void pqDropConnection(PGconn *conn, bool flushInput); -extern int pqPacketSend(PGconn *conn, char pack_type, - const void *buf, size_t buf_len); -extern bool pqGetHomeDirectory(char *buf, int bufsize); - -#ifdef ENABLE_THREAD_SAFETY -extern pgthreadlock_t pg_g_threadlock; - -#define pglock_thread() pg_g_threadlock(true) -#define pgunlock_thread() pg_g_threadlock(false) -#else -#define pglock_thread() ((void) 0) -#define pgunlock_thread() ((void) 0) -#endif - -/* === in fe-exec.c === */ - -extern void pqSetResultError(PGresult *res, PQExpBuffer errorMessage, int offset); -extern void *pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary); -extern char *pqResultStrdup(PGresult *res, const char *str); -extern void pqClearAsyncResult(PGconn *conn); -extern void pqSaveErrorResult(PGconn *conn); -extern PGresult *pqPrepareAsyncResult(PGconn *conn); -extern void pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) pg_attribute_printf(2, 3); -extern void pqSaveMessageField(PGresult *res, char code, - const char *value); -extern void pqSaveParameterStatus(PGconn *conn, const char *name, - const char *value); -extern int pqRowProcessor(PGconn *conn, const char **errmsgp); -extern void pqCommandQueueAdvance(PGconn *conn, bool isReadyForQuery, - bool gotSync); -extern int PQsendQueryContinue(PGconn *conn, const char *query); - -/* === in fe-protocol3.c === */ - -extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, - const PQEnvironmentOption *options); -extern void pqParseInput3(PGconn *conn); -extern int pqGetErrorNotice3(PGconn *conn, bool isError); -extern void pqBuildErrorMessage3(PQExpBuffer msg, const PGresult *res, - PGVerbosity verbosity, PGContextVisibility show_context); -extern int pqGetNegotiateProtocolVersion3(PGconn *conn); -extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); -extern int pqGetline3(PGconn *conn, char *s, int maxlen); -extern int pqGetlineAsync3(PGconn *conn, char *buffer, int bufsize); -extern int pqEndcopy3(PGconn *conn); -extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, - int *result_buf, int *actual_result_len, - int result_is_int, - const PQArgBlock *args, int nargs); - -/* === in fe-misc.c === */ - - /* - * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for - * Get, EOF merely means the buffer is exhausted, not that there is - * necessarily any error. - */ -extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn); -extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn); -extern int pqGetc(char *result, PGconn *conn); -extern int pqPutc(char c, PGconn *conn); -extern int pqGets(PQExpBuffer buf, PGconn *conn); -extern int pqGets_append(PQExpBuffer buf, PGconn *conn); -extern int pqPuts(const char *s, PGconn *conn); -extern int pqGetnchar(char *s, size_t len, PGconn *conn); -extern int pqSkipnchar(size_t len, PGconn *conn); -extern int pqPutnchar(const char *s, size_t len, PGconn *conn); -extern int pqGetInt(int *result, size_t bytes, PGconn *conn); -extern int pqPutInt(int value, size_t bytes, PGconn *conn); -extern int pqPutMsgStart(char msg_type, PGconn *conn); -extern int pqPutMsgEnd(PGconn *conn); -extern int pqReadData(PGconn *conn); -extern int pqFlush(PGconn *conn); -extern int pqWait(int forRead, int forWrite, PGconn *conn); -extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn, - time_t finish_time); -extern int pqReadReady(PGconn *conn); -extern int pqWriteReady(PGconn *conn); - -/* === in fe-secure.c === */ - -extern int pqsecure_initialize(PGconn *, bool, bool); -extern PostgresPollingStatusType pqsecure_open_client(PGconn *); -extern void pqsecure_close(PGconn *); -extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); -extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); -extern ssize_t pqsecure_raw_read(PGconn *, void *ptr, size_t len); -extern ssize_t pqsecure_raw_write(PGconn *, const void *ptr, size_t len); - -#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) -extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); -extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, - bool got_epipe); -#endif - -/* === SSL === */ - -/* - * The SSL implementation provides these functions. - */ - -/* - * Implementation of PQinitSSL(). - */ -extern void pgtls_init_library(bool do_ssl, int do_crypto); - -/* - * Initialize SSL library. - * - * The conn parameter is only used to be able to pass back an error - * message - no connection-local setup is made here. do_ssl controls - * if SSL is initialized, and do_crypto does the same for the crypto - * part. - * - * Returns 0 if OK, -1 on failure (adding a message to conn->errorMessage). - */ -extern int pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto); - -/* - * Begin or continue negotiating a secure session. - */ -extern PostgresPollingStatusType pgtls_open_client(PGconn *conn); - -/* - * Close SSL connection. - */ -extern void pgtls_close(PGconn *conn); - -/* - * Read data from a secure connection. - * - * On failure, this function is responsible for appending a suitable message - * to conn->errorMessage. The caller must still inspect errno, but only - * to determine whether to continue/retry after error. - */ -extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len); - -/* - * Is there unread data waiting in the SSL read buffer? - */ -extern bool pgtls_read_pending(PGconn *conn); - -/* - * Write data to a secure connection. - * - * On failure, this function is responsible for appending a suitable message - * to conn->errorMessage. The caller must still inspect errno, but only - * to determine whether to continue/retry after error. - */ -extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len); - -/* - * Get the hash of the server certificate, for SCRAM channel binding type - * tls-server-end-point. - * - * NULL is sent back to the caller in the event of an error, with an - * error message for the caller to consume. - * - * This is not supported with old versions of OpenSSL that don't have - * the X509_get_signature_nid() function. - */ -#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO)) -#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH -extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len); -#endif - -/* - * Verify that the server certificate matches the host name we connected to. - * - * The certificate's Common Name and Subject Alternative Names are considered. - * - * Returns 1 if the name matches, and 0 if it does not. On error, returns - * -1, and sets the libpq error message. - * - */ -extern int pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn, - int *names_examined, - char **first_name); - -/* === GSSAPI === */ - -#ifdef ENABLE_GSS - -/* - * Establish a GSSAPI-encrypted connection. - */ -extern PostgresPollingStatusType pqsecure_open_gss(PGconn *conn); - -/* - * Read and write functions for GSSAPI-encrypted connections, with internal - * buffering to handle nonblocking sockets. - */ -extern ssize_t pg_GSS_write(PGconn *conn, const void *ptr, size_t len); -extern ssize_t pg_GSS_read(PGconn *conn, void *ptr, size_t len); -#endif - -/* === in fe-trace.c === */ - -extern void pqTraceOutputMessage(PGconn *conn, const char *message, - bool toServer); -extern void pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message); - -/* === miscellaneous macros === */ - -/* - * Reset the conn's error-reporting state. - */ -#define pqClearConnErrorState(conn) \ - (resetPQExpBuffer(&(conn)->errorMessage), \ - (conn)->errorReported = 0) - -/* - * Check whether we have a PGresult pending to be returned --- either a - * constructed one in conn->result, or a "virtual" error result that we - * don't intend to materialize until the end of the query cycle. - */ -#define pgHavePendingResult(conn) \ - ((conn)->result != NULL || (conn)->error_result) - -/* - * this is so that we can check if a connection is non-blocking internally - * without the overhead of a function call - */ -#define pqIsnonblocking(conn) ((conn)->nonblocking) - -/* - * Connection's outbuffer threshold, for pipeline mode. - */ -#define OUTBUFFER_THRESHOLD 65536 - -#ifdef ENABLE_NLS -extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); -extern char *libpq_ngettext(const char *msgid, const char *msgid_plural, unsigned long n) pg_attribute_format_arg(1) pg_attribute_format_arg(2); -#else -#define libpq_gettext(x) (x) -#define libpq_ngettext(s, p, n) ((n) == 1 ? (s) : (p)) -#endif -/* - * libpq code should use the above, not _(), since that would use the - * surrounding programs's message catalog. - */ -#undef _ - -extern void libpq_append_error(PQExpBuffer errorMessage, const char *fmt,...) pg_attribute_printf(2, 3); -extern void libpq_append_conn_error(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3); - -/* - * These macros are needed to let error-handling code be portable between - * Unix and Windows. (ugh) - */ -#ifdef WIN32 -#define SOCK_ERRNO (WSAGetLastError()) -#define SOCK_STRERROR winsock_strerror -#define SOCK_ERRNO_SET(e) WSASetLastError(e) -#else -#define SOCK_ERRNO errno -#define SOCK_STRERROR strerror_r -#define SOCK_ERRNO_SET(e) (errno = (e)) -#endif - -#endif /* LIBPQ_INT_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.c b/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.c deleted file mode 100644 index de7e0328db..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.c +++ /dev/null @@ -1,412 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pqexpbuffer.c - * - * PQExpBuffer provides an indefinitely-extensible string data type. - * It can be used to buffer either ordinary C strings (null-terminated text) - * or arbitrary binary data. All storage is allocated with malloc(). - * - * This module is essentially the same as the backend's StringInfo data type, - * but it is intended for use in frontend libpq and client applications. - * Thus, it does not rely on palloc() nor elog(), nor psprintf.c which - * will exit() on error. - * - * It does rely on vsnprintf(); if configure finds that libc doesn't provide - * a usable vsnprintf(), then a copy of our own implementation of it will - * be linked into libpq. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/pqexpbuffer.c - * - *------------------------------------------------------------------------- - */ - -#include "postgres_fe.h" - -#include <limits.h> - -#include "pqexpbuffer.h" - -#ifdef WIN32 -#include "win32.h" -#endif - - -/* All "broken" PQExpBuffers point to this string. */ -static const char oom_buffer[1] = ""; - -/* Need a char * for unconstify() compatibility */ -static const char *oom_buffer_ptr = oom_buffer; - - -/* - * markPQExpBufferBroken - * - * Put a PQExpBuffer in "broken" state if it isn't already. - */ -static void -markPQExpBufferBroken(PQExpBuffer str) -{ - if (str->data != oom_buffer) - free(str->data); - - /* - * Casting away const here is a bit ugly, but it seems preferable to not - * marking oom_buffer const. We want to do that to encourage the compiler - * to put oom_buffer in read-only storage, so that anyone who tries to - * scribble on a broken PQExpBuffer will get a failure. - */ - str->data = unconstify(char *, oom_buffer_ptr); - str->len = 0; - str->maxlen = 0; -} - -/* - * createPQExpBuffer - * - * Create an empty 'PQExpBufferData' & return a pointer to it. - */ -PQExpBuffer -createPQExpBuffer(void) -{ - PQExpBuffer res; - - res = (PQExpBuffer) malloc(sizeof(PQExpBufferData)); - if (res != NULL) - initPQExpBuffer(res); - - return res; -} - -/* - * initPQExpBuffer - * - * Initialize a PQExpBufferData struct (with previously undefined contents) - * to describe an empty string. - */ -void -initPQExpBuffer(PQExpBuffer str) -{ - str->data = (char *) malloc(INITIAL_EXPBUFFER_SIZE); - if (str->data == NULL) - { - str->data = unconstify(char *, oom_buffer_ptr); /* see comment above */ - str->maxlen = 0; - str->len = 0; - } - else - { - str->maxlen = INITIAL_EXPBUFFER_SIZE; - str->len = 0; - str->data[0] = '\0'; - } -} - -/* - * destroyPQExpBuffer(str); - * - * free()s both the data buffer and the PQExpBufferData. - * This is the inverse of createPQExpBuffer(). - */ -void -destroyPQExpBuffer(PQExpBuffer str) -{ - if (str) - { - termPQExpBuffer(str); - free(str); - } -} - -/* - * termPQExpBuffer(str) - * free()s the data buffer but not the PQExpBufferData itself. - * This is the inverse of initPQExpBuffer(). - */ -void -termPQExpBuffer(PQExpBuffer str) -{ - if (str->data != oom_buffer) - free(str->data); - /* just for luck, make the buffer validly empty. */ - str->data = unconstify(char *, oom_buffer_ptr); /* see comment above */ - str->maxlen = 0; - str->len = 0; -} - -/* - * resetPQExpBuffer - * Reset a PQExpBuffer to empty - * - * Note: if possible, a "broken" PQExpBuffer is returned to normal. - */ -void -resetPQExpBuffer(PQExpBuffer str) -{ - if (str) - { - if (str->data != oom_buffer) - { - str->len = 0; - str->data[0] = '\0'; - } - else - { - /* try to reinitialize to valid state */ - initPQExpBuffer(str); - } - } -} - -/* - * enlargePQExpBuffer - * Make sure there is enough space for 'needed' more bytes in the buffer - * ('needed' does not include the terminating null). - * - * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case - * the buffer is left in "broken" state.) - */ -int -enlargePQExpBuffer(PQExpBuffer str, size_t needed) -{ - size_t newlen; - char *newdata; - - if (PQExpBufferBroken(str)) - return 0; /* already failed */ - - /* - * Guard against ridiculous "needed" values, which can occur if we're fed - * bogus data. Without this, we can get an overflow or infinite loop in - * the following. - */ - if (needed >= ((size_t) INT_MAX - str->len)) - { - markPQExpBufferBroken(str); - return 0; - } - - needed += str->len + 1; /* total space required now */ - - /* Because of the above test, we now have needed <= INT_MAX */ - - if (needed <= str->maxlen) - return 1; /* got enough space already */ - - /* - * We don't want to allocate just a little more space with each append; - * for efficiency, double the buffer size each time it overflows. - * Actually, we might need to more than double it if 'needed' is big... - */ - newlen = (str->maxlen > 0) ? (2 * str->maxlen) : 64; - while (needed > newlen) - newlen = 2 * newlen; - - /* - * Clamp to INT_MAX in case we went past it. Note we are assuming here - * that INT_MAX <= UINT_MAX/2, else the above loop could overflow. We - * will still have newlen >= needed. - */ - if (newlen > (size_t) INT_MAX) - newlen = (size_t) INT_MAX; - - newdata = (char *) realloc(str->data, newlen); - if (newdata != NULL) - { - str->data = newdata; - str->maxlen = newlen; - return 1; - } - - markPQExpBufferBroken(str); - return 0; -} - -/* - * printfPQExpBuffer - * Format text data under the control of fmt (an sprintf-like format string) - * and insert it into str. More space is allocated to str if necessary. - * This is a convenience routine that does the same thing as - * resetPQExpBuffer() followed by appendPQExpBuffer(). - */ -void -printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) -{ - int save_errno = errno; - va_list args; - bool done; - - resetPQExpBuffer(str); - - if (PQExpBufferBroken(str)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - errno = save_errno; - va_start(args, fmt); - done = appendPQExpBufferVA(str, fmt, args); - va_end(args); - } while (!done); -} - -/* - * appendPQExpBuffer - * - * Format text data under the control of fmt (an sprintf-like format string) - * and append it to whatever is already in str. More space is allocated - * to str if necessary. This is sort of like a combination of sprintf and - * strcat. - */ -void -appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) -{ - int save_errno = errno; - va_list args; - bool done; - - if (PQExpBufferBroken(str)) - return; /* already failed */ - - /* Loop in case we have to retry after enlarging the buffer. */ - do - { - errno = save_errno; - va_start(args, fmt); - done = appendPQExpBufferVA(str, fmt, args); - va_end(args); - } while (!done); -} - -/* - * appendPQExpBufferVA - * Shared guts of printfPQExpBuffer/appendPQExpBuffer. - * Attempt to format data and append it to str. Returns true if done - * (either successful or hard failure), false if need to retry. - * - * Caution: callers must be sure to preserve their entry-time errno - * when looping, in case the fmt contains "%m". - */ -bool -appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) -{ - size_t avail; - size_t needed; - int nprinted; - - /* - * Try to format the given string into the available space; but if there's - * hardly any space, don't bother trying, just enlarge the buffer first. - */ - if (str->maxlen > str->len + 16) - { - avail = str->maxlen - str->len; - - nprinted = vsnprintf(str->data + str->len, avail, fmt, args); - - /* - * If vsnprintf reports an error, fail (we assume this means there's - * something wrong with the format string). - */ - if (unlikely(nprinted < 0)) - { - markPQExpBufferBroken(str); - return true; - } - - if ((size_t) nprinted < avail) - { - /* Success. Note nprinted does not include trailing null. */ - str->len += nprinted; - return true; - } - - /* - * We assume a C99-compliant vsnprintf, so believe its estimate of the - * required space, and add one for the trailing null. (If it's wrong, - * the logic will still work, but we may loop multiple times.) - * - * Choke if the required space would exceed INT_MAX, since str->maxlen - * can't represent more than that. - */ - if (unlikely(nprinted > INT_MAX - 1)) - { - markPQExpBufferBroken(str); - return true; - } - needed = nprinted + 1; - } - else - { - /* - * We have to guess at how much to enlarge, since we're skipping the - * formatting work. Fortunately, because of enlargePQExpBuffer's - * preference for power-of-2 sizes, this number isn't very sensitive; - * the net effect is that we'll double the buffer size before trying - * to run vsnprintf, which seems sensible. - */ - needed = 32; - } - - /* Increase the buffer size and try again. */ - if (!enlargePQExpBuffer(str, needed)) - return true; /* oops, out of memory */ - - return false; -} - -/* - * appendPQExpBufferStr - * Append the given string to a PQExpBuffer, allocating more space - * if necessary. - */ -void -appendPQExpBufferStr(PQExpBuffer str, const char *data) -{ - appendBinaryPQExpBuffer(str, data, strlen(data)); -} - -/* - * appendPQExpBufferChar - * Append a single byte to str. - * Like appendPQExpBuffer(str, "%c", ch) but much faster. - */ -void -appendPQExpBufferChar(PQExpBuffer str, char ch) -{ - /* Make more room if needed */ - if (!enlargePQExpBuffer(str, 1)) - return; - - /* OK, append the character */ - str->data[str->len] = ch; - str->len++; - str->data[str->len] = '\0'; -} - -/* - * appendBinaryPQExpBuffer - * - * Append arbitrary binary data to a PQExpBuffer, allocating more space - * if necessary. - */ -void -appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen) -{ - /* Make more room if needed */ - if (!enlargePQExpBuffer(str, datalen)) - return; - - /* OK, append the data */ - memcpy(str->data + str->len, data, datalen); - str->len += datalen; - - /* - * Keep a trailing null in place, even though it's probably useless for - * binary data... - */ - str->data[str->len] = '\0'; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.h b/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.h deleted file mode 100644 index 020e94e357..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/pqexpbuffer.h +++ /dev/null @@ -1,192 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pqexpbuffer.h - * Declarations/definitions for "PQExpBuffer" functions. - * - * PQExpBuffer provides an indefinitely-extensible string data type. - * It can be used to buffer either ordinary C strings (null-terminated text) - * or arbitrary binary data. All storage is allocated with malloc(). - * - * This module is essentially the same as the backend's StringInfo data type, - * but it is intended for use in frontend libpq and client applications. - * Thus, it does not rely on palloc() nor elog(). - * - * It does rely on vsnprintf(); if configure finds that libc doesn't provide - * a usable vsnprintf(), then a copy of our own implementation of it will - * be linked into libpq. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * src/interfaces/libpq/pqexpbuffer.h - * - *------------------------------------------------------------------------- - */ -#ifndef PQEXPBUFFER_H -#define PQEXPBUFFER_H - -/*------------------------- - * PQExpBufferData holds information about an extensible string. - * data is the current buffer for the string (allocated with malloc). - * len is the current string length. There is guaranteed to be - * a terminating '\0' at data[len], although this is not very - * useful when the string holds binary data rather than text. - * maxlen is the allocated size in bytes of 'data', i.e. the maximum - * string size (including the terminating '\0' char) that we can - * currently store in 'data' without having to reallocate - * more space. We must always have maxlen > len. - * - * An exception occurs if we failed to allocate enough memory for the string - * buffer. In that case data points to a statically allocated empty string, - * and len = maxlen = 0. - *------------------------- - */ -typedef struct PQExpBufferData -{ - char *data; - size_t len; - size_t maxlen; -} PQExpBufferData; - -typedef PQExpBufferData *PQExpBuffer; - -/*------------------------ - * Test for a broken (out of memory) PQExpBuffer. - * When a buffer is "broken", all operations except resetting or deleting it - * are no-ops. - *------------------------ - */ -#define PQExpBufferBroken(str) \ - ((str) == NULL || (str)->maxlen == 0) - -/*------------------------ - * Same, but for use when using a static or local PQExpBufferData struct. - * For that, a null-pointer test is useless and may draw compiler warnings. - *------------------------ - */ -#define PQExpBufferDataBroken(buf) \ - ((buf).maxlen == 0) - -/*------------------------ - * Initial size of the data buffer in a PQExpBuffer. - * NB: this must be large enough to hold error messages that might - * be returned by PQrequestCancel(). - *------------------------ - */ -#define INITIAL_EXPBUFFER_SIZE 256 - -/*------------------------ - * There are two ways to create a PQExpBuffer object initially: - * - * PQExpBuffer stringptr = createPQExpBuffer(); - * Both the PQExpBufferData and the data buffer are malloc'd. - * - * PQExpBufferData string; - * initPQExpBuffer(&string); - * The data buffer is malloc'd but the PQExpBufferData is presupplied. - * This is appropriate if the PQExpBufferData is a field of another - * struct. - *------------------------- - */ - -/*------------------------ - * createPQExpBuffer - * Create an empty 'PQExpBufferData' & return a pointer to it. - */ -extern PQExpBuffer createPQExpBuffer(void); - -/*------------------------ - * initPQExpBuffer - * Initialize a PQExpBufferData struct (with previously undefined contents) - * to describe an empty string. - */ -extern void initPQExpBuffer(PQExpBuffer str); - -/*------------------------ - * To destroy a PQExpBuffer, use either: - * - * destroyPQExpBuffer(str); - * free()s both the data buffer and the PQExpBufferData. - * This is the inverse of createPQExpBuffer(). - * - * termPQExpBuffer(str) - * free()s the data buffer but not the PQExpBufferData itself. - * This is the inverse of initPQExpBuffer(). - * - * NOTE: some routines build up a string using PQExpBuffer, and then - * release the PQExpBufferData but return the data string itself to their - * caller. At that point the data string looks like a plain malloc'd - * string. - */ -extern void destroyPQExpBuffer(PQExpBuffer str); -extern void termPQExpBuffer(PQExpBuffer str); - -/*------------------------ - * resetPQExpBuffer - * Reset a PQExpBuffer to empty - * - * Note: if possible, a "broken" PQExpBuffer is returned to normal. - */ -extern void resetPQExpBuffer(PQExpBuffer str); - -/*------------------------ - * enlargePQExpBuffer - * Make sure there is enough space for 'needed' more bytes in the buffer - * ('needed' does not include the terminating null). - * - * Returns 1 if OK, 0 if failed to enlarge buffer. (In the latter case - * the buffer is left in "broken" state.) - */ -extern int enlargePQExpBuffer(PQExpBuffer str, size_t needed); - -/*------------------------ - * printfPQExpBuffer - * Format text data under the control of fmt (an sprintf-like format string) - * and insert it into str. More space is allocated to str if necessary. - * This is a convenience routine that does the same thing as - * resetPQExpBuffer() followed by appendPQExpBuffer(). - */ -extern void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); - -/*------------------------ - * appendPQExpBuffer - * Format text data under the control of fmt (an sprintf-like format string) - * and append it to whatever is already in str. More space is allocated - * to str if necessary. This is sort of like a combination of sprintf and - * strcat. - */ -extern void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...) pg_attribute_printf(2, 3); - -/*------------------------ - * appendPQExpBufferVA - * Attempt to format data and append it to str. Returns true if done - * (either successful or hard failure), false if need to retry. - * - * Caution: callers must be sure to preserve their entry-time errno - * when looping, in case the fmt contains "%m". - */ -extern bool appendPQExpBufferVA(PQExpBuffer str, const char *fmt, va_list args) pg_attribute_printf(2, 0); - -/*------------------------ - * appendPQExpBufferStr - * Append the given string to a PQExpBuffer, allocating more space - * if necessary. - */ -extern void appendPQExpBufferStr(PQExpBuffer str, const char *data); - -/*------------------------ - * appendPQExpBufferChar - * Append a single byte to str. - * Like appendPQExpBuffer(str, "%c", ch) but much faster. - */ -extern void appendPQExpBufferChar(PQExpBuffer str, char ch); - -/*------------------------ - * appendBinaryPQExpBuffer - * Append arbitrary binary data to a PQExpBuffer, allocating more space - * if necessary. - */ -extern void appendBinaryPQExpBuffer(PQExpBuffer str, - const char *data, size_t datalen); - -#endif /* PQEXPBUFFER_H */ diff --git a/contrib/libs/libpq/src/interfaces/libpq/pthread-win32.c b/contrib/libs/libpq/src/interfaces/libpq/pthread-win32.c deleted file mode 100644 index 8e65637387..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/pthread-win32.c +++ /dev/null @@ -1,60 +0,0 @@ -/*------------------------------------------------------------------------- -* -* pthread-win32.c -* partial pthread implementation for win32 -* -* Copyright (c) 2004-2023, PostgreSQL Global Development Group -* IDENTIFICATION -* src/interfaces/libpq/pthread-win32.c -* -*------------------------------------------------------------------------- -*/ - -#include "postgres_fe.h" - -#include "pthread-win32.h" - -DWORD -pthread_self(void) -{ - return GetCurrentThreadId(); -} - -void -pthread_setspecific(pthread_key_t key, void *val) -{ -} - -void * -pthread_getspecific(pthread_key_t key) -{ - return NULL; -} - -int -pthread_mutex_init(pthread_mutex_t *mp, void *attr) -{ - *mp = (CRITICAL_SECTION *) malloc(sizeof(CRITICAL_SECTION)); - if (!*mp) - return 1; - InitializeCriticalSection(*mp); - return 0; -} - -int -pthread_mutex_lock(pthread_mutex_t *mp) -{ - if (!*mp) - return 1; - EnterCriticalSection(*mp); - return 0; -} - -int -pthread_mutex_unlock(pthread_mutex_t *mp) -{ - if (!*mp) - return 1; - LeaveCriticalSection(*mp); - return 0; -} diff --git a/contrib/libs/libpq/src/interfaces/libpq/win32.c b/contrib/libs/libpq/src/interfaces/libpq/win32.c deleted file mode 100644 index e4d29eefa6..0000000000 --- a/contrib/libs/libpq/src/interfaces/libpq/win32.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * src/interfaces/libpq/win32.c - * - * - * FILE - * win32.c - * - * DESCRIPTION - * Win32 support functions. - * - * Contains table and functions for looking up win32 socket error - * descriptions. But will/may contain other win32 helper functions - * for libpq. - * - * The error constants are taken from the Frambak Bakfram LGSOCKET - * library guys who in turn took them from the Winsock FAQ. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - */ - -/* Make stuff compile faster by excluding not used stuff */ - -#define VC_EXTRALEAN -#ifndef __MINGW32__ -#define NOGDI -#endif -#define NOCRYPT - -#include "postgres_fe.h" - -#include "win32.h" - -/* Declared here to avoid pulling in all includes, which causes name collisions */ -#ifdef ENABLE_NLS -extern char *libpq_gettext(const char *msgid) pg_attribute_format_arg(1); -#else -#define libpq_gettext(x) (x) -#endif - - -static struct WSErrorEntry -{ - DWORD error; - const char *description; -} WSErrors[] = - -{ - { - 0, "No error" - }, - { - WSAEINTR, "Interrupted system call" - }, - { - WSAEBADF, "Bad file number" - }, - { - WSAEACCES, "Permission denied" - }, - { - WSAEFAULT, "Bad address" - }, - { - WSAEINVAL, "Invalid argument" - }, - { - WSAEMFILE, "Too many open sockets" - }, - { - WSAEWOULDBLOCK, "Operation would block" - }, - { - WSAEINPROGRESS, "Operation now in progress" - }, - { - WSAEALREADY, "Operation already in progress" - }, - { - WSAENOTSOCK, "Socket operation on non-socket" - }, - { - WSAEDESTADDRREQ, "Destination address required" - }, - { - WSAEMSGSIZE, "Message too long" - }, - { - WSAEPROTOTYPE, "Protocol wrong type for socket" - }, - { - WSAENOPROTOOPT, "Bad protocol option" - }, - { - WSAEPROTONOSUPPORT, "Protocol not supported" - }, - { - WSAESOCKTNOSUPPORT, "Socket type not supported" - }, - { - WSAEOPNOTSUPP, "Operation not supported on socket" - }, - { - WSAEPFNOSUPPORT, "Protocol family not supported" - }, - { - WSAEAFNOSUPPORT, "Address family not supported" - }, - { - WSAEADDRINUSE, "Address already in use" - }, - { - WSAEADDRNOTAVAIL, "Cannot assign requested address" - }, - { - WSAENETDOWN, "Network is down" - }, - { - WSAENETUNREACH, "Network is unreachable" - }, - { - WSAENETRESET, "Net connection reset" - }, - { - WSAECONNABORTED, "Software caused connection abort" - }, - { - WSAECONNRESET, "Connection reset by peer" - }, - { - WSAENOBUFS, "No buffer space available" - }, - { - WSAEISCONN, "Socket is already connected" - }, - { - WSAENOTCONN, "Socket is not connected" - }, - { - WSAESHUTDOWN, "Cannot send after socket shutdown" - }, - { - WSAETOOMANYREFS, "Too many references, cannot splice" - }, - { - WSAETIMEDOUT, "Connection timed out" - }, - { - WSAECONNREFUSED, "Connection refused" - }, - { - WSAELOOP, "Too many levels of symbolic links" - }, - { - WSAENAMETOOLONG, "File name too long" - }, - { - WSAEHOSTDOWN, "Host is down" - }, - { - WSAEHOSTUNREACH, "No route to host" - }, - { - WSAENOTEMPTY, "Directory not empty" - }, - { - WSAEPROCLIM, "Too many processes" - }, - { - WSAEUSERS, "Too many users" - }, - { - WSAEDQUOT, "Disc quota exceeded" - }, - { - WSAESTALE, "Stale NFS file handle" - }, - { - WSAEREMOTE, "Too many levels of remote in path" - }, - { - WSASYSNOTREADY, "Network system is unavailable" - }, - { - WSAVERNOTSUPPORTED, "Winsock version out of range" - }, - { - WSANOTINITIALISED, "WSAStartup not yet called" - }, - { - WSAEDISCON, "Graceful shutdown in progress" - }, - { - WSAHOST_NOT_FOUND, "Host not found" - }, - { - WSATRY_AGAIN, "NA Host not found / SERVFAIL" - }, - { - WSANO_RECOVERY, "Non recoverable FORMERR||REFUSED||NOTIMP" - }, - { - WSANO_DATA, "No host data of that type was found" - }, - { - 0, 0 - } /* End of table */ -}; - - -/* - * Returns 0 if not found, linear but who cares, at this moment - * we're already in pain :) - */ - -static int -LookupWSErrorMessage(DWORD err, char *dest) -{ - struct WSErrorEntry *e; - - for (e = WSErrors; e->description; e++) - { - if (e->error == err) - { - strcpy(dest, e->description); - return 1; - } - } - return 0; -} - - -struct MessageDLL -{ - const char *dll_name; - void *handle; - int loaded; /* BOOL */ -} dlls[] = - -{ - { - "netmsg.dll", 0, 0 - }, - { - "winsock.dll", 0, 0 - }, - { - "ws2_32.dll", 0, 0 - }, - { - "wsock32n.dll", 0, 0 - }, - { - "mswsock.dll", 0, 0 - }, - { - "ws2help.dll", 0, 0 - }, - { - "ws2thk.dll", 0, 0 - }, - { - 0, 0, 1 - } /* Last one, no dll, always loaded */ -}; - -#define DLLS_SIZE (sizeof(dlls)/sizeof(struct MessageDLL)) - -/* - * Returns a description of the socket error by first trying - * to find it in the lookup table, and if that fails, tries - * to load any of the winsock dlls to find that message. - */ - -const char * -winsock_strerror(int err, char *strerrbuf, size_t buflen) -{ - unsigned long flags; - int offs, - i; - int success = LookupWSErrorMessage(err, strerrbuf); - - for (i = 0; !success && i < DLLS_SIZE; i++) - { - - if (!dlls[i].loaded) - { - dlls[i].loaded = 1; /* Only load once */ - dlls[i].handle = (void *) LoadLibraryEx(dlls[i].dll_name, - 0, - LOAD_LIBRARY_AS_DATAFILE); - } - - if (dlls[i].dll_name && !dlls[i].handle) - continue; /* Didn't load */ - - flags = FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_IGNORE_INSERTS - | (dlls[i].handle ? FORMAT_MESSAGE_FROM_HMODULE : 0); - - success = 0 != FormatMessage(flags, - dlls[i].handle, err, - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - strerrbuf, buflen - 64, - 0); - } - - if (!success) - sprintf(strerrbuf, libpq_gettext("unrecognized socket error: 0x%08X/%d"), err, err); - else - { - strerrbuf[buflen - 1] = '\0'; - offs = strlen(strerrbuf); - if (offs > (int) buflen - 64) - offs = buflen - 64; - sprintf(strerrbuf + offs, " (0x%08X/%d)", err, err); - } - return strerrbuf; -} diff --git a/contrib/libs/libpq/src/port/README b/contrib/libs/libpq/src/port/README deleted file mode 100644 index 97f18a6233..0000000000 --- a/contrib/libs/libpq/src/port/README +++ /dev/null @@ -1,32 +0,0 @@ -src/port/README - -libpgport -========= - -libpgport must have special behavior. It supplies functions to both -libraries and applications. However, there are two complexities: - -1) Libraries need to use object files that are compiled with exactly -the same flags as the library. libpgport might not use the same flags, -so it is necessary to recompile the object files for individual -libraries. This is done by removing -lpgport from the link line: - - # Need to recompile any libpgport object files - LIBS := $(filter-out -lpgport, $(LIBS)) - -and adding infrastructure to recompile the object files: - - OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \ - connect.o misc.o path.o exec.o \ - $(filter strlcat.o, $(LIBOBJS)) - -The problem is that there is no testing of which object files need to be -added, but missing functions usually show up when linking user -applications. - -2) For applications, we use -lpgport before -lpq, so the static files -from libpgport are linked first. This avoids having applications -dependent on symbols that are _used_ by libpq, but not intended to be -exported by libpq. libpq's libpgport usage changes over time, so such a -dependency is a problem. Windows, Linux, AIX, and macOS use an export -list to control the symbols exported by libpq. diff --git a/contrib/libs/libpq/src/port/bsearch_arg.c b/contrib/libs/libpq/src/port/bsearch_arg.c deleted file mode 100644 index 641b40c353..0000000000 --- a/contrib/libs/libpq/src/port/bsearch_arg.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * bsearch_arg.c: bsearch variant with a user-supplied pointer - * - * Copyright (c) 2021-2023, PostgreSQL Global Development Group - * Copyright (c) 1990 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. [rescinded 22 July 1999] - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * src/port/bsearch_arg.c - */ - -#include "c.h" - -/* - * Perform a binary search. - * - * The code below is a bit sneaky. After a comparison fails, we - * divide the work in half by moving either left or right. If lim - * is odd, moving left simply involves halving lim: e.g., when lim - * is 5 we look at item 2, so we change lim to 2 so that we will - * look at items 0 & 1. If lim is even, the same applies. If lim - * is odd, moving right again involves halving lim, this time moving - * the base up one item past p: e.g., when lim is 5 we change base - * to item 3 and make lim 2 so that we will look at items 3 and 4. - * If lim is even, however, we have to shrink it by one before - * halving: e.g., when lim is 4, we still looked at item 2, so we - * have to make lim 3, then halve, obtaining 1, so that we will only - * look at item 3. - */ -void * -bsearch_arg(const void *key, const void *base0, - size_t nmemb, size_t size, - int (*compar) (const void *, const void *, void *), - void *arg) -{ - const char *base = (const char *) base0; - int lim, - cmp; - const void *p; - - for (lim = nmemb; lim != 0; lim >>= 1) - { - p = base + (lim >> 1) * size; - cmp = (*compar) (key, p, arg); - if (cmp == 0) - return (void *) p; - if (cmp > 0) - { /* key > p: move right */ - base = (const char *) p + size; - lim--; - } /* else move left */ - } - return (NULL); -} diff --git a/contrib/libs/libpq/src/port/chklocale.c b/contrib/libs/libpq/src/port/chklocale.c deleted file mode 100644 index 6fa6810a46..0000000000 --- a/contrib/libs/libpq/src/port/chklocale.c +++ /dev/null @@ -1,433 +0,0 @@ -/*------------------------------------------------------------------------- - * - * chklocale.c - * Functions for handling locale-related info - * - * - * Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/port/chklocale.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#ifdef HAVE_LANGINFO_H -#include <langinfo.h> -#endif - -#include "mb/pg_wchar.h" - - -/* - * This table needs to recognize all the CODESET spellings for supported - * backend encodings, as well as frontend-only encodings where possible - * (the latter case is currently only needed for initdb to recognize - * error situations). On Windows, we rely on entries for codepage - * numbers (CPnnn). - * - * Note that we search the table with pg_strcasecmp(), so variant - * capitalizations don't need their own entries. - */ -struct encoding_match -{ - enum pg_enc pg_enc_code; - const char *system_enc_name; -}; - -static const struct encoding_match encoding_match_list[] = { - {PG_EUC_JP, "EUC-JP"}, - {PG_EUC_JP, "eucJP"}, - {PG_EUC_JP, "IBM-eucJP"}, - {PG_EUC_JP, "sdeckanji"}, - {PG_EUC_JP, "CP20932"}, - - {PG_EUC_CN, "EUC-CN"}, - {PG_EUC_CN, "eucCN"}, - {PG_EUC_CN, "IBM-eucCN"}, - {PG_EUC_CN, "GB2312"}, - {PG_EUC_CN, "dechanzi"}, - {PG_EUC_CN, "CP20936"}, - - {PG_EUC_KR, "EUC-KR"}, - {PG_EUC_KR, "eucKR"}, - {PG_EUC_KR, "IBM-eucKR"}, - {PG_EUC_KR, "deckorean"}, - {PG_EUC_KR, "5601"}, - {PG_EUC_KR, "CP51949"}, - - {PG_EUC_TW, "EUC-TW"}, - {PG_EUC_TW, "eucTW"}, - {PG_EUC_TW, "IBM-eucTW"}, - {PG_EUC_TW, "cns11643"}, - /* No codepage for EUC-TW ? */ - - {PG_UTF8, "UTF-8"}, - {PG_UTF8, "utf8"}, - {PG_UTF8, "CP65001"}, - - {PG_LATIN1, "ISO-8859-1"}, - {PG_LATIN1, "ISO8859-1"}, - {PG_LATIN1, "iso88591"}, - {PG_LATIN1, "CP28591"}, - - {PG_LATIN2, "ISO-8859-2"}, - {PG_LATIN2, "ISO8859-2"}, - {PG_LATIN2, "iso88592"}, - {PG_LATIN2, "CP28592"}, - - {PG_LATIN3, "ISO-8859-3"}, - {PG_LATIN3, "ISO8859-3"}, - {PG_LATIN3, "iso88593"}, - {PG_LATIN3, "CP28593"}, - - {PG_LATIN4, "ISO-8859-4"}, - {PG_LATIN4, "ISO8859-4"}, - {PG_LATIN4, "iso88594"}, - {PG_LATIN4, "CP28594"}, - - {PG_LATIN5, "ISO-8859-9"}, - {PG_LATIN5, "ISO8859-9"}, - {PG_LATIN5, "iso88599"}, - {PG_LATIN5, "CP28599"}, - - {PG_LATIN6, "ISO-8859-10"}, - {PG_LATIN6, "ISO8859-10"}, - {PG_LATIN6, "iso885910"}, - - {PG_LATIN7, "ISO-8859-13"}, - {PG_LATIN7, "ISO8859-13"}, - {PG_LATIN7, "iso885913"}, - - {PG_LATIN8, "ISO-8859-14"}, - {PG_LATIN8, "ISO8859-14"}, - {PG_LATIN8, "iso885914"}, - - {PG_LATIN9, "ISO-8859-15"}, - {PG_LATIN9, "ISO8859-15"}, - {PG_LATIN9, "iso885915"}, - {PG_LATIN9, "CP28605"}, - - {PG_LATIN10, "ISO-8859-16"}, - {PG_LATIN10, "ISO8859-16"}, - {PG_LATIN10, "iso885916"}, - - {PG_KOI8R, "KOI8-R"}, - {PG_KOI8R, "CP20866"}, - - {PG_KOI8U, "KOI8-U"}, - {PG_KOI8U, "CP21866"}, - - {PG_WIN866, "CP866"}, - {PG_WIN874, "CP874"}, - {PG_WIN1250, "CP1250"}, - {PG_WIN1251, "CP1251"}, - {PG_WIN1251, "ansi-1251"}, - {PG_WIN1252, "CP1252"}, - {PG_WIN1253, "CP1253"}, - {PG_WIN1254, "CP1254"}, - {PG_WIN1255, "CP1255"}, - {PG_WIN1256, "CP1256"}, - {PG_WIN1257, "CP1257"}, - {PG_WIN1258, "CP1258"}, - - {PG_ISO_8859_5, "ISO-8859-5"}, - {PG_ISO_8859_5, "ISO8859-5"}, - {PG_ISO_8859_5, "iso88595"}, - {PG_ISO_8859_5, "CP28595"}, - - {PG_ISO_8859_6, "ISO-8859-6"}, - {PG_ISO_8859_6, "ISO8859-6"}, - {PG_ISO_8859_6, "iso88596"}, - {PG_ISO_8859_6, "CP28596"}, - - {PG_ISO_8859_7, "ISO-8859-7"}, - {PG_ISO_8859_7, "ISO8859-7"}, - {PG_ISO_8859_7, "iso88597"}, - {PG_ISO_8859_7, "CP28597"}, - - {PG_ISO_8859_8, "ISO-8859-8"}, - {PG_ISO_8859_8, "ISO8859-8"}, - {PG_ISO_8859_8, "iso88598"}, - {PG_ISO_8859_8, "CP28598"}, - - {PG_SJIS, "SJIS"}, - {PG_SJIS, "PCK"}, - {PG_SJIS, "CP932"}, - {PG_SJIS, "SHIFT_JIS"}, - - {PG_BIG5, "BIG5"}, - {PG_BIG5, "BIG5HKSCS"}, - {PG_BIG5, "Big5-HKSCS"}, - {PG_BIG5, "CP950"}, - - {PG_GBK, "GBK"}, - {PG_GBK, "CP936"}, - - {PG_UHC, "UHC"}, - {PG_UHC, "CP949"}, - - {PG_JOHAB, "JOHAB"}, - {PG_JOHAB, "CP1361"}, - - {PG_GB18030, "GB18030"}, - {PG_GB18030, "CP54936"}, - - {PG_SHIFT_JIS_2004, "SJIS_2004"}, - - {PG_SQL_ASCII, "US-ASCII"}, - - {PG_SQL_ASCII, NULL} /* end marker */ -}; - -#ifdef WIN32 -/* - * On Windows, use CP<code page number> instead of the nl_langinfo() result - * - * This routine uses GetLocaleInfoEx() to parse short locale names like - * "de-DE", "fr-FR", etc. If those cannot be parsed correctly process falls - * back to the pre-VS-2010 manual parsing done with using - * <Language>_<Country>.<CodePage> as a base. - * - * Returns a malloc()'d string for the caller to free. - */ -static char * -win32_langinfo(const char *ctype) -{ - char *r = NULL; - char *codepage; - -#if defined(_MSC_VER) - uint32 cp; - WCHAR wctype[LOCALE_NAME_MAX_LENGTH]; - - memset(wctype, 0, sizeof(wctype)); - MultiByteToWideChar(CP_ACP, 0, ctype, -1, wctype, LOCALE_NAME_MAX_LENGTH); - - if (GetLocaleInfoEx(wctype, - LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, - (LPWSTR) &cp, sizeof(cp) / sizeof(WCHAR)) > 0) - { - r = malloc(16); /* excess */ - if (r != NULL) - { - /* - * If the return value is CP_ACP that means no ANSI code page is - * available, so only Unicode can be used for the locale. - */ - if (cp == CP_ACP) - strcpy(r, "utf8"); - else - sprintf(r, "CP%u", cp); - } - } - else -#endif - { - /* - * Locale format on Win32 is <Language>_<Country>.<CodePage>. For - * example, English_United States.1252. If we see digits after the - * last dot, assume it's a codepage number. Otherwise, we might be - * dealing with a Unix-style locale string; Windows' setlocale() will - * take those even though GetLocaleInfoEx() won't, so we end up here. - * In that case, just return what's after the last dot and hope we can - * find it in our table. - */ - codepage = strrchr(ctype, '.'); - if (codepage != NULL) - { - size_t ln; - - codepage++; - ln = strlen(codepage); - r = malloc(ln + 3); - if (r != NULL) - { - if (strspn(codepage, "0123456789") == ln) - sprintf(r, "CP%s", codepage); - else - strcpy(r, codepage); - } - } - } - - return r; -} - -#ifndef FRONTEND -/* - * Given a Windows code page identifier, find the corresponding PostgreSQL - * encoding. Issue a warning and return -1 if none found. - */ -int -pg_codepage_to_encoding(UINT cp) -{ - char sys[16]; - int i; - - sprintf(sys, "CP%u", cp); - - /* Check the table */ - for (i = 0; encoding_match_list[i].system_enc_name; i++) - if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0) - return encoding_match_list[i].pg_enc_code; - - ereport(WARNING, - (errmsg("could not determine encoding for codeset \"%s\"", sys))); - - return -1; -} -#endif -#endif /* WIN32 */ - -#if (defined(HAVE_LANGINFO_H) && defined(CODESET)) || defined(WIN32) - -/* - * Given a setting for LC_CTYPE, return the Postgres ID of the associated - * encoding, if we can determine it. Return -1 if we can't determine it. - * - * Pass in NULL to get the encoding for the current locale setting. - * Pass "" to get the encoding selected by the server's environment. - * - * If the result is PG_SQL_ASCII, callers should treat it as being compatible - * with any desired encoding. - * - * If running in the backend and write_message is false, this function must - * cope with the possibility that elog() and palloc() are not yet usable. - */ -int -pg_get_encoding_from_locale(const char *ctype, bool write_message) -{ - char *sys; - int i; - - /* Get the CODESET property, and also LC_CTYPE if not passed in */ - if (ctype) - { - char *save; - char *name; - - /* If locale is C or POSIX, we can allow all encodings */ - if (pg_strcasecmp(ctype, "C") == 0 || - pg_strcasecmp(ctype, "POSIX") == 0) - return PG_SQL_ASCII; - - save = setlocale(LC_CTYPE, NULL); - if (!save) - return -1; /* setlocale() broken? */ - /* must copy result, or it might change after setlocale */ - save = strdup(save); - if (!save) - return -1; /* out of memory; unlikely */ - - name = setlocale(LC_CTYPE, ctype); - if (!name) - { - free(save); - return -1; /* bogus ctype passed in? */ - } - -#ifndef WIN32 - sys = nl_langinfo(CODESET); - if (sys) - sys = strdup(sys); -#else - sys = win32_langinfo(name); -#endif - - setlocale(LC_CTYPE, save); - free(save); - } - else - { - /* much easier... */ - ctype = setlocale(LC_CTYPE, NULL); - if (!ctype) - return -1; /* setlocale() broken? */ - - /* If locale is C or POSIX, we can allow all encodings */ - if (pg_strcasecmp(ctype, "C") == 0 || - pg_strcasecmp(ctype, "POSIX") == 0) - return PG_SQL_ASCII; - -#ifndef WIN32 - sys = nl_langinfo(CODESET); - if (sys) - sys = strdup(sys); -#else - sys = win32_langinfo(ctype); -#endif - } - - if (!sys) - return -1; /* out of memory; unlikely */ - - /* Check the table */ - for (i = 0; encoding_match_list[i].system_enc_name; i++) - { - if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0) - { - free(sys); - return encoding_match_list[i].pg_enc_code; - } - } - - /* Special-case kluges for particular platforms go here */ - -#ifdef __darwin__ - - /* - * Current macOS has many locales that report an empty string for CODESET, - * but they all seem to actually use UTF-8. - */ - if (strlen(sys) == 0) - { - free(sys); - return PG_UTF8; - } -#endif - - /* - * We print a warning if we got a CODESET string but couldn't recognize - * it. This means we need another entry in the table. - */ - if (write_message) - { -#ifdef FRONTEND - fprintf(stderr, _("could not determine encoding for locale \"%s\": codeset is \"%s\""), - ctype, sys); - /* keep newline separate so there's only one translatable string */ - fputc('\n', stderr); -#else - ereport(WARNING, - (errmsg("could not determine encoding for locale \"%s\": codeset is \"%s\"", - ctype, sys))); -#endif - } - - free(sys); - return -1; -} -#else /* (HAVE_LANGINFO_H && CODESET) || WIN32 */ - -/* - * stub if no multi-language platform support - * - * Note: we could return -1 here, but that would have the effect of - * forcing users to specify an encoding to initdb on such platforms. - * It seems better to silently default to SQL_ASCII. - */ -int -pg_get_encoding_from_locale(const char *ctype, bool write_message) -{ - return PG_SQL_ASCII; -} - -#endif /* (HAVE_LANGINFO_H && CODESET) || WIN32 */ diff --git a/contrib/libs/libpq/src/port/dirmod.c b/contrib/libs/libpq/src/port/dirmod.c deleted file mode 100644 index 07dd190cbc..0000000000 --- a/contrib/libs/libpq/src/port/dirmod.c +++ /dev/null @@ -1,422 +0,0 @@ -/*------------------------------------------------------------------------- - * - * dirmod.c - * directory handling functions - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * This includes replacement versions of functions that work on - * Windows. - * - * IDENTIFICATION - * src/port/dirmod.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -/* Don't modify declarations in system headers */ -#if defined(WIN32) || defined(__CYGWIN__) -#undef rename -#undef unlink -#endif - -#include <unistd.h> -#include <sys/stat.h> - -#if defined(WIN32) || defined(__CYGWIN__) -#ifndef __CYGWIN__ -#include <winioctl.h> -#else -#include <windows.h> -#include <w32api/winioctl.h> -#endif -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -#include "port/win32ntdll.h" -#endif - -#if defined(WIN32) || defined(__CYGWIN__) - -/* - * pgrename - */ -int -pgrename(const char *from, const char *to) -{ - int loops = 0; - - /* - * We need to loop because even though PostgreSQL uses flags that allow - * rename while the file is open, other applications might have the file - * open without those flags. However, we won't wait indefinitely for - * someone else to close the file, as the caller might be holding locks - * and blocking other backends. - */ -#if defined(WIN32) && !defined(__CYGWIN__) - while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)) -#else - while (rename(from, to) < 0) -#endif - { -#if defined(WIN32) && !defined(__CYGWIN__) - DWORD err = GetLastError(); - - _dosmaperr(err); - - /* - * Modern NT-based Windows versions return ERROR_SHARING_VIOLATION if - * another process has the file open without FILE_SHARE_DELETE. - * ERROR_LOCK_VIOLATION has also been seen with some anti-virus - * software. This used to check for just ERROR_ACCESS_DENIED, so - * presumably you can get that too with some OS versions. We don't - * expect real permission errors where we currently use rename(). - */ - if (err != ERROR_ACCESS_DENIED && - err != ERROR_SHARING_VIOLATION && - err != ERROR_LOCK_VIOLATION) - return -1; -#else - if (errno != EACCES) - return -1; -#endif - - if (++loops > 100) /* time out after 10 sec */ - return -1; - pg_usleep(100000); /* us */ - } - return 0; -} - -/* - * Check if _pglstat64()'s reason for failure was STATUS_DELETE_PENDING. - * This doesn't apply to Cygwin, which has its own lstat() that would report - * the case as EACCES. -*/ -static bool -lstat_error_was_status_delete_pending(void) -{ - if (errno != ENOENT) - return false; -#if defined(WIN32) && !defined(__CYGWIN__) - if (pg_RtlGetLastNtStatus() == STATUS_DELETE_PENDING) - return true; -#endif - return false; -} - -/* - * pgunlink - */ -int -pgunlink(const char *path) -{ - bool is_lnk; - int loops = 0; - struct stat st; - - /* - * This function might be called for a regular file or for a junction - * point (which we use to emulate symlinks). The latter must be unlinked - * with rmdir() on Windows. Before we worry about any of that, let's see - * if we can unlink directly, since that's expected to be the most common - * case. - */ - if (unlink(path) == 0) - return 0; - if (errno != EACCES) - return -1; - - /* - * EACCES is reported for many reasons including unlink() of a junction - * point. Check if that's the case so we can redirect to rmdir(). - * - * Note that by checking only once, we can't cope with a path that changes - * from regular file to junction point underneath us while we're retrying - * due to sharing violations, but that seems unlikely. We could perhaps - * prevent that by holding a file handle ourselves across the lstat() and - * the retry loop, but that seems like over-engineering for now. - * - * In the special case of a STATUS_DELETE_PENDING error (file already - * unlinked, but someone still has it open), we don't want to report - * ENOENT to the caller immediately, because rmdir(parent) would probably - * fail. We want to wait until the file truly goes away so that simple - * recursive directory unlink algorithms work. - */ - if (lstat(path, &st) < 0) - { - if (lstat_error_was_status_delete_pending()) - is_lnk = false; - else - return -1; - } - else - is_lnk = S_ISLNK(st.st_mode); - - /* - * We need to loop because even though PostgreSQL uses flags that allow - * unlink while the file is open, other applications might have the file - * open without those flags. However, we won't wait indefinitely for - * someone else to close the file, as the caller might be holding locks - * and blocking other backends. - */ - while ((is_lnk ? rmdir(path) : unlink(path)) < 0) - { - if (errno != EACCES) - return -1; - if (++loops > 100) /* time out after 10 sec */ - return -1; - pg_usleep(100000); /* us */ - } - return 0; -} - -/* We undefined these above; now redefine for possible use below */ -#define rename(from, to) pgrename(from, to) -#define unlink(path) pgunlink(path) -#endif /* defined(WIN32) || defined(__CYGWIN__) */ - - -#if defined(WIN32) && !defined(__CYGWIN__) /* Cygwin has its own symlinks */ - -/* - * pgsymlink support: - * - * This struct is a replacement for REPARSE_DATA_BUFFER which is defined in VC6 winnt.h - * but omitted in later SDK functions. - * We only need the SymbolicLinkReparseBuffer part of the original struct's union. - */ -typedef struct -{ - DWORD ReparseTag; - WORD ReparseDataLength; - WORD Reserved; - /* SymbolicLinkReparseBuffer */ - WORD SubstituteNameOffset; - WORD SubstituteNameLength; - WORD PrintNameOffset; - WORD PrintNameLength; - WCHAR PathBuffer[FLEXIBLE_ARRAY_MEMBER]; -} REPARSE_JUNCTION_DATA_BUFFER; - -#define REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE \ - FIELD_OFFSET(REPARSE_JUNCTION_DATA_BUFFER, SubstituteNameOffset) - - -/* - * pgsymlink - uses Win32 junction points - * - * For reference: http://www.codeproject.com/KB/winsdk/junctionpoints.aspx - */ -int -pgsymlink(const char *oldpath, const char *newpath) -{ - HANDLE dirhandle; - DWORD len; - char buffer[MAX_PATH * sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)]; - char nativeTarget[MAX_PATH]; - char *p = nativeTarget; - REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer; - - CreateDirectory(newpath, 0); - dirhandle = CreateFile(newpath, GENERIC_READ | GENERIC_WRITE, - 0, 0, OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0); - - if (dirhandle == INVALID_HANDLE_VALUE) - { - _dosmaperr(GetLastError()); - return -1; - } - - /* make sure we have an unparsed native win32 path */ - if (memcmp("\\??\\", oldpath, 4) != 0) - snprintf(nativeTarget, sizeof(nativeTarget), "\\??\\%s", oldpath); - else - strlcpy(nativeTarget, oldpath, sizeof(nativeTarget)); - - while ((p = strchr(p, '/')) != NULL) - *p++ = '\\'; - - len = strlen(nativeTarget) * sizeof(WCHAR); - reparseBuf->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - reparseBuf->ReparseDataLength = len + 12; - reparseBuf->Reserved = 0; - reparseBuf->SubstituteNameOffset = 0; - reparseBuf->SubstituteNameLength = len; - reparseBuf->PrintNameOffset = len + sizeof(WCHAR); - reparseBuf->PrintNameLength = 0; - MultiByteToWideChar(CP_ACP, 0, nativeTarget, -1, - reparseBuf->PathBuffer, MAX_PATH); - - /* - * FSCTL_SET_REPARSE_POINT is coded differently depending on SDK version; - * we use our own definition - */ - if (!DeviceIoControl(dirhandle, - CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_ANY_ACCESS), - reparseBuf, - reparseBuf->ReparseDataLength + REPARSE_JUNCTION_DATA_BUFFER_HEADER_SIZE, - 0, 0, &len, 0)) - { - LPSTR msg; - int save_errno; - - _dosmaperr(GetLastError()); - save_errno = errno; - - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - (LPSTR) &msg, 0, NULL); -#ifndef FRONTEND - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not set junction for \"%s\": %s", - nativeTarget, msg))); -#else - fprintf(stderr, _("could not set junction for \"%s\": %s\n"), - nativeTarget, msg); -#endif - LocalFree(msg); - - CloseHandle(dirhandle); - RemoveDirectory(newpath); - - errno = save_errno; - - return -1; - } - - CloseHandle(dirhandle); - - return 0; -} - -/* - * pgreadlink - uses Win32 junction points - */ -int -pgreadlink(const char *path, char *buf, size_t size) -{ - DWORD attr; - HANDLE h; - char buffer[MAX_PATH * sizeof(WCHAR) + offsetof(REPARSE_JUNCTION_DATA_BUFFER, PathBuffer)]; - REPARSE_JUNCTION_DATA_BUFFER *reparseBuf = (REPARSE_JUNCTION_DATA_BUFFER *) buffer; - DWORD len; - int r; - - attr = GetFileAttributes(path); - if (attr == INVALID_FILE_ATTRIBUTES) - { - _dosmaperr(GetLastError()); - return -1; - } - if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) == 0) - { - errno = EINVAL; - return -1; - } - - h = CreateFile(path, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - 0); - if (h == INVALID_HANDLE_VALUE) - { - _dosmaperr(GetLastError()); - return -1; - } - - if (!DeviceIoControl(h, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - (LPVOID) reparseBuf, - sizeof(buffer), - &len, - NULL)) - { - LPSTR msg; - - errno = 0; - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, GetLastError(), - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - (LPSTR) &msg, 0, NULL); -#ifndef FRONTEND - ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not get junction for \"%s\": %s", - path, msg))); -#else - fprintf(stderr, _("could not get junction for \"%s\": %s\n"), - path, msg); -#endif - LocalFree(msg); - CloseHandle(h); - errno = EINVAL; - return -1; - } - CloseHandle(h); - - /* Got it, let's get some results from this */ - if (reparseBuf->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT) - { - errno = EINVAL; - return -1; - } - - r = WideCharToMultiByte(CP_ACP, 0, - reparseBuf->PathBuffer, -1, - buf, - size, - NULL, NULL); - - if (r <= 0) - { - errno = EINVAL; - return -1; - } - - /* r includes the null terminator */ - r -= 1; - - /* - * If the path starts with "\??\" followed by a "drive absolute" path - * (known to Windows APIs as RtlPathTypeDriveAbsolute), then strip that - * prefix. This undoes some of the transformation performed by - * pgsymlink(), to get back to a format that users are used to seeing. We - * don't know how to transform other path types that might be encountered - * outside PGDATA, so we just return them directly. - */ - if (r >= 7 && - buf[0] == '\\' && - buf[1] == '?' && - buf[2] == '?' && - buf[3] == '\\' && - isalpha(buf[4]) && - buf[5] == ':' && - buf[6] == '\\') - { - memmove(buf, buf + 4, strlen(buf + 4) + 1); - r -= 4; - } - return r; -} - -#endif /* defined(WIN32) && !defined(__CYGWIN__) */ diff --git a/contrib/libs/libpq/src/port/getpeereid.c b/contrib/libs/libpq/src/port/getpeereid.c deleted file mode 100644 index 3b040e076b..0000000000 --- a/contrib/libs/libpq/src/port/getpeereid.c +++ /dev/null @@ -1,78 +0,0 @@ -/*------------------------------------------------------------------------- - * - * getpeereid.c - * get peer userid for UNIX-domain socket connection - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * - * IDENTIFICATION - * src/port/getpeereid.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <unistd.h> -#ifdef HAVE_UCRED_H -#include <ucred.h> -#endif -#ifdef HAVE_SYS_UCRED_H -#include <sys/ucred.h> -#endif - - -/* - * BSD-style getpeereid() for platforms that lack it. - */ -int -getpeereid(int sock, uid_t *uid, gid_t *gid) -{ -#if defined(SO_PEERCRED) - /* Linux: use getsockopt(SO_PEERCRED) */ - struct ucred peercred; - socklen_t so_len = sizeof(peercred); - - if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 || - so_len != sizeof(peercred)) - return -1; - *uid = peercred.uid; - *gid = peercred.gid; - return 0; -#elif defined(LOCAL_PEERCRED) - /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */ - struct xucred peercred; - socklen_t so_len = sizeof(peercred); - - if (getsockopt(sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 || - so_len != sizeof(peercred) || - peercred.cr_version != XUCRED_VERSION) - return -1; - *uid = peercred.cr_uid; - *gid = peercred.cr_gid; - return 0; -#elif defined(HAVE_GETPEERUCRED) - /* Solaris: use getpeerucred() */ - ucred_t *ucred; - - ucred = NULL; /* must be initialized to NULL */ - if (getpeerucred(sock, &ucred) == -1) - return -1; - - *uid = ucred_geteuid(ucred); - *gid = ucred_getegid(ucred); - ucred_free(ucred); - - if (*uid == (uid_t) (-1) || *gid == (gid_t) (-1)) - return -1; - return 0; -#else - /* No implementation available on this platform */ - errno = ENOSYS; - return -1; -#endif -} diff --git a/contrib/libs/libpq/src/port/inet_aton.c b/contrib/libs/libpq/src/port/inet_aton.c deleted file mode 100644 index adaf18adb3..0000000000 --- a/contrib/libs/libpq/src/port/inet_aton.c +++ /dev/null @@ -1,149 +0,0 @@ -/* src/port/inet_aton.c - * - * This inet_aton() function was taken from the GNU C library and - * incorporated into Postgres for those systems which do not have this - * routine in their standard C libraries. - * - * The function was been extracted whole from the file inet_aton.c in - * Release 5.3.12 of the Linux C library, which is derived from the - * GNU C library, by Bryan Henderson in October 1996. The copyright - * notice from that file is below. - */ - -/* - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. */ - -#include "c.h" - -#include <netinet/in.h> -#include <ctype.h> - -#include "port/pg_bswap.h" - -/* - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - */ -int -inet_aton(const char *cp, struct in_addr *addr) -{ - unsigned int val; - int base, - n; - char c; - u_int parts[4]; - u_int *pp = parts; - - for (;;) - { - /* - * Collect number up to ``.''. Values are specified as for C: 0x=hex, - * 0=octal, other=decimal. - */ - val = 0; - base = 10; - if (*cp == '0') - { - if (*++cp == 'x' || *cp == 'X') - base = 16, cp++; - else - base = 8; - } - while ((c = *cp) != '\0') - { - if (isdigit((unsigned char) c)) - { - val = (val * base) + (c - '0'); - cp++; - continue; - } - if (base == 16 && isxdigit((unsigned char) c)) - { - val = (val << 4) + - (c + 10 - (islower((unsigned char) c) ? 'a' : 'A')); - cp++; - continue; - } - break; - } - if (*cp == '.') - { - /* - * Internet format: a.b.c.d a.b.c (with c treated as 16-bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3 || val > 0xff) - return 0; - *pp++ = val, cp++; - } - else - break; - } - - /* - * Check for trailing junk. - */ - while (*cp) - if (!isspace((unsigned char) *cp++)) - return 0; - - /* - * Concoct the address according to the number of parts specified. - */ - n = pp - parts + 1; - switch (n) - { - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffff) - return 0; - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) - return 0; - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) - return 0; - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - if (addr) - addr->s_addr = pg_hton32(val); - return 1; -} diff --git a/contrib/libs/libpq/src/port/inet_net_ntop.c b/contrib/libs/libpq/src/port/inet_net_ntop.c deleted file mode 100644 index 4044f22450..0000000000 --- a/contrib/libs/libpq/src/port/inet_net_ntop.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * src/port/inet_net_ntop.c - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $"; -#endif - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#ifndef FRONTEND -#error #include "utils/inet.h" -#else -/* - * In a frontend build, we can't include inet.h, but we still need to have - * sensible definitions of these two constants. Note that pg_inet_net_ntop() - * assumes that PGSQL_AF_INET is equal to AF_INET. - */ -#define PGSQL_AF_INET (AF_INET + 0) -#define PGSQL_AF_INET6 (AF_INET + 1) -#endif - - -#define NS_IN6ADDRSZ 16 -#define NS_INT16SZ 2 - -#ifdef SPRINTF_CHAR -#define SPRINTF(x) strlen(sprintf/**/x) -#else -#define SPRINTF(x) ((size_t)sprintf x) -#endif - -static char *inet_net_ntop_ipv4(const u_char *src, int bits, - char *dst, size_t size); -static char *inet_net_ntop_ipv6(const u_char *src, int bits, - char *dst, size_t size); - - -/* - * char * - * pg_inet_net_ntop(af, src, bits, dst, size) - * convert host/network address from network to presentation format. - * "src"'s size is determined from its "af". - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * 192.5.5.1/28 has a nonzero host part, which means it isn't a network - * as called for by pg_inet_net_pton() but it can be a host address with - * an included netmask. - * author: - * Paul Vixie (ISC), October 1998 - */ -char * -pg_inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) -{ - /* - * We need to cover both the address family constants used by the PG inet - * type (PGSQL_AF_INET and PGSQL_AF_INET6) and those used by the system - * libraries (AF_INET and AF_INET6). We can safely assume PGSQL_AF_INET - * == AF_INET, but the INET6 constants are very likely to be different. - */ - switch (af) - { - case PGSQL_AF_INET: - return (inet_net_ntop_ipv4(src, bits, dst, size)); - case PGSQL_AF_INET6: -#if AF_INET6 != PGSQL_AF_INET6 - case AF_INET6: -#endif - return (inet_net_ntop_ipv6(src, bits, dst, size)); - default: - errno = EAFNOSUPPORT; - return (NULL); - } -} - -/* - * static char * - * inet_net_ntop_ipv4(src, bits, dst, size) - * convert IPv4 network address from network to presentation format. - * "src"'s size is determined from its "af". - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0b11110000 in its fourth octet. - * author: - * Paul Vixie (ISC), October 1998 - */ -static char * -inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) -{ - char *odst = dst; - char *t; - int len = 4; - int b; - - if (bits < 0 || bits > 32) - { - errno = EINVAL; - return (NULL); - } - - /* Always format all four octets, regardless of mask length. */ - for (b = len; b > 0; b--) - { - if (size <= sizeof ".255") - goto emsgsize; - t = dst; - if (dst != odst) - *dst++ = '.'; - dst += SPRINTF((dst, "%u", *src++)); - size -= (size_t) (dst - t); - } - - /* don't print masklen if 32 bits */ - if (bits != 32) - { - if (size <= sizeof "/32") - goto emsgsize; - dst += SPRINTF((dst, "/%u", bits)); - } - - return (odst); - -emsgsize: - errno = EMSGSIZE; - return (NULL); -} - -static int -decoct(const u_char *src, int bytes, char *dst, size_t size) -{ - char *odst = dst; - char *t; - int b; - - for (b = 1; b <= bytes; b++) - { - if (size <= sizeof "255.") - return (0); - t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b != bytes) - { - *dst++ = '.'; - *dst = '\0'; - } - size -= (size_t) (dst - t); - } - return (dst - odst); -} - -static char * -inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough to - * contain a value of the specified size. On some systems, like Crays, - * there is no such thing as an integer variable with 16 bits. Keep this - * in mind if you think this function should have been coded to use - * pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; - char *tp; - struct - { - int base, - len; - } best, cur; - u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i; - - if ((bits < -1) || (bits > 128)) - { - errno = EINVAL; - return (NULL); - } - - /* - * Preprocess: Copy the input (bytewise) array into a wordwise array. Find - * the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else - { - if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) - { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) - { - int n; - - n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp)); - if (n == 0) - { - errno = EMSGSIZE; - return (NULL); - } - tp += strlen(tp); - break; - } - tp += SPRINTF((tp, "%x", words[i])); - } - - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) - *tp++ = ':'; - *tp = '\0'; - - if (bits != -1 && bits != 128) - tp += SPRINTF((tp, "/%u", bits)); - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t) (tp - tmp) > size) - { - errno = EMSGSIZE; - return (NULL); - } - strcpy(dst, tmp); - return (dst); -} diff --git a/contrib/libs/libpq/src/port/noblock.c b/contrib/libs/libpq/src/port/noblock.c deleted file mode 100644 index d050a03085..0000000000 --- a/contrib/libs/libpq/src/port/noblock.c +++ /dev/null @@ -1,66 +0,0 @@ -/*------------------------------------------------------------------------- - * - * noblock.c - * set a file descriptor as blocking or non-blocking - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/port/noblock.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <fcntl.h> - - -/* - * Put socket into nonblock mode. - * Returns true on success, false on failure. - */ -bool -pg_set_noblock(pgsocket sock) -{ -#if !defined(WIN32) - int flags; - - flags = fcntl(sock, F_GETFL); - if (flags < 0) - return false; - if (fcntl(sock, F_SETFL, (flags | O_NONBLOCK)) == -1) - return false; - return true; -#else - unsigned long ioctlsocket_ret = 1; - - /* Returns non-0 on failure, while fcntl() returns -1 on failure */ - return (ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0); -#endif -} - -/* - * Put socket into blocking mode. - * Returns true on success, false on failure. - */ -bool -pg_set_block(pgsocket sock) -{ -#if !defined(WIN32) - int flags; - - flags = fcntl(sock, F_GETFL); - if (flags < 0) - return false; - if (fcntl(sock, F_SETFL, (flags & ~O_NONBLOCK)) == -1) - return false; - return true; -#else - unsigned long ioctlsocket_ret = 0; - - /* Returns non-0 on failure, while fcntl() returns -1 on failure */ - return (ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0); -#endif -} diff --git a/contrib/libs/libpq/src/port/open.c b/contrib/libs/libpq/src/port/open.c deleted file mode 100644 index 0bd9755006..0000000000 --- a/contrib/libs/libpq/src/port/open.c +++ /dev/null @@ -1,222 +0,0 @@ -/*------------------------------------------------------------------------- - * - * open.c - * Win32 open() replacement - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * src/port/open.c - * - *------------------------------------------------------------------------- - */ - -#ifdef WIN32 - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include "port/win32ntdll.h" - -#include <fcntl.h> -#include <assert.h> -#include <sys/stat.h> - -static int -openFlagsToCreateFileFlags(int openFlags) -{ - switch (openFlags & (O_CREAT | O_TRUNC | O_EXCL)) - { - /* O_EXCL is meaningless without O_CREAT */ - case 0: - case O_EXCL: - return OPEN_EXISTING; - - case O_CREAT: - return OPEN_ALWAYS; - - /* O_EXCL is meaningless without O_CREAT */ - case O_TRUNC: - case O_TRUNC | O_EXCL: - return TRUNCATE_EXISTING; - - case O_CREAT | O_TRUNC: - return CREATE_ALWAYS; - - /* O_TRUNC is meaningless with O_CREAT */ - case O_CREAT | O_EXCL: - case O_CREAT | O_TRUNC | O_EXCL: - return CREATE_NEW; - } - - /* will never get here */ - return 0; -} - -/* - * Internal function used by pgwin32_open() and _pgstat64(). When - * backup_semantics is true, directories may be opened (for limited uses). On - * failure, INVALID_HANDLE_VALUE is returned and errno is set. - */ -HANDLE -pgwin32_open_handle(const char *fileName, int fileFlags, bool backup_semantics) -{ - HANDLE h; - SECURITY_ATTRIBUTES sa; - int loops = 0; - - if (initialize_ntdll() < 0) - return INVALID_HANDLE_VALUE; - - /* Check that we can handle the request */ - assert((fileFlags & ((O_RDONLY | O_WRONLY | O_RDWR) | O_APPEND | - (O_RANDOM | O_SEQUENTIAL | O_TEMPORARY) | - _O_SHORT_LIVED | O_DSYNC | O_DIRECT | - (O_CREAT | O_TRUNC | O_EXCL) | (O_TEXT | O_BINARY))) == fileFlags); - - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - sa.lpSecurityDescriptor = NULL; - - while ((h = CreateFile(fileName, - /* cannot use O_RDONLY, as it == 0 */ - (fileFlags & O_RDWR) ? (GENERIC_WRITE | GENERIC_READ) : - ((fileFlags & O_WRONLY) ? GENERIC_WRITE : GENERIC_READ), - /* These flags allow concurrent rename/unlink */ - (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE), - &sa, - openFlagsToCreateFileFlags(fileFlags), - FILE_ATTRIBUTE_NORMAL | - (backup_semantics ? FILE_FLAG_BACKUP_SEMANTICS : 0) | - ((fileFlags & O_RANDOM) ? FILE_FLAG_RANDOM_ACCESS : 0) | - ((fileFlags & O_SEQUENTIAL) ? FILE_FLAG_SEQUENTIAL_SCAN : 0) | - ((fileFlags & _O_SHORT_LIVED) ? FILE_ATTRIBUTE_TEMPORARY : 0) | - ((fileFlags & O_TEMPORARY) ? FILE_FLAG_DELETE_ON_CLOSE : 0) | - ((fileFlags & O_DIRECT) ? FILE_FLAG_NO_BUFFERING : 0) | - ((fileFlags & O_DSYNC) ? FILE_FLAG_WRITE_THROUGH : 0), - NULL)) == INVALID_HANDLE_VALUE) - { - /* - * Sharing violation or locking error can indicate antivirus, backup - * or similar software that's locking the file. Wait a bit and try - * again, giving up after 30 seconds. - */ - DWORD err = GetLastError(); - - if (err == ERROR_SHARING_VIOLATION || - err == ERROR_LOCK_VIOLATION) - { -#ifndef FRONTEND - if (loops == 50) - ereport(LOG, - (errmsg("could not open file \"%s\": %s", fileName, - (err == ERROR_SHARING_VIOLATION) ? _("sharing violation") : _("lock violation")), - errdetail("Continuing to retry for 30 seconds."), - errhint("You might have antivirus, backup, or similar software interfering with the database system."))); -#endif - - if (loops < 300) - { - pg_usleep(100000); - loops++; - continue; - } - } - - /* - * ERROR_ACCESS_DENIED is returned if the file is deleted but not yet - * gone (Windows NT status code is STATUS_DELETE_PENDING). In that - * case, we'd better ask for the NT status too so we can translate it - * to a more Unix-like error. We hope that nothing clobbers the NT - * status in between the internal NtCreateFile() call and CreateFile() - * returning. - * - * If there's no O_CREAT flag, then we'll pretend the file is - * invisible. With O_CREAT, we have no choice but to report that - * there's a file in the way (which wouldn't happen on Unix). - */ - if (err == ERROR_ACCESS_DENIED && - pg_RtlGetLastNtStatus() == STATUS_DELETE_PENDING) - { - if (fileFlags & O_CREAT) - err = ERROR_FILE_EXISTS; - else - err = ERROR_FILE_NOT_FOUND; - } - - _dosmaperr(err); - return INVALID_HANDLE_VALUE; - } - - return h; -} - -int -pgwin32_open(const char *fileName, int fileFlags,...) -{ - HANDLE h; - int fd; - - h = pgwin32_open_handle(fileName, fileFlags, false); - if (h == INVALID_HANDLE_VALUE) - return -1; - -#ifdef FRONTEND - - /* - * Since PostgreSQL 12, those concurrent-safe versions of open() and - * fopen() can be used by frontends, having as side-effect to switch the - * file-translation mode from O_TEXT to O_BINARY if none is specified. - * Caller may want to enforce the binary or text mode, but if nothing is - * defined make sure that the default mode maps with what versions older - * than 12 have been doing. - */ - if ((fileFlags & O_BINARY) == 0) - fileFlags |= O_TEXT; -#endif - - /* _open_osfhandle will, on error, set errno accordingly */ - if ((fd = _open_osfhandle((intptr_t) h, fileFlags & O_APPEND)) < 0) - CloseHandle(h); /* will not affect errno */ - else if (fileFlags & (O_TEXT | O_BINARY) && - _setmode(fd, fileFlags & (O_TEXT | O_BINARY)) < 0) - { - _close(fd); - return -1; - } - - return fd; -} - -FILE * -pgwin32_fopen(const char *fileName, const char *mode) -{ - int openmode = 0; - int fd; - - if (strstr(mode, "r+")) - openmode |= O_RDWR; - else if (strchr(mode, 'r')) - openmode |= O_RDONLY; - if (strstr(mode, "w+")) - openmode |= O_RDWR | O_CREAT | O_TRUNC; - else if (strchr(mode, 'w')) - openmode |= O_WRONLY | O_CREAT | O_TRUNC; - if (strchr(mode, 'a')) - openmode |= O_WRONLY | O_CREAT | O_APPEND; - - if (strchr(mode, 'b')) - openmode |= O_BINARY; - if (strchr(mode, 't')) - openmode |= O_TEXT; - - fd = pgwin32_open(fileName, openmode); - if (fd == -1) - return NULL; - return _fdopen(fd, mode); -} - -#endif diff --git a/contrib/libs/libpq/src/port/path.c b/contrib/libs/libpq/src/port/path.c deleted file mode 100644 index 65c7943fee..0000000000 --- a/contrib/libs/libpq/src/port/path.c +++ /dev/null @@ -1,1057 +0,0 @@ -/*------------------------------------------------------------------------- - * - * path.c - * portable path handling routines - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/path.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -#include <ctype.h> -#include <sys/stat.h> -#ifdef WIN32 -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0500 -#ifdef near -#undef near -#endif -#define near -#include <shlobj.h> -#else -#include <unistd.h> -#endif - -#include "pg_config_paths.h" - - -#ifndef WIN32 -#define IS_PATH_VAR_SEP(ch) ((ch) == ':') -#else -#define IS_PATH_VAR_SEP(ch) ((ch) == ';') -#endif - -static void make_relative_path(char *ret_path, const char *target_path, - const char *bin_path, const char *my_exec_path); -static char *trim_directory(char *path); -static void trim_trailing_separator(char *path); -static char *append_subdir_to_path(char *path, char *subdir); - - -/* - * skip_drive - * - * On Windows, a path may begin with "C:" or "//network/". Advance over - * this and point to the effective start of the path. - */ -#ifdef WIN32 - -static char * -skip_drive(const char *path) -{ - if (IS_DIR_SEP(path[0]) && IS_DIR_SEP(path[1])) - { - path += 2; - while (*path && !IS_DIR_SEP(*path)) - path++; - } - else if (isalpha((unsigned char) path[0]) && path[1] == ':') - { - path += 2; - } - return (char *) path; -} -#else - -#define skip_drive(path) (path) -#endif - -/* - * has_drive_prefix - * - * Return true if the given pathname has a drive prefix. - */ -bool -has_drive_prefix(const char *path) -{ -#ifdef WIN32 - return skip_drive(path) != path; -#else - return false; -#endif -} - -/* - * first_dir_separator - * - * Find the location of the first directory separator, return - * NULL if not found. - */ -char * -first_dir_separator(const char *filename) -{ - const char *p; - - for (p = skip_drive(filename); *p; p++) - if (IS_DIR_SEP(*p)) - return unconstify(char *, p); - return NULL; -} - -/* - * first_path_var_separator - * - * Find the location of the first path separator (i.e. ':' on - * Unix, ';' on Windows), return NULL if not found. - */ -char * -first_path_var_separator(const char *pathlist) -{ - const char *p; - - /* skip_drive is not needed */ - for (p = pathlist; *p; p++) - if (IS_PATH_VAR_SEP(*p)) - return unconstify(char *, p); - return NULL; -} - -/* - * last_dir_separator - * - * Find the location of the last directory separator, return - * NULL if not found. - */ -char * -last_dir_separator(const char *filename) -{ - const char *p, - *ret = NULL; - - for (p = skip_drive(filename); *p; p++) - if (IS_DIR_SEP(*p)) - ret = p; - return unconstify(char *, ret); -} - - -/* - * make_native_path - on WIN32, change / to \ in the path - * - * This effectively undoes canonicalize_path. - * - * This is required because WIN32 COPY is an internal CMD.EXE - * command and doesn't process forward slashes in the same way - * as external commands. Quoting the first argument to COPY - * does not convert forward to backward slashes, but COPY does - * properly process quoted forward slashes in the second argument. - * - * COPY works with quoted forward slashes in the first argument - * only if the current directory is the same as the directory - * of the first argument. - */ -void -make_native_path(char *filename) -{ -#ifdef WIN32 - char *p; - - for (p = filename; *p; p++) - if (*p == '/') - *p = '\\'; -#endif -} - - -/* - * This function cleans up the paths for use with either cmd.exe or Msys - * on Windows. We need them to use filenames without spaces, for which a - * short filename is the safest equivalent, eg: - * C:/Progra~1/ - */ -void -cleanup_path(char *path) -{ -#ifdef WIN32 - char *ptr; - - /* - * GetShortPathName() will fail if the path does not exist, or short names - * are disabled on this file system. In both cases, we just return the - * original path. This is particularly useful for --sysconfdir, which - * might not exist. - */ - GetShortPathName(path, path, MAXPGPATH - 1); - - /* Replace '\' with '/' */ - for (ptr = path; *ptr; ptr++) - { - if (*ptr == '\\') - *ptr = '/'; - } -#endif -} - - -/* - * join_path_components - join two path components, inserting a slash - * - * We omit the slash if either given component is empty. - * - * ret_path is the output area (must be of size MAXPGPATH) - * - * ret_path can be the same as head, but not the same as tail. - */ -void -join_path_components(char *ret_path, - const char *head, const char *tail) -{ - if (ret_path != head) - strlcpy(ret_path, head, MAXPGPATH); - - /* - * We used to try to simplify some cases involving "." and "..", but now - * we just leave that to be done by canonicalize_path() later. - */ - - if (*tail) - { - /* only separate with slash if head wasn't empty */ - snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path), - "%s%s", - (*(skip_drive(head)) != '\0') ? "/" : "", - tail); - } -} - - -/* State-machine states for canonicalize_path */ -typedef enum -{ - ABSOLUTE_PATH_INIT, /* Just past the leading '/' (and Windows - * drive name if any) of an absolute path */ - ABSOLUTE_WITH_N_DEPTH, /* We collected 'pathdepth' directories in an - * absolute path */ - RELATIVE_PATH_INIT, /* At start of a relative path */ - RELATIVE_WITH_N_DEPTH, /* We collected 'pathdepth' directories in a - * relative path */ - RELATIVE_WITH_PARENT_REF /* Relative path containing only double-dots */ -} canonicalize_state; - -/* - * Clean up path by: - * o make Win32 path use Unix slashes - * o remove trailing quote on Win32 - * o remove trailing slash - * o remove duplicate (adjacent) separators - * o remove '.' (unless path reduces to only '.') - * o process '..' ourselves, removing it if possible - */ -void -canonicalize_path(char *path) -{ - char *p, - *to_p; - char *spath; - char *parsed; - char *unparse; - bool was_sep = false; - canonicalize_state state; - int pathdepth = 0; /* counts collected regular directory names */ - -#ifdef WIN32 - - /* - * The Windows command processor will accept suitably quoted paths with - * forward slashes, but barfs badly with mixed forward and back slashes. - */ - for (p = path; *p; p++) - { - if (*p == '\\') - *p = '/'; - } - - /* - * In Win32, if you do: prog.exe "a b" "\c\d\" the system will pass \c\d" - * as argv[2], so trim off trailing quote. - */ - if (p > path && *(p - 1) == '"') - *(p - 1) = '/'; -#endif - - /* - * Removing the trailing slash on a path means we never get ugly double - * trailing slashes. Also, Win32 can't stat() a directory with a trailing - * slash. Don't remove a leading slash, though. - */ - trim_trailing_separator(path); - - /* - * Remove duplicate adjacent separators - */ - p = path; -#ifdef WIN32 - /* Don't remove leading double-slash on Win32 */ - if (*p) - p++; -#endif - to_p = p; - for (; *p; p++, to_p++) - { - /* Handle many adjacent slashes, like "/a///b" */ - while (*p == '/' && was_sep) - p++; - if (to_p != p) - *to_p = *p; - was_sep = (*p == '/'); - } - *to_p = '\0'; - - /* - * Remove any uses of "." and process ".." ourselves - * - * Note that "/../.." should reduce to just "/", while "../.." has to be - * kept as-is. Also note that we want a Windows drive spec to be visible - * to trim_directory(), but it's not part of the logic that's looking at - * the name components; hence distinction between path and spath. - * - * This loop overwrites the path in-place. This is safe since we'll never - * make the path longer. "unparse" points to where we are reading the - * path, "parse" to where we are writing. - */ - spath = skip_drive(path); - if (*spath == '\0') - return; /* empty path is returned as-is */ - - if (*spath == '/') - { - state = ABSOLUTE_PATH_INIT; - /* Skip the leading slash for absolute path */ - parsed = unparse = (spath + 1); - } - else - { - state = RELATIVE_PATH_INIT; - parsed = unparse = spath; - } - - while (*unparse != '\0') - { - char *unparse_next; - bool is_double_dot; - - /* Split off this dir name, and set unparse_next to the next one */ - unparse_next = unparse; - while (*unparse_next && *unparse_next != '/') - unparse_next++; - if (*unparse_next != '\0') - *unparse_next++ = '\0'; - - /* Identify type of this dir name */ - if (strcmp(unparse, ".") == 0) - { - /* We can ignore "." components in all cases */ - unparse = unparse_next; - continue; - } - - if (strcmp(unparse, "..") == 0) - is_double_dot = true; - else - { - /* adjacent separators were eliminated above */ - Assert(*unparse != '\0'); - is_double_dot = false; - } - - switch (state) - { - case ABSOLUTE_PATH_INIT: - /* We can ignore ".." immediately after / */ - if (!is_double_dot) - { - /* Append first dir name (we already have leading slash) */ - parsed = append_subdir_to_path(parsed, unparse); - state = ABSOLUTE_WITH_N_DEPTH; - pathdepth++; - } - break; - case ABSOLUTE_WITH_N_DEPTH: - if (is_double_dot) - { - /* Remove last parsed dir */ - /* (trim_directory won't remove the leading slash) */ - *parsed = '\0'; - parsed = trim_directory(path); - if (--pathdepth == 0) - state = ABSOLUTE_PATH_INIT; - } - else - { - /* Append normal dir */ - *parsed++ = '/'; - parsed = append_subdir_to_path(parsed, unparse); - pathdepth++; - } - break; - case RELATIVE_PATH_INIT: - if (is_double_dot) - { - /* Append irreducible double-dot (..) */ - parsed = append_subdir_to_path(parsed, unparse); - state = RELATIVE_WITH_PARENT_REF; - } - else - { - /* Append normal dir */ - parsed = append_subdir_to_path(parsed, unparse); - state = RELATIVE_WITH_N_DEPTH; - pathdepth++; - } - break; - case RELATIVE_WITH_N_DEPTH: - if (is_double_dot) - { - /* Remove last parsed dir */ - *parsed = '\0'; - parsed = trim_directory(path); - if (--pathdepth == 0) - { - /* - * If the output path is now empty, we're back to the - * INIT state. However, we could have processed a - * path like "../dir/.." and now be down to "..", in - * which case enter the correct state for that. - */ - if (parsed == spath) - state = RELATIVE_PATH_INIT; - else - state = RELATIVE_WITH_PARENT_REF; - } - } - else - { - /* Append normal dir */ - *parsed++ = '/'; - parsed = append_subdir_to_path(parsed, unparse); - pathdepth++; - } - break; - case RELATIVE_WITH_PARENT_REF: - if (is_double_dot) - { - /* Append next irreducible double-dot (..) */ - *parsed++ = '/'; - parsed = append_subdir_to_path(parsed, unparse); - } - else - { - /* Append normal dir */ - *parsed++ = '/'; - parsed = append_subdir_to_path(parsed, unparse); - - /* - * We can now start counting normal dirs. But if later - * double-dots make us remove this dir again, we'd better - * revert to RELATIVE_WITH_PARENT_REF not INIT state. - */ - state = RELATIVE_WITH_N_DEPTH; - pathdepth = 1; - } - break; - } - - unparse = unparse_next; - } - - /* - * If our output path is empty at this point, insert ".". We don't want - * to do this any earlier because it'd result in an extra dot in corner - * cases such as "../dir/..". Since we rejected the wholly-empty-path - * case above, there is certainly room. - */ - if (parsed == spath) - *parsed++ = '.'; - - /* And finally, ensure the output path is nul-terminated. */ - *parsed = '\0'; -} - -/* - * Detect whether a path contains any parent-directory references ("..") - * - * The input *must* have been put through canonicalize_path previously. - */ -bool -path_contains_parent_reference(const char *path) -{ - /* - * Once canonicalized, an absolute path cannot contain any ".." at all, - * while a relative path could contain ".."(s) only at the start. So it - * is sufficient to check the start of the path, after skipping any - * Windows drive/network specifier. - */ - path = skip_drive(path); /* C: shouldn't affect our conclusion */ - - if (path[0] == '.' && - path[1] == '.' && - (path[2] == '\0' || path[2] == '/')) - return true; - - return false; -} - -/* - * Detect whether a path is only in or below the current working directory. - * - * The input *must* have been put through canonicalize_path previously. - * - * An absolute path that matches the current working directory should - * return false (we only want relative to the cwd). - */ -bool -path_is_relative_and_below_cwd(const char *path) -{ - if (is_absolute_path(path)) - return false; - /* don't allow anything above the cwd */ - else if (path_contains_parent_reference(path)) - return false; -#ifdef WIN32 - - /* - * On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is - * relative to the cwd on that drive, or the drive's root directory if - * that drive has no cwd. Because the path itself cannot tell us which is - * the case, we have to assume the worst, i.e. that it is not below the - * cwd. We could use GetFullPathName() to find the full path but that - * could change if the current directory for the drive changes underneath - * us, so we just disallow it. - */ - else if (isalpha((unsigned char) path[0]) && path[1] == ':' && - !IS_DIR_SEP(path[2])) - return false; -#endif - else - return true; -} - -/* - * Detect whether path1 is a prefix of path2 (including equality). - * - * This is pretty trivial, but it seems better to export a function than - * to export IS_DIR_SEP. - */ -bool -path_is_prefix_of_path(const char *path1, const char *path2) -{ - int path1_len = strlen(path1); - - if (strncmp(path1, path2, path1_len) == 0 && - (IS_DIR_SEP(path2[path1_len]) || path2[path1_len] == '\0')) - return true; - return false; -} - -/* - * Extracts the actual name of the program as called - - * stripped of .exe suffix if any - */ -const char * -get_progname(const char *argv0) -{ - const char *nodir_name; - char *progname; - - nodir_name = last_dir_separator(argv0); - if (nodir_name) - nodir_name++; - else - nodir_name = skip_drive(argv0); - - /* - * Make a copy in case argv[0] is modified by ps_status. Leaks memory, but - * called only once. - */ - progname = strdup(nodir_name); - if (progname == NULL) - { - fprintf(stderr, "%s: out of memory\n", nodir_name); - abort(); /* This could exit the postmaster */ - } - -#if defined(__CYGWIN__) || defined(WIN32) - /* strip ".exe" suffix, regardless of case */ - if (strlen(progname) > sizeof(EXE) - 1 && - pg_strcasecmp(progname + strlen(progname) - (sizeof(EXE) - 1), EXE) == 0) - progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0'; -#endif - - return progname; -} - - -/* - * dir_strcmp: strcmp except any two DIR_SEP characters are considered equal, - * and we honor filesystem case insensitivity if known - */ -static int -dir_strcmp(const char *s1, const char *s2) -{ - while (*s1 && *s2) - { - if ( -#ifndef WIN32 - *s1 != *s2 -#else - /* On windows, paths are case-insensitive */ - pg_tolower((unsigned char) *s1) != pg_tolower((unsigned char) *s2) -#endif - && !(IS_DIR_SEP(*s1) && IS_DIR_SEP(*s2))) - return (int) *s1 - (int) *s2; - s1++, s2++; - } - if (*s1) - return 1; /* s1 longer */ - if (*s2) - return -1; /* s2 longer */ - return 0; -} - - -/* - * make_relative_path - make a path relative to the actual binary location - * - * This function exists to support relocation of installation trees. - * - * ret_path is the output area (must be of size MAXPGPATH) - * target_path is the compiled-in path to the directory we want to find - * bin_path is the compiled-in path to the directory of executables - * my_exec_path is the actual location of my executable - * - * We determine the common prefix of target_path and bin_path, then compare - * the remainder of bin_path to the last directory component(s) of - * my_exec_path. If they match, build the result as the part of my_exec_path - * preceding the match, joined to the remainder of target_path. If no match, - * return target_path as-is. - * - * For example: - * target_path = '/usr/local/share/postgresql' - * bin_path = '/usr/local/bin' - * my_exec_path = '/opt/pgsql/bin/postgres' - * Given these inputs, the common prefix is '/usr/local/', the tail of - * bin_path is 'bin' which does match the last directory component of - * my_exec_path, so we would return '/opt/pgsql/share/postgresql' - */ -static void -make_relative_path(char *ret_path, const char *target_path, - const char *bin_path, const char *my_exec_path) -{ - int prefix_len; - int tail_start; - int tail_len; - int i; - - /* - * Determine the common prefix --- note we require it to end on a - * directory separator, consider eg '/usr/lib' and '/usr/libexec'. - */ - prefix_len = 0; - for (i = 0; target_path[i] && bin_path[i]; i++) - { - if (IS_DIR_SEP(target_path[i]) && IS_DIR_SEP(bin_path[i])) - prefix_len = i + 1; - else if (target_path[i] != bin_path[i]) - break; - } - if (prefix_len == 0) - goto no_match; /* no common prefix? */ - tail_len = strlen(bin_path) - prefix_len; - - /* - * Set up my_exec_path without the actual executable name, and - * canonicalize to simplify comparison to bin_path. - */ - strlcpy(ret_path, my_exec_path, MAXPGPATH); - trim_directory(ret_path); /* remove my executable name */ - canonicalize_path(ret_path); - - /* - * Tail match? - */ - tail_start = (int) strlen(ret_path) - tail_len; - if (tail_start > 0 && - IS_DIR_SEP(ret_path[tail_start - 1]) && - dir_strcmp(ret_path + tail_start, bin_path + prefix_len) == 0) - { - ret_path[tail_start] = '\0'; - trim_trailing_separator(ret_path); - join_path_components(ret_path, ret_path, target_path + prefix_len); - canonicalize_path(ret_path); - return; - } - -no_match: - strlcpy(ret_path, target_path, MAXPGPATH); - canonicalize_path(ret_path); -} - - -/* - * make_absolute_path - * - * If the given pathname isn't already absolute, make it so, interpreting - * it relative to the current working directory. - * - * Also canonicalizes the path. The result is always a malloc'd copy. - * - * In backend, failure cases result in ereport(ERROR); in frontend, - * we write a complaint on stderr and return NULL. - * - * Note: interpretation of relative-path arguments during postmaster startup - * should happen before doing ChangeToDataDir(), else the user will probably - * not like the results. - */ -char * -make_absolute_path(const char *path) -{ - char *new; - - /* Returning null for null input is convenient for some callers */ - if (path == NULL) - return NULL; - - if (!is_absolute_path(path)) - { - char *buf; - size_t buflen; - - buflen = MAXPGPATH; - for (;;) - { - buf = malloc(buflen); - if (!buf) - { -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#else - fprintf(stderr, _("out of memory\n")); - return NULL; -#endif - } - - if (getcwd(buf, buflen)) - break; - else if (errno == ERANGE) - { - free(buf); - buflen *= 2; - continue; - } - else - { - int save_errno = errno; - - free(buf); - errno = save_errno; -#ifndef FRONTEND - elog(ERROR, "could not get current working directory: %m"); -#else - fprintf(stderr, _("could not get current working directory: %s\n"), - strerror(errno)); - return NULL; -#endif - } - } - - new = malloc(strlen(buf) + strlen(path) + 2); - if (!new) - { - free(buf); -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#else - fprintf(stderr, _("out of memory\n")); - return NULL; -#endif - } - sprintf(new, "%s/%s", buf, path); - free(buf); - } - else - { - new = strdup(path); - if (!new) - { -#ifndef FRONTEND - ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of memory"))); -#else - fprintf(stderr, _("out of memory\n")); - return NULL; -#endif - } - } - - /* Make sure punctuation is canonical, too */ - canonicalize_path(new); - - return new; -} - - -/* - * get_share_path - */ -void -get_share_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, PGSHAREDIR, PGBINDIR, my_exec_path); -} - -/* - * get_etc_path - */ -void -get_etc_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, SYSCONFDIR, PGBINDIR, my_exec_path); -} - -/* - * get_include_path - */ -void -get_include_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, INCLUDEDIR, PGBINDIR, my_exec_path); -} - -/* - * get_pkginclude_path - */ -void -get_pkginclude_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, PKGINCLUDEDIR, PGBINDIR, my_exec_path); -} - -/* - * get_includeserver_path - */ -void -get_includeserver_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, INCLUDEDIRSERVER, PGBINDIR, my_exec_path); -} - -/* - * get_lib_path - */ -void -get_lib_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, LIBDIR, PGBINDIR, my_exec_path); -} - -/* - * get_pkglib_path - */ -void -get_pkglib_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, PKGLIBDIR, PGBINDIR, my_exec_path); -} - -/* - * get_locale_path - */ -void -get_locale_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, LOCALEDIR, PGBINDIR, my_exec_path); -} - -/* - * get_doc_path - */ -void -get_doc_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, DOCDIR, PGBINDIR, my_exec_path); -} - -/* - * get_html_path - */ -void -get_html_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, HTMLDIR, PGBINDIR, my_exec_path); -} - -/* - * get_man_path - */ -void -get_man_path(const char *my_exec_path, char *ret_path) -{ - make_relative_path(ret_path, MANDIR, PGBINDIR, my_exec_path); -} - - -/* - * get_home_path - * - * On Unix, this actually returns the user's home directory. On Windows - * it returns the PostgreSQL-specific application data folder. - */ -bool -get_home_path(char *ret_path) -{ -#ifndef WIN32 - /* - * We first consult $HOME. If that's unset, try to get the info from - * <pwd.h>. - */ - const char *home; - - home = getenv("HOME"); - if (home == NULL || home[0] == '\0') - return pg_get_user_home_dir(geteuid(), ret_path, MAXPGPATH); - strlcpy(ret_path, home, MAXPGPATH); - return true; -#else - char *tmppath; - - /* - * Note: We use getenv() here because the more modern SHGetFolderPath() - * would force the backend to link with shell32.lib, which eats valuable - * desktop heap. XXX This function is used only in psql, which already - * brings in shell32 via libpq. Moving this function to its own file - * would keep it out of the backend, freeing it from this concern. - */ - tmppath = getenv("APPDATA"); - if (!tmppath) - return false; - snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath); - return true; -#endif -} - - -/* - * get_parent_directory - * - * Modify the given string in-place to name the parent directory of the - * named file. - * - * If the input is just a file name with no directory part, the result is - * an empty string, not ".". This is appropriate when the next step is - * join_path_components(), but might need special handling otherwise. - * - * Caution: this will not produce desirable results if the string ends - * with "..". For most callers this is not a problem since the string - * is already known to name a regular file. If in doubt, apply - * canonicalize_path() first. - */ -void -get_parent_directory(char *path) -{ - trim_directory(path); -} - - -/* - * trim_directory - * - * Trim trailing directory from path, that is, remove any trailing slashes, - * the last pathname component, and the slash just ahead of it --- but never - * remove a leading slash. - * - * For the convenience of canonicalize_path, the path's new end location - * is returned. - */ -static char * -trim_directory(char *path) -{ - char *p; - - path = skip_drive(path); - - if (path[0] == '\0') - return path; - - /* back up over trailing slash(es) */ - for (p = path + strlen(path) - 1; IS_DIR_SEP(*p) && p > path; p--) - ; - /* back up over directory name */ - for (; !IS_DIR_SEP(*p) && p > path; p--) - ; - /* if multiple slashes before directory name, remove 'em all */ - for (; p > path && IS_DIR_SEP(*(p - 1)); p--) - ; - /* don't erase a leading slash */ - if (p == path && IS_DIR_SEP(*p)) - p++; - *p = '\0'; - return p; -} - - -/* - * trim_trailing_separator - * - * trim off trailing slashes, but not a leading slash - */ -static void -trim_trailing_separator(char *path) -{ - char *p; - - path = skip_drive(path); - p = path + strlen(path); - if (p > path) - for (p--; p > path && IS_DIR_SEP(*p); p--) - *p = '\0'; -} - -/* - * append_subdir_to_path - * - * Append the currently-considered subdirectory name to the output - * path in canonicalize_path. Return the new end location of the - * output path. - * - * Since canonicalize_path updates the path in-place, we must use - * memmove not memcpy, and we don't yet terminate the path with '\0'. - */ -static char * -append_subdir_to_path(char *path, char *subdir) -{ - size_t len = strlen(subdir); - - /* No need to copy data if path and subdir are the same. */ - if (path != subdir) - memmove(path, subdir, len); - - return path + len; -} diff --git a/contrib/libs/libpq/src/port/pg_bitutils.c b/contrib/libs/libpq/src/port/pg_bitutils.c deleted file mode 100644 index 1f3dea2d4b..0000000000 --- a/contrib/libs/libpq/src/port/pg_bitutils.c +++ /dev/null @@ -1,335 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_bitutils.c - * Miscellaneous functions for bit-wise operations. - * - * Copyright (c) 2019-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/port/pg_bitutils.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#ifdef HAVE__GET_CPUID -#include <cpuid.h> -#endif -#ifdef HAVE__CPUID -#include <intrin.h> -#endif - -#include "port/pg_bitutils.h" - - -/* - * Array giving the position of the left-most set bit for each possible - * byte value. We count the right-most position as the 0th bit, and the - * left-most the 7th bit. The 0th entry of the array should not be used. - * - * Note: this is not used by the functions in pg_bitutils.h when - * HAVE__BUILTIN_CLZ is defined, but we provide it anyway, so that - * extensions possibly compiled with a different compiler can use it. - */ -const uint8 pg_leftmost_one_pos[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -}; - -/* - * Array giving the position of the right-most set bit for each possible - * byte value. We count the right-most position as the 0th bit, and the - * left-most the 7th bit. The 0th entry of the array should not be used. - * - * Note: this is not used by the functions in pg_bitutils.h when - * HAVE__BUILTIN_CTZ is defined, but we provide it anyway, so that - * extensions possibly compiled with a different compiler can use it. - */ -const uint8 pg_rightmost_one_pos[256] = { - 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 -}; - -/* - * Array giving the number of 1-bits in each possible byte value. - * - * Note: we export this for use by functions in which explicit use - * of the popcount functions seems unlikely to be a win. - */ -const uint8 pg_number_of_ones[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 -}; - -static int pg_popcount32_slow(uint32 word); -static int pg_popcount64_slow(uint64 word); - -#ifdef TRY_POPCNT_FAST -static bool pg_popcount_available(void); -static int pg_popcount32_choose(uint32 word); -static int pg_popcount64_choose(uint64 word); -static int pg_popcount32_fast(uint32 word); -static int pg_popcount64_fast(uint64 word); - -int (*pg_popcount32) (uint32 word) = pg_popcount32_choose; -int (*pg_popcount64) (uint64 word) = pg_popcount64_choose; -#endif /* TRY_POPCNT_FAST */ - -#ifdef TRY_POPCNT_FAST - -/* - * Return true if CPUID indicates that the POPCNT instruction is available. - */ -static bool -pg_popcount_available(void) -{ - unsigned int exx[4] = {0, 0, 0, 0}; - -#if defined(HAVE__GET_CPUID) - __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); -#elif defined(HAVE__CPUID) - __cpuid(exx, 1); -#else -#error cpuid instruction not available -#endif - - return (exx[2] & (1 << 23)) != 0; /* POPCNT */ -} - -/* - * These functions get called on the first call to pg_popcount32 etc. - * They detect whether we can use the asm implementations, and replace - * the function pointers so that subsequent calls are routed directly to - * the chosen implementation. - */ -static int -pg_popcount32_choose(uint32 word) -{ - if (pg_popcount_available()) - { - pg_popcount32 = pg_popcount32_fast; - pg_popcount64 = pg_popcount64_fast; - } - else - { - pg_popcount32 = pg_popcount32_slow; - pg_popcount64 = pg_popcount64_slow; - } - - return pg_popcount32(word); -} - -static int -pg_popcount64_choose(uint64 word) -{ - if (pg_popcount_available()) - { - pg_popcount32 = pg_popcount32_fast; - pg_popcount64 = pg_popcount64_fast; - } - else - { - pg_popcount32 = pg_popcount32_slow; - pg_popcount64 = pg_popcount64_slow; - } - - return pg_popcount64(word); -} - -/* - * pg_popcount32_fast - * Return the number of 1 bits set in word - */ -static int -pg_popcount32_fast(uint32 word) -{ -#ifdef _MSC_VER - return __popcnt(word); -#else - uint32 res; - -__asm__ __volatile__(" popcntl %1,%0\n":"=q"(res):"rm"(word):"cc"); - return (int) res; -#endif -} - -/* - * pg_popcount64_fast - * Return the number of 1 bits set in word - */ -static int -pg_popcount64_fast(uint64 word) -{ -#ifdef _MSC_VER - return __popcnt64(word); -#else - uint64 res; - -__asm__ __volatile__(" popcntq %1,%0\n":"=q"(res):"rm"(word):"cc"); - return (int) res; -#endif -} - -#endif /* TRY_POPCNT_FAST */ - - -/* - * pg_popcount32_slow - * Return the number of 1 bits set in word - */ -static int -pg_popcount32_slow(uint32 word) -{ -#ifdef HAVE__BUILTIN_POPCOUNT - return __builtin_popcount(word); -#else /* !HAVE__BUILTIN_POPCOUNT */ - int result = 0; - - while (word != 0) - { - result += pg_number_of_ones[word & 255]; - word >>= 8; - } - - return result; -#endif /* HAVE__BUILTIN_POPCOUNT */ -} - -/* - * pg_popcount64_slow - * Return the number of 1 bits set in word - */ -static int -pg_popcount64_slow(uint64 word) -{ -#ifdef HAVE__BUILTIN_POPCOUNT -#if defined(HAVE_LONG_INT_64) - return __builtin_popcountl(word); -#elif defined(HAVE_LONG_LONG_INT_64) - return __builtin_popcountll(word); -#else -#error must have a working 64-bit integer datatype -#endif -#else /* !HAVE__BUILTIN_POPCOUNT */ - int result = 0; - - while (word != 0) - { - result += pg_number_of_ones[word & 255]; - word >>= 8; - } - - return result; -#endif /* HAVE__BUILTIN_POPCOUNT */ -} - -#ifndef TRY_POPCNT_FAST - -/* - * When the POPCNT instruction is not available, there's no point in using - * function pointers to vary the implementation between the fast and slow - * method. We instead just make these actual external functions when - * TRY_POPCNT_FAST is not defined. The compiler should be able to inline - * the slow versions here. - */ -int -pg_popcount32(uint32 word) -{ - return pg_popcount32_slow(word); -} - -int -pg_popcount64(uint64 word) -{ - return pg_popcount64_slow(word); -} - -#endif /* !TRY_POPCNT_FAST */ - -/* - * pg_popcount - * Returns the number of 1-bits in buf - */ -uint64 -pg_popcount(const char *buf, int bytes) -{ - uint64 popcnt = 0; - -#if SIZEOF_VOID_P >= 8 - /* Process in 64-bit chunks if the buffer is aligned. */ - if (buf == (const char *) TYPEALIGN(8, buf)) - { - const uint64 *words = (const uint64 *) buf; - - while (bytes >= 8) - { - popcnt += pg_popcount64(*words++); - bytes -= 8; - } - - buf = (const char *) words; - } -#else - /* Process in 32-bit chunks if the buffer is aligned. */ - if (buf == (const char *) TYPEALIGN(4, buf)) - { - const uint32 *words = (const uint32 *) buf; - - while (bytes >= 4) - { - popcnt += pg_popcount32(*words++); - bytes -= 4; - } - - buf = (const char *) words; - } -#endif - - /* Process any remaining bytes */ - while (bytes--) - popcnt += pg_number_of_ones[(unsigned char) *buf++]; - - return popcnt; -} diff --git a/contrib/libs/libpq/src/port/pg_config_paths.h b/contrib/libs/libpq/src/port/pg_config_paths.h deleted file mode 100644 index ba4db149b6..0000000000 --- a/contrib/libs/libpq/src/port/pg_config_paths.h +++ /dev/null @@ -1,12 +0,0 @@ -#define PGBINDIR "/var/empty/postgresql-16.2/bin" -#define PGSHAREDIR "/var/empty/postgresql-16.2/share" -#define SYSCONFDIR "/etc/postgresql" -#define INCLUDEDIR "/var/empty/postgresql-16.2/include" -#define PKGINCLUDEDIR "/var/empty/postgresql-16.2/include" -#define INCLUDEDIRSERVER "/var/empty/postgresql-16.2/include/server" -#define LIBDIR "/var/empty/tmp/out/lib" -#define PKGLIBDIR "/var/empty/tmp/out/lib/postgresql" -#define LOCALEDIR "/var/empty/postgresql-16.2/share/locale" -#define DOCDIR "/var/empty/postgresql-16.2/share/doc/" -#define HTMLDIR "/var/empty/postgresql-16.2/share/doc/" -#define MANDIR "/var/empty/postgresql-16.2/share/man" diff --git a/contrib/libs/libpq/src/port/pg_crc32c_sb8.c b/contrib/libs/libpq/src/port/pg_crc32c_sb8.c deleted file mode 100644 index cdd3e05123..0000000000 --- a/contrib/libs/libpq/src/port/pg_crc32c_sb8.c +++ /dev/null @@ -1,1169 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_crc32c_sb8.c - * Compute CRC-32C checksum using slicing-by-8 algorithm. - * - * Michael E. Kounavis, Frank L. Berry, - * "Novel Table Lookup-Based Algorithms for High-Performance CRC - * Generation", IEEE Transactions on Computers, vol.57, no. 11, - * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85 - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/pg_crc32c_sb8.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include "port/pg_crc32c.h" - -static const uint32 pg_crc32c_table[8][256]; - -/* Accumulate one input byte */ -#ifdef WORDS_BIGENDIAN -#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8) -#else -#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8) -#endif - -pg_crc32c -pg_comp_crc32c_sb8(pg_crc32c crc, const void *data, size_t len) -{ - const unsigned char *p = data; - const uint32 *p4; - - /* - * Handle 0-3 initial bytes one at a time, so that the loop below starts - * with a pointer aligned to four bytes. - */ - while (len > 0 && ((uintptr_t) p & 3)) - { - crc = CRC8(*p++); - len--; - } - - /* - * Process eight bytes of data at a time. - */ - p4 = (const uint32 *) p; - while (len >= 8) - { - uint32 a = *p4++ ^ crc; - uint32 b = *p4++; - -#ifdef WORDS_BIGENDIAN - const uint8 c0 = b; - const uint8 c1 = b >> 8; - const uint8 c2 = b >> 16; - const uint8 c3 = b >> 24; - const uint8 c4 = a; - const uint8 c5 = a >> 8; - const uint8 c6 = a >> 16; - const uint8 c7 = a >> 24; -#else - const uint8 c0 = b >> 24; - const uint8 c1 = b >> 16; - const uint8 c2 = b >> 8; - const uint8 c3 = b; - const uint8 c4 = a >> 24; - const uint8 c5 = a >> 16; - const uint8 c6 = a >> 8; - const uint8 c7 = a; -#endif - - crc = - pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^ - pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^ - pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^ - pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7]; - - len -= 8; - } - - /* - * Handle any remaining bytes one at a time. - */ - p = (const unsigned char *) p4; - while (len > 0) - { - crc = CRC8(*p++); - len--; - } - - return crc; -} - -/* - * Lookup tables for the slicing-by-8 algorithm, for the so-called Castagnoli - * polynomial (the same that is used e.g. in iSCSI), 0x1EDC6F41. Using - * Williams' terms, this is the "normal", not "reflected" version. However, on - * big-endian systems the values in the tables are stored in byte-reversed - * order (IOW, the tables are stored in little-endian order even on big-endian - * systems). - */ -static const uint32 pg_crc32c_table[8][256] = { -#ifndef WORDS_BIGENDIAN - { - 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, - 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, - 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B, - 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24, - 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B, - 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384, - 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54, - 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B, - 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A, - 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35, - 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5, - 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA, - 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45, - 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A, - 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A, - 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595, - 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48, - 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957, - 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687, - 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198, - 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927, - 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38, - 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8, - 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7, - 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096, - 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789, - 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859, - 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46, - 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9, - 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6, - 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36, - 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829, - 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C, - 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93, - 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043, - 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C, - 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3, - 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC, - 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C, - 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033, - 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652, - 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D, - 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D, - 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982, - 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D, - 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622, - 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2, - 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED, - 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530, - 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F, - 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF, - 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0, - 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F, - 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540, - 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90, - 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F, - 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE, - 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1, - 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321, - 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E, - 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81, - 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E, - 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E, - 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 - }, - { - 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899, - 0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945, - 0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21, - 0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD, - 0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918, - 0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4, - 0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0, - 0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C, - 0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B, - 0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47, - 0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823, - 0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF, - 0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A, - 0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6, - 0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2, - 0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E, - 0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D, - 0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41, - 0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25, - 0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9, - 0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C, - 0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0, - 0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4, - 0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78, - 0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F, - 0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43, - 0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27, - 0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB, - 0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E, - 0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2, - 0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6, - 0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A, - 0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260, - 0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC, - 0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8, - 0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004, - 0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1, - 0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D, - 0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059, - 0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185, - 0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162, - 0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE, - 0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA, - 0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306, - 0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3, - 0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F, - 0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B, - 0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287, - 0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464, - 0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8, - 0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC, - 0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600, - 0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5, - 0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439, - 0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D, - 0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781, - 0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766, - 0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA, - 0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE, - 0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502, - 0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7, - 0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B, - 0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F, - 0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483 - }, - { - 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073, - 0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469, - 0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6, - 0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC, - 0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9, - 0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3, - 0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C, - 0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726, - 0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67, - 0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D, - 0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2, - 0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8, - 0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED, - 0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7, - 0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828, - 0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32, - 0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA, - 0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0, - 0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F, - 0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75, - 0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20, - 0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A, - 0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5, - 0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF, - 0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE, - 0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4, - 0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B, - 0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161, - 0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634, - 0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E, - 0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1, - 0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB, - 0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730, - 0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A, - 0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5, - 0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF, - 0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA, - 0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0, - 0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F, - 0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065, - 0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24, - 0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E, - 0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1, - 0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB, - 0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE, - 0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4, - 0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B, - 0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71, - 0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9, - 0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3, - 0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C, - 0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36, - 0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63, - 0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79, - 0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6, - 0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC, - 0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD, - 0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7, - 0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238, - 0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622, - 0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177, - 0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D, - 0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2, - 0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8 - }, - { - 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939, - 0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA, - 0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF, - 0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C, - 0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804, - 0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7, - 0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2, - 0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11, - 0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2, - 0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41, - 0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54, - 0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7, - 0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F, - 0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C, - 0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69, - 0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A, - 0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE, - 0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D, - 0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538, - 0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB, - 0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3, - 0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610, - 0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405, - 0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6, - 0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255, - 0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6, - 0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3, - 0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040, - 0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368, - 0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B, - 0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E, - 0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D, - 0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006, - 0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5, - 0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0, - 0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213, - 0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B, - 0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8, - 0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD, - 0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E, - 0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D, - 0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E, - 0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B, - 0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698, - 0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0, - 0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443, - 0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656, - 0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5, - 0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1, - 0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12, - 0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07, - 0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4, - 0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC, - 0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F, - 0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A, - 0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9, - 0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A, - 0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99, - 0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C, - 0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F, - 0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57, - 0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4, - 0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1, - 0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842 - }, - { - 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4, - 0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44, - 0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65, - 0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5, - 0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127, - 0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97, - 0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6, - 0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406, - 0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3, - 0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13, - 0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32, - 0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082, - 0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470, - 0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0, - 0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1, - 0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151, - 0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A, - 0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA, - 0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB, - 0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B, - 0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89, - 0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539, - 0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018, - 0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8, - 0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D, - 0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD, - 0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C, - 0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C, - 0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE, - 0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E, - 0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F, - 0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF, - 0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8, - 0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18, - 0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39, - 0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089, - 0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B, - 0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB, - 0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA, - 0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A, - 0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF, - 0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F, - 0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E, - 0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE, - 0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C, - 0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C, - 0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD, - 0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D, - 0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06, - 0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6, - 0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497, - 0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27, - 0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5, - 0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065, - 0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544, - 0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4, - 0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51, - 0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1, - 0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0, - 0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70, - 0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82, - 0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532, - 0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013, - 0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3 - }, - { - 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA, - 0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD, - 0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5, - 0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2, - 0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4, - 0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93, - 0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB, - 0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C, - 0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57, - 0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20, - 0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548, - 0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F, - 0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69, - 0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E, - 0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576, - 0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201, - 0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031, - 0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746, - 0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E, - 0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59, - 0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F, - 0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778, - 0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810, - 0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67, - 0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC, - 0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB, - 0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3, - 0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4, - 0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682, - 0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5, - 0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D, - 0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA, - 0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C, - 0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B, - 0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413, - 0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364, - 0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32, - 0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45, - 0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D, - 0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A, - 0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81, - 0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6, - 0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E, - 0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9, - 0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF, - 0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8, - 0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0, - 0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7, - 0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7, - 0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090, - 0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8, - 0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F, - 0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9, - 0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE, - 0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6, - 0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1, - 0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A, - 0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D, - 0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975, - 0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02, - 0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154, - 0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623, - 0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B, - 0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C - }, - { - 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558, - 0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089, - 0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B, - 0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA, - 0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE, - 0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F, - 0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD, - 0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C, - 0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5, - 0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334, - 0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6, - 0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67, - 0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43, - 0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992, - 0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110, - 0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1, - 0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222, - 0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3, - 0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71, - 0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0, - 0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884, - 0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55, - 0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7, - 0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006, - 0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F, - 0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E, - 0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC, - 0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D, - 0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39, - 0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8, - 0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A, - 0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB, - 0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC, - 0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D, - 0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF, - 0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E, - 0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A, - 0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB, - 0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59, - 0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988, - 0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811, - 0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0, - 0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542, - 0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093, - 0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7, - 0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766, - 0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4, - 0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35, - 0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6, - 0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907, - 0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185, - 0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454, - 0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670, - 0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1, - 0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23, - 0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2, - 0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B, - 0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA, - 0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238, - 0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9, - 0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD, - 0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C, - 0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E, - 0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F - }, - { - 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769, - 0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504, - 0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3, - 0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE, - 0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD, - 0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0, - 0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07, - 0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A, - 0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0, - 0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D, - 0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A, - 0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447, - 0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44, - 0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929, - 0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E, - 0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3, - 0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B, - 0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36, - 0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881, - 0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC, - 0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF, - 0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782, - 0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135, - 0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358, - 0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2, - 0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF, - 0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18, - 0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75, - 0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076, - 0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B, - 0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC, - 0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1, - 0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D, - 0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360, - 0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7, - 0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA, - 0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9, - 0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4, - 0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63, - 0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E, - 0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494, - 0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9, - 0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E, - 0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223, - 0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20, - 0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D, - 0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA, - 0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97, - 0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F, - 0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852, - 0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5, - 0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88, - 0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B, - 0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6, - 0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751, - 0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C, - 0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6, - 0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB, - 0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C, - 0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911, - 0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612, - 0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F, - 0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8, - 0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5 - } -#else /* !WORDS_BIGENDIAN */ - { - 0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013, - 0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4, - 0xCF58D98A, 0xCCDBB278, 0x3828E26B, 0x3BAB8999, - 0xD0CF434D, 0xD34C28BF, 0x27BF78AC, 0x243C135E, - 0x6FC75E10, 0x6C4435E2, 0x98B765F1, 0x9B340E03, - 0x7050C4D7, 0x73D3AF25, 0x8720FF36, 0x84A394C4, - 0xA09F879A, 0xA31CEC68, 0x57EFBC7B, 0x546CD789, - 0xBF081D5D, 0xBC8B76AF, 0x487826BC, 0x4BFB4D4E, - 0xDE8EBD20, 0xDD0DD6D2, 0x29FE86C1, 0x2A7DED33, - 0xC11927E7, 0xC29A4C15, 0x36691C06, 0x35EA77F4, - 0x11D664AA, 0x12550F58, 0xE6A65F4B, 0xE52534B9, - 0x0E41FE6D, 0x0DC2959F, 0xF931C58C, 0xFAB2AE7E, - 0xB149E330, 0xB2CA88C2, 0x4639D8D1, 0x45BAB323, - 0xAEDE79F7, 0xAD5D1205, 0x59AE4216, 0x5A2D29E4, - 0x7E113ABA, 0x7D925148, 0x8961015B, 0x8AE26AA9, - 0x6186A07D, 0x6205CB8F, 0x96F69B9C, 0x9575F06E, - 0xBC1D7B41, 0xBF9E10B3, 0x4B6D40A0, 0x48EE2B52, - 0xA38AE186, 0xA0098A74, 0x54FADA67, 0x5779B195, - 0x7345A2CB, 0x70C6C939, 0x8435992A, 0x87B6F2D8, - 0x6CD2380C, 0x6F5153FE, 0x9BA203ED, 0x9821681F, - 0xD3DA2551, 0xD0594EA3, 0x24AA1EB0, 0x27297542, - 0xCC4DBF96, 0xCFCED464, 0x3B3D8477, 0x38BEEF85, - 0x1C82FCDB, 0x1F019729, 0xEBF2C73A, 0xE871ACC8, - 0x0315661C, 0x00960DEE, 0xF4655DFD, 0xF7E6360F, - 0x6293C661, 0x6110AD93, 0x95E3FD80, 0x96609672, - 0x7D045CA6, 0x7E873754, 0x8A746747, 0x89F70CB5, - 0xADCB1FEB, 0xAE487419, 0x5ABB240A, 0x59384FF8, - 0xB25C852C, 0xB1DFEEDE, 0x452CBECD, 0x46AFD53F, - 0x0D549871, 0x0ED7F383, 0xFA24A390, 0xF9A7C862, - 0x12C302B6, 0x11406944, 0xE5B33957, 0xE63052A5, - 0xC20C41FB, 0xC18F2A09, 0x357C7A1A, 0x36FF11E8, - 0xDD9BDB3C, 0xDE18B0CE, 0x2AEBE0DD, 0x29688B2F, - 0x783BF682, 0x7BB89D70, 0x8F4BCD63, 0x8CC8A691, - 0x67AC6C45, 0x642F07B7, 0x90DC57A4, 0x935F3C56, - 0xB7632F08, 0xB4E044FA, 0x401314E9, 0x43907F1B, - 0xA8F4B5CF, 0xAB77DE3D, 0x5F848E2E, 0x5C07E5DC, - 0x17FCA892, 0x147FC360, 0xE08C9373, 0xE30FF881, - 0x086B3255, 0x0BE859A7, 0xFF1B09B4, 0xFC986246, - 0xD8A47118, 0xDB271AEA, 0x2FD44AF9, 0x2C57210B, - 0xC733EBDF, 0xC4B0802D, 0x3043D03E, 0x33C0BBCC, - 0xA6B54BA2, 0xA5362050, 0x51C57043, 0x52461BB1, - 0xB922D165, 0xBAA1BA97, 0x4E52EA84, 0x4DD18176, - 0x69ED9228, 0x6A6EF9DA, 0x9E9DA9C9, 0x9D1EC23B, - 0x767A08EF, 0x75F9631D, 0x810A330E, 0x828958FC, - 0xC97215B2, 0xCAF17E40, 0x3E022E53, 0x3D8145A1, - 0xD6E58F75, 0xD566E487, 0x2195B494, 0x2216DF66, - 0x062ACC38, 0x05A9A7CA, 0xF15AF7D9, 0xF2D99C2B, - 0x19BD56FF, 0x1A3E3D0D, 0xEECD6D1E, 0xED4E06EC, - 0xC4268DC3, 0xC7A5E631, 0x3356B622, 0x30D5DDD0, - 0xDBB11704, 0xD8327CF6, 0x2CC12CE5, 0x2F424717, - 0x0B7E5449, 0x08FD3FBB, 0xFC0E6FA8, 0xFF8D045A, - 0x14E9CE8E, 0x176AA57C, 0xE399F56F, 0xE01A9E9D, - 0xABE1D3D3, 0xA862B821, 0x5C91E832, 0x5F1283C0, - 0xB4764914, 0xB7F522E6, 0x430672F5, 0x40851907, - 0x64B90A59, 0x673A61AB, 0x93C931B8, 0x904A5A4A, - 0x7B2E909E, 0x78ADFB6C, 0x8C5EAB7F, 0x8FDDC08D, - 0x1AA830E3, 0x192B5B11, 0xEDD80B02, 0xEE5B60F0, - 0x053FAA24, 0x06BCC1D6, 0xF24F91C5, 0xF1CCFA37, - 0xD5F0E969, 0xD673829B, 0x2280D288, 0x2103B97A, - 0xCA6773AE, 0xC9E4185C, 0x3D17484F, 0x3E9423BD, - 0x756F6EF3, 0x76EC0501, 0x821F5512, 0x819C3EE0, - 0x6AF8F434, 0x697B9FC6, 0x9D88CFD5, 0x9E0BA427, - 0xBA37B779, 0xB9B4DC8B, 0x4D478C98, 0x4EC4E76A, - 0xA5A02DBE, 0xA623464C, 0x52D0165F, 0x51537DAD, - }, - { - 0x00000000, 0x7798A213, 0xEE304527, 0x99A8E734, - 0xDC618A4E, 0xABF9285D, 0x3251CF69, 0x45C96D7A, - 0xB8C3149D, 0xCF5BB68E, 0x56F351BA, 0x216BF3A9, - 0x64A29ED3, 0x133A3CC0, 0x8A92DBF4, 0xFD0A79E7, - 0x81F1C53F, 0xF669672C, 0x6FC18018, 0x1859220B, - 0x5D904F71, 0x2A08ED62, 0xB3A00A56, 0xC438A845, - 0x3932D1A2, 0x4EAA73B1, 0xD7029485, 0xA09A3696, - 0xE5535BEC, 0x92CBF9FF, 0x0B631ECB, 0x7CFBBCD8, - 0x02E38B7F, 0x757B296C, 0xECD3CE58, 0x9B4B6C4B, - 0xDE820131, 0xA91AA322, 0x30B24416, 0x472AE605, - 0xBA209FE2, 0xCDB83DF1, 0x5410DAC5, 0x238878D6, - 0x664115AC, 0x11D9B7BF, 0x8871508B, 0xFFE9F298, - 0x83124E40, 0xF48AEC53, 0x6D220B67, 0x1ABAA974, - 0x5F73C40E, 0x28EB661D, 0xB1438129, 0xC6DB233A, - 0x3BD15ADD, 0x4C49F8CE, 0xD5E11FFA, 0xA279BDE9, - 0xE7B0D093, 0x90287280, 0x098095B4, 0x7E1837A7, - 0x04C617FF, 0x735EB5EC, 0xEAF652D8, 0x9D6EF0CB, - 0xD8A79DB1, 0xAF3F3FA2, 0x3697D896, 0x410F7A85, - 0xBC050362, 0xCB9DA171, 0x52354645, 0x25ADE456, - 0x6064892C, 0x17FC2B3F, 0x8E54CC0B, 0xF9CC6E18, - 0x8537D2C0, 0xF2AF70D3, 0x6B0797E7, 0x1C9F35F4, - 0x5956588E, 0x2ECEFA9D, 0xB7661DA9, 0xC0FEBFBA, - 0x3DF4C65D, 0x4A6C644E, 0xD3C4837A, 0xA45C2169, - 0xE1954C13, 0x960DEE00, 0x0FA50934, 0x783DAB27, - 0x06259C80, 0x71BD3E93, 0xE815D9A7, 0x9F8D7BB4, - 0xDA4416CE, 0xADDCB4DD, 0x347453E9, 0x43ECF1FA, - 0xBEE6881D, 0xC97E2A0E, 0x50D6CD3A, 0x274E6F29, - 0x62870253, 0x151FA040, 0x8CB74774, 0xFB2FE567, - 0x87D459BF, 0xF04CFBAC, 0x69E41C98, 0x1E7CBE8B, - 0x5BB5D3F1, 0x2C2D71E2, 0xB58596D6, 0xC21D34C5, - 0x3F174D22, 0x488FEF31, 0xD1270805, 0xA6BFAA16, - 0xE376C76C, 0x94EE657F, 0x0D46824B, 0x7ADE2058, - 0xF9FAC3FB, 0x8E6261E8, 0x17CA86DC, 0x605224CF, - 0x259B49B5, 0x5203EBA6, 0xCBAB0C92, 0xBC33AE81, - 0x4139D766, 0x36A17575, 0xAF099241, 0xD8913052, - 0x9D585D28, 0xEAC0FF3B, 0x7368180F, 0x04F0BA1C, - 0x780B06C4, 0x0F93A4D7, 0x963B43E3, 0xE1A3E1F0, - 0xA46A8C8A, 0xD3F22E99, 0x4A5AC9AD, 0x3DC26BBE, - 0xC0C81259, 0xB750B04A, 0x2EF8577E, 0x5960F56D, - 0x1CA99817, 0x6B313A04, 0xF299DD30, 0x85017F23, - 0xFB194884, 0x8C81EA97, 0x15290DA3, 0x62B1AFB0, - 0x2778C2CA, 0x50E060D9, 0xC94887ED, 0xBED025FE, - 0x43DA5C19, 0x3442FE0A, 0xADEA193E, 0xDA72BB2D, - 0x9FBBD657, 0xE8237444, 0x718B9370, 0x06133163, - 0x7AE88DBB, 0x0D702FA8, 0x94D8C89C, 0xE3406A8F, - 0xA68907F5, 0xD111A5E6, 0x48B942D2, 0x3F21E0C1, - 0xC22B9926, 0xB5B33B35, 0x2C1BDC01, 0x5B837E12, - 0x1E4A1368, 0x69D2B17B, 0xF07A564F, 0x87E2F45C, - 0xFD3CD404, 0x8AA47617, 0x130C9123, 0x64943330, - 0x215D5E4A, 0x56C5FC59, 0xCF6D1B6D, 0xB8F5B97E, - 0x45FFC099, 0x3267628A, 0xABCF85BE, 0xDC5727AD, - 0x999E4AD7, 0xEE06E8C4, 0x77AE0FF0, 0x0036ADE3, - 0x7CCD113B, 0x0B55B328, 0x92FD541C, 0xE565F60F, - 0xA0AC9B75, 0xD7343966, 0x4E9CDE52, 0x39047C41, - 0xC40E05A6, 0xB396A7B5, 0x2A3E4081, 0x5DA6E292, - 0x186F8FE8, 0x6FF72DFB, 0xF65FCACF, 0x81C768DC, - 0xFFDF5F7B, 0x8847FD68, 0x11EF1A5C, 0x6677B84F, - 0x23BED535, 0x54267726, 0xCD8E9012, 0xBA163201, - 0x471C4BE6, 0x3084E9F5, 0xA92C0EC1, 0xDEB4ACD2, - 0x9B7DC1A8, 0xECE563BB, 0x754D848F, 0x02D5269C, - 0x7E2E9A44, 0x09B63857, 0x901EDF63, 0xE7867D70, - 0xA24F100A, 0xD5D7B219, 0x4C7F552D, 0x3BE7F73E, - 0xC6ED8ED9, 0xB1752CCA, 0x28DDCBFE, 0x5F4569ED, - 0x1A8C0497, 0x6D14A684, 0xF4BC41B0, 0x8324E3A3, - }, - { - 0x00000000, 0x7E9241A5, 0x0D526F4F, 0x73C02EEA, - 0x1AA4DE9E, 0x64369F3B, 0x17F6B1D1, 0x6964F074, - 0xC53E5138, 0xBBAC109D, 0xC86C3E77, 0xB6FE7FD2, - 0xDF9A8FA6, 0xA108CE03, 0xD2C8E0E9, 0xAC5AA14C, - 0x8A7DA270, 0xF4EFE3D5, 0x872FCD3F, 0xF9BD8C9A, - 0x90D97CEE, 0xEE4B3D4B, 0x9D8B13A1, 0xE3195204, - 0x4F43F348, 0x31D1B2ED, 0x42119C07, 0x3C83DDA2, - 0x55E72DD6, 0x2B756C73, 0x58B54299, 0x2627033C, - 0x14FB44E1, 0x6A690544, 0x19A92BAE, 0x673B6A0B, - 0x0E5F9A7F, 0x70CDDBDA, 0x030DF530, 0x7D9FB495, - 0xD1C515D9, 0xAF57547C, 0xDC977A96, 0xA2053B33, - 0xCB61CB47, 0xB5F38AE2, 0xC633A408, 0xB8A1E5AD, - 0x9E86E691, 0xE014A734, 0x93D489DE, 0xED46C87B, - 0x8422380F, 0xFAB079AA, 0x89705740, 0xF7E216E5, - 0x5BB8B7A9, 0x252AF60C, 0x56EAD8E6, 0x28789943, - 0x411C6937, 0x3F8E2892, 0x4C4E0678, 0x32DC47DD, - 0xD98065C7, 0xA7122462, 0xD4D20A88, 0xAA404B2D, - 0xC324BB59, 0xBDB6FAFC, 0xCE76D416, 0xB0E495B3, - 0x1CBE34FF, 0x622C755A, 0x11EC5BB0, 0x6F7E1A15, - 0x061AEA61, 0x7888ABC4, 0x0B48852E, 0x75DAC48B, - 0x53FDC7B7, 0x2D6F8612, 0x5EAFA8F8, 0x203DE95D, - 0x49591929, 0x37CB588C, 0x440B7666, 0x3A9937C3, - 0x96C3968F, 0xE851D72A, 0x9B91F9C0, 0xE503B865, - 0x8C674811, 0xF2F509B4, 0x8135275E, 0xFFA766FB, - 0xCD7B2126, 0xB3E96083, 0xC0294E69, 0xBEBB0FCC, - 0xD7DFFFB8, 0xA94DBE1D, 0xDA8D90F7, 0xA41FD152, - 0x0845701E, 0x76D731BB, 0x05171F51, 0x7B855EF4, - 0x12E1AE80, 0x6C73EF25, 0x1FB3C1CF, 0x6121806A, - 0x47068356, 0x3994C2F3, 0x4A54EC19, 0x34C6ADBC, - 0x5DA25DC8, 0x23301C6D, 0x50F03287, 0x2E627322, - 0x8238D26E, 0xFCAA93CB, 0x8F6ABD21, 0xF1F8FC84, - 0x989C0CF0, 0xE60E4D55, 0x95CE63BF, 0xEB5C221A, - 0x4377278B, 0x3DE5662E, 0x4E2548C4, 0x30B70961, - 0x59D3F915, 0x2741B8B0, 0x5481965A, 0x2A13D7FF, - 0x864976B3, 0xF8DB3716, 0x8B1B19FC, 0xF5895859, - 0x9CEDA82D, 0xE27FE988, 0x91BFC762, 0xEF2D86C7, - 0xC90A85FB, 0xB798C45E, 0xC458EAB4, 0xBACAAB11, - 0xD3AE5B65, 0xAD3C1AC0, 0xDEFC342A, 0xA06E758F, - 0x0C34D4C3, 0x72A69566, 0x0166BB8C, 0x7FF4FA29, - 0x16900A5D, 0x68024BF8, 0x1BC26512, 0x655024B7, - 0x578C636A, 0x291E22CF, 0x5ADE0C25, 0x244C4D80, - 0x4D28BDF4, 0x33BAFC51, 0x407AD2BB, 0x3EE8931E, - 0x92B23252, 0xEC2073F7, 0x9FE05D1D, 0xE1721CB8, - 0x8816ECCC, 0xF684AD69, 0x85448383, 0xFBD6C226, - 0xDDF1C11A, 0xA36380BF, 0xD0A3AE55, 0xAE31EFF0, - 0xC7551F84, 0xB9C75E21, 0xCA0770CB, 0xB495316E, - 0x18CF9022, 0x665DD187, 0x159DFF6D, 0x6B0FBEC8, - 0x026B4EBC, 0x7CF90F19, 0x0F3921F3, 0x71AB6056, - 0x9AF7424C, 0xE46503E9, 0x97A52D03, 0xE9376CA6, - 0x80539CD2, 0xFEC1DD77, 0x8D01F39D, 0xF393B238, - 0x5FC91374, 0x215B52D1, 0x529B7C3B, 0x2C093D9E, - 0x456DCDEA, 0x3BFF8C4F, 0x483FA2A5, 0x36ADE300, - 0x108AE03C, 0x6E18A199, 0x1DD88F73, 0x634ACED6, - 0x0A2E3EA2, 0x74BC7F07, 0x077C51ED, 0x79EE1048, - 0xD5B4B104, 0xAB26F0A1, 0xD8E6DE4B, 0xA6749FEE, - 0xCF106F9A, 0xB1822E3F, 0xC24200D5, 0xBCD04170, - 0x8E0C06AD, 0xF09E4708, 0x835E69E2, 0xFDCC2847, - 0x94A8D833, 0xEA3A9996, 0x99FAB77C, 0xE768F6D9, - 0x4B325795, 0x35A01630, 0x466038DA, 0x38F2797F, - 0x5196890B, 0x2F04C8AE, 0x5CC4E644, 0x2256A7E1, - 0x0471A4DD, 0x7AE3E578, 0x0923CB92, 0x77B18A37, - 0x1ED57A43, 0x60473BE6, 0x1387150C, 0x6D1554A9, - 0xC14FF5E5, 0xBFDDB440, 0xCC1D9AAA, 0xB28FDB0F, - 0xDBEB2B7B, 0xA5796ADE, 0xD6B94434, 0xA82B0591, - }, - { - 0x00000000, 0xB8AA45DD, 0x812367BF, 0x39892262, - 0xF331227B, 0x4B9B67A6, 0x721245C4, 0xCAB80019, - 0xE66344F6, 0x5EC9012B, 0x67402349, 0xDFEA6694, - 0x1552668D, 0xADF82350, 0x94710132, 0x2CDB44EF, - 0x3DB164E9, 0x851B2134, 0xBC920356, 0x0438468B, - 0xCE804692, 0x762A034F, 0x4FA3212D, 0xF70964F0, - 0xDBD2201F, 0x637865C2, 0x5AF147A0, 0xE25B027D, - 0x28E30264, 0x904947B9, 0xA9C065DB, 0x116A2006, - 0x8B1425D7, 0x33BE600A, 0x0A374268, 0xB29D07B5, - 0x782507AC, 0xC08F4271, 0xF9066013, 0x41AC25CE, - 0x6D776121, 0xD5DD24FC, 0xEC54069E, 0x54FE4343, - 0x9E46435A, 0x26EC0687, 0x1F6524E5, 0xA7CF6138, - 0xB6A5413E, 0x0E0F04E3, 0x37862681, 0x8F2C635C, - 0x45946345, 0xFD3E2698, 0xC4B704FA, 0x7C1D4127, - 0x50C605C8, 0xE86C4015, 0xD1E56277, 0x694F27AA, - 0xA3F727B3, 0x1B5D626E, 0x22D4400C, 0x9A7E05D1, - 0xE75FA6AB, 0x5FF5E376, 0x667CC114, 0xDED684C9, - 0x146E84D0, 0xACC4C10D, 0x954DE36F, 0x2DE7A6B2, - 0x013CE25D, 0xB996A780, 0x801F85E2, 0x38B5C03F, - 0xF20DC026, 0x4AA785FB, 0x732EA799, 0xCB84E244, - 0xDAEEC242, 0x6244879F, 0x5BCDA5FD, 0xE367E020, - 0x29DFE039, 0x9175A5E4, 0xA8FC8786, 0x1056C25B, - 0x3C8D86B4, 0x8427C369, 0xBDAEE10B, 0x0504A4D6, - 0xCFBCA4CF, 0x7716E112, 0x4E9FC370, 0xF63586AD, - 0x6C4B837C, 0xD4E1C6A1, 0xED68E4C3, 0x55C2A11E, - 0x9F7AA107, 0x27D0E4DA, 0x1E59C6B8, 0xA6F38365, - 0x8A28C78A, 0x32828257, 0x0B0BA035, 0xB3A1E5E8, - 0x7919E5F1, 0xC1B3A02C, 0xF83A824E, 0x4090C793, - 0x51FAE795, 0xE950A248, 0xD0D9802A, 0x6873C5F7, - 0xA2CBC5EE, 0x1A618033, 0x23E8A251, 0x9B42E78C, - 0xB799A363, 0x0F33E6BE, 0x36BAC4DC, 0x8E108101, - 0x44A88118, 0xFC02C4C5, 0xC58BE6A7, 0x7D21A37A, - 0x3FC9A052, 0x8763E58F, 0xBEEAC7ED, 0x06408230, - 0xCCF88229, 0x7452C7F4, 0x4DDBE596, 0xF571A04B, - 0xD9AAE4A4, 0x6100A179, 0x5889831B, 0xE023C6C6, - 0x2A9BC6DF, 0x92318302, 0xABB8A160, 0x1312E4BD, - 0x0278C4BB, 0xBAD28166, 0x835BA304, 0x3BF1E6D9, - 0xF149E6C0, 0x49E3A31D, 0x706A817F, 0xC8C0C4A2, - 0xE41B804D, 0x5CB1C590, 0x6538E7F2, 0xDD92A22F, - 0x172AA236, 0xAF80E7EB, 0x9609C589, 0x2EA38054, - 0xB4DD8585, 0x0C77C058, 0x35FEE23A, 0x8D54A7E7, - 0x47ECA7FE, 0xFF46E223, 0xC6CFC041, 0x7E65859C, - 0x52BEC173, 0xEA1484AE, 0xD39DA6CC, 0x6B37E311, - 0xA18FE308, 0x1925A6D5, 0x20AC84B7, 0x9806C16A, - 0x896CE16C, 0x31C6A4B1, 0x084F86D3, 0xB0E5C30E, - 0x7A5DC317, 0xC2F786CA, 0xFB7EA4A8, 0x43D4E175, - 0x6F0FA59A, 0xD7A5E047, 0xEE2CC225, 0x568687F8, - 0x9C3E87E1, 0x2494C23C, 0x1D1DE05E, 0xA5B7A583, - 0xD89606F9, 0x603C4324, 0x59B56146, 0xE11F249B, - 0x2BA72482, 0x930D615F, 0xAA84433D, 0x122E06E0, - 0x3EF5420F, 0x865F07D2, 0xBFD625B0, 0x077C606D, - 0xCDC46074, 0x756E25A9, 0x4CE707CB, 0xF44D4216, - 0xE5276210, 0x5D8D27CD, 0x640405AF, 0xDCAE4072, - 0x1616406B, 0xAEBC05B6, 0x973527D4, 0x2F9F6209, - 0x034426E6, 0xBBEE633B, 0x82674159, 0x3ACD0484, - 0xF075049D, 0x48DF4140, 0x71566322, 0xC9FC26FF, - 0x5382232E, 0xEB2866F3, 0xD2A14491, 0x6A0B014C, - 0xA0B30155, 0x18194488, 0x219066EA, 0x993A2337, - 0xB5E167D8, 0x0D4B2205, 0x34C20067, 0x8C6845BA, - 0x46D045A3, 0xFE7A007E, 0xC7F3221C, 0x7F5967C1, - 0x6E3347C7, 0xD699021A, 0xEF102078, 0x57BA65A5, - 0x9D0265BC, 0x25A82061, 0x1C210203, 0xA48B47DE, - 0x88500331, 0x30FA46EC, 0x0973648E, 0xB1D92153, - 0x7B61214A, 0xC3CB6497, 0xFA4246F5, 0x42E80328, - }, - { - 0x00000000, 0xAC6F1138, 0x58DF2270, 0xF4B03348, - 0xB0BE45E0, 0x1CD154D8, 0xE8616790, 0x440E76A8, - 0x910B67C5, 0x3D6476FD, 0xC9D445B5, 0x65BB548D, - 0x21B52225, 0x8DDA331D, 0x796A0055, 0xD505116D, - 0xD361228F, 0x7F0E33B7, 0x8BBE00FF, 0x27D111C7, - 0x63DF676F, 0xCFB07657, 0x3B00451F, 0x976F5427, - 0x426A454A, 0xEE055472, 0x1AB5673A, 0xB6DA7602, - 0xF2D400AA, 0x5EBB1192, 0xAA0B22DA, 0x066433E2, - 0x57B5A81B, 0xFBDAB923, 0x0F6A8A6B, 0xA3059B53, - 0xE70BEDFB, 0x4B64FCC3, 0xBFD4CF8B, 0x13BBDEB3, - 0xC6BECFDE, 0x6AD1DEE6, 0x9E61EDAE, 0x320EFC96, - 0x76008A3E, 0xDA6F9B06, 0x2EDFA84E, 0x82B0B976, - 0x84D48A94, 0x28BB9BAC, 0xDC0BA8E4, 0x7064B9DC, - 0x346ACF74, 0x9805DE4C, 0x6CB5ED04, 0xC0DAFC3C, - 0x15DFED51, 0xB9B0FC69, 0x4D00CF21, 0xE16FDE19, - 0xA561A8B1, 0x090EB989, 0xFDBE8AC1, 0x51D19BF9, - 0xAE6A5137, 0x0205400F, 0xF6B57347, 0x5ADA627F, - 0x1ED414D7, 0xB2BB05EF, 0x460B36A7, 0xEA64279F, - 0x3F6136F2, 0x930E27CA, 0x67BE1482, 0xCBD105BA, - 0x8FDF7312, 0x23B0622A, 0xD7005162, 0x7B6F405A, - 0x7D0B73B8, 0xD1646280, 0x25D451C8, 0x89BB40F0, - 0xCDB53658, 0x61DA2760, 0x956A1428, 0x39050510, - 0xEC00147D, 0x406F0545, 0xB4DF360D, 0x18B02735, - 0x5CBE519D, 0xF0D140A5, 0x046173ED, 0xA80E62D5, - 0xF9DFF92C, 0x55B0E814, 0xA100DB5C, 0x0D6FCA64, - 0x4961BCCC, 0xE50EADF4, 0x11BE9EBC, 0xBDD18F84, - 0x68D49EE9, 0xC4BB8FD1, 0x300BBC99, 0x9C64ADA1, - 0xD86ADB09, 0x7405CA31, 0x80B5F979, 0x2CDAE841, - 0x2ABEDBA3, 0x86D1CA9B, 0x7261F9D3, 0xDE0EE8EB, - 0x9A009E43, 0x366F8F7B, 0xC2DFBC33, 0x6EB0AD0B, - 0xBBB5BC66, 0x17DAAD5E, 0xE36A9E16, 0x4F058F2E, - 0x0B0BF986, 0xA764E8BE, 0x53D4DBF6, 0xFFBBCACE, - 0x5CD5A26E, 0xF0BAB356, 0x040A801E, 0xA8659126, - 0xEC6BE78E, 0x4004F6B6, 0xB4B4C5FE, 0x18DBD4C6, - 0xCDDEC5AB, 0x61B1D493, 0x9501E7DB, 0x396EF6E3, - 0x7D60804B, 0xD10F9173, 0x25BFA23B, 0x89D0B303, - 0x8FB480E1, 0x23DB91D9, 0xD76BA291, 0x7B04B3A9, - 0x3F0AC501, 0x9365D439, 0x67D5E771, 0xCBBAF649, - 0x1EBFE724, 0xB2D0F61C, 0x4660C554, 0xEA0FD46C, - 0xAE01A2C4, 0x026EB3FC, 0xF6DE80B4, 0x5AB1918C, - 0x0B600A75, 0xA70F1B4D, 0x53BF2805, 0xFFD0393D, - 0xBBDE4F95, 0x17B15EAD, 0xE3016DE5, 0x4F6E7CDD, - 0x9A6B6DB0, 0x36047C88, 0xC2B44FC0, 0x6EDB5EF8, - 0x2AD52850, 0x86BA3968, 0x720A0A20, 0xDE651B18, - 0xD80128FA, 0x746E39C2, 0x80DE0A8A, 0x2CB11BB2, - 0x68BF6D1A, 0xC4D07C22, 0x30604F6A, 0x9C0F5E52, - 0x490A4F3F, 0xE5655E07, 0x11D56D4F, 0xBDBA7C77, - 0xF9B40ADF, 0x55DB1BE7, 0xA16B28AF, 0x0D043997, - 0xF2BFF359, 0x5ED0E261, 0xAA60D129, 0x060FC011, - 0x4201B6B9, 0xEE6EA781, 0x1ADE94C9, 0xB6B185F1, - 0x63B4949C, 0xCFDB85A4, 0x3B6BB6EC, 0x9704A7D4, - 0xD30AD17C, 0x7F65C044, 0x8BD5F30C, 0x27BAE234, - 0x21DED1D6, 0x8DB1C0EE, 0x7901F3A6, 0xD56EE29E, - 0x91609436, 0x3D0F850E, 0xC9BFB646, 0x65D0A77E, - 0xB0D5B613, 0x1CBAA72B, 0xE80A9463, 0x4465855B, - 0x006BF3F3, 0xAC04E2CB, 0x58B4D183, 0xF4DBC0BB, - 0xA50A5B42, 0x09654A7A, 0xFDD57932, 0x51BA680A, - 0x15B41EA2, 0xB9DB0F9A, 0x4D6B3CD2, 0xE1042DEA, - 0x34013C87, 0x986E2DBF, 0x6CDE1EF7, 0xC0B10FCF, - 0x84BF7967, 0x28D0685F, 0xDC605B17, 0x700F4A2F, - 0x766B79CD, 0xDA0468F5, 0x2EB45BBD, 0x82DB4A85, - 0xC6D53C2D, 0x6ABA2D15, 0x9E0A1E5D, 0x32650F65, - 0xE7601E08, 0x4B0F0F30, 0xBFBF3C78, 0x13D02D40, - 0x57DE5BE8, 0xFBB14AD0, 0x0F017998, 0xA36E68A0, - }, - { - 0x00000000, 0x196B30EF, 0xC3A08CDB, 0xDACBBC34, - 0x7737F5B2, 0x6E5CC55D, 0xB4977969, 0xADFC4986, - 0x1F180660, 0x0673368F, 0xDCB88ABB, 0xC5D3BA54, - 0x682FF3D2, 0x7144C33D, 0xAB8F7F09, 0xB2E44FE6, - 0x3E300CC0, 0x275B3C2F, 0xFD90801B, 0xE4FBB0F4, - 0x4907F972, 0x506CC99D, 0x8AA775A9, 0x93CC4546, - 0x21280AA0, 0x38433A4F, 0xE288867B, 0xFBE3B694, - 0x561FFF12, 0x4F74CFFD, 0x95BF73C9, 0x8CD44326, - 0x8D16F485, 0x947DC46A, 0x4EB6785E, 0x57DD48B1, - 0xFA210137, 0xE34A31D8, 0x39818DEC, 0x20EABD03, - 0x920EF2E5, 0x8B65C20A, 0x51AE7E3E, 0x48C54ED1, - 0xE5390757, 0xFC5237B8, 0x26998B8C, 0x3FF2BB63, - 0xB326F845, 0xAA4DC8AA, 0x7086749E, 0x69ED4471, - 0xC4110DF7, 0xDD7A3D18, 0x07B1812C, 0x1EDAB1C3, - 0xAC3EFE25, 0xB555CECA, 0x6F9E72FE, 0x76F54211, - 0xDB090B97, 0xC2623B78, 0x18A9874C, 0x01C2B7A3, - 0xEB5B040E, 0xF23034E1, 0x28FB88D5, 0x3190B83A, - 0x9C6CF1BC, 0x8507C153, 0x5FCC7D67, 0x46A74D88, - 0xF443026E, 0xED283281, 0x37E38EB5, 0x2E88BE5A, - 0x8374F7DC, 0x9A1FC733, 0x40D47B07, 0x59BF4BE8, - 0xD56B08CE, 0xCC003821, 0x16CB8415, 0x0FA0B4FA, - 0xA25CFD7C, 0xBB37CD93, 0x61FC71A7, 0x78974148, - 0xCA730EAE, 0xD3183E41, 0x09D38275, 0x10B8B29A, - 0xBD44FB1C, 0xA42FCBF3, 0x7EE477C7, 0x678F4728, - 0x664DF08B, 0x7F26C064, 0xA5ED7C50, 0xBC864CBF, - 0x117A0539, 0x081135D6, 0xD2DA89E2, 0xCBB1B90D, - 0x7955F6EB, 0x603EC604, 0xBAF57A30, 0xA39E4ADF, - 0x0E620359, 0x170933B6, 0xCDC28F82, 0xD4A9BF6D, - 0x587DFC4B, 0x4116CCA4, 0x9BDD7090, 0x82B6407F, - 0x2F4A09F9, 0x36213916, 0xECEA8522, 0xF581B5CD, - 0x4765FA2B, 0x5E0ECAC4, 0x84C576F0, 0x9DAE461F, - 0x30520F99, 0x29393F76, 0xF3F28342, 0xEA99B3AD, - 0xD6B7081C, 0xCFDC38F3, 0x151784C7, 0x0C7CB428, - 0xA180FDAE, 0xB8EBCD41, 0x62207175, 0x7B4B419A, - 0xC9AF0E7C, 0xD0C43E93, 0x0A0F82A7, 0x1364B248, - 0xBE98FBCE, 0xA7F3CB21, 0x7D387715, 0x645347FA, - 0xE88704DC, 0xF1EC3433, 0x2B278807, 0x324CB8E8, - 0x9FB0F16E, 0x86DBC181, 0x5C107DB5, 0x457B4D5A, - 0xF79F02BC, 0xEEF43253, 0x343F8E67, 0x2D54BE88, - 0x80A8F70E, 0x99C3C7E1, 0x43087BD5, 0x5A634B3A, - 0x5BA1FC99, 0x42CACC76, 0x98017042, 0x816A40AD, - 0x2C96092B, 0x35FD39C4, 0xEF3685F0, 0xF65DB51F, - 0x44B9FAF9, 0x5DD2CA16, 0x87197622, 0x9E7246CD, - 0x338E0F4B, 0x2AE53FA4, 0xF02E8390, 0xE945B37F, - 0x6591F059, 0x7CFAC0B6, 0xA6317C82, 0xBF5A4C6D, - 0x12A605EB, 0x0BCD3504, 0xD1068930, 0xC86DB9DF, - 0x7A89F639, 0x63E2C6D6, 0xB9297AE2, 0xA0424A0D, - 0x0DBE038B, 0x14D53364, 0xCE1E8F50, 0xD775BFBF, - 0x3DEC0C12, 0x24873CFD, 0xFE4C80C9, 0xE727B026, - 0x4ADBF9A0, 0x53B0C94F, 0x897B757B, 0x90104594, - 0x22F40A72, 0x3B9F3A9D, 0xE15486A9, 0xF83FB646, - 0x55C3FFC0, 0x4CA8CF2F, 0x9663731B, 0x8F0843F4, - 0x03DC00D2, 0x1AB7303D, 0xC07C8C09, 0xD917BCE6, - 0x74EBF560, 0x6D80C58F, 0xB74B79BB, 0xAE204954, - 0x1CC406B2, 0x05AF365D, 0xDF648A69, 0xC60FBA86, - 0x6BF3F300, 0x7298C3EF, 0xA8537FDB, 0xB1384F34, - 0xB0FAF897, 0xA991C878, 0x735A744C, 0x6A3144A3, - 0xC7CD0D25, 0xDEA63DCA, 0x046D81FE, 0x1D06B111, - 0xAFE2FEF7, 0xB689CE18, 0x6C42722C, 0x752942C3, - 0xD8D50B45, 0xC1BE3BAA, 0x1B75879E, 0x021EB771, - 0x8ECAF457, 0x97A1C4B8, 0x4D6A788C, 0x54014863, - 0xF9FD01E5, 0xE096310A, 0x3A5D8D3E, 0x2336BDD1, - 0x91D2F237, 0x88B9C2D8, 0x52727EEC, 0x4B194E03, - 0xE6E50785, 0xFF8E376A, 0x25458B5E, 0x3C2EBBB1, - }, - { - 0x00000000, 0xC82C0368, 0x905906D0, 0x587505B8, - 0xD1C5E0A5, 0x19E9E3CD, 0x419CE675, 0x89B0E51D, - 0x53FD2D4E, 0x9BD12E26, 0xC3A42B9E, 0x0B8828F6, - 0x8238CDEB, 0x4A14CE83, 0x1261CB3B, 0xDA4DC853, - 0xA6FA5B9C, 0x6ED658F4, 0x36A35D4C, 0xFE8F5E24, - 0x773FBB39, 0xBF13B851, 0xE766BDE9, 0x2F4ABE81, - 0xF50776D2, 0x3D2B75BA, 0x655E7002, 0xAD72736A, - 0x24C29677, 0xECEE951F, 0xB49B90A7, 0x7CB793CF, - 0xBD835B3D, 0x75AF5855, 0x2DDA5DED, 0xE5F65E85, - 0x6C46BB98, 0xA46AB8F0, 0xFC1FBD48, 0x3433BE20, - 0xEE7E7673, 0x2652751B, 0x7E2770A3, 0xB60B73CB, - 0x3FBB96D6, 0xF79795BE, 0xAFE29006, 0x67CE936E, - 0x1B7900A1, 0xD35503C9, 0x8B200671, 0x430C0519, - 0xCABCE004, 0x0290E36C, 0x5AE5E6D4, 0x92C9E5BC, - 0x48842DEF, 0x80A82E87, 0xD8DD2B3F, 0x10F12857, - 0x9941CD4A, 0x516DCE22, 0x0918CB9A, 0xC134C8F2, - 0x7A07B77A, 0xB22BB412, 0xEA5EB1AA, 0x2272B2C2, - 0xABC257DF, 0x63EE54B7, 0x3B9B510F, 0xF3B75267, - 0x29FA9A34, 0xE1D6995C, 0xB9A39CE4, 0x718F9F8C, - 0xF83F7A91, 0x301379F9, 0x68667C41, 0xA04A7F29, - 0xDCFDECE6, 0x14D1EF8E, 0x4CA4EA36, 0x8488E95E, - 0x0D380C43, 0xC5140F2B, 0x9D610A93, 0x554D09FB, - 0x8F00C1A8, 0x472CC2C0, 0x1F59C778, 0xD775C410, - 0x5EC5210D, 0x96E92265, 0xCE9C27DD, 0x06B024B5, - 0xC784EC47, 0x0FA8EF2F, 0x57DDEA97, 0x9FF1E9FF, - 0x16410CE2, 0xDE6D0F8A, 0x86180A32, 0x4E34095A, - 0x9479C109, 0x5C55C261, 0x0420C7D9, 0xCC0CC4B1, - 0x45BC21AC, 0x8D9022C4, 0xD5E5277C, 0x1DC92414, - 0x617EB7DB, 0xA952B4B3, 0xF127B10B, 0x390BB263, - 0xB0BB577E, 0x78975416, 0x20E251AE, 0xE8CE52C6, - 0x32839A95, 0xFAAF99FD, 0xA2DA9C45, 0x6AF69F2D, - 0xE3467A30, 0x2B6A7958, 0x731F7CE0, 0xBB337F88, - 0xF40E6EF5, 0x3C226D9D, 0x64576825, 0xAC7B6B4D, - 0x25CB8E50, 0xEDE78D38, 0xB5928880, 0x7DBE8BE8, - 0xA7F343BB, 0x6FDF40D3, 0x37AA456B, 0xFF864603, - 0x7636A31E, 0xBE1AA076, 0xE66FA5CE, 0x2E43A6A6, - 0x52F43569, 0x9AD83601, 0xC2AD33B9, 0x0A8130D1, - 0x8331D5CC, 0x4B1DD6A4, 0x1368D31C, 0xDB44D074, - 0x01091827, 0xC9251B4F, 0x91501EF7, 0x597C1D9F, - 0xD0CCF882, 0x18E0FBEA, 0x4095FE52, 0x88B9FD3A, - 0x498D35C8, 0x81A136A0, 0xD9D43318, 0x11F83070, - 0x9848D56D, 0x5064D605, 0x0811D3BD, 0xC03DD0D5, - 0x1A701886, 0xD25C1BEE, 0x8A291E56, 0x42051D3E, - 0xCBB5F823, 0x0399FB4B, 0x5BECFEF3, 0x93C0FD9B, - 0xEF776E54, 0x275B6D3C, 0x7F2E6884, 0xB7026BEC, - 0x3EB28EF1, 0xF69E8D99, 0xAEEB8821, 0x66C78B49, - 0xBC8A431A, 0x74A64072, 0x2CD345CA, 0xE4FF46A2, - 0x6D4FA3BF, 0xA563A0D7, 0xFD16A56F, 0x353AA607, - 0x8E09D98F, 0x4625DAE7, 0x1E50DF5F, 0xD67CDC37, - 0x5FCC392A, 0x97E03A42, 0xCF953FFA, 0x07B93C92, - 0xDDF4F4C1, 0x15D8F7A9, 0x4DADF211, 0x8581F179, - 0x0C311464, 0xC41D170C, 0x9C6812B4, 0x544411DC, - 0x28F38213, 0xE0DF817B, 0xB8AA84C3, 0x708687AB, - 0xF93662B6, 0x311A61DE, 0x696F6466, 0xA143670E, - 0x7B0EAF5D, 0xB322AC35, 0xEB57A98D, 0x237BAAE5, - 0xAACB4FF8, 0x62E74C90, 0x3A924928, 0xF2BE4A40, - 0x338A82B2, 0xFBA681DA, 0xA3D38462, 0x6BFF870A, - 0xE24F6217, 0x2A63617F, 0x721664C7, 0xBA3A67AF, - 0x6077AFFC, 0xA85BAC94, 0xF02EA92C, 0x3802AA44, - 0xB1B24F59, 0x799E4C31, 0x21EB4989, 0xE9C74AE1, - 0x9570D92E, 0x5D5CDA46, 0x0529DFFE, 0xCD05DC96, - 0x44B5398B, 0x8C993AE3, 0xD4EC3F5B, 0x1CC03C33, - 0xC68DF460, 0x0EA1F708, 0x56D4F2B0, 0x9EF8F1D8, - 0x174814C5, 0xDF6417AD, 0x87111215, 0x4F3D117D, - }, - { - 0x00000000, 0x277D3C49, 0x4EFA7892, 0x698744DB, - 0x6D821D21, 0x4AFF2168, 0x237865B3, 0x040559FA, - 0xDA043B42, 0xFD79070B, 0x94FE43D0, 0xB3837F99, - 0xB7862663, 0x90FB1A2A, 0xF97C5EF1, 0xDE0162B8, - 0xB4097684, 0x93744ACD, 0xFAF30E16, 0xDD8E325F, - 0xD98B6BA5, 0xFEF657EC, 0x97711337, 0xB00C2F7E, - 0x6E0D4DC6, 0x4970718F, 0x20F73554, 0x078A091D, - 0x038F50E7, 0x24F26CAE, 0x4D752875, 0x6A08143C, - 0x9965000D, 0xBE183C44, 0xD79F789F, 0xF0E244D6, - 0xF4E71D2C, 0xD39A2165, 0xBA1D65BE, 0x9D6059F7, - 0x43613B4F, 0x641C0706, 0x0D9B43DD, 0x2AE67F94, - 0x2EE3266E, 0x099E1A27, 0x60195EFC, 0x476462B5, - 0x2D6C7689, 0x0A114AC0, 0x63960E1B, 0x44EB3252, - 0x40EE6BA8, 0x679357E1, 0x0E14133A, 0x29692F73, - 0xF7684DCB, 0xD0157182, 0xB9923559, 0x9EEF0910, - 0x9AEA50EA, 0xBD976CA3, 0xD4102878, 0xF36D1431, - 0x32CB001A, 0x15B63C53, 0x7C317888, 0x5B4C44C1, - 0x5F491D3B, 0x78342172, 0x11B365A9, 0x36CE59E0, - 0xE8CF3B58, 0xCFB20711, 0xA63543CA, 0x81487F83, - 0x854D2679, 0xA2301A30, 0xCBB75EEB, 0xECCA62A2, - 0x86C2769E, 0xA1BF4AD7, 0xC8380E0C, 0xEF453245, - 0xEB406BBF, 0xCC3D57F6, 0xA5BA132D, 0x82C72F64, - 0x5CC64DDC, 0x7BBB7195, 0x123C354E, 0x35410907, - 0x314450FD, 0x16396CB4, 0x7FBE286F, 0x58C31426, - 0xABAE0017, 0x8CD33C5E, 0xE5547885, 0xC22944CC, - 0xC62C1D36, 0xE151217F, 0x88D665A4, 0xAFAB59ED, - 0x71AA3B55, 0x56D7071C, 0x3F5043C7, 0x182D7F8E, - 0x1C282674, 0x3B551A3D, 0x52D25EE6, 0x75AF62AF, - 0x1FA77693, 0x38DA4ADA, 0x515D0E01, 0x76203248, - 0x72256BB2, 0x555857FB, 0x3CDF1320, 0x1BA22F69, - 0xC5A34DD1, 0xE2DE7198, 0x8B593543, 0xAC24090A, - 0xA82150F0, 0x8F5C6CB9, 0xE6DB2862, 0xC1A6142B, - 0x64960134, 0x43EB3D7D, 0x2A6C79A6, 0x0D1145EF, - 0x09141C15, 0x2E69205C, 0x47EE6487, 0x609358CE, - 0xBE923A76, 0x99EF063F, 0xF06842E4, 0xD7157EAD, - 0xD3102757, 0xF46D1B1E, 0x9DEA5FC5, 0xBA97638C, - 0xD09F77B0, 0xF7E24BF9, 0x9E650F22, 0xB918336B, - 0xBD1D6A91, 0x9A6056D8, 0xF3E71203, 0xD49A2E4A, - 0x0A9B4CF2, 0x2DE670BB, 0x44613460, 0x631C0829, - 0x671951D3, 0x40646D9A, 0x29E32941, 0x0E9E1508, - 0xFDF30139, 0xDA8E3D70, 0xB30979AB, 0x947445E2, - 0x90711C18, 0xB70C2051, 0xDE8B648A, 0xF9F658C3, - 0x27F73A7B, 0x008A0632, 0x690D42E9, 0x4E707EA0, - 0x4A75275A, 0x6D081B13, 0x048F5FC8, 0x23F26381, - 0x49FA77BD, 0x6E874BF4, 0x07000F2F, 0x207D3366, - 0x24786A9C, 0x030556D5, 0x6A82120E, 0x4DFF2E47, - 0x93FE4CFF, 0xB48370B6, 0xDD04346D, 0xFA790824, - 0xFE7C51DE, 0xD9016D97, 0xB086294C, 0x97FB1505, - 0x565D012E, 0x71203D67, 0x18A779BC, 0x3FDA45F5, - 0x3BDF1C0F, 0x1CA22046, 0x7525649D, 0x525858D4, - 0x8C593A6C, 0xAB240625, 0xC2A342FE, 0xE5DE7EB7, - 0xE1DB274D, 0xC6A61B04, 0xAF215FDF, 0x885C6396, - 0xE25477AA, 0xC5294BE3, 0xACAE0F38, 0x8BD33371, - 0x8FD66A8B, 0xA8AB56C2, 0xC12C1219, 0xE6512E50, - 0x38504CE8, 0x1F2D70A1, 0x76AA347A, 0x51D70833, - 0x55D251C9, 0x72AF6D80, 0x1B28295B, 0x3C551512, - 0xCF380123, 0xE8453D6A, 0x81C279B1, 0xA6BF45F8, - 0xA2BA1C02, 0x85C7204B, 0xEC406490, 0xCB3D58D9, - 0x153C3A61, 0x32410628, 0x5BC642F3, 0x7CBB7EBA, - 0x78BE2740, 0x5FC31B09, 0x36445FD2, 0x1139639B, - 0x7B3177A7, 0x5C4C4BEE, 0x35CB0F35, 0x12B6337C, - 0x16B36A86, 0x31CE56CF, 0x58491214, 0x7F342E5D, - 0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E, - 0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F - } -#endif /* WORDS_BIGENDIAN */ -}; diff --git a/contrib/libs/libpq/src/port/pg_crc32c_sse42.c b/contrib/libs/libpq/src/port/pg_crc32c_sse42.c deleted file mode 100644 index 0bac452717..0000000000 --- a/contrib/libs/libpq/src/port/pg_crc32c_sse42.c +++ /dev/null @@ -1,69 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_crc32c_sse42.c - * Compute CRC-32C checksum using Intel SSE 4.2 instructions. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/pg_crc32c_sse42.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include <nmmintrin.h> - -#include "port/pg_crc32c.h" - -pg_attribute_no_sanitize_alignment() -pg_crc32c -pg_comp_crc32c_sse42(pg_crc32c crc, const void *data, size_t len) -{ - const unsigned char *p = data; - const unsigned char *pend = p + len; - - /* - * Process eight bytes of data at a time. - * - * NB: We do unaligned accesses here. The Intel architecture allows that, - * and performance testing didn't show any performance gain from aligning - * the begin address. - */ -#ifdef __x86_64__ - while (p + 8 <= pend) - { - crc = (uint32) _mm_crc32_u64(crc, *((const uint64 *) p)); - p += 8; - } - - /* Process remaining full four bytes if any */ - if (p + 4 <= pend) - { - crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); - p += 4; - } -#else - - /* - * Process four bytes at a time. (The eight byte instruction is not - * available on the 32-bit x86 architecture). - */ - while (p + 4 <= pend) - { - crc = _mm_crc32_u32(crc, *((const unsigned int *) p)); - p += 4; - } -#endif /* __x86_64__ */ - - /* Process any remaining bytes one at a time. */ - while (p < pend) - { - crc = _mm_crc32_u8(crc, *p); - p++; - } - - return crc; -} diff --git a/contrib/libs/libpq/src/port/pg_crc32c_sse42_choose.c b/contrib/libs/libpq/src/port/pg_crc32c_sse42_choose.c deleted file mode 100644 index 41ff4a35ad..0000000000 --- a/contrib/libs/libpq/src/port/pg_crc32c_sse42_choose.c +++ /dev/null @@ -1,64 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_crc32c_sse42_choose.c - * Choose between Intel SSE 4.2 and software CRC-32C implementation. - * - * On first call, checks if the CPU we're running on supports Intel SSE - * 4.2. If it does, use the special SSE instructions for CRC-32C - * computation. Otherwise, fall back to the pure software implementation - * (slicing-by-8). - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/pg_crc32c_sse42_choose.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#ifdef HAVE__GET_CPUID -#include <cpuid.h> -#endif - -#ifdef HAVE__CPUID -#include <intrin.h> -#endif - -#include "port/pg_crc32c.h" - -static bool -pg_crc32c_sse42_available(void) -{ - unsigned int exx[4] = {0, 0, 0, 0}; - -#if defined(HAVE__GET_CPUID) - __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]); -#elif defined(HAVE__CPUID) - __cpuid(exx, 1); -#else -#error cpuid instruction not available -#endif - - return (exx[2] & (1 << 20)) != 0; /* SSE 4.2 */ -} - -/* - * This gets called on the first call. It replaces the function pointer - * so that subsequent calls are routed directly to the chosen implementation. - */ -static pg_crc32c -pg_comp_crc32c_choose(pg_crc32c crc, const void *data, size_t len) -{ - if (pg_crc32c_sse42_available()) - pg_comp_crc32c = pg_comp_crc32c_sse42; - else - pg_comp_crc32c = pg_comp_crc32c_sb8; - - return pg_comp_crc32c(crc, data, len); -} - -pg_crc32c (*pg_comp_crc32c) (pg_crc32c crc, const void *data, size_t len) = pg_comp_crc32c_choose; diff --git a/contrib/libs/libpq/src/port/pg_strong_random.c b/contrib/libs/libpq/src/port/pg_strong_random.c deleted file mode 100644 index 862c84aa6f..0000000000 --- a/contrib/libs/libpq/src/port/pg_strong_random.c +++ /dev/null @@ -1,182 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_strong_random.c - * generate a cryptographically secure random number - * - * Our definition of "strong" is that it's suitable for generating random - * salts and query cancellation keys, during authentication. - * - * Note: this code is run quite early in postmaster and backend startup; - * therefore, even when built for backend, it cannot rely on backend - * infrastructure such as elog() or palloc(). - * - * Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/port/pg_strong_random.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <fcntl.h> -#include <unistd.h> -#include <sys/time.h> - -/* - * pg_strong_random & pg_strong_random_init - * - * Generate requested number of random bytes. The returned bytes are - * cryptographically secure, suitable for use e.g. in authentication. - * - * Before pg_strong_random is called in any process, the generator must first - * be initialized by calling pg_strong_random_init(). - * - * We rely on system facilities for actually generating the numbers. - * We support a number of sources: - * - * 1. OpenSSL's RAND_bytes() - * 2. Windows' CryptGenRandom() function - * 3. /dev/urandom - * - * Returns true on success, and false if none of the sources - * were available. NB: It is important to check the return value! - * Proceeding with key generation when no random data was available - * would lead to predictable keys and security issues. - */ - - - -#ifdef USE_OPENSSL - -#include <openssl/rand.h> - -void -pg_strong_random_init(void) -{ - /* - * Make sure processes do not share OpenSSL randomness state. This is no - * longer required in OpenSSL 1.1.1 and later versions, but until we drop - * support for version < 1.1.1 we need to do this. - */ - RAND_poll(); -} - -bool -pg_strong_random(void *buf, size_t len) -{ - int i; - - /* - * Check that OpenSSL's CSPRNG has been sufficiently seeded, and if not - * add more seed data using RAND_poll(). With some older versions of - * OpenSSL, it may be necessary to call RAND_poll() a number of times. If - * RAND_poll() fails to generate seed data within the given amount of - * retries, subsequent RAND_bytes() calls will fail, but we allow that to - * happen to let pg_strong_random() callers handle that with appropriate - * error handling. - */ -#define NUM_RAND_POLL_RETRIES 8 - - for (i = 0; i < NUM_RAND_POLL_RETRIES; i++) - { - if (RAND_status() == 1) - { - /* The CSPRNG is sufficiently seeded */ - break; - } - - RAND_poll(); - } - - if (RAND_bytes(buf, len) == 1) - return true; - return false; -} - -#elif WIN32 - -#include <wincrypt.h> -/* - * Cache a global crypto provider that only gets freed when the process - * exits, in case we need random numbers more than once. - */ -static HCRYPTPROV hProvider = 0; - -void -pg_strong_random_init(void) -{ - /* No initialization needed on WIN32 */ -} - -bool -pg_strong_random(void *buf, size_t len) -{ - if (hProvider == 0) - { - if (!CryptAcquireContext(&hProvider, - NULL, - MS_DEF_PROV, - PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { - /* - * On failure, set back to 0 in case the value was for some reason - * modified. - */ - hProvider = 0; - } - } - /* Re-check in case we just retrieved the provider */ - if (hProvider != 0) - { - if (CryptGenRandom(hProvider, len, buf)) - return true; - } - return false; -} - -#else /* not USE_OPENSSL or WIN32 */ - -/* - * Without OpenSSL or Win32 support, just read /dev/urandom ourselves. - */ - -void -pg_strong_random_init(void) -{ - /* No initialization needed */ -} - -bool -pg_strong_random(void *buf, size_t len) -{ - int f; - char *p = buf; - ssize_t res; - - f = open("/dev/urandom", O_RDONLY, 0); - if (f == -1) - return false; - - while (len) - { - res = read(f, p, len); - if (res <= 0) - { - if (errno == EINTR) - continue; /* interrupted by signal, just retry */ - - close(f); - return false; - } - - p += res; - len -= res; - } - - close(f); - return true; -} -#endif diff --git a/contrib/libs/libpq/src/port/pgcheckdir.c b/contrib/libs/libpq/src/port/pgcheckdir.c deleted file mode 100644 index 94aa40ca8f..0000000000 --- a/contrib/libs/libpq/src/port/pgcheckdir.c +++ /dev/null @@ -1,92 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgcheckdir.c - * - * A simple subroutine to check whether a directory exists and is empty or not. - * Useful in both initdb and the backend. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/port/pgcheckdir.c - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <dirent.h> - - -/* - * Test to see if a directory exists and is empty or not. - * - * Returns: - * 0 if nonexistent - * 1 if exists and empty - * 2 if exists and contains _only_ dot files - * 3 if exists and contains a mount point - * 4 if exists and not empty - * -1 if trouble accessing directory (errno reflects the error) - */ -int -pg_check_dir(const char *dir) -{ - int result = 1; - DIR *chkdir; - struct dirent *file; - bool dot_found = false; - bool mount_found = false; - int readdir_errno; - - chkdir = opendir(dir); - if (chkdir == NULL) - return (errno == ENOENT) ? 0 : -1; - - while (errno = 0, (file = readdir(chkdir)) != NULL) - { - if (strcmp(".", file->d_name) == 0 || - strcmp("..", file->d_name) == 0) - { - /* skip this and parent directory */ - continue; - } -#ifndef WIN32 - /* file starts with "." */ - else if (file->d_name[0] == '.') - { - dot_found = true; - } - /* lost+found directory */ - else if (strcmp("lost+found", file->d_name) == 0) - { - mount_found = true; - } -#endif - else - { - result = 4; /* not empty */ - break; - } - } - - if (errno) - result = -1; /* some kind of I/O error? */ - - /* Close chkdir and avoid overwriting the readdir errno on success */ - readdir_errno = errno; - if (closedir(chkdir)) - result = -1; /* error executing closedir */ - else - errno = readdir_errno; - - /* We report on mount point if we find a lost+found directory */ - if (result == 1 && mount_found) - result = 3; - - /* We report on dot-files if we _only_ find dot files */ - if (result == 1 && dot_found) - result = 2; - - return result; -} diff --git a/contrib/libs/libpq/src/port/pgmkdirp.c b/contrib/libs/libpq/src/port/pgmkdirp.c deleted file mode 100644 index d943559760..0000000000 --- a/contrib/libs/libpq/src/port/pgmkdirp.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This is adapted from FreeBSD's src/bin/mkdir/mkdir.c, which bears - * the following copyright notice: - * - * Copyright (c) 1983, 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "c.h" - -#include <sys/stat.h> - - -/* - * pg_mkdir_p --- create a directory and, if necessary, parent directories - * - * This is equivalent to "mkdir -p" except we don't complain if the target - * directory already exists. - * - * We assume the path is in canonical form, i.e., uses / as the separator. - * - * omode is the file permissions bits for the target directory. Note that any - * parent directories that have to be created get permissions according to the - * prevailing umask, but with u+wx forced on to ensure we can create there. - * (We declare omode as int, not mode_t, to minimize dependencies for port.h.) - * - * Returns 0 on success, -1 (with errno set) on failure. - * - * Note that on failure, the path arg has been modified to show the particular - * directory level we had problems with. - */ -int -pg_mkdir_p(char *path, int omode) -{ - struct stat sb; - mode_t numask, - oumask; - int last, - retval; - char *p; - - retval = 0; - p = path; - -#ifdef WIN32 - /* skip network and drive specifiers for win32 */ - if (strlen(p) >= 2) - { - if (p[0] == '/' && p[1] == '/') - { - /* network drive */ - p = strstr(p + 2, "/"); - if (p == NULL) - { - errno = EINVAL; - return -1; - } - } - else if (p[1] == ':' && - ((p[0] >= 'a' && p[0] <= 'z') || - (p[0] >= 'A' && p[0] <= 'Z'))) - { - /* local drive */ - p += 2; - } - } -#endif - - /* - * POSIX 1003.2: For each dir operand that does not name an existing - * directory, effects equivalent to those caused by the following command - * shall occur: - * - * mkdir -p -m $(umask -S),u+wx $(dirname dir) && mkdir [-m mode] dir - * - * We change the user's umask and then restore it, instead of doing - * chmod's. Note we assume umask() can't change errno. - */ - oumask = umask(0); - numask = oumask & ~(S_IWUSR | S_IXUSR); - (void) umask(numask); - - if (p[0] == '/') /* Skip leading '/'. */ - ++p; - for (last = 0; !last; ++p) - { - if (p[0] == '\0') - last = 1; - else if (p[0] != '/') - continue; - *p = '\0'; - if (!last && p[1] == '\0') - last = 1; - - if (last) - (void) umask(oumask); - - /* check for pre-existing directory */ - if (stat(path, &sb) == 0) - { - if (!S_ISDIR(sb.st_mode)) - { - if (last) - errno = EEXIST; - else - errno = ENOTDIR; - retval = -1; - break; - } - } - else if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0) - { - retval = -1; - break; - } - if (!last) - *p = '/'; - } - - /* ensure we restored umask */ - (void) umask(oumask); - - return retval; -} diff --git a/contrib/libs/libpq/src/port/pgsleep.c b/contrib/libs/libpq/src/port/pgsleep.c deleted file mode 100644 index a1bcd78e4b..0000000000 --- a/contrib/libs/libpq/src/port/pgsleep.c +++ /dev/null @@ -1,57 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgsleep.c - * Portable delay handling. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * src/port/pgsleep.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include <time.h> - -/* - * In a Windows backend, we don't use this implementation, but rather - * the signal-aware version in src/backend/port/win32/signal.c. - */ -#if defined(FRONTEND) || !defined(WIN32) - -/* - * pg_usleep --- delay the specified number of microseconds. - * - * NOTE: Although the delay is specified in microseconds, older Unixen and - * Windows use periodic kernel ticks to wake up, which might increase the delay - * time significantly. We've observed delay increases as large as 20 - * milliseconds on supported platforms. - * - * On machines where "long" is 32 bits, the maximum delay is ~2000 seconds. - * - * CAUTION: It's not a good idea to use long sleeps in the backend. They will - * silently return early if a signal is caught, but that doesn't include - * latches being set on most OSes, and even signal handlers that set MyLatch - * might happen to run before the sleep begins, allowing the full delay. - * Better practice is to use WaitLatch() with a timeout, so that backends - * respond to latches and signals promptly. - */ -void -pg_usleep(long microsec) -{ - if (microsec > 0) - { -#ifndef WIN32 - struct timespec delay; - - delay.tv_sec = microsec / 1000000L; - delay.tv_nsec = (microsec % 1000000L) * 1000; - (void) nanosleep(&delay, NULL); -#else - SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE); -#endif - } -} - -#endif /* defined(FRONTEND) || !defined(WIN32) */ diff --git a/contrib/libs/libpq/src/port/pgstrcasecmp.c b/contrib/libs/libpq/src/port/pgstrcasecmp.c deleted file mode 100644 index 27c1546f6f..0000000000 --- a/contrib/libs/libpq/src/port/pgstrcasecmp.c +++ /dev/null @@ -1,151 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgstrcasecmp.c - * Portable SQL-like case-independent comparisons and conversions. - * - * SQL99 specifies Unicode-aware case normalization, which we don't yet - * have the infrastructure for. Instead we use tolower() to provide a - * locale-aware translation. However, there are some locales where this - * is not right either (eg, Turkish may do strange things with 'i' and - * 'I'). Our current compromise is to use tolower() for characters with - * the high bit set, and use an ASCII-only downcasing for 7-bit - * characters. - * - * NB: this code should match downcase_truncate_identifier() in scansup.c. - * - * We also provide strict ASCII-only case conversion functions, which can - * be used to implement C/POSIX case folding semantics no matter what the - * C library thinks the locale is. - * - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * src/port/pgstrcasecmp.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -#include <ctype.h> - - -/* - * Case-independent comparison of two null-terminated strings. - */ -int -pg_strcasecmp(const char *s1, const char *s2) -{ - for (;;) - { - unsigned char ch1 = (unsigned char) *s1++; - unsigned char ch2 = (unsigned char) *s2++; - - if (ch1 != ch2) - { - if (ch1 >= 'A' && ch1 <= 'Z') - ch1 += 'a' - 'A'; - else if (IS_HIGHBIT_SET(ch1) && isupper(ch1)) - ch1 = tolower(ch1); - - if (ch2 >= 'A' && ch2 <= 'Z') - ch2 += 'a' - 'A'; - else if (IS_HIGHBIT_SET(ch2) && isupper(ch2)) - ch2 = tolower(ch2); - - if (ch1 != ch2) - return (int) ch1 - (int) ch2; - } - if (ch1 == 0) - break; - } - return 0; -} - -/* - * Case-independent comparison of two not-necessarily-null-terminated strings. - * At most n bytes will be examined from each string. - */ -int -pg_strncasecmp(const char *s1, const char *s2, size_t n) -{ - while (n-- > 0) - { - unsigned char ch1 = (unsigned char) *s1++; - unsigned char ch2 = (unsigned char) *s2++; - - if (ch1 != ch2) - { - if (ch1 >= 'A' && ch1 <= 'Z') - ch1 += 'a' - 'A'; - else if (IS_HIGHBIT_SET(ch1) && isupper(ch1)) - ch1 = tolower(ch1); - - if (ch2 >= 'A' && ch2 <= 'Z') - ch2 += 'a' - 'A'; - else if (IS_HIGHBIT_SET(ch2) && isupper(ch2)) - ch2 = tolower(ch2); - - if (ch1 != ch2) - return (int) ch1 - (int) ch2; - } - if (ch1 == 0) - break; - } - return 0; -} - -/* - * Fold a character to upper case. - * - * Unlike some versions of toupper(), this is safe to apply to characters - * that aren't lower case letters. Note however that the whole thing is - * a bit bogus for multibyte character sets. - */ -unsigned char -pg_toupper(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'z') - ch += 'A' - 'a'; - else if (IS_HIGHBIT_SET(ch) && islower(ch)) - ch = toupper(ch); - return ch; -} - -/* - * Fold a character to lower case. - * - * Unlike some versions of tolower(), this is safe to apply to characters - * that aren't upper case letters. Note however that the whole thing is - * a bit bogus for multibyte character sets. - */ -unsigned char -pg_tolower(unsigned char ch) -{ - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - else if (IS_HIGHBIT_SET(ch) && isupper(ch)) - ch = tolower(ch); - return ch; -} - -/* - * Fold a character to upper case, following C/POSIX locale rules. - */ -unsigned char -pg_ascii_toupper(unsigned char ch) -{ - if (ch >= 'a' && ch <= 'z') - ch += 'A' - 'a'; - return ch; -} - -/* - * Fold a character to lower case, following C/POSIX locale rules. - */ -unsigned char -pg_ascii_tolower(unsigned char ch) -{ - if (ch >= 'A' && ch <= 'Z') - ch += 'a' - 'A'; - return ch; -} diff --git a/contrib/libs/libpq/src/port/pgstrsignal.c b/contrib/libs/libpq/src/port/pgstrsignal.c deleted file mode 100644 index 7d76d1cca9..0000000000 --- a/contrib/libs/libpq/src/port/pgstrsignal.c +++ /dev/null @@ -1,64 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pgstrsignal.c - * Identify a Unix signal number - * - * On platforms compliant with modern POSIX, this just wraps strsignal(3). - * Elsewhere, we do the best we can. - * - * This file is not currently built in MSVC builds, since it's useless - * on non-Unix platforms. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * IDENTIFICATION - * src/port/pgstrsignal.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - - -/* - * pg_strsignal - * - * Return a string identifying the given Unix signal number. - * - * The result is declared "const char *" because callers should not - * modify the string. Note, however, that POSIX does not promise that - * the string will remain valid across later calls to strsignal(). - * - * This version guarantees to return a non-NULL pointer, although - * some platforms' versions of strsignal() reputedly do not. - * - * Note that the fallback cases just return constant strings such as - * "unrecognized signal". Project style is for callers to print the - * numeric signal value along with the result of this function, so - * there's no need to work harder than that. - */ -const char * -pg_strsignal(int signum) -{ - const char *result; - - /* - * If we have strsignal(3), use that --- but check its result for NULL. - */ -#ifdef HAVE_STRSIGNAL - result = strsignal(signum); - if (result == NULL) - result = "unrecognized signal"; -#else - - /* - * We used to have code here to try to use sys_siglist[] if available. - * However, it seems that all platforms with sys_siglist[] have also had - * strsignal() for many years now, so that was just a waste of code. - */ - result = "(signal names not available on this platform)"; -#endif - - return result; -} diff --git a/contrib/libs/libpq/src/port/pqsignal.c b/contrib/libs/libpq/src/port/pqsignal.c deleted file mode 100644 index de9ed2c566..0000000000 --- a/contrib/libs/libpq/src/port/pqsignal.c +++ /dev/null @@ -1,62 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pqsignal.c - * reliable BSD-style signal(2) routine stolen from RWW who stole it - * from Stevens... - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/pqsignal.c - * - * We now assume that all Unix-oid systems have POSIX sigaction(2) - * with support for restartable signals (SA_RESTART). We used to also - * support BSD-style signal(2), but there really shouldn't be anything - * out there anymore that doesn't have the POSIX API. - * - * Windows, of course, is resolutely in a class by itself. In the backend, - * we don't use this file at all; src/backend/port/win32/signal.c provides - * pqsignal() for the backend environment. Frontend programs can use - * this version of pqsignal() if they wish, but beware that this does - * not provide restartable signals on Windows. - * - * ------------------------------------------------------------------------ - */ - -#include "c.h" - -#include <signal.h> - -#ifndef FRONTEND -#error #include "libpq/pqsignal.h" -#endif - -/* - * Set up a signal handler, with SA_RESTART, for signal "signo" - * - * Returns the previous handler. - */ -pqsigfunc -pqsignal(int signo, pqsigfunc func) -{ -#if !(defined(WIN32) && defined(FRONTEND)) - struct sigaction act, - oact; - - act.sa_handler = func; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_RESTART; -#ifdef SA_NOCLDSTOP - if (signo == SIGCHLD) - act.sa_flags |= SA_NOCLDSTOP; -#endif - if (sigaction(signo, &act, &oact) < 0) - return SIG_ERR; - return oact.sa_handler; -#else - /* Forward to Windows native signal system. */ - return signal(signo, func); -#endif -} diff --git a/contrib/libs/libpq/src/port/pthread-win32.h b/contrib/libs/libpq/src/port/pthread-win32.h deleted file mode 100644 index 97ccc17a12..0000000000 --- a/contrib/libs/libpq/src/port/pthread-win32.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * src/port/pthread-win32.h - */ -#ifndef __PTHREAD_H -#define __PTHREAD_H - -typedef ULONG pthread_key_t; -typedef CRITICAL_SECTION *pthread_mutex_t; -typedef int pthread_once_t; - -DWORD pthread_self(void); - -void pthread_setspecific(pthread_key_t, void *); -void *pthread_getspecific(pthread_key_t); - -int pthread_mutex_init(pthread_mutex_t *, void *attr); -int pthread_mutex_lock(pthread_mutex_t *); - -/* blocking */ -int pthread_mutex_unlock(pthread_mutex_t *); - -#endif diff --git a/contrib/libs/libpq/src/port/qsort.c b/contrib/libs/libpq/src/port/qsort.c deleted file mode 100644 index 7879e6cd56..0000000000 --- a/contrib/libs/libpq/src/port/qsort.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * qsort.c: standard quicksort algorithm - */ - -#include "c.h" - -#define ST_SORT pg_qsort -#define ST_ELEMENT_TYPE_VOID -#define ST_COMPARE_RUNTIME_POINTER -#define ST_SCOPE -#define ST_DECLARE -#define ST_DEFINE -#include "lib/sort_template.h" - -/* - * qsort comparator wrapper for strcmp. - */ -int -pg_qsort_strcmp(const void *a, const void *b) -{ - return strcmp(*(const char *const *) a, *(const char *const *) b); -} diff --git a/contrib/libs/libpq/src/port/qsort_arg.c b/contrib/libs/libpq/src/port/qsort_arg.c deleted file mode 100644 index fa7e11a3b8..0000000000 --- a/contrib/libs/libpq/src/port/qsort_arg.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * qsort_arg.c: qsort with a passthrough "void *" argument - */ - -#include "c.h" - -#define ST_SORT qsort_arg -#define ST_ELEMENT_TYPE_VOID -#define ST_COMPARATOR_TYPE_NAME qsort_arg_comparator -#define ST_COMPARE_RUNTIME_POINTER -#define ST_COMPARE_ARG_TYPE void -#define ST_SCOPE -#define ST_DEFINE -#include "lib/sort_template.h" diff --git a/contrib/libs/libpq/src/port/quotes.c b/contrib/libs/libpq/src/port/quotes.c deleted file mode 100644 index a80e88d69b..0000000000 --- a/contrib/libs/libpq/src/port/quotes.c +++ /dev/null @@ -1,51 +0,0 @@ -/*------------------------------------------------------------------------- - * - * quotes.c - * string quoting and escaping functions - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/quotes.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -/* - * Escape (by doubling) any single quotes or backslashes in given string - * - * Note: this is used to process postgresql.conf entries and to quote - * string literals in pg_basebackup for writing the recovery configuration. - * Since postgresql.conf strings are defined to treat backslashes as escapes, - * we have to double backslashes here. - * - * Since this function is only used for parsing or creating configuration - * files, we do not care about encoding considerations. - * - * Returns a malloced() string that it's the responsibility of the caller - * to free. - */ -char * -escape_single_quotes_ascii(const char *src) -{ - int len = strlen(src), - i, - j; - char *result = malloc(len * 2 + 1); - - if (!result) - return NULL; - - for (i = 0, j = 0; i < len; i++) - { - if (SQL_STR_DOUBLE(src[i], true)) - result[j++] = src[i]; - result[j++] = src[i]; - } - result[j] = '\0'; - return result; -} diff --git a/contrib/libs/libpq/src/port/snprintf.c b/contrib/libs/libpq/src/port/snprintf.c deleted file mode 100644 index e3e316e049..0000000000 --- a/contrib/libs/libpq/src/port/snprintf.c +++ /dev/null @@ -1,1535 +0,0 @@ -/* - * Copyright (c) 1983, 1995, 1996 Eric P. Allman - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * src/port/snprintf.c - */ - -#include "c.h" - -#include <math.h> - -/* - * We used to use the platform's NL_ARGMAX here, but that's a bad idea, - * first because the point of this module is to remove platform dependencies - * not perpetuate them, and second because some platforms use ridiculously - * large values, leading to excessive stack consumption in dopr(). - */ -#define PG_NL_ARGMAX 31 - - -/* - * SNPRINTF, VSNPRINTF and friends - * - * These versions have been grabbed off the net. They have been - * cleaned up to compile properly and support for most of the C99 - * specification has been added. Remaining unimplemented features are: - * - * 1. No locale support: the radix character is always '.' and the ' - * (single quote) format flag is ignored. - * - * 2. No support for the "%n" format specification. - * - * 3. No support for wide characters ("lc" and "ls" formats). - * - * 4. No support for "long double" ("Lf" and related formats). - * - * 5. Space and '#' flags are not implemented. - * - * In addition, we support some extensions over C99: - * - * 1. Argument order control through "%n$" and "*n$", as required by POSIX. - * - * 2. "%m" expands to the value of strerror(errno), where errno is the - * value that variable had at the start of the call. This is a glibc - * extension, but a very useful one. - * - * - * Historically the result values of sprintf/snprintf varied across platforms. - * This implementation now follows the C99 standard: - * - * 1. -1 is returned if an error is detected in the format string, or if - * a write to the target stream fails (as reported by fwrite). Note that - * overrunning snprintf's target buffer is *not* an error. - * - * 2. For successful writes to streams, the actual number of bytes written - * to the stream is returned. - * - * 3. For successful sprintf/snprintf, the number of bytes that would have - * been written to an infinite-size buffer (excluding the trailing '\0') - * is returned. snprintf will truncate its output to fit in the buffer - * (ensuring a trailing '\0' unless count == 0), but this is not reflected - * in the function result. - * - * snprintf buffer overrun can be detected by checking for function result - * greater than or equal to the supplied count. - */ - -/************************************************************** - * Original: - * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 - * A bombproof version of doprnt (dopr) included. - * Sigh. This sort of thing is always nasty do deal with. Note that - * the version here does not include floating point. (now it does ... tgl) - **************************************************************/ - -/* Prevent recursion */ -#undef vsnprintf -#undef snprintf -#undef vsprintf -#undef sprintf -#undef vfprintf -#undef fprintf -#undef vprintf -#undef printf - -/* - * Info about where the formatted output is going. - * - * dopr and subroutines will not write at/past bufend, but snprintf - * reserves one byte, ensuring it may place the trailing '\0' there. - * - * In snprintf, we use nchars to count the number of bytes dropped on the - * floor due to buffer overrun. The correct result of snprintf is thus - * (bufptr - bufstart) + nchars. (This isn't as inconsistent as it might - * seem: nchars is the number of emitted bytes that are not in the buffer now, - * either because we sent them to the stream or because we couldn't fit them - * into the buffer to begin with.) - */ -typedef struct -{ - char *bufptr; /* next buffer output position */ - char *bufstart; /* first buffer element */ - char *bufend; /* last+1 buffer element, or NULL */ - /* bufend == NULL is for sprintf, where we assume buf is big enough */ - FILE *stream; /* eventual output destination, or NULL */ - int nchars; /* # chars sent to stream, or dropped */ - bool failed; /* call is a failure; errno is set */ -} PrintfTarget; - -/* - * Info about the type and value of a formatting parameter. Note that we - * don't currently support "long double", "wint_t", or "wchar_t *" data, - * nor the '%n' formatting code; else we'd need more types. Also, at this - * level we need not worry about signed vs unsigned values. - */ -typedef enum -{ - ATYPE_NONE = 0, - ATYPE_INT, - ATYPE_LONG, - ATYPE_LONGLONG, - ATYPE_DOUBLE, - ATYPE_CHARPTR -} PrintfArgType; - -typedef union -{ - int i; - long l; - long long ll; - double d; - char *cptr; -} PrintfArgValue; - - -static void flushbuffer(PrintfTarget *target); -static void dopr(PrintfTarget *target, const char *format, va_list args); - - -/* - * Externally visible entry points. - * - * All of these are just wrappers around dopr(). Note it's essential that - * they not change the value of "errno" before reaching dopr(). - */ - -int -pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args) -{ - PrintfTarget target; - char onebyte[1]; - - /* - * C99 allows the case str == NULL when count == 0. Rather than - * special-casing this situation further down, we substitute a one-byte - * local buffer. Callers cannot tell, since the function result doesn't - * depend on count. - */ - if (count == 0) - { - str = onebyte; - count = 1; - } - target.bufstart = target.bufptr = str; - target.bufend = str + count - 1; - target.stream = NULL; - target.nchars = 0; - target.failed = false; - dopr(&target, fmt, args); - *(target.bufptr) = '\0'; - return target.failed ? -1 : (target.bufptr - target.bufstart - + target.nchars); -} - -int -pg_snprintf(char *str, size_t count, const char *fmt,...) -{ - int len; - va_list args; - - va_start(args, fmt); - len = pg_vsnprintf(str, count, fmt, args); - va_end(args); - return len; -} - -int -pg_vsprintf(char *str, const char *fmt, va_list args) -{ - PrintfTarget target; - - target.bufstart = target.bufptr = str; - target.bufend = NULL; - target.stream = NULL; - target.nchars = 0; /* not really used in this case */ - target.failed = false; - dopr(&target, fmt, args); - *(target.bufptr) = '\0'; - return target.failed ? -1 : (target.bufptr - target.bufstart - + target.nchars); -} - -int -pg_sprintf(char *str, const char *fmt,...) -{ - int len; - va_list args; - - va_start(args, fmt); - len = pg_vsprintf(str, fmt, args); - va_end(args); - return len; -} - -int -pg_vfprintf(FILE *stream, const char *fmt, va_list args) -{ - PrintfTarget target; - char buffer[1024]; /* size is arbitrary */ - - if (stream == NULL) - { - errno = EINVAL; - return -1; - } - target.bufstart = target.bufptr = buffer; - target.bufend = buffer + sizeof(buffer); /* use the whole buffer */ - target.stream = stream; - target.nchars = 0; - target.failed = false; - dopr(&target, fmt, args); - /* dump any remaining buffer contents */ - flushbuffer(&target); - return target.failed ? -1 : target.nchars; -} - -int -pg_fprintf(FILE *stream, const char *fmt,...) -{ - int len; - va_list args; - - va_start(args, fmt); - len = pg_vfprintf(stream, fmt, args); - va_end(args); - return len; -} - -int -pg_vprintf(const char *fmt, va_list args) -{ - return pg_vfprintf(stdout, fmt, args); -} - -int -pg_printf(const char *fmt,...) -{ - int len; - va_list args; - - va_start(args, fmt); - len = pg_vfprintf(stdout, fmt, args); - va_end(args); - return len; -} - -/* - * Attempt to write the entire buffer to target->stream; discard the entire - * buffer in any case. Call this only when target->stream is defined. - */ -static void -flushbuffer(PrintfTarget *target) -{ - size_t nc = target->bufptr - target->bufstart; - - /* - * Don't write anything if we already failed; this is to ensure we - * preserve the original failure's errno. - */ - if (!target->failed && nc > 0) - { - size_t written; - - written = fwrite(target->bufstart, 1, nc, target->stream); - target->nchars += written; - if (written != nc) - target->failed = true; - } - target->bufptr = target->bufstart; -} - - -static bool find_arguments(const char *format, va_list args, - PrintfArgValue *argvalues); -static void fmtstr(const char *value, int leftjust, int minlen, int maxwidth, - int pointflag, PrintfTarget *target); -static void fmtptr(const void *value, PrintfTarget *target); -static void fmtint(long long value, char type, int forcesign, - int leftjust, int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target); -static void fmtchar(int value, int leftjust, int minlen, PrintfTarget *target); -static void fmtfloat(double value, char type, int forcesign, - int leftjust, int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target); -static void dostr(const char *str, int slen, PrintfTarget *target); -static void dopr_outch(int c, PrintfTarget *target); -static void dopr_outchmulti(int c, int slen, PrintfTarget *target); -static int adjust_sign(int is_negative, int forcesign, int *signvalue); -static int compute_padlen(int minlen, int vallen, int leftjust); -static void leading_pad(int zpad, int signvalue, int *padlen, - PrintfTarget *target); -static void trailing_pad(int padlen, PrintfTarget *target); - -/* - * If strchrnul exists (it's a glibc-ism), it's a good bit faster than the - * equivalent manual loop. If it doesn't exist, provide a replacement. - * - * Note: glibc declares this as returning "char *", but that would require - * casting away const internally, so we don't follow that detail. - */ -#ifndef HAVE_STRCHRNUL - -static inline const char * -strchrnul(const char *s, int c) -{ - while (*s != '\0' && *s != c) - s++; - return s; -} - -#else - -/* - * glibc's <string.h> declares strchrnul only if _GNU_SOURCE is defined. - * While we typically use that on glibc platforms, configure will set - * HAVE_STRCHRNUL whether it's used or not. Fill in the missing declaration - * so that this file will compile cleanly with or without _GNU_SOURCE. - */ -#ifndef _GNU_SOURCE -extern char *strchrnul(const char *s, int c); -#endif - -#endif /* HAVE_STRCHRNUL */ - - -/* - * dopr(): the guts of *printf for all cases. - */ -static void -dopr(PrintfTarget *target, const char *format, va_list args) -{ - int save_errno = errno; - const char *first_pct = NULL; - int ch; - bool have_dollar; - bool have_star; - bool afterstar; - int accum; - int longlongflag; - int longflag; - int pointflag; - int leftjust; - int fieldwidth; - int precision; - int zpad; - int forcesign; - int fmtpos; - int cvalue; - long long numvalue; - double fvalue; - const char *strvalue; - PrintfArgValue argvalues[PG_NL_ARGMAX + 1]; - - /* - * Initially, we suppose the format string does not use %n$. The first - * time we come to a conversion spec that has that, we'll call - * find_arguments() to check for consistent use of %n$ and fill the - * argvalues array with the argument values in the correct order. - */ - have_dollar = false; - - while (*format != '\0') - { - /* Locate next conversion specifier */ - if (*format != '%') - { - /* Scan to next '%' or end of string */ - const char *next_pct = strchrnul(format + 1, '%'); - - /* Dump literal data we just scanned over */ - dostr(format, next_pct - format, target); - if (target->failed) - break; - - if (*next_pct == '\0') - break; - format = next_pct; - } - - /* - * Remember start of first conversion spec; if we find %n$, then it's - * sufficient for find_arguments() to start here, without rescanning - * earlier literal text. - */ - if (first_pct == NULL) - first_pct = format; - - /* Process conversion spec starting at *format */ - format++; - - /* Fast path for conversion spec that is exactly %s */ - if (*format == 's') - { - format++; - strvalue = va_arg(args, char *); - if (strvalue == NULL) - strvalue = "(null)"; - dostr(strvalue, strlen(strvalue), target); - if (target->failed) - break; - continue; - } - - fieldwidth = precision = zpad = leftjust = forcesign = 0; - longflag = longlongflag = pointflag = 0; - fmtpos = accum = 0; - have_star = afterstar = false; -nextch2: - ch = *format++; - switch (ch) - { - case '-': - leftjust = 1; - goto nextch2; - case '+': - forcesign = 1; - goto nextch2; - case '0': - /* set zero padding if no nonzero digits yet */ - if (accum == 0 && !pointflag) - zpad = '0'; - /* FALL THRU */ - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - accum = accum * 10 + (ch - '0'); - goto nextch2; - case '.': - if (have_star) - have_star = false; - else - fieldwidth = accum; - pointflag = 1; - accum = 0; - goto nextch2; - case '*': - if (have_dollar) - { - /* - * We'll process value after reading n$. Note it's OK to - * assume have_dollar is set correctly, because in a valid - * format string the initial % must have had n$ if * does. - */ - afterstar = true; - } - else - { - /* fetch and process value now */ - int starval = va_arg(args, int); - - if (pointflag) - { - precision = starval; - if (precision < 0) - { - precision = 0; - pointflag = 0; - } - } - else - { - fieldwidth = starval; - if (fieldwidth < 0) - { - leftjust = 1; - fieldwidth = -fieldwidth; - } - } - } - have_star = true; - accum = 0; - goto nextch2; - case '$': - /* First dollar sign? */ - if (!have_dollar) - { - /* Yup, so examine all conversion specs in format */ - if (!find_arguments(first_pct, args, argvalues)) - goto bad_format; - have_dollar = true; - } - if (afterstar) - { - /* fetch and process star value */ - int starval = argvalues[accum].i; - - if (pointflag) - { - precision = starval; - if (precision < 0) - { - precision = 0; - pointflag = 0; - } - } - else - { - fieldwidth = starval; - if (fieldwidth < 0) - { - leftjust = 1; - fieldwidth = -fieldwidth; - } - } - afterstar = false; - } - else - fmtpos = accum; - accum = 0; - goto nextch2; - case 'l': - if (longflag) - longlongflag = 1; - else - longflag = 1; - goto nextch2; - case 'z': -#if SIZEOF_SIZE_T == 8 -#ifdef HAVE_LONG_INT_64 - longflag = 1; -#elif defined(HAVE_LONG_LONG_INT_64) - longlongflag = 1; -#else -#error "Don't know how to print 64bit integers" -#endif -#else - /* assume size_t is same size as int */ -#endif - goto nextch2; - case 'h': - case '\'': - /* ignore these */ - goto nextch2; - case 'd': - case 'i': - if (!have_star) - { - if (pointflag) - precision = accum; - else - fieldwidth = accum; - } - if (have_dollar) - { - if (longlongflag) - numvalue = argvalues[fmtpos].ll; - else if (longflag) - numvalue = argvalues[fmtpos].l; - else - numvalue = argvalues[fmtpos].i; - } - else - { - if (longlongflag) - numvalue = va_arg(args, long long); - else if (longflag) - numvalue = va_arg(args, long); - else - numvalue = va_arg(args, int); - } - fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad, - precision, pointflag, target); - break; - case 'o': - case 'u': - case 'x': - case 'X': - if (!have_star) - { - if (pointflag) - precision = accum; - else - fieldwidth = accum; - } - if (have_dollar) - { - if (longlongflag) - numvalue = (unsigned long long) argvalues[fmtpos].ll; - else if (longflag) - numvalue = (unsigned long) argvalues[fmtpos].l; - else - numvalue = (unsigned int) argvalues[fmtpos].i; - } - else - { - if (longlongflag) - numvalue = (unsigned long long) va_arg(args, long long); - else if (longflag) - numvalue = (unsigned long) va_arg(args, long); - else - numvalue = (unsigned int) va_arg(args, int); - } - fmtint(numvalue, ch, forcesign, leftjust, fieldwidth, zpad, - precision, pointflag, target); - break; - case 'c': - if (!have_star) - { - if (pointflag) - precision = accum; - else - fieldwidth = accum; - } - if (have_dollar) - cvalue = (unsigned char) argvalues[fmtpos].i; - else - cvalue = (unsigned char) va_arg(args, int); - fmtchar(cvalue, leftjust, fieldwidth, target); - break; - case 's': - if (!have_star) - { - if (pointflag) - precision = accum; - else - fieldwidth = accum; - } - if (have_dollar) - strvalue = argvalues[fmtpos].cptr; - else - strvalue = va_arg(args, char *); - /* If string is NULL, silently substitute "(null)" */ - if (strvalue == NULL) - strvalue = "(null)"; - fmtstr(strvalue, leftjust, fieldwidth, precision, pointflag, - target); - break; - case 'p': - /* fieldwidth/leftjust are ignored ... */ - if (have_dollar) - strvalue = argvalues[fmtpos].cptr; - else - strvalue = va_arg(args, char *); - fmtptr((const void *) strvalue, target); - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (!have_star) - { - if (pointflag) - precision = accum; - else - fieldwidth = accum; - } - if (have_dollar) - fvalue = argvalues[fmtpos].d; - else - fvalue = va_arg(args, double); - fmtfloat(fvalue, ch, forcesign, leftjust, - fieldwidth, zpad, - precision, pointflag, - target); - break; - case 'm': - { - char errbuf[PG_STRERROR_R_BUFLEN]; - const char *errm = strerror_r(save_errno, - errbuf, sizeof(errbuf)); - - dostr(errm, strlen(errm), target); - } - break; - case '%': - dopr_outch('%', target); - break; - default: - - /* - * Anything else --- in particular, '\0' indicating end of - * format string --- is bogus. - */ - goto bad_format; - } - - /* Check for failure after each conversion spec */ - if (target->failed) - break; - } - - return; - -bad_format: - errno = EINVAL; - target->failed = true; -} - -/* - * find_arguments(): sort out the arguments for a format spec with %n$ - * - * If format is valid, return true and fill argvalues[i] with the value - * for the conversion spec that has %i$ or *i$. Else return false. - */ -static bool -find_arguments(const char *format, va_list args, - PrintfArgValue *argvalues) -{ - int ch; - bool afterstar; - int accum; - int longlongflag; - int longflag; - int fmtpos; - int i; - int last_dollar = 0; /* Init to "no dollar arguments known" */ - PrintfArgType argtypes[PG_NL_ARGMAX + 1] = {0}; - - /* - * This loop must accept the same format strings as the one in dopr(). - * However, we don't need to analyze them to the same level of detail. - * - * Since we're only called if there's a dollar-type spec somewhere, we can - * fail immediately if we find a non-dollar spec. Per the C99 standard, - * all argument references in the format string must be one or the other. - */ - while (*format != '\0') - { - /* Locate next conversion specifier */ - if (*format != '%') - { - /* Unlike dopr, we can just quit if there's no more specifiers */ - format = strchr(format + 1, '%'); - if (format == NULL) - break; - } - - /* Process conversion spec starting at *format */ - format++; - longflag = longlongflag = 0; - fmtpos = accum = 0; - afterstar = false; -nextch1: - ch = *format++; - switch (ch) - { - case '-': - case '+': - goto nextch1; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - accum = accum * 10 + (ch - '0'); - goto nextch1; - case '.': - accum = 0; - goto nextch1; - case '*': - if (afterstar) - return false; /* previous star missing dollar */ - afterstar = true; - accum = 0; - goto nextch1; - case '$': - if (accum <= 0 || accum > PG_NL_ARGMAX) - return false; - if (afterstar) - { - if (argtypes[accum] && - argtypes[accum] != ATYPE_INT) - return false; - argtypes[accum] = ATYPE_INT; - last_dollar = Max(last_dollar, accum); - afterstar = false; - } - else - fmtpos = accum; - accum = 0; - goto nextch1; - case 'l': - if (longflag) - longlongflag = 1; - else - longflag = 1; - goto nextch1; - case 'z': -#if SIZEOF_SIZE_T == 8 -#ifdef HAVE_LONG_INT_64 - longflag = 1; -#elif defined(HAVE_LONG_LONG_INT_64) - longlongflag = 1; -#else -#error "Don't know how to print 64bit integers" -#endif -#else - /* assume size_t is same size as int */ -#endif - goto nextch1; - case 'h': - case '\'': - /* ignore these */ - goto nextch1; - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - if (fmtpos) - { - PrintfArgType atype; - - if (longlongflag) - atype = ATYPE_LONGLONG; - else if (longflag) - atype = ATYPE_LONG; - else - atype = ATYPE_INT; - if (argtypes[fmtpos] && - argtypes[fmtpos] != atype) - return false; - argtypes[fmtpos] = atype; - last_dollar = Max(last_dollar, fmtpos); - } - else - return false; /* non-dollar conversion spec */ - break; - case 'c': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_INT) - return false; - argtypes[fmtpos] = ATYPE_INT; - last_dollar = Max(last_dollar, fmtpos); - } - else - return false; /* non-dollar conversion spec */ - break; - case 's': - case 'p': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_CHARPTR) - return false; - argtypes[fmtpos] = ATYPE_CHARPTR; - last_dollar = Max(last_dollar, fmtpos); - } - else - return false; /* non-dollar conversion spec */ - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (fmtpos) - { - if (argtypes[fmtpos] && - argtypes[fmtpos] != ATYPE_DOUBLE) - return false; - argtypes[fmtpos] = ATYPE_DOUBLE; - last_dollar = Max(last_dollar, fmtpos); - } - else - return false; /* non-dollar conversion spec */ - break; - case 'm': - case '%': - break; - default: - return false; /* bogus format string */ - } - - /* - * If we finish the spec with afterstar still set, there's a - * non-dollar star in there. - */ - if (afterstar) - return false; /* non-dollar conversion spec */ - } - - /* - * Format appears valid so far, so collect the arguments in physical - * order. (Since we rejected any non-dollar specs that would have - * collected arguments, we know that dopr() hasn't collected any yet.) - */ - for (i = 1; i <= last_dollar; i++) - { - switch (argtypes[i]) - { - case ATYPE_NONE: - return false; - case ATYPE_INT: - argvalues[i].i = va_arg(args, int); - break; - case ATYPE_LONG: - argvalues[i].l = va_arg(args, long); - break; - case ATYPE_LONGLONG: - argvalues[i].ll = va_arg(args, long long); - break; - case ATYPE_DOUBLE: - argvalues[i].d = va_arg(args, double); - break; - case ATYPE_CHARPTR: - argvalues[i].cptr = va_arg(args, char *); - break; - } - } - - return true; -} - -static void -fmtstr(const char *value, int leftjust, int minlen, int maxwidth, - int pointflag, PrintfTarget *target) -{ - int padlen, - vallen; /* amount to pad */ - - /* - * If a maxwidth (precision) is specified, we must not fetch more bytes - * than that. - */ - if (pointflag) - vallen = strnlen(value, maxwidth); - else - vallen = strlen(value); - - padlen = compute_padlen(minlen, vallen, leftjust); - - if (padlen > 0) - { - dopr_outchmulti(' ', padlen, target); - padlen = 0; - } - - dostr(value, vallen, target); - - trailing_pad(padlen, target); -} - -static void -fmtptr(const void *value, PrintfTarget *target) -{ - int vallen; - char convert[64]; - - /* we rely on regular C library's snprintf to do the basic conversion */ - vallen = snprintf(convert, sizeof(convert), "%p", value); - if (vallen < 0) - target->failed = true; - else - dostr(convert, vallen, target); -} - -static void -fmtint(long long value, char type, int forcesign, int leftjust, - int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target) -{ - unsigned long long uvalue; - int base; - int dosign; - const char *cvt = "0123456789abcdef"; - int signvalue = 0; - char convert[64]; - int vallen = 0; - int padlen; /* amount to pad */ - int zeropad; /* extra leading zeroes */ - - switch (type) - { - case 'd': - case 'i': - base = 10; - dosign = 1; - break; - case 'o': - base = 8; - dosign = 0; - break; - case 'u': - base = 10; - dosign = 0; - break; - case 'x': - base = 16; - dosign = 0; - break; - case 'X': - cvt = "0123456789ABCDEF"; - base = 16; - dosign = 0; - break; - default: - return; /* keep compiler quiet */ - } - - /* disable MSVC warning about applying unary minus to an unsigned value */ -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable: 4146) -#endif - /* Handle +/- */ - if (dosign && adjust_sign((value < 0), forcesign, &signvalue)) - uvalue = -(unsigned long long) value; - else - uvalue = (unsigned long long) value; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - /* - * SUS: the result of converting 0 with an explicit precision of 0 is no - * characters - */ - if (value == 0 && pointflag && precision == 0) - vallen = 0; - else - { - /* - * Convert integer to string. We special-case each of the possible - * base values so as to avoid general-purpose divisions. On most - * machines, division by a fixed constant can be done much more - * cheaply than a general divide. - */ - if (base == 10) - { - do - { - convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 10]; - uvalue = uvalue / 10; - } while (uvalue); - } - else if (base == 16) - { - do - { - convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 16]; - uvalue = uvalue / 16; - } while (uvalue); - } - else /* base == 8 */ - { - do - { - convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 8]; - uvalue = uvalue / 8; - } while (uvalue); - } - } - - zeropad = Max(0, precision - vallen); - - padlen = compute_padlen(minlen, vallen + zeropad, leftjust); - - leading_pad(zpad, signvalue, &padlen, target); - - if (zeropad > 0) - dopr_outchmulti('0', zeropad, target); - - dostr(convert + sizeof(convert) - vallen, vallen, target); - - trailing_pad(padlen, target); -} - -static void -fmtchar(int value, int leftjust, int minlen, PrintfTarget *target) -{ - int padlen; /* amount to pad */ - - padlen = compute_padlen(minlen, 1, leftjust); - - if (padlen > 0) - { - dopr_outchmulti(' ', padlen, target); - padlen = 0; - } - - dopr_outch(value, target); - - trailing_pad(padlen, target); -} - -static void -fmtfloat(double value, char type, int forcesign, int leftjust, - int minlen, int zpad, int precision, int pointflag, - PrintfTarget *target) -{ - int signvalue = 0; - int prec; - int vallen; - char fmt[8]; - char convert[1024]; - int zeropadlen = 0; /* amount to pad with zeroes */ - int padlen; /* amount to pad with spaces */ - - /* - * We rely on the regular C library's snprintf to do the basic conversion, - * then handle padding considerations here. - * - * The dynamic range of "double" is about 1E+-308 for IEEE math, and not - * too wildly more than that with other hardware. In "f" format, snprintf - * could therefore generate at most 308 characters to the left of the - * decimal point; while we need to allow the precision to get as high as - * 308+17 to ensure that we don't truncate significant digits from very - * small values. To handle both these extremes, we use a buffer of 1024 - * bytes and limit requested precision to 350 digits; this should prevent - * buffer overrun even with non-IEEE math. If the original precision - * request was more than 350, separately pad with zeroes. - * - * We handle infinities and NaNs specially to ensure platform-independent - * output. - */ - if (precision < 0) /* cover possible overflow of "accum" */ - precision = 0; - prec = Min(precision, 350); - - if (isnan(value)) - { - strcpy(convert, "NaN"); - vallen = 3; - /* no zero padding, regardless of precision spec */ - } - else - { - /* - * Handle sign (NaNs have no sign, so we don't do this in the case - * above). "value < 0.0" will not be true for IEEE minus zero, so we - * detect that by looking for the case where value equals 0.0 - * according to == but not according to memcmp. - */ - static const double dzero = 0.0; - - if (adjust_sign((value < 0.0 || - (value == 0.0 && - memcmp(&value, &dzero, sizeof(double)) != 0)), - forcesign, &signvalue)) - value = -value; - - if (isinf(value)) - { - strcpy(convert, "Infinity"); - vallen = 8; - /* no zero padding, regardless of precision spec */ - } - else if (pointflag) - { - zeropadlen = precision - prec; - fmt[0] = '%'; - fmt[1] = '.'; - fmt[2] = '*'; - fmt[3] = type; - fmt[4] = '\0'; - vallen = snprintf(convert, sizeof(convert), fmt, prec, value); - } - else - { - fmt[0] = '%'; - fmt[1] = type; - fmt[2] = '\0'; - vallen = snprintf(convert, sizeof(convert), fmt, value); - } - if (vallen < 0) - goto fail; - - /* - * Windows, alone among our supported platforms, likes to emit - * three-digit exponent fields even when two digits would do. Hack - * such results to look like the way everyone else does it. - */ -#ifdef WIN32 - if (vallen >= 6 && - convert[vallen - 5] == 'e' && - convert[vallen - 3] == '0') - { - convert[vallen - 3] = convert[vallen - 2]; - convert[vallen - 2] = convert[vallen - 1]; - vallen--; - } -#endif - } - - padlen = compute_padlen(minlen, vallen + zeropadlen, leftjust); - - leading_pad(zpad, signvalue, &padlen, target); - - if (zeropadlen > 0) - { - /* If 'e' or 'E' format, inject zeroes before the exponent */ - char *epos = strrchr(convert, 'e'); - - if (!epos) - epos = strrchr(convert, 'E'); - if (epos) - { - /* pad before exponent */ - dostr(convert, epos - convert, target); - dopr_outchmulti('0', zeropadlen, target); - dostr(epos, vallen - (epos - convert), target); - } - else - { - /* no exponent, pad after the digits */ - dostr(convert, vallen, target); - dopr_outchmulti('0', zeropadlen, target); - } - } - else - { - /* no zero padding, just emit the number as-is */ - dostr(convert, vallen, target); - } - - trailing_pad(padlen, target); - return; - -fail: - target->failed = true; -} - -/* - * Nonstandard entry point to print a double value efficiently. - * - * This is approximately equivalent to strfromd(), but has an API more - * adapted to what float8out() wants. The behavior is like snprintf() - * with a format of "%.ng", where n is the specified precision. - * However, the target buffer must be nonempty (i.e. count > 0), and - * the precision is silently bounded to a sane range. - */ -int -pg_strfromd(char *str, size_t count, int precision, double value) -{ - PrintfTarget target; - int signvalue = 0; - int vallen; - char fmt[8]; - char convert[64]; - - /* Set up the target like pg_snprintf, but require nonempty buffer */ - Assert(count > 0); - target.bufstart = target.bufptr = str; - target.bufend = str + count - 1; - target.stream = NULL; - target.nchars = 0; - target.failed = false; - - /* - * We bound precision to a reasonable range; the combination of this and - * the knowledge that we're using "g" format without padding allows the - * convert[] buffer to be reasonably small. - */ - if (precision < 1) - precision = 1; - else if (precision > 32) - precision = 32; - - /* - * The rest is just an inlined version of the fmtfloat() logic above, - * simplified using the knowledge that no padding is wanted. - */ - if (isnan(value)) - { - strcpy(convert, "NaN"); - vallen = 3; - } - else - { - static const double dzero = 0.0; - - if (value < 0.0 || - (value == 0.0 && - memcmp(&value, &dzero, sizeof(double)) != 0)) - { - signvalue = '-'; - value = -value; - } - - if (isinf(value)) - { - strcpy(convert, "Infinity"); - vallen = 8; - } - else - { - fmt[0] = '%'; - fmt[1] = '.'; - fmt[2] = '*'; - fmt[3] = 'g'; - fmt[4] = '\0'; - vallen = snprintf(convert, sizeof(convert), fmt, precision, value); - if (vallen < 0) - { - target.failed = true; - goto fail; - } - -#ifdef WIN32 - if (vallen >= 6 && - convert[vallen - 5] == 'e' && - convert[vallen - 3] == '0') - { - convert[vallen - 3] = convert[vallen - 2]; - convert[vallen - 2] = convert[vallen - 1]; - vallen--; - } -#endif - } - } - - if (signvalue) - dopr_outch(signvalue, &target); - - dostr(convert, vallen, &target); - -fail: - *(target.bufptr) = '\0'; - return target.failed ? -1 : (target.bufptr - target.bufstart - + target.nchars); -} - - -static void -dostr(const char *str, int slen, PrintfTarget *target) -{ - /* fast path for common case of slen == 1 */ - if (slen == 1) - { - dopr_outch(*str, target); - return; - } - - while (slen > 0) - { - int avail; - - if (target->bufend != NULL) - avail = target->bufend - target->bufptr; - else - avail = slen; - if (avail <= 0) - { - /* buffer full, can we dump to stream? */ - if (target->stream == NULL) - { - target->nchars += slen; /* no, lose the data */ - return; - } - flushbuffer(target); - continue; - } - avail = Min(avail, slen); - memmove(target->bufptr, str, avail); - target->bufptr += avail; - str += avail; - slen -= avail; - } -} - -static void -dopr_outch(int c, PrintfTarget *target) -{ - if (target->bufend != NULL && target->bufptr >= target->bufend) - { - /* buffer full, can we dump to stream? */ - if (target->stream == NULL) - { - target->nchars++; /* no, lose the data */ - return; - } - flushbuffer(target); - } - *(target->bufptr++) = c; -} - -static void -dopr_outchmulti(int c, int slen, PrintfTarget *target) -{ - /* fast path for common case of slen == 1 */ - if (slen == 1) - { - dopr_outch(c, target); - return; - } - - while (slen > 0) - { - int avail; - - if (target->bufend != NULL) - avail = target->bufend - target->bufptr; - else - avail = slen; - if (avail <= 0) - { - /* buffer full, can we dump to stream? */ - if (target->stream == NULL) - { - target->nchars += slen; /* no, lose the data */ - return; - } - flushbuffer(target); - continue; - } - avail = Min(avail, slen); - memset(target->bufptr, c, avail); - target->bufptr += avail; - slen -= avail; - } -} - - -static int -adjust_sign(int is_negative, int forcesign, int *signvalue) -{ - if (is_negative) - { - *signvalue = '-'; - return true; - } - else if (forcesign) - *signvalue = '+'; - return false; -} - - -static int -compute_padlen(int minlen, int vallen, int leftjust) -{ - int padlen; - - padlen = minlen - vallen; - if (padlen < 0) - padlen = 0; - if (leftjust) - padlen = -padlen; - return padlen; -} - - -static void -leading_pad(int zpad, int signvalue, int *padlen, PrintfTarget *target) -{ - int maxpad; - - if (*padlen > 0 && zpad) - { - if (signvalue) - { - dopr_outch(signvalue, target); - --(*padlen); - signvalue = 0; - } - if (*padlen > 0) - { - dopr_outchmulti(zpad, *padlen, target); - *padlen = 0; - } - } - maxpad = (signvalue != 0); - if (*padlen > maxpad) - { - dopr_outchmulti(' ', *padlen - maxpad, target); - *padlen = maxpad; - } - if (signvalue) - { - dopr_outch(signvalue, target); - if (*padlen > 0) - --(*padlen); - else if (*padlen < 0) - ++(*padlen); - } -} - - -static void -trailing_pad(int padlen, PrintfTarget *target) -{ - if (padlen < 0) - dopr_outchmulti(' ', -padlen, target); -} diff --git a/contrib/libs/libpq/src/port/strerror.c b/contrib/libs/libpq/src/port/strerror.c deleted file mode 100644 index 26827d6db4..0000000000 --- a/contrib/libs/libpq/src/port/strerror.c +++ /dev/null @@ -1,312 +0,0 @@ -/*------------------------------------------------------------------------- - * - * strerror.c - * Replacements for standard strerror() and strerror_r() functions - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/strerror.c - * - *------------------------------------------------------------------------- - */ -#include "c.h" - -/* - * Within this file, "strerror" means the platform's function not pg_strerror, - * and likewise for "strerror_r" - */ -#undef strerror -#undef strerror_r - -static char *gnuish_strerror_r(int errnum, char *buf, size_t buflen); -static char *get_errno_symbol(int errnum); -#ifdef WIN32 -static char *win32_socket_strerror(int errnum, char *buf, size_t buflen); -#endif - - -/* - * A slightly cleaned-up version of strerror() - */ -char * -pg_strerror(int errnum) -{ - static char errorstr_buf[PG_STRERROR_R_BUFLEN]; - - return pg_strerror_r(errnum, errorstr_buf, sizeof(errorstr_buf)); -} - -/* - * A slightly cleaned-up version of strerror_r() - */ -char * -pg_strerror_r(int errnum, char *buf, size_t buflen) -{ - char *str; - - /* If it's a Windows Winsock error, that needs special handling */ -#ifdef WIN32 - /* Winsock error code range, per WinError.h */ - if (errnum >= 10000 && errnum <= 11999) - return win32_socket_strerror(errnum, buf, buflen); -#endif - - /* Try the platform's strerror_r(), or maybe just strerror() */ - str = gnuish_strerror_r(errnum, buf, buflen); - - /* - * Some strerror()s return an empty string for out-of-range errno. This - * is ANSI C spec compliant, but not exactly useful. Also, we may get - * back strings of question marks if libc cannot transcode the message to - * the codeset specified by LC_CTYPE. If we get nothing useful, first try - * get_errno_symbol(), and if that fails, print the numeric errno. - */ - if (str == NULL || *str == '\0' || *str == '?') - str = get_errno_symbol(errnum); - - if (str == NULL) - { - snprintf(buf, buflen, _("operating system error %d"), errnum); - str = buf; - } - - return str; -} - -/* - * Simple wrapper to emulate GNU strerror_r if what the platform provides is - * POSIX. Also, if platform lacks strerror_r altogether, fall back to plain - * strerror; it might not be very thread-safe, but tough luck. - */ -static char * -gnuish_strerror_r(int errnum, char *buf, size_t buflen) -{ -#ifdef HAVE_STRERROR_R -#ifdef STRERROR_R_INT - /* POSIX API */ - if (strerror_r(errnum, buf, buflen) == 0) - return buf; - return NULL; /* let caller deal with failure */ -#else - /* GNU API */ - return strerror_r(errnum, buf, buflen); -#endif -#else /* !HAVE_STRERROR_R */ - char *sbuf = strerror(errnum); - - if (sbuf == NULL) /* can this still happen anywhere? */ - return NULL; - /* To minimize thread-unsafety hazard, copy into caller's buffer */ - strlcpy(buf, sbuf, buflen); - return buf; -#endif -} - -/* - * Returns a symbol (e.g. "ENOENT") for an errno code. - * Returns NULL if the code is unrecognized. - */ -static char * -get_errno_symbol(int errnum) -{ - switch (errnum) - { - case E2BIG: - return "E2BIG"; - case EACCES: - return "EACCES"; - case EADDRINUSE: - return "EADDRINUSE"; - case EADDRNOTAVAIL: - return "EADDRNOTAVAIL"; - case EAFNOSUPPORT: - return "EAFNOSUPPORT"; -#ifdef EAGAIN - case EAGAIN: - return "EAGAIN"; -#endif -#ifdef EALREADY - case EALREADY: - return "EALREADY"; -#endif - case EBADF: - return "EBADF"; -#ifdef EBADMSG - case EBADMSG: - return "EBADMSG"; -#endif - case EBUSY: - return "EBUSY"; - case ECHILD: - return "ECHILD"; - case ECONNABORTED: - return "ECONNABORTED"; - case ECONNREFUSED: - return "ECONNREFUSED"; - case ECONNRESET: - return "ECONNRESET"; - case EDEADLK: - return "EDEADLK"; - case EDOM: - return "EDOM"; - case EEXIST: - return "EEXIST"; - case EFAULT: - return "EFAULT"; - case EFBIG: - return "EFBIG"; - case EHOSTDOWN: - return "EHOSTDOWN"; - case EHOSTUNREACH: - return "EHOSTUNREACH"; - case EIDRM: - return "EIDRM"; - case EINPROGRESS: - return "EINPROGRESS"; - case EINTR: - return "EINTR"; - case EINVAL: - return "EINVAL"; - case EIO: - return "EIO"; - case EISCONN: - return "EISCONN"; - case EISDIR: - return "EISDIR"; -#ifdef ELOOP - case ELOOP: - return "ELOOP"; -#endif - case EMFILE: - return "EMFILE"; - case EMLINK: - return "EMLINK"; - case EMSGSIZE: - return "EMSGSIZE"; - case ENAMETOOLONG: - return "ENAMETOOLONG"; - case ENETDOWN: - return "ENETDOWN"; - case ENETRESET: - return "ENETRESET"; - case ENETUNREACH: - return "ENETUNREACH"; - case ENFILE: - return "ENFILE"; - case ENOBUFS: - return "ENOBUFS"; - case ENODEV: - return "ENODEV"; - case ENOENT: - return "ENOENT"; - case ENOEXEC: - return "ENOEXEC"; - case ENOMEM: - return "ENOMEM"; - case ENOSPC: - return "ENOSPC"; - case ENOSYS: - return "ENOSYS"; - case ENOTCONN: - return "ENOTCONN"; - case ENOTDIR: - return "ENOTDIR"; -#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */ - case ENOTEMPTY: - return "ENOTEMPTY"; -#endif - case ENOTSOCK: - return "ENOTSOCK"; -#ifdef ENOTSUP - case ENOTSUP: - return "ENOTSUP"; -#endif - case ENOTTY: - return "ENOTTY"; - case ENXIO: - return "ENXIO"; -#if defined(EOPNOTSUPP) && (!defined(ENOTSUP) || (EOPNOTSUPP != ENOTSUP)) - case EOPNOTSUPP: - return "EOPNOTSUPP"; -#endif -#ifdef EOVERFLOW - case EOVERFLOW: - return "EOVERFLOW"; -#endif - case EPERM: - return "EPERM"; - case EPIPE: - return "EPIPE"; - case EPROTONOSUPPORT: - return "EPROTONOSUPPORT"; - case ERANGE: - return "ERANGE"; -#ifdef EROFS - case EROFS: - return "EROFS"; -#endif - case ESRCH: - return "ESRCH"; - case ETIMEDOUT: - return "ETIMEDOUT"; -#ifdef ETXTBSY - case ETXTBSY: - return "ETXTBSY"; -#endif -#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) - case EWOULDBLOCK: - return "EWOULDBLOCK"; -#endif - case EXDEV: - return "EXDEV"; - } - - return NULL; -} - - -#ifdef WIN32 - -/* - * Windows' strerror() doesn't know the Winsock codes, so handle them this way - */ -static char * -win32_socket_strerror(int errnum, char *buf, size_t buflen) -{ - static HANDLE handleDLL = INVALID_HANDLE_VALUE; - - if (handleDLL == INVALID_HANDLE_VALUE) - { - handleDLL = LoadLibraryEx("netmsg.dll", NULL, - DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if (handleDLL == NULL) - { - snprintf(buf, buflen, - "winsock error %d (could not load netmsg.dll to translate: error code %lu)", - errnum, GetLastError()); - return buf; - } - } - - ZeroMemory(buf, buflen); - if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_FROM_HMODULE, - handleDLL, - errnum, - MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), - buf, - buflen - 1, - NULL) == 0) - { - /* Failed to get id */ - snprintf(buf, buflen, "unrecognized winsock error %d", errnum); - } - - return buf; -} - -#endif /* WIN32 */ diff --git a/contrib/libs/libpq/src/port/tar.c b/contrib/libs/libpq/src/port/tar.c deleted file mode 100644 index 4afe9f2533..0000000000 --- a/contrib/libs/libpq/src/port/tar.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "c.h" - -#include <sys/stat.h> - -#include "pgtar.h" - -/* - * Print a numeric field in a tar header. The field starts at *s and is of - * length len; val is the value to be written. - * - * Per POSIX, the way to write a number is in octal with leading zeroes and - * one trailing space (or NUL, but we use space) at the end of the specified - * field width. - * - * However, the given value may not fit in the available space in octal form. - * If that's true, we use the GNU extension of writing \200 followed by the - * number in base-256 form (ie, stored in binary MSB-first). (Note: here we - * support only non-negative numbers, so we don't worry about the GNU rules - * for handling negative numbers.) - */ -void -print_tar_number(char *s, int len, uint64 val) -{ - if (val < (((uint64) 1) << ((len - 1) * 3))) - { - /* Use octal with trailing space */ - s[--len] = ' '; - while (len) - { - s[--len] = (val & 7) + '0'; - val >>= 3; - } - } - else - { - /* Use base-256 with leading \200 */ - s[0] = '\200'; - while (len > 1) - { - s[--len] = (val & 255); - val >>= 8; - } - } -} - - -/* - * Read a numeric field in a tar header. The field starts at *s and is of - * length len. - * - * The POSIX-approved format for a number is octal, ending with a space or - * NUL. However, for values that don't fit, we recognize the GNU extension - * of \200 followed by the number in base-256 form (ie, stored in binary - * MSB-first). (Note: here we support only non-negative numbers, so we don't - * worry about the GNU rules for handling negative numbers.) - */ -uint64 -read_tar_number(const char *s, int len) -{ - uint64 result = 0; - - if (*s == '\200') - { - /* base-256 */ - while (--len) - { - result <<= 8; - result |= (unsigned char) (*++s); - } - } - else - { - /* octal */ - while (len-- && *s >= '0' && *s <= '7') - { - result <<= 3; - result |= (*s - '0'); - s++; - } - } - return result; -} - - -/* - * Calculate the tar checksum for a header. The header is assumed to always - * be 512 bytes, per the tar standard. - */ -int -tarChecksum(char *header) -{ - int i, - sum; - - /* - * Per POSIX, the checksum is the simple sum of all bytes in the header, - * treating the bytes as unsigned, and treating the checksum field (at - * offset 148) as though it contained 8 spaces. - */ - sum = 8 * ' '; /* presumed value for checksum field */ - for (i = 0; i < 512; i++) - if (i < 148 || i >= 156) - sum += 0xFF & header[i]; - return sum; -} - - -/* - * Fill in the buffer pointed to by h with a tar format header. This buffer - * must always have space for 512 characters, which is a requirement of - * the tar format. - */ -enum tarError -tarCreateHeader(char *h, const char *filename, const char *linktarget, - pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime) -{ - if (strlen(filename) > 99) - return TAR_NAME_TOO_LONG; - - if (linktarget && strlen(linktarget) > 99) - return TAR_SYMLINK_TOO_LONG; - - memset(h, 0, 512); /* assume tar header size */ - - /* Name 100 */ - strlcpy(&h[0], filename, 100); - if (linktarget != NULL || S_ISDIR(mode)) - { - /* - * We only support symbolic links to directories, and this is - * indicated in the tar format by adding a slash at the end of the - * name, the same as for regular directories. - */ - int flen = strlen(filename); - - flen = Min(flen, 99); - h[flen] = '/'; - h[flen + 1] = '\0'; - } - - /* Mode 8 - this doesn't include the file type bits (S_IFMT) */ - print_tar_number(&h[100], 8, (mode & 07777)); - - /* User ID 8 */ - print_tar_number(&h[108], 8, uid); - - /* Group 8 */ - print_tar_number(&h[116], 8, gid); - - /* File size 12 */ - if (linktarget != NULL || S_ISDIR(mode)) - /* Symbolic link or directory has size zero */ - print_tar_number(&h[124], 12, 0); - else - print_tar_number(&h[124], 12, size); - - /* Mod Time 12 */ - print_tar_number(&h[136], 12, mtime); - - /* Checksum 8 cannot be calculated until we've filled all other fields */ - - if (linktarget != NULL) - { - /* Type - Symbolic link */ - h[156] = '2'; - /* Link Name 100 */ - strlcpy(&h[157], linktarget, 100); - } - else if (S_ISDIR(mode)) - { - /* Type - directory */ - h[156] = '5'; - } - else - { - /* Type - regular file */ - h[156] = '0'; - } - - /* Magic 6 */ - strcpy(&h[257], "ustar"); - - /* Version 2 */ - memcpy(&h[263], "00", 2); - - /* User 32 */ - /* XXX: Do we need to care about setting correct username? */ - strlcpy(&h[265], "postgres", 32); - - /* Group 32 */ - /* XXX: Do we need to care about setting correct group name? */ - strlcpy(&h[297], "postgres", 32); - - /* Major Dev 8 */ - print_tar_number(&h[329], 8, 0); - - /* Minor Dev 8 */ - print_tar_number(&h[337], 8, 0); - - /* Prefix 155 - not used, leave as nulls */ - - /* Finally, compute and insert the checksum */ - print_tar_number(&h[148], 8, tarChecksum(h)); - - return TAR_OK; -} diff --git a/contrib/libs/libpq/src/port/thread.c b/contrib/libs/libpq/src/port/thread.c deleted file mode 100644 index 375c89b297..0000000000 --- a/contrib/libs/libpq/src/port/thread.c +++ /dev/null @@ -1,96 +0,0 @@ -/*------------------------------------------------------------------------- - * - * thread.c - * - * Prototypes and macros around system calls, used to help make - * threaded libraries reentrant and safe to use from threaded applications. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * src/port/thread.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include <pwd.h> - - -/* - * Historically, the code in this module had to deal with operating systems - * that lacked getpwuid_r(). - */ - -#ifndef WIN32 - -/* - * pg_get_user_name - get the name of the user with the given ID - * - * On success, the user name is returned into the buffer (of size buflen), - * and "true" is returned. On failure, a localized error message is - * returned into the buffer, and "false" is returned. - */ -bool -pg_get_user_name(uid_t user_id, char *buffer, size_t buflen) -{ - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pw = NULL; - int pwerr; - - pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw); - if (pw != NULL) - { - strlcpy(buffer, pw->pw_name, buflen); - return true; - } - if (pwerr != 0) - snprintf(buffer, buflen, - _("could not look up local user ID %d: %s"), - (int) user_id, - strerror_r(pwerr, pwdbuf, sizeof(pwdbuf))); - else - snprintf(buffer, buflen, - _("local user with ID %d does not exist"), - (int) user_id); - return false; -} - -/* - * pg_get_user_home_dir - get the home directory of the user with the given ID - * - * On success, the directory path is returned into the buffer (of size buflen), - * and "true" is returned. On failure, a localized error message is - * returned into the buffer, and "false" is returned. - * - * Note that this does not incorporate the common behavior of checking - * $HOME first, since it's independent of which user_id is queried. - */ -bool -pg_get_user_home_dir(uid_t user_id, char *buffer, size_t buflen) -{ - char pwdbuf[BUFSIZ]; - struct passwd pwdstr; - struct passwd *pw = NULL; - int pwerr; - - pwerr = getpwuid_r(user_id, &pwdstr, pwdbuf, sizeof(pwdbuf), &pw); - if (pw != NULL) - { - strlcpy(buffer, pw->pw_dir, buflen); - return true; - } - if (pwerr != 0) - snprintf(buffer, buflen, - _("could not look up local user ID %d: %s"), - (int) user_id, - strerror_r(pwerr, pwdbuf, sizeof(pwdbuf))); - else - snprintf(buffer, buflen, - _("local user with ID %d does not exist"), - (int) user_id); - return false; -} - -#endif /* !WIN32 */ diff --git a/contrib/libs/libpq/src/port/win32common.c b/contrib/libs/libpq/src/port/win32common.c deleted file mode 100644 index 2fd78f7f93..0000000000 --- a/contrib/libs/libpq/src/port/win32common.c +++ /dev/null @@ -1,68 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32common.c - * Common routines shared among the win32*.c ports. - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/win32common.c - * - *------------------------------------------------------------------------- - */ - -#ifdef FRONTEND -#include "postgres_fe.h" -#else -#include "postgres.h" -#endif - -#ifdef WIN32 - -/* - * pgwin32_get_file_type - * - * Convenience wrapper for GetFileType() with specific error handling for all the - * port implementations. Returns the file type associated with a HANDLE. - * - * On error, sets errno with FILE_TYPE_UNKNOWN as file type. - */ -DWORD -pgwin32_get_file_type(HANDLE hFile) -{ - DWORD fileType = FILE_TYPE_UNKNOWN; - DWORD lastError; - - errno = 0; - - /* - * When stdin, stdout, and stderr aren't associated with a stream the - * special value -2 is returned: - * https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/get-osfhandle - */ - if (hFile == INVALID_HANDLE_VALUE || hFile == (HANDLE) -2) - { - errno = EINVAL; - return FILE_TYPE_UNKNOWN; - } - - fileType = GetFileType(hFile); - lastError = GetLastError(); - - /* - * Invoke GetLastError in order to distinguish between a "valid" return of - * FILE_TYPE_UNKNOWN and its return due to a calling error. In case of - * success, GetLastError() returns NO_ERROR. - */ - if (fileType == FILE_TYPE_UNKNOWN && lastError != NO_ERROR) - { - _dosmaperr(lastError); - return FILE_TYPE_UNKNOWN; - } - - return fileType; -} - -#endif /* WIN32 */ diff --git a/contrib/libs/libpq/src/port/win32error.c b/contrib/libs/libpq/src/port/win32error.c deleted file mode 100644 index d7c3048eba..0000000000 --- a/contrib/libs/libpq/src/port/win32error.c +++ /dev/null @@ -1,214 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32error.c - * Map win32 error codes to errno values - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/port/win32error.c - * - *------------------------------------------------------------------------- - */ - -#ifndef FRONTEND -#include "postgres.h" -#else -#include "postgres_fe.h" -#endif - -static const struct -{ - DWORD winerr; - int doserr; -} doserrors[] = - -{ - { - ERROR_INVALID_FUNCTION, EINVAL - }, - { - ERROR_FILE_NOT_FOUND, ENOENT - }, - { - ERROR_PATH_NOT_FOUND, ENOENT - }, - { - ERROR_TOO_MANY_OPEN_FILES, EMFILE - }, - { - ERROR_ACCESS_DENIED, EACCES - }, - { - ERROR_INVALID_HANDLE, EBADF - }, - { - ERROR_ARENA_TRASHED, ENOMEM - }, - { - ERROR_NOT_ENOUGH_MEMORY, ENOMEM - }, - { - ERROR_INVALID_BLOCK, ENOMEM - }, - { - ERROR_BAD_ENVIRONMENT, E2BIG - }, - { - ERROR_BAD_FORMAT, ENOEXEC - }, - { - ERROR_INVALID_ACCESS, EINVAL - }, - { - ERROR_INVALID_DATA, EINVAL - }, - { - ERROR_INVALID_DRIVE, ENOENT - }, - { - ERROR_CURRENT_DIRECTORY, EACCES - }, - { - ERROR_NOT_SAME_DEVICE, EXDEV - }, - { - ERROR_NO_MORE_FILES, ENOENT - }, - { - ERROR_LOCK_VIOLATION, EACCES - }, - { - ERROR_SHARING_VIOLATION, EACCES - }, - { - ERROR_BAD_NETPATH, ENOENT - }, - { - ERROR_NETWORK_ACCESS_DENIED, EACCES - }, - { - ERROR_BAD_NET_NAME, ENOENT - }, - { - ERROR_FILE_EXISTS, EEXIST - }, - { - ERROR_CANNOT_MAKE, EACCES - }, - { - ERROR_FAIL_I24, EACCES - }, - { - ERROR_INVALID_PARAMETER, EINVAL - }, - { - ERROR_NO_PROC_SLOTS, EAGAIN - }, - { - ERROR_DRIVE_LOCKED, EACCES - }, - { - ERROR_BROKEN_PIPE, EPIPE - }, - { - ERROR_DISK_FULL, ENOSPC - }, - { - ERROR_INVALID_TARGET_HANDLE, EBADF - }, - { - ERROR_INVALID_HANDLE, EINVAL - }, - { - ERROR_WAIT_NO_CHILDREN, ECHILD - }, - { - ERROR_CHILD_NOT_COMPLETE, ECHILD - }, - { - ERROR_DIRECT_ACCESS_HANDLE, EBADF - }, - { - ERROR_NEGATIVE_SEEK, EINVAL - }, - { - ERROR_SEEK_ON_DEVICE, EACCES - }, - { - ERROR_DIR_NOT_EMPTY, ENOTEMPTY - }, - { - ERROR_NOT_LOCKED, EACCES - }, - { - ERROR_BAD_PATHNAME, ENOENT - }, - { - ERROR_MAX_THRDS_REACHED, EAGAIN - }, - { - ERROR_LOCK_FAILED, EACCES - }, - { - ERROR_ALREADY_EXISTS, EEXIST - }, - { - ERROR_FILENAME_EXCED_RANGE, ENOENT - }, - { - ERROR_NESTING_NOT_ALLOWED, EAGAIN - }, - { - ERROR_NOT_ENOUGH_QUOTA, ENOMEM - }, - { - ERROR_DELETE_PENDING, ENOENT - }, - { - ERROR_INVALID_NAME, ENOENT - }, - { - ERROR_CANT_RESOLVE_FILENAME, ENOENT - } -}; - -void -_dosmaperr(unsigned long e) -{ - int i; - - if (e == 0) - { - errno = 0; - return; - } - - for (i = 0; i < lengthof(doserrors); i++) - { - if (doserrors[i].winerr == e) - { - int doserr = doserrors[i].doserr; - -#ifndef FRONTEND - ereport(DEBUG5, - (errmsg_internal("mapped win32 error code %lu to %d", - e, doserr))); -#elif defined(FRONTEND_DEBUG) - fprintf(stderr, "mapped win32 error code %lu to %d", e, doserr); -#endif - errno = doserr; - return; - } - } - -#ifndef FRONTEND - ereport(LOG, - (errmsg_internal("unrecognized win32 error code: %lu", - e))); -#else - fprintf(stderr, "unrecognized win32 error code: %lu", e); -#endif - - errno = EINVAL; -} diff --git a/contrib/libs/libpq/src/port/win32gettimeofday.c b/contrib/libs/libpq/src/port/win32gettimeofday.c deleted file mode 100644 index 1e00f7ee14..0000000000 --- a/contrib/libs/libpq/src/port/win32gettimeofday.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * win32gettimeofday.c - * Win32 gettimeofday() replacement - * - * src/port/win32gettimeofday.c - * - * Copyright (c) 2003 SRA, Inc. - * Copyright (c) 2003 SKC, Inc. - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose, without fee, and without a - * written agreement is hereby granted, provided that the above - * copyright notice and this paragraph and the following two - * paragraphs appear in all copies. - * - * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, - * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING - * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS - * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS - * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "c.h" - -#include <sysinfoapi.h> - -#include <sys/time.h> - -/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */ -static const unsigned __int64 epoch = UINT64CONST(116444736000000000); - -/* - * FILETIME represents the number of 100-nanosecond intervals since - * January 1, 1601 (UTC). - */ -#define FILETIME_UNITS_PER_SEC 10000000L -#define FILETIME_UNITS_PER_USEC 10 - - -/* - * timezone information is stored outside the kernel so tzp isn't used anymore. - * - * Note: this function is not for Win32 high precision timing purposes. See - * elapsed_time(). - */ -int -gettimeofday(struct timeval *tp, void *tzp) -{ - FILETIME file_time; - ULARGE_INTEGER ularge; - - /* - * POSIX declines to define what tzp points to, saying "If tzp is not a - * null pointer, the behavior is unspecified". Let's take this - * opportunity to verify that noplace in Postgres tries to use any - * unportable behavior. - */ - Assert(tzp == NULL); - - GetSystemTimePreciseAsFileTime(&file_time); - ularge.LowPart = file_time.dwLowDateTime; - ularge.HighPart = file_time.dwHighDateTime; - - tp->tv_sec = (long) ((ularge.QuadPart - epoch) / FILETIME_UNITS_PER_SEC); - tp->tv_usec = (long) (((ularge.QuadPart - epoch) % FILETIME_UNITS_PER_SEC) - / FILETIME_UNITS_PER_USEC); - - return 0; -} diff --git a/contrib/libs/libpq/src/port/win32ntdll.c b/contrib/libs/libpq/src/port/win32ntdll.c deleted file mode 100644 index 3b38cdb34c..0000000000 --- a/contrib/libs/libpq/src/port/win32ntdll.c +++ /dev/null @@ -1,71 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32ntdll.c - * Dynamically loaded Windows NT functions. - * - * Portions Copyright (c) 2021-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/win32ntdll.c - * - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#include "port/win32ntdll.h" - -RtlGetLastNtStatus_t pg_RtlGetLastNtStatus; -RtlNtStatusToDosError_t pg_RtlNtStatusToDosError; -NtFlushBuffersFileEx_t pg_NtFlushBuffersFileEx; - -typedef struct NtDllRoutine -{ - const char *name; - pg_funcptr_t *address; -} NtDllRoutine; - -static const NtDllRoutine routines[] = { - {"RtlGetLastNtStatus", (pg_funcptr_t *) &pg_RtlGetLastNtStatus}, - {"RtlNtStatusToDosError", (pg_funcptr_t *) &pg_RtlNtStatusToDosError}, - {"NtFlushBuffersFileEx", (pg_funcptr_t *) &pg_NtFlushBuffersFileEx} -}; - -static bool initialized; - -int -initialize_ntdll(void) -{ - HMODULE module; - - if (initialized) - return 0; - - if (!(module = LoadLibraryEx("ntdll.dll", NULL, 0))) - { - _dosmaperr(GetLastError()); - return -1; - } - - for (int i = 0; i < lengthof(routines); ++i) - { - pg_funcptr_t address; - - address = (pg_funcptr_t) GetProcAddress(module, routines[i].name); - if (!address) - { - _dosmaperr(GetLastError()); - FreeLibrary(module); - - return -1; - } - - *(pg_funcptr_t *) routines[i].address = address; - } - - initialized = true; - - return 0; -} diff --git a/contrib/libs/libpq/src/port/win32setlocale.c b/contrib/libs/libpq/src/port/win32setlocale.c deleted file mode 100644 index e2c85b0048..0000000000 --- a/contrib/libs/libpq/src/port/win32setlocale.c +++ /dev/null @@ -1,193 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32setlocale.c - * Wrapper to work around bugs in Windows setlocale() implementation - * - * Copyright (c) 2011-2023, PostgreSQL Global Development Group - * - * IDENTIFICATION - * src/port/win32setlocale.c - * - * - * The setlocale() function in Windows is broken in two ways. First, it - * has a problem with locale names that have a dot in the country name. For - * example: - * - * "Chinese (Traditional)_Hong Kong S.A.R..950" - * - * For some reason, setlocale() doesn't accept that as argument, even though - * setlocale(LC_ALL, NULL) returns exactly that. Fortunately, it accepts - * various alternative names for such countries, so to work around the broken - * setlocale() function, we map the troublemaking locale names to accepted - * aliases, before calling setlocale(). - * - * The second problem is that the locale name for "Norwegian (Bokmål)" - * contains a non-ASCII character. That's problematic, because it's not clear - * what encoding the locale name itself is supposed to be in, when you - * haven't yet set a locale. Also, it causes problems when the cluster - * contains databases with different encodings, as the locale name is stored - * in the pg_database system catalog. To work around that, when setlocale() - * returns that locale name, map it to a pure-ASCII alias for the same - * locale. - *------------------------------------------------------------------------- - */ - -#include "c.h" - -#undef setlocale - -struct locale_map -{ - /* - * String in locale name to replace. Can be a single string (end is NULL), - * or separate start and end strings. If two strings are given, the locale - * name must contain both of them, and everything between them is - * replaced. This is used for a poor-man's regexp search, allowing - * replacement of "start.*end". - */ - const char *locale_name_start; - const char *locale_name_end; - - const char *replacement; /* string to replace the match with */ -}; - -/* - * Mappings applied before calling setlocale(), to the argument. - */ -static const struct locale_map locale_map_argument[] = { - /* - * "HKG" is listed here: - * http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.71%29.aspx - * (Country/Region Strings). - * - * "ARE" is the ISO-3166 three-letter code for U.A.E. It is not on the - * above list, but seems to work anyway. - */ - {"Hong Kong S.A.R.", NULL, "HKG"}, - {"U.A.E.", NULL, "ARE"}, - - /* - * The ISO-3166 country code for Macau S.A.R. is MAC, but Windows doesn't - * seem to recognize that. And Macau isn't listed in the table of accepted - * abbreviations linked above. Fortunately, "ZHM" seems to be accepted as - * an alias for "Chinese (Traditional)_Macau S.A.R..950". I'm not sure - * where "ZHM" comes from, must be some legacy naming scheme. But hey, it - * works. - * - * Note that unlike HKG and ARE, ZHM is an alias for the *whole* locale - * name, not just the country part. - * - * Some versions of Windows spell it "Macau", others "Macao". - */ - {"Chinese (Traditional)_Macau S.A.R..950", NULL, "ZHM"}, - {"Chinese_Macau S.A.R..950", NULL, "ZHM"}, - {"Chinese (Traditional)_Macao S.A.R..950", NULL, "ZHM"}, - {"Chinese_Macao S.A.R..950", NULL, "ZHM"}, - {NULL, NULL, NULL} -}; - -/* - * Mappings applied after calling setlocale(), to its return value. - */ -static const struct locale_map locale_map_result[] = { - /* - * "Norwegian (Bokmål)" locale name contains the a-ring character. - * Map it to a pure-ASCII alias. - * - * It's not clear what encoding setlocale() uses when it returns the - * locale name, so to play it safe, we search for "Norwegian (Bok*l)". - * - * Just to make life even more complicated, some versions of Windows spell - * the locale name without parentheses. Translate that too. - */ - {"Norwegian (Bokm", "l)_Norway", "Norwegian_Norway"}, - {"Norwegian Bokm", "l_Norway", "Norwegian_Norway"}, - {NULL, NULL, NULL} -}; - -#define MAX_LOCALE_NAME_LEN 100 - -static const char * -map_locale(const struct locale_map *map, const char *locale) -{ - static char aliasbuf[MAX_LOCALE_NAME_LEN]; - int i; - - /* Check if the locale name matches any of the problematic ones. */ - for (i = 0; map[i].locale_name_start != NULL; i++) - { - const char *needle_start = map[i].locale_name_start; - const char *needle_end = map[i].locale_name_end; - const char *replacement = map[i].replacement; - char *match; - char *match_start = NULL; - char *match_end = NULL; - - match = strstr(locale, needle_start); - if (match) - { - /* - * Found a match for the first part. If this was a two-part - * replacement, find the second part. - */ - match_start = match; - if (needle_end) - { - match = strstr(match_start + strlen(needle_start), needle_end); - if (match) - match_end = match + strlen(needle_end); - else - match_start = NULL; - } - else - match_end = match_start + strlen(needle_start); - } - - if (match_start) - { - /* Found a match. Replace the matched string. */ - int matchpos = match_start - locale; - int replacementlen = strlen(replacement); - char *rest = match_end; - int restlen = strlen(rest); - - /* check that the result fits in the static buffer */ - if (matchpos + replacementlen + restlen + 1 > MAX_LOCALE_NAME_LEN) - return NULL; - - memcpy(&aliasbuf[0], &locale[0], matchpos); - memcpy(&aliasbuf[matchpos], replacement, replacementlen); - /* includes null terminator */ - memcpy(&aliasbuf[matchpos + replacementlen], rest, restlen + 1); - - return aliasbuf; - } - } - - /* no match, just return the original string */ - return locale; -} - -char * -pgwin32_setlocale(int category, const char *locale) -{ - const char *argument; - char *result; - - if (locale == NULL) - argument = NULL; - else - argument = map_locale(locale_map_argument, locale); - - /* Call the real setlocale() function */ - result = setlocale(category, argument); - - /* - * setlocale() is specified to return a "char *" that the caller is - * forbidden to modify, so casting away the "const" is innocuous. - */ - if (result) - result = unconstify(char *, map_locale(locale_map_result, result)); - - return result; -} diff --git a/contrib/libs/libpq/src/port/win32stat.c b/contrib/libs/libpq/src/port/win32stat.c deleted file mode 100644 index aa3a0c174e..0000000000 --- a/contrib/libs/libpq/src/port/win32stat.c +++ /dev/null @@ -1,306 +0,0 @@ -/*------------------------------------------------------------------------- - * - * win32stat.c - * Replacements for <sys/stat.h> functions using GetFileInformationByHandle - * - * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * src/port/win32stat.c - * - *------------------------------------------------------------------------- - */ - -#ifdef WIN32 - -#include "c.h" -#include "port/win32ntdll.h" - -#include <windows.h> - -/* - * Convert a FILETIME struct into a 64 bit time_t. - */ -static __time64_t -filetime_to_time(const FILETIME *ft) -{ - ULARGE_INTEGER unified_ft = {0}; - static const uint64 EpochShift = UINT64CONST(116444736000000000); - - unified_ft.LowPart = ft->dwLowDateTime; - unified_ft.HighPart = ft->dwHighDateTime; - - if (unified_ft.QuadPart < EpochShift) - return -1; - - unified_ft.QuadPart -= EpochShift; - unified_ft.QuadPart /= 10 * 1000 * 1000; - - return unified_ft.QuadPart; -} - -/* - * Convert WIN32 file attributes to a Unix-style mode. - * - * Only owner permissions are set. - */ -static unsigned short -fileattr_to_unixmode(int attr) -{ - unsigned short uxmode = 0; - - uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_DIRECTORY) ? - (_S_IFDIR) : (_S_IFREG)); - - uxmode |= (unsigned short) ((attr & FILE_ATTRIBUTE_READONLY) ? - (_S_IREAD) : (_S_IREAD | _S_IWRITE)); - - /* there is no need to simulate _S_IEXEC using CMD's PATHEXT extensions */ - uxmode |= _S_IEXEC; - - return uxmode; -} - -/* - * Convert WIN32 file information (from a HANDLE) to a struct stat. - */ -static int -fileinfo_to_stat(HANDLE hFile, struct stat *buf) -{ - BY_HANDLE_FILE_INFORMATION fiData; - - memset(buf, 0, sizeof(*buf)); - - /* - * GetFileInformationByHandle minimum supported version: Windows XP and - * Windows Server 2003, so it exists everywhere we care about. - */ - if (!GetFileInformationByHandle(hFile, &fiData)) - { - _dosmaperr(GetLastError()); - return -1; - } - - if (fiData.ftLastWriteTime.dwLowDateTime || - fiData.ftLastWriteTime.dwHighDateTime) - buf->st_mtime = filetime_to_time(&fiData.ftLastWriteTime); - - if (fiData.ftLastAccessTime.dwLowDateTime || - fiData.ftLastAccessTime.dwHighDateTime) - buf->st_atime = filetime_to_time(&fiData.ftLastAccessTime); - else - buf->st_atime = buf->st_mtime; - - if (fiData.ftCreationTime.dwLowDateTime || - fiData.ftCreationTime.dwHighDateTime) - buf->st_ctime = filetime_to_time(&fiData.ftCreationTime); - else - buf->st_ctime = buf->st_mtime; - - buf->st_mode = fileattr_to_unixmode(fiData.dwFileAttributes); - buf->st_nlink = fiData.nNumberOfLinks; - - buf->st_size = ((((uint64) fiData.nFileSizeHigh) << 32) | - fiData.nFileSizeLow); - - return 0; -} - -/* - * Windows implementation of lstat(). - */ -int -_pglstat64(const char *name, struct stat *buf) -{ - /* - * Our open wrapper will report STATUS_DELETE_PENDING as ENOENT. We - * request FILE_FLAG_BACKUP_SEMANTICS so that we can open directories too, - * for limited purposes. We use the private handle-based version, so we - * don't risk running out of fds. - */ - HANDLE hFile; - int ret; - - hFile = pgwin32_open_handle(name, O_RDONLY, true); - if (hFile == INVALID_HANDLE_VALUE) - { - if (errno == ENOENT) - { - /* - * If it's a junction point pointing to a non-existent path, we'll - * have ENOENT here (because pgwin32_open_handle does not use - * FILE_FLAG_OPEN_REPARSE_POINT). In that case, we'll try again - * with readlink() below, which will distinguish true ENOENT from - * pseudo-symlink. - */ - memset(buf, 0, sizeof(*buf)); - ret = 0; - } - else - return -1; - } - else - ret = fileinfo_to_stat(hFile, buf); - - /* - * Junction points appear as directories to fileinfo_to_stat(), so we'll - * need to do a bit more work to distinguish them. - */ - if ((ret == 0 && S_ISDIR(buf->st_mode)) || hFile == INVALID_HANDLE_VALUE) - { - char next[MAXPGPATH]; - ssize_t size; - - /* - * POSIX says we need to put the length of the target path into - * st_size. Use readlink() to get it, or learn that this is not a - * junction point. - */ - size = readlink(name, next, sizeof(next)); - if (size < 0) - { - if (errno == EACCES && - pg_RtlGetLastNtStatus() == STATUS_DELETE_PENDING) - { - /* Unlinked underneath us. */ - errno = ENOENT; - ret = -1; - } - else if (errno == EINVAL) - { - /* It's not a junction point, nothing to do. */ - } - else - { - /* Some other failure. */ - ret = -1; - } - } - else - { - /* It's a junction point, so report it as a symlink. */ - buf->st_mode &= ~S_IFDIR; - buf->st_mode |= S_IFLNK; - buf->st_size = size; - ret = 0; - } - } - - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); - return ret; -} - -/* - * Windows implementation of stat(). - */ -int -_pgstat64(const char *name, struct stat *buf) -{ - int loops = 0; - int ret; - char curr[MAXPGPATH]; - - ret = _pglstat64(name, buf); - - strlcpy(curr, name, MAXPGPATH); - - /* Do we need to follow a symlink (junction point)? */ - while (ret == 0 && S_ISLNK(buf->st_mode)) - { - char next[MAXPGPATH]; - ssize_t size; - - if (++loops > 8) - { - errno = ELOOP; - return -1; - } - - /* - * _pglstat64() already called readlink() once to be able to fill in - * st_size, and now we need to do it again to get the path to follow. - * That could be optimized, but stat() on symlinks is probably rare - * and this way is simple. - */ - size = readlink(curr, next, sizeof(next)); - if (size < 0) - { - if (errno == EACCES && - pg_RtlGetLastNtStatus() == STATUS_DELETE_PENDING) - { - /* Unlinked underneath us. */ - errno = ENOENT; - } - return -1; - } - if (size >= sizeof(next)) - { - errno = ENAMETOOLONG; - return -1; - } - next[size] = 0; - - ret = _pglstat64(next, buf); - strcpy(curr, next); - } - - return ret; -} - -/* - * Windows implementation of fstat(). - */ -int -_pgfstat64(int fileno, struct stat *buf) -{ - HANDLE hFile = (HANDLE) _get_osfhandle(fileno); - DWORD fileType = FILE_TYPE_UNKNOWN; - unsigned short st_mode; - - if (buf == NULL) - { - errno = EINVAL; - return -1; - } - - fileType = pgwin32_get_file_type(hFile); - if (errno != 0) - return -1; - - switch (fileType) - { - /* The specified file is a disk file */ - case FILE_TYPE_DISK: - return fileinfo_to_stat(hFile, buf); - - /* - * The specified file is a socket, a named pipe, or an anonymous - * pipe. - */ - case FILE_TYPE_PIPE: - st_mode = _S_IFIFO; - break; - /* The specified file is a character file */ - case FILE_TYPE_CHAR: - st_mode = _S_IFCHR; - break; - /* Unused flag and unknown file type */ - case FILE_TYPE_REMOTE: - case FILE_TYPE_UNKNOWN: - default: - errno = EINVAL; - return -1; - } - - memset(buf, 0, sizeof(*buf)); - buf->st_mode = st_mode; - buf->st_dev = fileno; - buf->st_rdev = fileno; - buf->st_nlink = 1; - return 0; -} - -#endif /* WIN32 */ |