]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experiments in making loadable extensions easier to program. The
authordrh <drh@noemail.net>
Thu, 18 Apr 2013 22:56:42 +0000 (22:56 +0000)
committerdrh <drh@noemail.net>
Thu, 18 Apr 2013 22:56:42 +0000 (22:56 +0000)
shared library filename tries various operating-system specific extensions
if the bare library name does not work.  And the entry point is derived
from the filename is the legacy entry point name "sqlite3_extension_init"
is not found.

FossilOrigin-Name: 6cfa1d73d79b9f0be8157f0a37c264dd95b031c8

manifest
manifest.uuid
src/loadext.c
src/sqlite.h.in

index e07c960b3c35b89fe930713d9faffdc968066a42..ed0d92dbadda49cbdadbf8a5c4e1ebb9c97d970a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sincorrect\scomment\s(a\scopy/paste\serror)\sin\sthe\smptester.\s\sNo\scode\nchanges.
-D 2013-04-18T20:33:41.233
+C Experiments\sin\smaking\sloadable\sextensions\seasier\sto\sprogram.\s\sThe\nshared\slibrary\sfilename\stries\svarious\soperating-system\sspecific\sextensions\nif\sthe\sbare\slibrary\sname\sdoes\snot\swork.\s\sAnd\sthe\sentry\spoint\sis\sderived\nfrom\sthe\sfilename\sis\sthe\slegacy\sentry\spoint\sname\s"sqlite3_extension_init"\nis\snot\sfound.
+D 2013-04-18T22:56:42.784
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 3dd3fcb87b70c78d99b2c8a03e44ec86d6ca9ce2
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -148,7 +148,7 @@ F src/insert.c f7cb141e8ce257cb6b15c497f09e4e23d6055599
 F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
-F src/loadext.c 1422eba4aa2b1fb5f7b3aef574752272477d21e2
+F src/loadext.c c48f7f3f170e502fe0cc20748e03c6e0b5a016c2
 F src/main.c de47c3e6b68f512b9e64ba2533ee4eecc9d501c1
 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
@@ -182,7 +182,7 @@ F src/resolve.c 10a1b332e3eb36e5d561085e18c58a8578cd7d73
 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
 F src/select.c 01540bcd3df3c8f1187158e77986028b1c667258
 F src/shell.c aca9d94653decd4496846dee0c7ba83eaf96a46d
-F src/sqlite.h.in 31442751f3a63a538777188b6dfe70aebed338ac
+F src/sqlite.h.in a291a999d28ebc16cd1fe7fdd010dfe5266ef767
 F src/sqlite3.rc fea433eb0a59f4c9393c8e6d76a6e2596b1fe0c0
 F src/sqlite3ext.h 7183ab832e23db0f934494f16928da127a571d75
 F src/sqliteInt.h 2a83cfec9963372b636b0cabd4b200c1f1074a99
@@ -1051,7 +1051,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 97894c2790eda7b5bce3cc79cb2a8ec2fde9b3ac
-P d0898fd76a54512894418e53ba28703e250c9ed3
-R 489ed5534c8ff7ba356053afa67de654
+P e94783f36ade43ef9d5b94db278622bcbce4179b
+R 5eb9b691174dd0ce00c815b019b68747
+T *branch * loadext
+T *sym-loadext *
+T -sym-trunk *
 U drh
-Z da35d51e74cda792a97ee9cf150ece03
+Z 1611e9ed5f0542b10fe5f2f8888ad81f
index 3b6aeacff2a6e70a7aeea90c582afcd839f45c9a..fc3b50454da79c71313d742a06dd8243b98579b6 100644 (file)
@@ -1 +1 @@
-e94783f36ade43ef9d5b94db278622bcbce4179b
\ No newline at end of file
+6cfa1d73d79b9f0be8157f0a37c264dd95b031c8
\ No newline at end of file
index 76450f2e8b01b32c4b517beef0b135acea6ac95e..cdcf6a93b8c40f914b94240ef14cb4a30a37eca1 100644 (file)
@@ -415,8 +415,23 @@ static int sqlite3LoadExtension(
   void *handle;
   int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   char *zErrmsg = 0;
+  const char *zEntry;
+  char *zAltEntry = 0;
   void **aHandle;
   int nMsg = 300 + sqlite3Strlen30(zFile);
+  int ii;
+
+  /* Shared library endings to try if zFile cannot be loaded as written */
+  static const char *azEndings[] = {
+#if SQLITE_OS_WIN
+     "dll"   
+#elif defined(__APPLE__)
+     "dylib"
+#else
+     "so"
+#endif
+  };
+
 
   if( pzErrMsg ) *pzErrMsg = 0;
 
@@ -433,11 +448,17 @@ static int sqlite3LoadExtension(
     return SQLITE_ERROR;
   }
 
-  if( zProc==0 ){
-    zProc = "sqlite3_extension_init";
-  }
+  zEntry = zProc ? zProc : "sqlite3_extension_init";
 
   handle = sqlite3OsDlOpen(pVfs, zFile);
+#if SQLITE_OS_UNIX || SQLITE_OS_WIN
+  for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
+    char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
+    if( zAltFile==0 ) return SQLITE_NOMEM;
+    handle = sqlite3OsDlOpen(pVfs, zAltFile);
+    sqlite3_free(zAltFile);
+  }
+#endif
   if( handle==0 ){
     if( pzErrMsg ){
       *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
@@ -450,20 +471,57 @@ static int sqlite3LoadExtension(
     return SQLITE_ERROR;
   }
   xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
-                   sqlite3OsDlSym(pVfs, handle, zProc);
+                   sqlite3OsDlSym(pVfs, handle, zEntry);
+
+  /* If no entry point was specified and the default legacy
+  ** entry point name "sqlite3_extension_init" was not found, then
+  ** construct an entry point name "sqlite3_X_init" where the X is
+  ** replaced by the lowercase value of every ASCII alphabetic 
+  ** character in the filename after the last "/" upto the first ".",
+  ** and eliding the first three characters if they are "lib".  
+  ** Examples:
+  **
+  **    /usr/local/lib/libExample5.4.3.so ==>  sqlite3_example_init
+  **    C:/lib/mathfuncs.dll              ==>  sqlite3_mathfuncs_init
+  */
+  if( xInit==0 && zProc==0 ){
+    int iFile, iEntry, c;
+    int ncFile = sqlite3Strlen30(zFile);
+    zAltEntry = sqlite3_malloc(ncFile+30);
+    if( zAltEntry==0 ){
+      sqlite3OsDlClose(pVfs, handle);
+      return SQLITE_NOMEM;
+    }
+    memcpy(zAltEntry, "sqlite3_", 8);
+    for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){}
+    iFile++;
+    if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3;
+    for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){
+      if( sqlite3Isalpha(c) ){
+        zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c];
+      }
+    }
+    memcpy(zAltEntry+iEntry, "_init", 6);
+    zEntry = zAltEntry;
+    xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
+                     sqlite3OsDlSym(pVfs, handle, zEntry);
+  }
   if( xInit==0 ){
     if( pzErrMsg ){
-      nMsg += sqlite3Strlen30(zProc);
+      nMsg += sqlite3Strlen30(zEntry);
       *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
       if( zErrmsg ){
         sqlite3_snprintf(nMsg, zErrmsg,
-            "no entry point [%s] in shared library [%s]", zProc,zFile);
+            "no entry point [%s] in shared library [%s]", zEntry, zFile);
         sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
       }
-      sqlite3OsDlClose(pVfs, handle);
     }
+    sqlite3OsDlClose(pVfs, handle);
+    sqlite3_free(zAltEntry);
     return SQLITE_ERROR;
-  }else if( xInit(db, &zErrmsg, &sqlite3Apis) ){
+  }
+  sqlite3_free(zAltEntry);
+  if( xInit(db, &zErrmsg, &sqlite3Apis) ){
     if( pzErrMsg ){
       *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg);
     }
index f4f02d3eac6d6f44d41985144316af1c1e2d0266..3c6291eebeb6d3bd6a40263c07f9abb046072a66 100644 (file)
@@ -5017,11 +5017,20 @@ int sqlite3_table_column_metadata(
 ** ^This interface loads an SQLite extension library from the named file.
 **
 ** ^The sqlite3_load_extension() interface attempts to load an
-** [SQLite extension] library contained in the file zFile.
+** [SQLite extension] library contained in the file zFile.  If
+** the file cannot be loaded directly, attempts are made to load
+** with various operating-system specific extensions added.
+** So for example, if "samplelib" cannot be loaded, then names like
+** "samplelib.so" or "samplelib.dylib" or "samplelib.dll" might
+** be tried also.
 **
 ** ^The entry point is zProc.
-** ^zProc may be 0, in which case the name of the entry point
-** defaults to "sqlite3_extension_init".
+** ^(zProc may be 0, in which case SQLite will try to come up with an
+** entry point name on its own.  It first tries "sqlite3_extension_init".
+** If that does not work, it constructs a name "sqlite3_X_init" where the
+** X is consists of the lower-case equivalent of all ASCII alphabetic
+** characters in the filename from the last "/" to the first following
+** "." and omitting any initial "lib".)^
 ** ^The sqlite3_load_extension() interface returns
 ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
 ** ^If an error occurs and pzErrMsg is not 0, then the