⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 调用sqlite开源数据的小程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code.  In place of** a legal notice, here is a blessing:****    May you do good and not evil.**    May you find forgiveness for yourself and forgive others.**    May you share freely, never taking more than you give.***************************************************************************** Utility functions used throughout sqlite.**** This file contains functions for allocating memory, comparing** strings, and stuff like that.**** $Id: util.c,v 1.146 2005/09/17 18:34:11 drh Exp $*/#include "sqliteInt.h"#include <stdarg.h>#include <ctype.h>#if SQLITE_MEMDEBUG>2 && defined(__GLIBC__)#include <execinfo.h>void print_stack_trace(){  void *bt[30];  int i;  int n = backtrace(bt, 30);  fprintf(stderr, "STACK: ");  for(i=0; i<n;i++){    fprintf(stderr, "%p ", bt[i]);  }  fprintf(stderr, "\n");}#else#define print_stack_trace()#endif/*** If malloc() ever fails, this global variable gets set to 1.** This causes the library to abort and never again function.*/int sqlite3_malloc_failed = 0;/*** If SQLITE_MEMDEBUG is defined, then use versions of malloc() and** free() that track memory usage and check for buffer overruns.*/#ifdef SQLITE_MEMDEBUG/*** For keeping track of the number of mallocs and frees.   This** is used to check for memory leaks.  The iMallocFail and iMallocReset** values are used to simulate malloc() failures during testing in ** order to verify that the library correctly handles an out-of-memory** condition.*/int sqlite3_nMalloc;         /* Number of sqliteMalloc() calls */int sqlite3_nFree;           /* Number of sqliteFree() calls */int sqlite3_memUsed;         /* Total memory obtained from malloc */int sqlite3_memMax;          /* Mem usage high-water mark */int sqlite3_iMallocFail;     /* Fail sqliteMalloc() after this many calls */int sqlite3_iMallocReset = -1; /* When iMallocFail reaches 0, set to this */#if SQLITE_MEMDEBUG>1static int memcnt = 0;#endif/*** Number of 32-bit guard words.  This should probably be a multiple of** 2 since on 64-bit machines we want the value returned by sqliteMalloc()** to be 8-byte aligned.*/#define N_GUARD 2/*** Check for a simulated memory allocation failure.  Return true if** the failure should be simulated.  Return false to proceed as normal.*/static int simulatedMallocFailure(int n, char *zFile, int line){  if( sqlite3_iMallocFail>=0 ){    sqlite3_iMallocFail--;    if( sqlite3_iMallocFail==0 ){      sqlite3_malloc_failed++;#if SQLITE_MEMDEBUG>1      fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",              n, zFile,line);#endif      sqlite3_iMallocFail = sqlite3_iMallocReset;      return 1;    }  }  return 0;}/*** Allocate new memory and set it to zero.  Return NULL if** no memory is available.*/void *sqlite3Malloc_(int n, int bZero, char *zFile, int line){  void *p;  int *pi;  int i, k;  if( n==0 ){    return 0;  }  if( simulatedMallocFailure(n, zFile, line) ){    return 0;  }  sqlite3_memUsed += n;  if( sqlite3_memMax<sqlite3_memUsed ) sqlite3_memMax = sqlite3_memUsed;  k = (n+sizeof(int)-1)/sizeof(int);  pi = malloc( (N_GUARD*2+1+k)*sizeof(int));  if( pi==0 ){    if( n>0 ) sqlite3_malloc_failed++;    return 0;  }  sqlite3_nMalloc++;  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;  pi[N_GUARD] = n;  for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;  p = &pi[N_GUARD+1];  memset(p, bZero==0, n);#if SQLITE_MEMDEBUG>1  print_stack_trace();  fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",      ++memcnt, n, (int)p, zFile,line);#endif  return p;}/*** This version of malloc is always a real function, never a macro*/void *sqlite3MallocX(int n){  return sqlite3Malloc_(n, 0, __FILE__, __LINE__);}/*** Check to see if the given pointer was obtained from sqliteMalloc()** and is able to hold at least N bytes.  Raise an exception if this** is not the case.**** This routine is used for testing purposes only.*/void sqlite3CheckMemory(void *p, int N){  int *pi = p;  int n, i, k;  pi -= N_GUARD+1;  for(i=0; i<N_GUARD; i++){    assert( pi[i]==0xdead1122 );  }  n = pi[N_GUARD];  assert( N>=0 && N<n );  k = (n+sizeof(int)-1)/sizeof(int);  for(i=0; i<N_GUARD; i++){    assert( pi[k+N_GUARD+1+i]==0xdead3344 );  }}/*** Free memory previously obtained from sqliteMalloc()*/void sqlite3Free_(void *p, char *zFile, int line){  if( p ){    int *pi, i, k, n;    pi = p;    pi -= N_GUARD+1;    sqlite3_nFree++;    for(i=0; i<N_GUARD; i++){      if( pi[i]!=0xdead1122 ){        fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);        return;      }    }    n = pi[N_GUARD];    sqlite3_memUsed -= n;    k = (n+sizeof(int)-1)/sizeof(int);    for(i=0; i<N_GUARD; i++){      if( pi[k+N_GUARD+1+i]!=0xdead3344 ){        fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);        return;      }    }    memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));#if SQLITE_MEMDEBUG>1    fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",         ++memcnt, n, (int)p, zFile,line);#endif    free(pi);  }}/*** Resize a prior allocation.  If p==0, then this routine** works just like sqliteMalloc().  If n==0, then this routine** works just like sqliteFree().*/void *sqlite3Realloc_(void *oldP, int n, char *zFile, int line){  int *oldPi, *pi, i, k, oldN, oldK;  void *p;  if( oldP==0 ){    return sqlite3Malloc_(n,1,zFile,line);  }  if( n==0 ){    sqlite3Free_(oldP,zFile,line);    return 0;  }  if( simulatedMallocFailure(n, zFile, line) ){    return 0;  }  oldPi = oldP;  oldPi -= N_GUARD+1;  if( oldPi[0]!=0xdead1122 ){    fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);    return 0;  }  oldN = oldPi[N_GUARD];  sqlite3_memUsed -= oldN;  oldK = (oldN+sizeof(int)-1)/sizeof(int);  for(i=0; i<N_GUARD; i++){    if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){      fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",              (int)oldP);      return 0;    }  }  k = (n + sizeof(int) - 1)/sizeof(int);  pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );  if( pi==0 ){    if( n>0 ) sqlite3_malloc_failed++;    return 0;  }  for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;  pi[N_GUARD] = n;  sqlite3_memUsed += n;  if( sqlite3_memMax<sqlite3_memUsed ) sqlite3_memMax = sqlite3_memUsed;  for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;  p = &pi[N_GUARD+1];  memcpy(p, oldP, n>oldN ? oldN : n);  if( n>oldN ){    memset(&((char*)p)[oldN], 0x55, n-oldN);  }  memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));  free(oldPi);#if SQLITE_MEMDEBUG>1  print_stack_trace();  fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",    ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);#endif  return p;}/*** Make a copy of a string in memory obtained from sqliteMalloc()*/char *sqlite3StrDup_(const char *z, char *zFile, int line){  char *zNew;  if( z==0 ) return 0;  zNew = sqlite3Malloc_(strlen(z)+1, 0, zFile, line);  if( zNew ) strcpy(zNew, z);  return zNew;}char *sqlite3StrNDup_(const char *z, int n, char *zFile, int line){  char *zNew;  if( z==0 ) return 0;  zNew = sqlite3Malloc_(n+1, 0, zFile, line);  if( zNew ){    memcpy(zNew, z, n);    zNew[n] = 0;  }  return zNew;}/*** A version of sqliteFree that is always a function, not a macro.*/void sqlite3FreeX(void *p){  sqliteFree(p);}#endif /* SQLITE_MEMDEBUG *//*** The following versions of malloc() and free() are for use in a** normal build.*/#if !defined(SQLITE_MEMDEBUG)/*** Allocate new memory and set it to zero.  Return NULL if** no memory is available.  See also sqliteMallocRaw().*/void *sqlite3Malloc(int n){  void *p;  if( n==0 ) return 0;  if( (p = malloc(n))==0 ){    if( n>0 ) sqlite3_malloc_failed++;  }else{    memset(p, 0, n);  }  return p;}/*** Allocate new memory but do not set it to zero.  Return NULL if** no memory is available.  See also sqliteMalloc().*/void *sqlite3MallocRaw(int n){  void *p;  if( n==0 ) return 0;  if( (p = malloc(n))==0 ){    if( n>0 ) sqlite3_malloc_failed++;  }  return p;}/*** Free memory previously obtained from sqliteMalloc()*/void sqlite3FreeX(void *p){  if( p ){    free(p);  }}/*** Resize a prior allocation.  If p==0, then this routine** works just like sqliteMalloc().  If n==0, then this routine** works just like sqliteFree().*/void *sqlite3Realloc(void *p, int n){  void *p2;  if( p==0 ){    return sqliteMalloc(n);  }  if( n==0 ){    sqliteFree(p);    return 0;  }  p2 = realloc(p, n);  if( p2==0 ){    if( n>0 ) sqlite3_malloc_failed++;  }  return p2;}/*** Make a copy of a string in memory obtained from sqliteMalloc()*/char *sqlite3StrDup(const char *z){  char *zNew;  if( z==0 ) return 0;  zNew = sqliteMallocRaw(strlen(z)+1);  if( zNew ) strcpy(zNew, z);  return zNew;}char *sqlite3StrNDup(const char *z, int n){  char *zNew;  if( z==0 ) return 0;  zNew = sqliteMallocRaw(n+1);  if( zNew ){    memcpy(zNew, z, n);    zNew[n] = 0;  }  return zNew;}#endif /* !defined(SQLITE_MEMDEBUG) *//*** Reallocate a buffer to a different size.  This is similar to** sqliteRealloc() except that if the allocation fails the buffer** is freed.*/void sqlite3ReallocOrFree(void **ppBuf, int newSize){  void *pNew = sqliteRealloc(*ppBuf, newSize);  if( pNew==0 ){    sqliteFree(*ppBuf);  }  *ppBuf = pNew;}/*** Create a string from the 2nd and subsequent arguments (up to the** first NULL argument), store the string in memory obtained from** sqliteMalloc() and make the pointer indicated by the 1st argument** point to that string.  The 1st argument must either be NULL or ** point to memory obtained from sqliteMalloc().*/void sqlite3SetString(char **pz, ...){  va_list ap;  int nByte;  const char *z;  char *zResult;  if( pz==0 ) return;  nByte = 1;  va_start(ap, pz);  while( (z = va_arg(ap, const char*))!=0 ){    nByte += strlen(z);  }  va_end(ap);  sqliteFree(*pz);  *pz = zResult = sqliteMallocRaw( nByte );  if( zResult==0 ){    return;  }  *zResult = 0;  va_start(ap, pz);  while( (z = va_arg(ap, const char*))!=0 ){    strcpy(zResult, z);    zResult += strlen(zResult);  }  va_end(ap);#ifdef SQLITE_MEMDEBUG#if SQLITE_MEMDEBUG>1  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);#endif#endif}/*** Set the most recent error code and error string for the sqlite** handle "db". The error code is set to "err_code".**** If it is not NULL, string zFormat specifies the format of the** error string in the style of the printf functions: The following** format characters are allowed:****      %s      Insert a string**      %z      A string that should be freed after use**      %d      Insert an integer**      %T      Insert a token**      %S      Insert the first element of a SrcList**** zFormat and any string tokens that follow it are assumed to be** encoded in UTF-8.**** To clear the most recent error for sqlite handle "db", sqlite3Error** should be called with err_code set to SQLITE_OK and zFormat set** to NULL.*/void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){  if( db && (db->pErr || (db->pErr = sqlite3ValueNew())) ){    db->errCode = err_code;    if( zFormat ){      char *z;      va_list ap;      va_start(ap, zFormat);      z = sqlite3VMPrintf(zFormat, ap);      va_end(ap);      sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, sqlite3FreeX);    }else{      sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);    }  }}/*** Add an error message to pParse->zErrMsg and increment pParse->nErr.** The following formatting characters are allowed:****      %s      Insert a string**      %z      A string that should be freed after use**      %d      Insert an integer**      %T      Insert a token**      %S      Insert the first element of a SrcList**** This function should be used to report any error that occurs whilst** compiling an SQL statement (i.e. within sqlite3_prepare()). The** last thing the sqlite3_prepare() function does is copy the error** stored by this function into the database handle using sqlite3Error().** Function sqlite3Error() should be used during statement execution** (sqlite3_step() etc.).*/void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){  va_list ap;  pParse->nErr++;  sqliteFree(pParse->zErrMsg);  va_start(ap, zFormat);  pParse->zErrMsg = sqlite3VMPrintf(zFormat, ap);  va_end(ap);}/*** Convert an SQL-style quoted string into a normal string by removing** the quote characters.  The conversion is done in-place.  If the** input does not begin with a quote character, then this routine** is a no-op.**** 2002-Feb-14: This routine is extended to remove MS-Access style** brackets from around identifers.  For example:  "[a-b-c]" becomes** "a-b-c".*/void sqlite3Dequote(char *z){  int quote;  int i, j;  if( z==0 ) return;  quote = z[0];  switch( quote ){    case '\'':  break;    case '"':   break;    case '`':   break;                /* For MySQL compatibility */    case '[':   quote = ']';  break;  /* For MS SqlServer compatibility */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -