diff --git a/ChangeLog b/ChangeLog index 6f138b04..adec146d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-01-21 James Henstridge + + * psycypg/*.h: apply HIDDEN to all global variables and functions + that should not be exported from the module. This results in a 5% + reduction in code size and shortens the dynamic symbol table. + + * psycopg/config.h: If GCC >= 4.0 is installed, define the HIDDEN + symbol to apply the "hidden" visibility attribute. + 2008-01-19 James Henstridge * tests/test_connection.py (ConnectionTests): add simple tests for diff --git a/psycopg/adapter_asis.h b/psycopg/adapter_asis.h index 3a0ff80f..f06c6ded 100644 --- a/psycopg/adapter_asis.h +++ b/psycopg/adapter_asis.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject asisType; +extern HIDDEN PyTypeObject asisType; typedef struct { PyObject_HEAD @@ -41,7 +43,7 @@ typedef struct { /* functions exported to psycopgmodule.c */ -extern PyObject *psyco_AsIs(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_AsIs(PyObject *module, PyObject *args); #define psyco_AsIs_doc \ "AsIs(obj) -> new AsIs wrapper object" diff --git a/psycopg/adapter_binary.h b/psycopg/adapter_binary.h index ea2e010e..66e27c4c 100644 --- a/psycopg/adapter_binary.h +++ b/psycopg/adapter_binary.h @@ -26,11 +26,13 @@ #include #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject binaryType; +extern HIDDEN PyTypeObject binaryType; typedef struct { PyObject_HEAD @@ -42,7 +44,7 @@ typedef struct { /* functions exported to psycopgmodule.c */ -extern PyObject *psyco_Binary(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Binary(PyObject *module, PyObject *args); #define psyco_Binary_doc \ "Binary(buffer) -> new binary object\n\n" \ "Build an object capable to hold a bynary string value." diff --git a/psycopg/adapter_datetime.h b/psycopg/adapter_datetime.h index 4530b9a9..50c97128 100644 --- a/psycopg/adapter_datetime.h +++ b/psycopg/adapter_datetime.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject pydatetimeType; +extern HIDDEN PyTypeObject pydatetimeType; typedef struct { PyObject_HEAD @@ -47,36 +49,36 @@ typedef struct { /* functions exported to psycopgmodule.c */ #ifdef PSYCOPG_DEFAULT_PYDATETIME -extern PyObject *psyco_Date(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Date(PyObject *module, PyObject *args); #define psyco_Date_doc \ "Date(year, month, day) -> new date\n\n" \ "Build an object holding a date value." -extern PyObject *psyco_Time(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Time(PyObject *module, PyObject *args); #define psyco_Time_doc \ "Time(hour, minutes, seconds, tzinfo=None) -> new time\n\n" \ "Build an object holding a time value." -extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Timestamp(PyObject *module, PyObject *args); #define psyco_Timestamp_doc \ "Timestamp(year, month, day, hour, minutes, seconds, tzinfo=None) -> new timestamp\n\n" \ "Build an object holding a timestamp value." -extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args); #define psyco_DateFromTicks_doc \ "DateFromTicks(ticks) -> new date\n\n" \ "Build an object holding a date value from the given ticks value.\n\n" \ "Ticks are the number of seconds since the epoch; see the documentation " \ "of the standard Python time module for details)." -extern PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args); #define psyco_TimeFromTicks_doc \ "TimeFromTicks(ticks) -> new time\n\n" \ "Build an object holding a time value from the given ticks value.\n\n" \ "Ticks are the number of seconds since the epoch; see the documentation " \ "of the standard Python time module for details)." -extern PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args); #define psyco_TimestampFromTicks_doc \ "TimestampFromTicks(ticks) -> new timestamp\n\n" \ "Build an object holding a timestamp value from the given ticks value.\n\n" \ @@ -85,19 +87,19 @@ extern PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args); #endif /* PSYCOPG_DEFAULT_PYDATETIME */ -extern PyObject *psyco_DateFromPy(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_DateFromPy(PyObject *module, PyObject *args); #define psyco_DateFromPy_doc \ "DateFromPy(datetime.date) -> new wrapper" -extern PyObject *psyco_TimeFromPy(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimeFromPy(PyObject *module, PyObject *args); #define psyco_TimeFromPy_doc \ "TimeFromPy(datetime.time) -> new wrapper" -extern PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args); #define psyco_TimestampFromPy_doc \ "TimestampFromPy(datetime.datetime) -> new wrapper" -extern PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args); #define psyco_IntervalFromPy_doc \ "IntervalFromPy(datetime.timedelta) -> new wrapper" diff --git a/psycopg/adapter_list.h b/psycopg/adapter_list.h index 9ffc52eb..9e7fb489 100644 --- a/psycopg/adapter_list.h +++ b/psycopg/adapter_list.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject listType; +extern HIDDEN PyTypeObject listType; typedef struct { PyObject_HEAD @@ -39,7 +41,7 @@ typedef struct { char *encoding; } listObject; -extern PyObject *psyco_List(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_List(PyObject *module, PyObject *args); #define psyco_List_doc \ "List(list, enc) -> new quoted list" diff --git a/psycopg/adapter_mxdatetime.h b/psycopg/adapter_mxdatetime.h index c8cc2d80..c43ab12c 100644 --- a/psycopg/adapter_mxdatetime.h +++ b/psycopg/adapter_mxdatetime.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject mxdatetimeType; +extern HIDDEN PyTypeObject mxdatetimeType; typedef struct { PyObject_HEAD @@ -46,45 +48,45 @@ typedef struct { /* functions exported to psycopgmodule.c */ #ifdef PSYCOPG_DEFAULT_MXDATETIME -extern PyObject *psyco_Date(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Date(PyObject *module, PyObject *args); #define psyco_Date_doc \ "Date(year, month, day) -> new date" -extern PyObject *psyco_Time(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Time(PyObject *module, PyObject *args); #define psyco_Time_doc \ "Time(hour, minutes, seconds) -> new time" -extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Timestamp(PyObject *module, PyObject *args); #define psyco_Timestamp_doc \ "Time(year, month, day, hour, minutes, seconds) -> new timestamp" -extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args); #define psyco_DateFromTicks_doc \ "DateFromTicks(ticks) -> new date" -extern PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args); #define psyco_TimeFromTicks_doc \ "TimeFromTicks(ticks) -> new time" -extern PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args); #define psyco_TimestampFromTicks_doc \ "TimestampFromTicks(ticks) -> new timestamp" #endif /* PSYCOPG_DEFAULT_MXDATETIME */ -extern PyObject *psyco_DateFromMx(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_DateFromMx(PyObject *module, PyObject *args); #define psyco_DateFromMx_doc \ "DateFromMx(mx) -> new date" -extern PyObject *psyco_TimeFromMx(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimeFromMx(PyObject *module, PyObject *args); #define psyco_TimeFromMx_doc \ "TimeFromMx(mx) -> new time" -extern PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args); #define psyco_TimestampFromMx_doc \ "TimestampFromMx(mx) -> new timestamp" -extern PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args); #define psyco_IntervalFromMx_doc \ "IntervalFromMx(mx) -> new interval" diff --git a/psycopg/adapter_pboolean.h b/psycopg/adapter_pboolean.h index 4349ddc4..31da6c08 100644 --- a/psycopg/adapter_pboolean.h +++ b/psycopg/adapter_pboolean.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject pbooleanType; +extern HIDDEN PyTypeObject pbooleanType; typedef struct { PyObject_HEAD @@ -41,7 +43,7 @@ typedef struct { /* functions exported to psycopgmodule.c */ -extern PyObject *psyco_Boolean(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_Boolean(PyObject *module, PyObject *args); #define psyco_Boolean_doc \ "Boolean(obj) -> new boolean value" diff --git a/psycopg/adapter_qstring.h b/psycopg/adapter_qstring.h index 572a2a58..aae56009 100644 --- a/psycopg/adapter_qstring.h +++ b/psycopg/adapter_qstring.h @@ -25,11 +25,13 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject qstringType; +extern HIDDEN PyTypeObject qstringType; typedef struct { PyObject_HEAD @@ -43,7 +45,7 @@ typedef struct { /* functions exported to psycopgmodule.c */ -extern PyObject *psyco_QuotedString(PyObject *module, PyObject *args); +HIDDEN PyObject *psyco_QuotedString(PyObject *module, PyObject *args); #define psyco_QuotedString_doc \ "QuotedString(str, enc) -> new quoted string" diff --git a/psycopg/config.h b/psycopg/config.h index eda2ea43..9c661ff9 100644 --- a/psycopg/config.h +++ b/psycopg/config.h @@ -22,9 +22,16 @@ #ifndef PSYCOPG_CONFIG_H #define PSYCOPG_CONFIG_H 1 +/* GCC 4.0 and later have support for specifying symbol visibility */ +#if __GNUC__ >= 4 +# define HIDDEN __attribute__((visibility("hidden"))) +#else +# define HIDDEN +#endif + /* debug printf-like function */ #ifdef PSYCOPG_DEBUG -extern int psycopg_debug_enabled; +extern HIDDEN int psycopg_debug_enabled; #endif #if defined( __GNUC__) && !defined(__APPLE__) diff --git a/psycopg/connection.h b/psycopg/connection.h index 068c7943..e4ef2f11 100644 --- a/psycopg/connection.h +++ b/psycopg/connection.h @@ -26,6 +26,8 @@ #include #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif @@ -39,7 +41,7 @@ extern "C" { /* Hard limit on the notices stored by the Python connection */ #define CONN_NOTICES_LIMIT 50 -extern PyTypeObject connectionType; +extern HIDDEN PyTypeObject connectionType; typedef struct { PyObject_HEAD @@ -76,12 +78,12 @@ typedef struct { } connectionObject; /* C-callable functions in connection_int.c and connection_ext.c */ -extern int conn_connect(connectionObject *self); -extern void conn_close(connectionObject *self); -extern int conn_commit(connectionObject *self); -extern int conn_rollback(connectionObject *self); -extern int conn_switch_isolation_level(connectionObject *self, int level); -extern int conn_set_client_encoding(connectionObject *self, char *enc); +HIDDEN int conn_connect(connectionObject *self); +HIDDEN void conn_close(connectionObject *self); +HIDDEN int conn_commit(connectionObject *self); +HIDDEN int conn_rollback(connectionObject *self); +HIDDEN int conn_switch_isolation_level(connectionObject *self, int level); +HIDDEN int conn_set_client_encoding(connectionObject *self, char *enc); /* exception-raising macros */ #define EXC_IF_CONN_CLOSED(self) if ((self)->closed > 0) { \ diff --git a/psycopg/cursor.h b/psycopg/cursor.h index d8af1e81..355dd275 100644 --- a/psycopg/cursor.h +++ b/psycopg/cursor.h @@ -26,13 +26,14 @@ #include #include +#include "psycopg/config.h" #include "psycopg/connection.h" #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject cursorType; +extern HIDDEN PyTypeObject cursorType; typedef struct { PyObject_HEAD @@ -80,7 +81,7 @@ typedef struct { } cursorObject; /* C-callable functions in cursor_int.c and cursor_ext.c */ -extern void curs_reset(cursorObject *self); +HIDDEN void curs_reset(cursorObject *self); /* exception-raising macros */ #define EXC_IF_CURS_CLOSED(self) \ diff --git a/psycopg/microprotocols.h b/psycopg/microprotocols.h index 1924df67..9418fdf2 100644 --- a/psycopg/microprotocols.h +++ b/psycopg/microprotocols.h @@ -24,6 +24,7 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" #include "psycopg/connection.h" #include "psycopg/cursor.h" @@ -33,7 +34,7 @@ extern "C" { /** adapters registry **/ -extern PyObject *psyco_adapters; +extern HIDDEN PyObject *psyco_adapters; /** the names of the three mandatory methods **/ @@ -44,16 +45,16 @@ extern PyObject *psyco_adapters; /** exported functions **/ /* used by module.c to init the microprotocols system */ -extern int microprotocols_init(PyObject *dict); -extern int microprotocols_add( +HIDDEN int microprotocols_init(PyObject *dict); +HIDDEN int microprotocols_add( PyTypeObject *type, PyObject *proto, PyObject *cast); -extern PyObject *microprotocols_adapt( +HIDDEN PyObject *microprotocols_adapt( PyObject *obj, PyObject *proto, PyObject *alt); -extern PyObject *microprotocol_getquoted( +HIDDEN PyObject *microprotocol_getquoted( PyObject *obj, connectionObject *conn); -extern PyObject * +HIDDEN PyObject * psyco_microprotocols_adapt(cursorObject *self, PyObject *args); #define psyco_microprotocols_adapt_doc \ "adapt(obj, protocol, alternate) -> object -- adapt obj to given protocol" diff --git a/psycopg/microprotocols_proto.h b/psycopg/microprotocols_proto.h index 45de4cc4..4f7e815d 100644 --- a/psycopg/microprotocols_proto.h +++ b/psycopg/microprotocols_proto.h @@ -26,11 +26,13 @@ #include #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif -extern PyTypeObject isqlquoteType; +extern HIDDEN PyTypeObject isqlquoteType; typedef struct { PyObject_HEAD diff --git a/psycopg/pqpath.h b/psycopg/pqpath.h index 9bb011c4..ee14fab4 100644 --- a/psycopg/pqpath.h +++ b/psycopg/pqpath.h @@ -22,6 +22,7 @@ #ifndef PSYCOPG_PQPATH_H #define PSYCOPG_PQPATH_H 1 +#include "psycopg/config.h" #include "psycopg/cursor.h" #include "psycopg/connection.h" @@ -30,20 +31,20 @@ #define CLEARPGRES(pgres) PQclear(pgres); pgres = NULL /* exported functions */ -extern int pq_fetch(cursorObject *curs); -extern int pq_execute(cursorObject *curs, const char *query, int async); -extern int pq_commit(connectionObject *conn); -extern int pq_abort_locked(connectionObject *conn, PGresult **pgres, +HIDDEN int pq_fetch(cursorObject *curs); +HIDDEN int pq_execute(cursorObject *curs, const char *query, int async); +HIDDEN int pq_commit(connectionObject *conn); +HIDDEN int pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error); -extern int pq_abort(connectionObject *conn); -extern int pq_is_busy(connectionObject *conn); +HIDDEN int pq_abort(connectionObject *conn); +HIDDEN int pq_is_busy(connectionObject *conn); -extern void pq_set_critical(connectionObject *conn, const char *msg); +HIDDEN void pq_set_critical(connectionObject *conn, const char *msg); -extern int pq_execute_command_locked(connectionObject *conn, +HIDDEN int pq_execute_command_locked(connectionObject *conn, const char *query, PGresult **pgres, char **error); -extern void pq_complete_error(connectionObject *conn, PGresult **pgres, +HIDDEN void pq_complete_error(connectionObject *conn, PGresult **pgres, char **error); #endif /* !defined(PSYCOPG_PQPATH_H) */ diff --git a/psycopg/psycopg.h b/psycopg/psycopg.h index e5eb70b9..6e166219 100644 --- a/psycopg/psycopg.h +++ b/psycopg/psycopg.h @@ -25,6 +25,8 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif @@ -77,12 +79,13 @@ extern "C" { #define PSYCOPG_API_pointers 2 #ifdef PSYCOPG_MODULE + /** This section is used when compiling psycopgmodule.c & co. **/ -extern psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO; -extern psyco_errors_set_RETURN psyco_errors_set psyco_errors_set_PROTO; +HIDDEN psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO; +HIDDEN psyco_errors_set_RETURN psyco_errors_set psyco_errors_set_PROTO; /* global excpetions */ -extern PyObject *Error, *Warning, *InterfaceError, *DatabaseError, +extern HIDDEN PyObject *Error, *Warning, *InterfaceError, *DatabaseError, *InternalError, *OperationalError, *ProgrammingError, *IntegrityError, *DataError, *NotSupportedError; #ifdef PSYCOPG_EXTENSIONS @@ -125,7 +128,7 @@ import_psycopg(void) #endif /* postgresql<->python encoding map */ -extern PyObject *psycoEncodings; +extern HIDDEN PyObject *psycoEncodings; typedef struct { char *pgenc; @@ -133,10 +136,10 @@ typedef struct { } encodingPair; /* the Decimal type, used by the DECIMAL typecaster */ -extern PyObject *psyco_GetDecimalType(void); +HIDDEN PyObject *psyco_GetDecimalType(void); /* some utility functions */ -extern void psyco_set_error(PyObject *exc, PyObject *curs, const char *msg, +HIDDEN void psyco_set_error(PyObject *exc, PyObject *curs, const char *msg, const char *pgerror, const char *pgcode); /* Exceptions docstrings */ diff --git a/psycopg/typecast.h b/psycopg/typecast.h index 162cd6a4..c64bc309 100644 --- a/psycopg/typecast.h +++ b/psycopg/typecast.h @@ -25,6 +25,8 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif @@ -34,7 +36,7 @@ typedef PyObject *(*typecast_function)(char *, Py_ssize_t len, PyObject *); /** typecast type **/ -extern PyTypeObject typecastType; +extern HIDDEN PyTypeObject typecastType; typedef struct { PyObject_HEAD @@ -59,28 +61,28 @@ typedef struct { } typecastObject_initlist; /* the type dictionary, much faster to access it globally */ -extern PyObject *psyco_types; -extern PyObject *psyco_binary_types; +extern HIDDEN PyObject *psyco_types; +extern HIDDEN PyObject *psyco_binary_types; /* the default casting objects, used when no other objects are available */ -extern PyObject *psyco_default_cast; -extern PyObject *psyco_default_binary_cast; +extern HIDDEN PyObject *psyco_default_cast; +extern HIDDEN PyObject *psyco_default_binary_cast; /** exported functions **/ /* used by module.c to init the type system and register types */ -extern int typecast_init(PyObject *dict); -extern int typecast_add(PyObject *obj, PyObject *dict, int binary); +HIDDEN int typecast_init(PyObject *dict); +HIDDEN int typecast_add(PyObject *obj, PyObject *dict, int binary); /* the C callable typecastObject creator function */ -extern PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d); +HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d); /* the python callable typecast creator function */ -extern PyObject *typecast_from_python( +HIDDEN PyObject *typecast_from_python( PyObject *self, PyObject *args, PyObject *keywds); /* the function used to dispatch typecasting calls */ -extern PyObject *typecast_cast( +HIDDEN PyObject *typecast_cast( PyObject *self, char *str, Py_ssize_t len, PyObject *curs); #endif /* !defined(PSYCOPG_TYPECAST_H) */ diff --git a/psycopg/typecast_binary.h b/psycopg/typecast_binary.h index fa026201..638a2f0b 100644 --- a/psycopg/typecast_binary.h +++ b/psycopg/typecast_binary.h @@ -25,13 +25,15 @@ #define PY_SSIZE_T_CLEAN #include +#include "psycopg/config.h" + #ifdef __cplusplus extern "C" { #endif /** chunk type **/ -extern PyTypeObject chunkType; +extern HIDDEN PyTypeObject chunkType; typedef struct { PyObject_HEAD