?? util.c
字號(hào):
/*** 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: qt/util.c 3.3.4 edited Mar 30 2004 $*/#include "sqliteInt.h"#include <stdarg.h>#include <ctype.h>/*** If malloc() ever fails, this global variable gets set to 1.** This causes the library to abort and never again function.*/int sqlite_malloc_failed = 0;/*** If MEMORY_DEBUG is defined, then use versions of malloc() and** free() that track memory usage and check for buffer overruns.*/#ifdef MEMORY_DEBUG/*** For keeping track of the number of mallocs and frees. This** is used to check for memory leaks.*/int sqlite_nMalloc; /* Number of sqliteMalloc() calls */int sqlite_nFree; /* Number of sqliteFree() calls */int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */#if MEMORY_DEBUG>1static int memcnt = 0;#endif/*** Number of 32-bit guard words*/#define N_GUARD 1/*** Allocate new memory and set it to zero. Return NULL if** no memory is available.*/void *sqliteMalloc_(int n, int bZero, char *zFile, int line){ void *p; int *pi; int i, k; if( sqlite_iMallocFail>=0 ){ sqlite_iMallocFail--; if( sqlite_iMallocFail==0 ){ sqlite_malloc_failed++;#if MEMORY_DEBUG>1 fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n", n, zFile,line);#endif sqlite_iMallocFail--; return 0; } } if( n==0 ) return 0; k = (n+sizeof(int)-1)/sizeof(int); pi = malloc( (N_GUARD*2+1+k)*sizeof(int)); if( pi==0 ){ sqlite_malloc_failed++; return 0; } sqlite_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 MEMORY_DEBUG>1 fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n", ++memcnt, n, (int)p, zFile,line);#endif return p;}/*** 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 sqliteCheckMemory(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 sqliteFree_(void *p, char *zFile, int line){ if( p ){ int *pi, i, k, n; pi = p; pi -= N_GUARD+1; sqlite_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]; 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 MEMORY_DEBUG>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 *sqliteRealloc_(void *oldP, int n, char *zFile, int line){ int *oldPi, *pi, i, k, oldN, oldK; void *p; if( oldP==0 ){ return sqliteMalloc_(n,1,zFile,line); } if( n==0 ){ sqliteFree_(oldP,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]; 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 ){ sqlite_malloc_failed++; return 0; } for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122; pi[N_GUARD] = n; 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], 0, n-oldN); } memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int)); free(oldPi);#if MEMORY_DEBUG>1 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 duplicate of a string into memory obtained from malloc()** Free the original string using sqliteFree().**** This routine is called on all strings that are passed outside of** the SQLite library. That way clients can free the string using free()** rather than having to call sqliteFree().*/void sqliteStrRealloc(char **pz){ char *zNew; if( pz==0 || *pz==0 ) return; zNew = malloc( strlen(*pz) + 1 ); if( zNew==0 ){ sqlite_malloc_failed++; sqliteFree(*pz); *pz = 0; } strcpy(zNew, *pz); sqliteFree(*pz); *pz = zNew;}/*** Make a copy of a string in memory obtained from sqliteMalloc()*/char *sqliteStrDup_(const char *z, char *zFile, int line){ char *zNew; if( z==0 ) return 0; zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line); if( zNew ) strcpy(zNew, z); return zNew;}char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){ char *zNew; if( z==0 ) return 0; zNew = sqliteMalloc_(n+1, 0, zFile, line); if( zNew ){ memcpy(zNew, z, n); zNew[n] = 0; } return zNew;}#endif /* MEMORY_DEBUG *//*** The following versions of malloc() and free() are for use in a** normal build.*/#if !defined(MEMORY_DEBUG)/*** Allocate new memory and set it to zero. Return NULL if** no memory is available. See also sqliteMallocRaw().*/void *sqliteMalloc(int n){ void *p; if( (p = malloc(n))==0 ){ if( n>0 ) sqlite_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 *sqliteMallocRaw(int n){ void *p; if( (p = malloc(n))==0 ){ if( n>0 ) sqlite_malloc_failed++; } return p;}/*** Free memory previously obtained from sqliteMalloc()*/void sqliteFree(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 *sqliteRealloc(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 ){ sqlite_malloc_failed++; } return p2;}/*** Make a copy of a string in memory obtained from sqliteMalloc()*/char *sqliteStrDup(const char *z){ char *zNew; if( z==0 ) return 0; zNew = sqliteMallocRaw(strlen(z)+1); if( zNew ) strcpy(zNew, z); return zNew;}char *sqliteStrNDup(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(MEMORY_DEBUG) *//*** 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 sqliteSetString(char **pz, const char *zFirst, ...){ va_list ap; int nByte; const char *z; char *zResult; if( pz==0 ) return; nByte = strlen(zFirst) + 1; va_start(ap, zFirst); while( (z = va_arg(ap, const char*))!=0 ){ nByte += strlen(z); } va_end(ap); sqliteFree(*pz); *pz = zResult = sqliteMallocRaw( nByte ); if( zResult==0 ){ return; } strcpy(zResult, zFirst); zResult += strlen(zResult); va_start(ap, zFirst); while( (z = va_arg(ap, const char*))!=0 ){ strcpy(zResult, z); zResult += strlen(zResult); } va_end(ap);#ifdef MEMORY_DEBUG#if MEMORY_DEBUG>1 fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);#endif#endif}/*** Works like sqliteSetString, but each string is now followed by** a length integer which specifies how much of the source string ** to copy (in bytes). -1 means use the whole string. The 1st ** argument must either be NULL or point to memory obtained from ** sqliteMalloc().*/void sqliteSetNString(char **pz, ...){ va_list ap; int nByte; const char *z; char *zResult; int n;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -