2828 static const char which_dbm [] = "GNU gdbm" ;
2929#elif defined(USE_NDBM )
3030 #include <ndbm.h>
31+ #ifdef _GDBM_H_
32+ /* ndbm.h is the GDBM compatibility interface. */
3133 static const char which_dbm [] = "GNU gdbm" ;
34+ #else
35+ static const char which_dbm [] = "ndbm" ;
36+ #endif
3237#elif defined(USE_BERKDB )
3338 #ifndef DB_DBM_HSEARCH
3439 #define DB_DBM_HSEARCH 1
@@ -628,6 +633,136 @@ static PyMethodDef dbmmodule_methods[] = {
628633 { 0 , 0 },
629634};
630635
636+ #if defined(GDBM_VERSION_MAJOR ) || defined(DB_VERSION_MAJOR )
637+ static PyStructSequence_Field version_info_fields [] = {
638+ {"major" , "Major release number" },
639+ {"minor" , "Minor release number" },
640+ {"patch" , "Patch release number" },
641+ {0 }
642+ };
643+
644+ static PyObject *
645+ make_version_info (PyTypeObject * type , int major , int minor , int patch )
646+ {
647+ PyObject * version ;
648+ int pos = 0 ;
649+
650+ version = PyStructSequence_New (type );
651+ if (version == NULL ) {
652+ return NULL ;
653+ }
654+
655+ #define SetItem (VALUE ) \
656+ PyStructSequence_SET_ITEM(version, pos++, VALUE); \
657+ if (PyErr_Occurred()) { \
658+ Py_DECREF(version); \
659+ return NULL; \
660+ }
661+
662+ SetItem (PyLong_FromLong (major ))
663+ SetItem (PyLong_FromLong (minor ))
664+ SetItem (PyLong_FromLong (patch ))
665+ #undef SetItem
666+
667+ return version ;
668+ }
669+ #endif
670+
671+ #if defined(GDBM_VERSION_MAJOR )
672+ PyDoc_STRVAR (gdbm_version_info__doc__ ,
673+ "_dbm.gdbm_version_info\n\
674+ \n\
675+ GDBM version information as a named tuple." );
676+
677+ static PyStructSequence_Desc gdbm_version_info_desc = {
678+ "_dbm.gdbm_version_info" , /* name */
679+ gdbm_version_info__doc__ , /* doc */
680+ version_info_fields , /* fields */
681+ 3
682+ };
683+
684+ static int
685+ add_version_constants (PyObject * module )
686+ {
687+ if (PyModule_AddStringConstant (module , "gdbm_version" , gdbm_version ) < 0 ) {
688+ return -1 ;
689+ }
690+ PyTypeObject * version_type ;
691+ version_type = PyStructSequence_NewType (& gdbm_version_info_desc );
692+ if (version_type == NULL ) {
693+ return -1 ;
694+ }
695+ if (PyModule_Add (module , "GDBM_VERSION_INFO" ,
696+ make_version_info (version_type , GDBM_VERSION_MAJOR ,
697+ GDBM_VERSION_MINOR , GDBM_VERSION_PATCH )) < 0 )
698+ {
699+ Py_DECREF (version_type );
700+ return -1 ;
701+ }
702+ if (PyModule_Add (module , "gdbm_version_info" ,
703+ make_version_info (version_type , gdbm_version_number [0 ],
704+ gdbm_version_number [1 ],
705+ gdbm_version_number [2 ])) < 0 )
706+ {
707+ Py_DECREF (version_type );
708+ return -1 ;
709+ }
710+ Py_DECREF (version_type );
711+ return 0 ;
712+ }
713+ #elif defined(DB_VERSION_MAJOR )
714+ PyDoc_STRVAR (bdb_version_info__doc__ ,
715+ "_dbm.bdb_version_info\n\
716+ \n\
717+ Berkeley DB version information as a named tuple." );
718+
719+ static PyStructSequence_Desc bdb_version_info_desc = {
720+ "_dbm.bdb_version_info" , /* name */
721+ bdb_version_info__doc__ , /* doc */
722+ version_info_fields , /* fields */
723+ 3
724+ };
725+
726+ static int
727+ add_version_constants (PyObject * module )
728+ {
729+ int major , minor , patch ;
730+ const char * version = db_version (& major , & minor , & patch );
731+ if (PyModule_AddStringConstant (module , "BDB_VERSION" , DB_VERSION_STRING ) < 0 ) {
732+ return -1 ;
733+ }
734+ if (PyModule_AddStringConstant (module , "bdb_version" , version ) < 0 ) {
735+ return -1 ;
736+ }
737+ PyTypeObject * version_type ;
738+ version_type = PyStructSequence_NewType (& bdb_version_info_desc );
739+ if (version_type == NULL ) {
740+ return -1 ;
741+ }
742+ if (PyModule_Add (module , "BDB_VERSION_INFO" ,
743+ make_version_info (version_type , DB_VERSION_MAJOR ,
744+ DB_VERSION_MINOR , DB_VERSION_PATCH )) < 0 )
745+ {
746+ Py_DECREF (version_type );
747+ return -1 ;
748+ }
749+ if (PyModule_Add (module , "bdb_version_info" ,
750+ make_version_info (version_type , major , minor , patch )) < 0 )
751+ {
752+ Py_DECREF (version_type );
753+ return -1 ;
754+ }
755+ Py_DECREF (version_type );
756+ return 0 ;
757+ }
758+ #else
759+ static int
760+ add_version_constants (PyObject * module )
761+ {
762+ return 0 ;
763+ }
764+ #endif
765+
631766static int
632767_dbm_exec (PyObject * module )
633768{
@@ -644,6 +779,9 @@ _dbm_exec(PyObject *module)
644779 if (PyModule_AddStringConstant (module , "library" , which_dbm ) < 0 ) {
645780 return -1 ;
646781 }
782+ if (add_version_constants (module ) < 0 ) {
783+ return -1 ;
784+ }
647785 if (PyModule_AddType (module , (PyTypeObject * )state -> dbm_error ) < 0 ) {
648786 return -1 ;
649787 }
0 commit comments