/* * mysqlStubInit.c -- * * Stubs tables for the foreign MySQL libraries so that * Tcl extensions can use them without the linker's knowing about them. * * @CREATED@ 2022-09-17 18:18:42Z by genExtStubs.tcl from ./generic/mysqlStubDefs.txt * * Copyright (c) 2010 by Kevin B. Kenny. * * Please refer to the file, 'license.terms' for the conditions on * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES. * *----------------------------------------------------------------------------- */ #include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #include #endif #include "fakemysql.h" /* * Static data used in this file */ /* * Names of the libraries that might contain the MySQL API */ #if defined(__CYGWIN__) && !defined(LIBPREFIX) # define LIBPREFIX "cyg" #else # define LIBPREFIX "lib" #endif static const char *const mysqlStubLibNames[] = { /* @LIBNAMES@: DO NOT EDIT THESE NAMES */ "mariadbclient", "mariadb", "mysqlclient_r", "mysqlclient", "mysql", NULL /* @END@ */ }; /* ABI Version numbers of the MySQL API that we can cope with */ static const char mysqlSuffixes[][4] = { "", ".3", ".21", ".20", ".19", ".18", ".17", ".16", ".15" }; /* Names of the functions that we need from MySQL */ static const char *const mysqlSymbolNames[] = { /* @SYMNAMES@: DO NOT EDIT THESE NAMES */ "mysql_server_init", "mysql_server_end", "mysql_affected_rows", "mysql_autocommit", "mysql_change_user", "mysql_close", "mysql_commit", "mysql_errno", "mysql_error", "mysql_fetch_fields", "mysql_fetch_lengths", "mysql_fetch_row", "mysql_field_count", "mysql_free_result", "mysql_get_client_version", "mysql_init", "mysql_list_fields", "mysql_list_tables", "mysql_num_fields", "mysql_options", "mysql_query", "mysql_real_connect", "mysql_rollback", "mysql_select_db", "mysql_sqlstate", "mysql_ssl_set", "mysql_stmt_affected_rows", "mysql_stmt_bind_param", "mysql_stmt_bind_result", "mysql_stmt_close", "mysql_stmt_errno", "mysql_stmt_error", "mysql_stmt_execute", "mysql_stmt_fetch", "mysql_stmt_fetch_column", "mysql_stmt_init", "mysql_stmt_prepare", "mysql_stmt_result_metadata", "mysql_stmt_sqlstate", "mysql_stmt_store_result", "mysql_store_result", NULL /* @END@ */ }; /* * Table containing pointers to the functions named above. */ static mysqlStubDefs mysqlStubsTable; const mysqlStubDefs* mysqlStubs = &mysqlStubsTable; /* *----------------------------------------------------------------------------- * * MysqlInitStubs -- * * Initialize the Stubs table for the MySQL API * * Results: * Returns the handle to the loaded MySQL client library, or NULL * if the load is unsuccessful. * * Leaves the name of the loaded client library in the interpreter if * successful. * * Leaves an error message in the interpreter on failure. * *----------------------------------------------------------------------------- */ MODULE_SCOPE Tcl_LoadHandle MysqlInitStubs(Tcl_Interp* interp) { int status; /* Status of Tcl library calls */ Tcl_Obj* path; /* Path name of a module to be loaded */ Tcl_Obj* shlibext; /* Extension to use for load modules */ Tcl_LoadHandle handle = NULL; /* Handle to a load module */ int i; size_t j; /* Determine the shared library extension */ status = Tcl_EvalEx(interp, "::info sharedlibextension", -1, TCL_EVAL_GLOBAL); if (status != TCL_OK) return NULL; shlibext = Tcl_GetObjResult(interp); Tcl_IncrRefCount(shlibext); /* Walk the list of possible library names to find an MySQL client */ status = TCL_ERROR; for (i = 0; status == TCL_ERROR && mysqlStubLibNames[i] != NULL; ++i) { for (j = 0; status == TCL_ERROR && (j < sizeof(mysqlSuffixes)/sizeof(mysqlSuffixes[0])); ++j) { path = Tcl_NewStringObj(LIBPREFIX, -1); Tcl_AppendToObj(path, mysqlStubLibNames[i], -1); #ifdef __CYGWIN__ if (*mysqlSuffixes[j]) { Tcl_AppendToObj(path, "-", -1); Tcl_AppendToObj(path, mysqlSuffixes[j]+1, -1); } #endif Tcl_AppendObjToObj(path, shlibext); #ifndef __CYGWIN__ Tcl_AppendToObj(path, mysqlSuffixes[j], -1); #endif Tcl_IncrRefCount(path); /* Try to load a client library and resolve symbols within it. */ Tcl_ResetResult(interp); status = Tcl_LoadFile(interp, path, mysqlSymbolNames, 0, &mysqlStubsTable, &handle); if (status != TCL_OK) { Tcl_DecrRefCount(path); } } } /* * Either we've successfully loaded a library (status == TCL_OK), * or we've run out of library names (in which case status==TCL_ERROR * and the error message reflects the last unsuccessful load attempt). */ Tcl_DecrRefCount(shlibext); if (status != TCL_OK) { return NULL; } Tcl_SetObjResult(interp, path); Tcl_DecrRefCount(path); return handle; }