From: SVN Migration Date: Fri, 6 Jun 2003 11:09:56 +0000 (+0000) Subject: This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. X-Git-Tag: php-4.3.3RC1~85 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5e852417dda6caa72cd9bdcae7300e36db078228;p=php This commit was manufactured by cvs2svn to create branch 'PHP_4_3'. --- diff --git a/ext/sqlite/libsqlite/src/opcodes.c b/ext/sqlite/libsqlite/src/opcodes.c new file mode 100644 index 0000000000..1363a0fa31 --- /dev/null +++ b/ext/sqlite/libsqlite/src/opcodes.c @@ -0,0 +1,131 @@ +/* Automatically generated file. Do not edit */ +char *sqliteOpcodeNames[] = { "???", + "Goto", + "Gosub", + "Return", + "Halt", + "Integer", + "String", + "Pop", + "Dup", + "Pull", + "Push", + "ColumnName", + "Callback", + "NullCallback", + "Concat", + "Add", + "Subtract", + "Multiply", + "Divide", + "Remainder", + "Function", + "BitAnd", + "BitOr", + "ShiftLeft", + "ShiftRight", + "AddImm", + "MustBeInt", + "Eq", + "Ne", + "Lt", + "Le", + "Gt", + "Ge", + "StrEq", + "StrNe", + "StrLt", + "StrLe", + "StrGt", + "StrGe", + "And", + "Or", + "Negative", + "AbsValue", + "Not", + "BitNot", + "Noop", + "If", + "IfNot", + "IsNull", + "NotNull", + "MakeRecord", + "MakeIdxKey", + "MakeKey", + "IncrKey", + "Checkpoint", + "Transaction", + "Commit", + "Rollback", + "ReadCookie", + "SetCookie", + "VerifyCookie", + "OpenRead", + "OpenWrite", + "OpenTemp", + "OpenPseudo", + "Close", + "MoveLt", + "MoveTo", + "Distinct", + "NotFound", + "Found", + "IsUnique", + "NotExists", + "NewRecno", + "PutIntKey", + "PutStrKey", + "Delete", + "KeyAsData", + "RowData", + "Column", + "Recno", + "FullKey", + "NullRow", + "Last", + "Rewind", + "Prev", + "Next", + "IdxPut", + "IdxDelete", + "IdxRecno", + "IdxLT", + "IdxGT", + "IdxGE", + "Destroy", + "Clear", + "CreateIndex", + "CreateTable", + "IntegrityCk", + "ListWrite", + "ListRewind", + "ListRead", + "ListReset", + "ListPush", + "ListPop", + "SortPut", + "SortMakeRec", + "SortMakeKey", + "Sort", + "SortNext", + "SortCallback", + "SortReset", + "FileOpen", + "FileRead", + "FileColumn", + "MemStore", + "MemLoad", + "MemIncr", + "AggReset", + "AggInit", + "AggFunc", + "AggFocus", + "AggSet", + "AggGet", + "AggNext", + "SetInsert", + "SetFound", + "SetNotFound", + "SetFirst", + "SetNext", +}; diff --git a/ext/sqlite/libsqlite/src/opcodes.h b/ext/sqlite/libsqlite/src/opcodes.h new file mode 100644 index 0000000000..ccd7da4ae3 --- /dev/null +++ b/ext/sqlite/libsqlite/src/opcodes.h @@ -0,0 +1,129 @@ +/* Automatically generated file. Do not edit */ +#define OP_Goto 1 +#define OP_Gosub 2 +#define OP_Return 3 +#define OP_Halt 4 +#define OP_Integer 5 +#define OP_String 6 +#define OP_Pop 7 +#define OP_Dup 8 +#define OP_Pull 9 +#define OP_Push 10 +#define OP_ColumnName 11 +#define OP_Callback 12 +#define OP_NullCallback 13 +#define OP_Concat 14 +#define OP_Add 15 +#define OP_Subtract 16 +#define OP_Multiply 17 +#define OP_Divide 18 +#define OP_Remainder 19 +#define OP_Function 20 +#define OP_BitAnd 21 +#define OP_BitOr 22 +#define OP_ShiftLeft 23 +#define OP_ShiftRight 24 +#define OP_AddImm 25 +#define OP_MustBeInt 26 +#define OP_Eq 27 +#define OP_Ne 28 +#define OP_Lt 29 +#define OP_Le 30 +#define OP_Gt 31 +#define OP_Ge 32 +#define OP_StrEq 33 +#define OP_StrNe 34 +#define OP_StrLt 35 +#define OP_StrLe 36 +#define OP_StrGt 37 +#define OP_StrGe 38 +#define OP_And 39 +#define OP_Or 40 +#define OP_Negative 41 +#define OP_AbsValue 42 +#define OP_Not 43 +#define OP_BitNot 44 +#define OP_Noop 45 +#define OP_If 46 +#define OP_IfNot 47 +#define OP_IsNull 48 +#define OP_NotNull 49 +#define OP_MakeRecord 50 +#define OP_MakeIdxKey 51 +#define OP_MakeKey 52 +#define OP_IncrKey 53 +#define OP_Checkpoint 54 +#define OP_Transaction 55 +#define OP_Commit 56 +#define OP_Rollback 57 +#define OP_ReadCookie 58 +#define OP_SetCookie 59 +#define OP_VerifyCookie 60 +#define OP_OpenRead 61 +#define OP_OpenWrite 62 +#define OP_OpenTemp 63 +#define OP_OpenPseudo 64 +#define OP_Close 65 +#define OP_MoveLt 66 +#define OP_MoveTo 67 +#define OP_Distinct 68 +#define OP_NotFound 69 +#define OP_Found 70 +#define OP_IsUnique 71 +#define OP_NotExists 72 +#define OP_NewRecno 73 +#define OP_PutIntKey 74 +#define OP_PutStrKey 75 +#define OP_Delete 76 +#define OP_KeyAsData 77 +#define OP_RowData 78 +#define OP_Column 79 +#define OP_Recno 80 +#define OP_FullKey 81 +#define OP_NullRow 82 +#define OP_Last 83 +#define OP_Rewind 84 +#define OP_Prev 85 +#define OP_Next 86 +#define OP_IdxPut 87 +#define OP_IdxDelete 88 +#define OP_IdxRecno 89 +#define OP_IdxLT 90 +#define OP_IdxGT 91 +#define OP_IdxGE 92 +#define OP_Destroy 93 +#define OP_Clear 94 +#define OP_CreateIndex 95 +#define OP_CreateTable 96 +#define OP_IntegrityCk 97 +#define OP_ListWrite 98 +#define OP_ListRewind 99 +#define OP_ListRead 100 +#define OP_ListReset 101 +#define OP_ListPush 102 +#define OP_ListPop 103 +#define OP_SortPut 104 +#define OP_SortMakeRec 105 +#define OP_SortMakeKey 106 +#define OP_Sort 107 +#define OP_SortNext 108 +#define OP_SortCallback 109 +#define OP_SortReset 110 +#define OP_FileOpen 111 +#define OP_FileRead 112 +#define OP_FileColumn 113 +#define OP_MemStore 114 +#define OP_MemLoad 115 +#define OP_MemIncr 116 +#define OP_AggReset 117 +#define OP_AggInit 118 +#define OP_AggFunc 119 +#define OP_AggFocus 120 +#define OP_AggSet 121 +#define OP_AggGet 122 +#define OP_AggNext 123 +#define OP_SetInsert 124 +#define OP_SetFound 125 +#define OP_SetNotFound 126 +#define OP_SetFirst 127 +#define OP_SetNext 128 diff --git a/ext/sqlite/libsqlite/src/os.h b/ext/sqlite/libsqlite/src/os.h new file mode 100644 index 0000000000..d7674267d7 --- /dev/null +++ b/ext/sqlite/libsqlite/src/os.h @@ -0,0 +1,178 @@ +/* +** 2001 September 16 +** +** 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. +** +****************************************************************************** +** +** This header file (together with is companion C source-code file +** "os.c") attempt to abstract the underlying operating system so that +** the SQLite library will work on both POSIX and windows systems. +*/ +#ifndef _SQLITE_OS_H_ +#define _SQLITE_OS_H_ + +/* +** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE +** to the compiler command line. +*/ + +/* +** These #defines should enable >2GB file support on Posix if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: RedHat 7.2) but you want your code to work +** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in RedHat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for MacOS. LFS is only supported on MacOS 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# define _FILE_OFFSET_BITS 64 +# define _LARGEFILE_SOURCE 1 +#endif + +/* +** Temporary files are named starting with this prefix followed by 16 random +** alphanumeric characters, and no file extension. They are stored in the +** OS's standard temporary file directory, and are deleted prior to exit. +** If sqlite is being embedded in another program, you may wish to change the +** prefix to reflect your program's name, so that if your program exits +** prematurely, old temporary files can be easily identified. This can be done +** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line. +*/ +#ifndef TEMP_FILE_PREFIX +# define TEMP_FILE_PREFIX "sqlite_" +#endif + +/* +** Figure out if we are dealing with Unix, Windows or MacOS. +** +** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix. +** The MacOS build is designed to use CodeWarrior (tested with v8) +*/ +#ifndef OS_UNIX +# ifndef OS_WIN +# ifndef OS_MAC +# if defined(__MACOS__) +# define OS_MAC 1 +# define OS_WIN 0 +# define OS_UNIX 0 +# elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__) +# define OS_MAC 0 +# define OS_WIN 1 +# define OS_UNIX 0 +# else +# define OS_MAC 0 +# define OS_WIN 0 +# define OS_UNIX 1 +# endif +# else +# define OS_WIN 0 +# define OS_UNIX 0 +# endif +# else +# define OS_MAC 0 +# define OS_UNIX 0 +# endif +#else +# define OS_MAC 0 +# define OS_WIN 0 +#endif + +/* +** A handle for an open file is stored in an OsFile object. +*/ +#if OS_UNIX +# include +# include +# include +# include + typedef struct OsFile OsFile; + struct OsFile { + struct lockInfo *pLock; /* Information about locks on this inode */ + int fd; /* The file descriptor */ + int locked; /* True if this user holds the lock */ + }; +# define SQLITE_TEMPNAME_SIZE 200 +# if defined(HAVE_USLEEP) && HAVE_USLEEP +# define SQLITE_MIN_SLEEP_MS 1 +# else +# define SQLITE_MIN_SLEEP_MS 1000 +# endif +#endif + +#if OS_WIN +#include +#include + typedef struct OsFile OsFile; + struct OsFile { + HANDLE h; /* Handle for accessing the file */ + int locked; /* 0: unlocked, <0: write lock, >0: read lock */ + }; +# if defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 off_t; +# else + typedef long long off_t; +# endif +# define SQLITE_TEMPNAME_SIZE (MAX_PATH+50) +# define SQLITE_MIN_SLEEP_MS 1 +#endif + +#if OS_MAC +# include +# include + typedef struct OsFile OsFile; + struct OsFile { + SInt16 refNum; /* Data fork/file reference number */ + SInt16 refNumRF; /* Resource fork reference number (for locking) */ + int locked; /* 0: unlocked, <0: write lock, >0: read lock */ + int delOnClose; /* True if file is to be deleted on close */ + char *pathToDel; /* Name of file to delete on close */ + }; +# ifdef _LARGE_FILE + typedef SInt64 off_t; +# else + typedef SInt32 off_t; +# endif +# define SQLITE_TEMPNAME_SIZE _MAX_PATH +# define SQLITE_MIN_SLEEP_MS 17 +#endif + +int sqliteOsDelete(const char*); +int sqliteOsFileExists(const char*); +int sqliteOsFileRename(const char*, const char*); +int sqliteOsOpenReadWrite(const char*, OsFile*, int*); +int sqliteOsOpenExclusive(const char*, OsFile*, int); +int sqliteOsOpenReadOnly(const char*, OsFile*); +int sqliteOsTempFileName(char*); +int sqliteOsClose(OsFile*); +int sqliteOsRead(OsFile*, void*, int amt); +int sqliteOsWrite(OsFile*, const void*, int amt); +int sqliteOsSeek(OsFile*, off_t offset); +int sqliteOsSync(OsFile*); +int sqliteOsTruncate(OsFile*, off_t size); +int sqliteOsFileSize(OsFile*, off_t *pSize); +int sqliteOsReadLock(OsFile*); +int sqliteOsWriteLock(OsFile*); +int sqliteOsUnlock(OsFile*); +int sqliteOsRandomSeed(char*); +int sqliteOsSleep(int ms); +void sqliteOsEnterMutex(void); +void sqliteOsLeaveMutex(void); +char *sqliteOsFullPathname(const char*); + + + +#endif /* _SQLITE_OS_H_ */ diff --git a/ext/sqlite/libsqlite/src/parse.h b/ext/sqlite/libsqlite/src/parse.h new file mode 100644 index 0000000000..aba9766596 --- /dev/null +++ b/ext/sqlite/libsqlite/src/parse.h @@ -0,0 +1,130 @@ +#define TK_ABORT 1 +#define TK_AFTER 2 +#define TK_AGG_FUNCTION 3 +#define TK_ALL 4 +#define TK_AND 5 +#define TK_AS 6 +#define TK_ASC 7 +#define TK_ATTACH 8 +#define TK_BEFORE 9 +#define TK_BEGIN 10 +#define TK_BETWEEN 11 +#define TK_BITAND 12 +#define TK_BITNOT 13 +#define TK_BITOR 14 +#define TK_BY 15 +#define TK_CASCADE 16 +#define TK_CASE 17 +#define TK_CHECK 18 +#define TK_CLUSTER 19 +#define TK_COLLATE 20 +#define TK_COLUMN 21 +#define TK_COMMA 22 +#define TK_COMMENT 23 +#define TK_COMMIT 24 +#define TK_CONCAT 25 +#define TK_CONFLICT 26 +#define TK_CONSTRAINT 27 +#define TK_COPY 28 +#define TK_CREATE 29 +#define TK_DATABASE 30 +#define TK_DEFAULT 31 +#define TK_DEFERRABLE 32 +#define TK_DEFERRED 33 +#define TK_DELETE 34 +#define TK_DELIMITERS 35 +#define TK_DESC 36 +#define TK_DETACH 37 +#define TK_DISTINCT 38 +#define TK_DOT 39 +#define TK_DROP 40 +#define TK_EACH 41 +#define TK_ELSE 42 +#define TK_END 43 +#define TK_END_OF_FILE 44 +#define TK_EQ 45 +#define TK_EXCEPT 46 +#define TK_EXPLAIN 47 +#define TK_FAIL 48 +#define TK_FLOAT 49 +#define TK_FOR 50 +#define TK_FOREIGN 51 +#define TK_FROM 52 +#define TK_FUNCTION 53 +#define TK_GE 54 +#define TK_GLOB 55 +#define TK_GROUP 56 +#define TK_GT 57 +#define TK_HAVING 58 +#define TK_ID 59 +#define TK_IGNORE 60 +#define TK_ILLEGAL 61 +#define TK_IMMEDIATE 62 +#define TK_IN 63 +#define TK_INDEX 64 +#define TK_INITIALLY 65 +#define TK_INSERT 66 +#define TK_INSTEAD 67 +#define TK_INTEGER 68 +#define TK_INTERSECT 69 +#define TK_INTO 70 +#define TK_IS 71 +#define TK_ISNULL 72 +#define TK_JOIN 73 +#define TK_JOIN_KW 74 +#define TK_KEY 75 +#define TK_LE 76 +#define TK_LIKE 77 +#define TK_LIMIT 78 +#define TK_LP 79 +#define TK_LSHIFT 80 +#define TK_LT 81 +#define TK_MATCH 82 +#define TK_MINUS 83 +#define TK_NE 84 +#define TK_NOT 85 +#define TK_NOTNULL 86 +#define TK_NULL 87 +#define TK_OF 88 +#define TK_OFFSET 89 +#define TK_ON 90 +#define TK_OR 91 +#define TK_ORACLE_OUTER_JOIN 92 +#define TK_ORDER 93 +#define TK_PLUS 94 +#define TK_PRAGMA 95 +#define TK_PRIMARY 96 +#define TK_RAISE 97 +#define TK_REFERENCES 98 +#define TK_REM 99 +#define TK_REPLACE 100 +#define TK_RESTRICT 101 +#define TK_ROLLBACK 102 +#define TK_ROW 103 +#define TK_RP 104 +#define TK_RSHIFT 105 +#define TK_SELECT 106 +#define TK_SEMI 107 +#define TK_SET 108 +#define TK_SLASH 109 +#define TK_SPACE 110 +#define TK_STAR 111 +#define TK_STATEMENT 112 +#define TK_STRING 113 +#define TK_TABLE 114 +#define TK_TEMP 115 +#define TK_THEN 116 +#define TK_TRANSACTION 117 +#define TK_TRIGGER 118 +#define TK_UMINUS 119 +#define TK_UNCLOSED_STRING 120 +#define TK_UNION 121 +#define TK_UNIQUE 122 +#define TK_UPDATE 123 +#define TK_UPLUS 124 +#define TK_USING 125 +#define TK_VACUUM 126 +#define TK_VALUES 127 +#define TK_VIEW 128 +#define TK_WHEN 129 +#define TK_WHERE 130 diff --git a/ext/sqlite/libsqlite/src/printf.c b/ext/sqlite/libsqlite/src/printf.c new file mode 100644 index 0000000000..8587f80d28 --- /dev/null +++ b/ext/sqlite/libsqlite/src/printf.c @@ -0,0 +1,823 @@ +/* +** The "printf" code that follows dates from the 1980's. It is in +** the public domain. The original comments are included here for +** completeness. They are slightly out-of-date. +** +** The following modules is an enhanced replacement for the "printf" subroutines +** found in the standard C library. The following enhancements are +** supported: +** +** + Additional functions. The standard set of "printf" functions +** includes printf, fprintf, sprintf, vprintf, vfprintf, and +** vsprintf. This module adds the following: +** +** * snprintf -- Works like sprintf, but has an extra argument +** which is the size of the buffer written to. +** +** * mprintf -- Similar to sprintf. Writes output to memory +** obtained from malloc. +** +** * xprintf -- Calls a function to dispose of output. +** +** * nprintf -- No output, but returns the number of characters +** that would have been output by printf. +** +** * A v- version (ex: vsnprintf) of every function is also +** supplied. +** +** + A few extensions to the formatting notation are supported: +** +** * The "=" flag (similar to "-") causes the output to be +** be centered in the appropriately sized field. +** +** * The %b field outputs an integer in binary notation. +** +** * The %c field now accepts a precision. The character output +** is repeated by the number of times the precision specifies. +** +** * The %' field works like %c, but takes as its character the +** next character of the format string, instead of the next +** argument. For example, printf("%.78'-") prints 78 minus +** signs, the same as printf("%.78c",'-'). +** +** + When compiled using GCC on a SPARC, this version of printf is +** faster than the library printf for SUN OS 4.1. +** +** + All functions are fully reentrant. +** +*/ +#include "sqliteInt.h" + +/* +** Undefine COMPATIBILITY to make some slight changes in the way things +** work. I think the changes are an improvement, but they are not +** backwards compatible. +*/ +/* #define COMPATIBILITY / * Compatible with SUN OS 4.1 */ + +/* +** Conversion types fall into various categories as defined by the +** following enumeration. +*/ +enum et_type { /* The type of the format field */ + etRADIX, /* Integer types. %d, %x, %o, and so forth */ + etFLOAT, /* Floating point. %f */ + etEXP, /* Exponentional notation. %e and %E */ + etGENERIC, /* Floating or exponential, depending on exponent. %g */ + etSIZE, /* Return number of characters processed so far. %n */ + etSTRING, /* Strings. %s */ + etPERCENT, /* Percent symbol. %% */ + etCHARX, /* Characters. %c */ + etERROR, /* Used to indicate no such conversion type */ +/* The rest are extensions, not normally found in printf() */ + etCHARLIT, /* Literal characters. %' */ + etSQLESCAPE, /* Strings with '\'' doubled. %q */ + etSQLESCAPE2, /* Strings with '\'' doubled and enclosed in '', + NULL pointers replaced by SQL NULL. %Q */ + etORDINAL /* 1st, 2nd, 3rd and so forth */ +}; + +/* +** Each builtin conversion character (ex: the 'd' in "%d") is described +** by an instance of the following structure +*/ +typedef struct et_info { /* Information about each format field */ + int fmttype; /* The format field code letter */ + int base; /* The base for radix conversion */ + char *charset; /* The character set for conversion */ + int flag_signed; /* Is the quantity signed? */ + char *prefix; /* Prefix on non-zero values in alt format */ + enum et_type type; /* Conversion paradigm */ +} et_info; + +/* +** The following table is searched linearly, so it is good to put the +** most frequently used conversion types first. +*/ +static et_info fmtinfo[] = { + { 'd', 10, "0123456789", 1, 0, etRADIX, }, + { 's', 0, 0, 0, 0, etSTRING, }, + { 'q', 0, 0, 0, 0, etSQLESCAPE, }, + { 'Q', 0, 0, 0, 0, etSQLESCAPE2, }, + { 'c', 0, 0, 0, 0, etCHARX, }, + { 'o', 8, "01234567", 0, "0", etRADIX, }, + { 'u', 10, "0123456789", 0, 0, etRADIX, }, + { 'x', 16, "0123456789abcdef", 0, "x0", etRADIX, }, + { 'X', 16, "0123456789ABCDEF", 0, "X0", etRADIX, }, + { 'r', 10, "0123456789", 0, 0, etORDINAL, }, + { 'f', 0, 0, 1, 0, etFLOAT, }, + { 'e', 0, "e", 1, 0, etEXP, }, + { 'E', 0, "E", 1, 0, etEXP, }, + { 'g', 0, "e", 1, 0, etGENERIC, }, + { 'G', 0, "E", 1, 0, etGENERIC, }, + { 'i', 10, "0123456789", 1, 0, etRADIX, }, + { 'n', 0, 0, 0, 0, etSIZE, }, + { '%', 0, 0, 0, 0, etPERCENT, }, + { 'b', 2, "01", 0, "b0", etRADIX, }, /* Binary */ + { 'p', 10, "0123456789", 0, 0, etRADIX, }, /* Pointers */ + { '\'', 0, 0, 0, 0, etCHARLIT, }, /* Literal char */ +}; +#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0])) + +/* +** If NOFLOATINGPOINT is defined, then none of the floating point +** conversions will work. +*/ +#ifndef etNOFLOATINGPOINT +/* +** "*val" is a double such that 0.1 <= *val < 10.0 +** Return the ascii code for the leading digit of *val, then +** multiply "*val" by 10.0 to renormalize. +** +** Example: +** input: *val = 3.14159 +** output: *val = 1.4159 function return = '3' +** +** The counter *cnt is incremented each time. After counter exceeds +** 16 (the number of significant digits in a 64-bit float) '0' is +** always returned. +*/ +static int et_getdigit(double *val, int *cnt){ + int digit; + double d; + if( (*cnt)++ >= 16 ) return '0'; + digit = (int)*val; + d = digit; + digit += '0'; + *val = (*val - d)*10.0; + return digit; +} +#endif + +#define etBUFSIZE 1000 /* Size of the output buffer */ + +/* +** The root program. All variations call this core. +** +** INPUTS: +** func This is a pointer to a function taking three arguments +** 1. A pointer to anything. Same as the "arg" parameter. +** 2. A pointer to the list of characters to be output +** (Note, this list is NOT null terminated.) +** 3. An integer number of characters to be output. +** (Note: This number might be zero.) +** +** arg This is the pointer to anything which will be passed as the +** first argument to "func". Use it for whatever you like. +** +** fmt This is the format string, as in the usual print. +** +** ap This is a pointer to a list of arguments. Same as in +** vfprint. +** +** OUTPUTS: +** The return value is the total number of characters sent to +** the function "func". Returns -1 on a error. +** +** Note that the order in which automatic variables are declared below +** seems to make a big difference in determining how fast this beast +** will run. +*/ +static int vxprintf( + void (*func)(void*,char*,int), + void *arg, + const char *format, + va_list ap +){ + register const char *fmt; /* The format string. */ + register int c; /* Next character in the format string */ + register char *bufpt; /* Pointer to the conversion buffer */ + register int precision; /* Precision of the current field */ + register int length; /* Length of the field */ + register int idx; /* A general purpose loop counter */ + int count; /* Total number of characters output */ + int width; /* Width of the current field */ + int flag_leftjustify; /* True if "-" flag is present */ + int flag_plussign; /* True if "+" flag is present */ + int flag_blanksign; /* True if " " flag is present */ + int flag_alternateform; /* True if "#" flag is present */ + int flag_zeropad; /* True if field width constant starts with zero */ + int flag_long; /* True if "l" flag is present */ + int flag_center; /* True if "=" flag is present */ + unsigned long longvalue; /* Value for integer types */ + double realvalue; /* Value for real types */ + et_info *infop; /* Pointer to the appropriate info structure */ + char buf[etBUFSIZE]; /* Conversion buffer */ + char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ + int errorflag = 0; /* True if an error is encountered */ + enum et_type xtype; /* Conversion paradigm */ + char *zExtra; /* Extra memory used for etTCLESCAPE conversions */ + static char spaces[] = " " + " "; +#define etSPACESIZE (sizeof(spaces)-1) +#ifndef etNOFLOATINGPOINT + int exp; /* exponent of real numbers */ + double rounder; /* Used for rounding floating point values */ + int flag_dp; /* True if decimal point should be shown */ + int flag_rtz; /* True if trailing zeros should be removed */ + int flag_exp; /* True to force display of the exponent */ + int nsd; /* Number of significant digits returned */ +#endif + + fmt = format; /* Put in a register for speed */ + count = length = 0; + bufpt = 0; + for(; (c=(*fmt))!=0; ++fmt){ + if( c!='%' ){ + register int amt; + bufpt = (char *)fmt; + amt = 1; + while( (c=(*++fmt))!='%' && c!=0 ) amt++; + (*func)(arg,bufpt,amt); + count += amt; + if( c==0 ) break; + } + if( (c=(*++fmt))==0 ){ + errorflag = 1; + (*func)(arg,"%",1); + count++; + break; + } + /* Find out what flags are present */ + flag_leftjustify = flag_plussign = flag_blanksign = + flag_alternateform = flag_zeropad = flag_center = 0; + do{ + switch( c ){ + case '-': flag_leftjustify = 1; c = 0; break; + case '+': flag_plussign = 1; c = 0; break; + case ' ': flag_blanksign = 1; c = 0; break; + case '#': flag_alternateform = 1; c = 0; break; + case '0': flag_zeropad = 1; c = 0; break; + case '=': flag_center = 1; c = 0; break; + default: break; + } + }while( c==0 && (c=(*++fmt))!=0 ); + if( flag_center ) flag_leftjustify = 0; + /* Get the field width */ + width = 0; + if( c=='*' ){ + width = va_arg(ap,int); + if( width<0 ){ + flag_leftjustify = 1; + width = -width; + } + c = *++fmt; + }else{ + while( c>='0' && c<='9' ){ + width = width*10 + c - '0'; + c = *++fmt; + } + } + if( width > etBUFSIZE-10 ){ + width = etBUFSIZE-10; + } + /* Get the precision */ + if( c=='.' ){ + precision = 0; + c = *++fmt; + if( c=='*' ){ + precision = va_arg(ap,int); +#ifndef etCOMPATIBILITY + /* This is sensible, but SUN OS 4.1 doesn't do it. */ + if( precision<0 ) precision = -precision; +#endif + c = *++fmt; + }else{ + while( c>='0' && c<='9' ){ + precision = precision*10 + c - '0'; + c = *++fmt; + } + } + /* Limit the precision to prevent overflowing buf[] during conversion */ + if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40; + }else{ + precision = -1; + } + /* Get the conversion type modifier */ + if( c=='l' ){ + flag_long = 1; + c = *++fmt; + }else{ + flag_long = 0; + } + /* Fetch the info entry for the field */ + infop = 0; + for(idx=0; idxtype; + } + zExtra = 0; + + /* + ** At this point, variables are initialized as follows: + ** + ** flag_alternateform TRUE if a '#' is present. + ** flag_plussign TRUE if a '+' is present. + ** flag_leftjustify TRUE if a '-' is present or if the + ** field width was negative. + ** flag_zeropad TRUE if the width began with 0. + ** flag_long TRUE if the letter 'l' (ell) prefixed + ** the conversion character. + ** flag_blanksign TRUE if a ' ' is present. + ** width The specified field width. This is + ** always non-negative. Zero is the default. + ** precision The specified precision. The default + ** is -1. + ** xtype The class of the conversion. + ** infop Pointer to the appropriate info struct. + */ + switch( xtype ){ + case etORDINAL: + case etRADIX: + if( flag_long ) longvalue = va_arg(ap,long); + else longvalue = va_arg(ap,int); +#ifdef etCOMPATIBILITY + /* For the format %#x, the value zero is printed "0" not "0x0". + ** I think this is stupid. */ + if( longvalue==0 ) flag_alternateform = 0; +#else + /* More sensible: turn off the prefix for octal (to prevent "00"), + ** but leave the prefix for hex. */ + if( longvalue==0 && infop->base==8 ) flag_alternateform = 0; +#endif + if( infop->flag_signed ){ + if( *(long*)&longvalue<0 ){ + longvalue = -*(long*)&longvalue; + prefix = '-'; + }else if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + }else prefix = 0; + if( flag_zeropad && precision3 || (b>10 && b<14) ){ + bufpt[0] = 't'; + bufpt[1] = 'h'; + }else if( a==1 ){ + bufpt[0] = 's'; + bufpt[1] = 't'; + }else if( a==2 ){ + bufpt[0] = 'n'; + bufpt[1] = 'd'; + }else if( a==3 ){ + bufpt[0] = 'r'; + bufpt[1] = 'd'; + } + } + { + register char *cset; /* Use registers for speed */ + register int base; + cset = infop->charset; + base = infop->base; + do{ /* Convert to ascii */ + *(--bufpt) = cset[longvalue%base]; + longvalue = longvalue/base; + }while( longvalue>0 ); + } + length = (long)&buf[etBUFSIZE]-(long)bufpt; + for(idx=precision-length; idx>0; idx--){ + *(--bufpt) = '0'; /* Zero pad */ + } + if( prefix ) *(--bufpt) = prefix; /* Add sign */ + if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */ + char *pre, x; + pre = infop->prefix; + if( *bufpt!=pre[0] ){ + for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x; + } + } + length = (long)&buf[etBUFSIZE]-(long)bufpt; + break; + case etFLOAT: + case etEXP: + case etGENERIC: + realvalue = va_arg(ap,double); +#ifndef etNOFLOATINGPOINT + if( precision<0 ) precision = 6; /* Set default precision */ + if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10; + if( realvalue<0.0 ){ + realvalue = -realvalue; + prefix = '-'; + }else{ + if( flag_plussign ) prefix = '+'; + else if( flag_blanksign ) prefix = ' '; + else prefix = 0; + } + if( infop->type==etGENERIC && precision>0 ) precision--; + rounder = 0.0; +#ifdef COMPATIBILITY + /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */ + for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1); +#else + /* It makes more sense to use 0.5 */ + for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1); +#endif + if( infop->type==etFLOAT ) realvalue += rounder; + /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ + exp = 0; + if( realvalue>0.0 ){ + int k = 0; + while( realvalue>=1e8 && k++<100 ){ realvalue *= 1e-8; exp+=8; } + while( realvalue>=10.0 && k++<100 ){ realvalue *= 0.1; exp++; } + while( realvalue<1e-8 && k++<100 ){ realvalue *= 1e8; exp-=8; } + while( realvalue<1.0 && k++<100 ){ realvalue *= 10.0; exp--; } + if( k>=100 ){ + bufpt = "NaN"; + length = 3; + break; + } + } + bufpt = buf; + /* + ** If the field type is etGENERIC, then convert to either etEXP + ** or etFLOAT, as appropriate. + */ + flag_exp = xtype==etEXP; + if( xtype!=etFLOAT ){ + realvalue += rounder; + if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + } + if( xtype==etGENERIC ){ + flag_rtz = !flag_alternateform; + if( exp<-4 || exp>precision ){ + xtype = etEXP; + }else{ + precision = precision - exp; + xtype = etFLOAT; + } + }else{ + flag_rtz = 0; + } + /* + ** The "exp+precision" test causes output to be of type etEXP if + ** the precision is too large to fit in buf[]. + */ + nsd = 0; + if( xtype==etFLOAT && exp+precision0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */ + else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd); + if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */ + for(exp++; exp<0 && precision>0; precision--, exp++){ + *(bufpt++) = '0'; + } + while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); + *(bufpt--) = 0; /* Null terminate */ + if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + }else{ /* etEXP or etGENERIC */ + flag_dp = (precision>0 || flag_alternateform); + if( prefix ) *(bufpt++) = prefix; /* Sign */ + *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */ + if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */ + while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd); + bufpt--; /* point to last digit */ + if( flag_rtz && flag_dp ){ /* Remove tail zeros */ + while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0; + if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0; + } + bufpt++; /* point to next free slot */ + if( exp || flag_exp ){ + *(bufpt++) = infop->charset[0]; + if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */ + else { *(bufpt++) = '+'; } + if( exp>=100 ){ + *(bufpt++) = (exp/100)+'0'; /* 100's digit */ + exp %= 100; + } + *(bufpt++) = exp/10+'0'; /* 10's digit */ + *(bufpt++) = exp%10+'0'; /* 1's digit */ + } + } + /* The converted number is in buf[] and zero terminated. Output it. + ** Note that the number is in the usual order, not reversed as with + ** integer conversions. */ + length = (long)bufpt-(long)buf; + bufpt = buf; + + /* Special case: Add leading zeros if the flag_zeropad flag is + ** set and we are not left justified */ + if( flag_zeropad && !flag_leftjustify && length < width){ + int i; + int nPad = width - length; + for(i=width; i>=nPad; i--){ + bufpt[i] = bufpt[i-nPad]; + } + i = prefix!=0; + while( nPad-- ) bufpt[i++] = '0'; + length = width; + } +#endif + break; + case etSIZE: + *(va_arg(ap,int*)) = count; + length = width = 0; + break; + case etPERCENT: + buf[0] = '%'; + bufpt = buf; + length = 1; + break; + case etCHARLIT: + case etCHARX: + c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt); + if( precision>=0 ){ + for(idx=1; idx=0 && precisionetBUFSIZE ){ + bufpt = zExtra = sqliteMalloc( n ); + if( bufpt==0 ) return -1; + }else{ + bufpt = buf; + } + j = 0; + if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + for(i=0; (c=arg[i])!=0; i++){ + bufpt[j++] = c; + if( c=='\'' ) bufpt[j++] = c; + } + if( !isnull && xtype==etSQLESCAPE2 ) bufpt[j++] = '\''; + bufpt[j] = 0; + length = j; + if( precision>=0 && precision0 ){ + if( flag_center ){ + nspace = nspace/2; + width -= nspace; + flag_leftjustify = 1; + } + count += nspace; + while( nspace>=etSPACESIZE ){ + (*func)(arg,spaces,etSPACESIZE); + nspace -= etSPACESIZE; + } + if( nspace>0 ) (*func)(arg,spaces,nspace); + } + } + if( length>0 ){ + (*func)(arg,bufpt,length); + count += length; + } + if( flag_leftjustify ){ + register int nspace; + nspace = width-length; + if( nspace>0 ){ + count += nspace; + while( nspace>=etSPACESIZE ){ + (*func)(arg,spaces,etSPACESIZE); + nspace -= etSPACESIZE; + } + if( nspace>0 ) (*func)(arg,spaces,nspace); + } + } + if( zExtra ){ + sqliteFree(zExtra); + } + }/* End for loop over the format string */ + return errorflag ? -1 : count; +} /* End of function */ + + +/* This structure is used to store state information about the +** write to memory that is currently in progress. +*/ +struct sgMprintf { + char *zBase; /* A base allocation */ + char *zText; /* The string collected so far */ + int nChar; /* Length of the string so far */ + int nAlloc; /* Amount of space allocated in zText */ +}; + +/* +** This function implements the callback from vxprintf. +** +** This routine add nNewChar characters of text in zNewText to +** the sgMprintf structure pointed to by "arg". +*/ +static void mout(void *arg, char *zNewText, int nNewChar){ + struct sgMprintf *pM = (struct sgMprintf*)arg; + if( pM->nChar + nNewChar + 1 > pM->nAlloc ){ + pM->nAlloc = pM->nChar + nNewChar*2 + 1; + if( pM->zText==pM->zBase ){ + pM->zText = sqliteMalloc(pM->nAlloc); + if( pM->zText && pM->nChar ) memcpy(pM->zText,pM->zBase,pM->nChar); + }else{ + char *z = sqliteRealloc(pM->zText, pM->nAlloc); + if( z==0 ){ + sqliteFree(pM->zText); + pM->nChar = 0; + pM->nAlloc = 0; + } + pM->zText = z; + } + } + if( pM->zText ){ + memcpy(&pM->zText[pM->nChar], zNewText, nNewChar); + pM->nChar += nNewChar; + pM->zText[pM->nChar] = 0; + } +} + +/* +** sqlite_mprintf() works like printf(), but allocations memory to hold the +** resulting string and returns a pointer to the allocated memory. Use +** sqliteFree() to release the memory allocated. +*/ +char *sqliteMPrintf(const char *zFormat, ...){ + va_list ap; + struct sgMprintf sMprintf; + char zBuf[200]; + + sMprintf.nChar = 0; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zText = zBuf; + sMprintf.zBase = zBuf; + va_start(ap,zFormat); + vxprintf(mout,&sMprintf,zFormat,ap); + va_end(ap); + sMprintf.zText[sMprintf.nChar] = 0; + return sqliteRealloc(sMprintf.zText, sMprintf.nChar+1); +} + +/* +** sqlite_mprintf() works like printf(), but allocations memory to hold the +** resulting string and returns a pointer to the allocated memory. Use +** sqliteFree() to release the memory allocated. +*/ +char *sqlite_mprintf(const char *zFormat, ...){ + va_list ap; + struct sgMprintf sMprintf; + char *zNew; + char zBuf[200]; + + sMprintf.nChar = 0; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zText = zBuf; + sMprintf.zBase = zBuf; + va_start(ap,zFormat); + vxprintf(mout,&sMprintf,zFormat,ap); + va_end(ap); + sMprintf.zText[sMprintf.nChar] = 0; + zNew = malloc( sMprintf.nChar+1 ); + if( zNew ) strcpy(zNew,sMprintf.zText); + if( sMprintf.zText!=sMprintf.zBase ){ + sqliteFree(sMprintf.zText); + } + return zNew; +} + +/* This is the varargs version of sqlite_mprintf. +*/ +char *sqlite_vmprintf(const char *zFormat, va_list ap){ + struct sgMprintf sMprintf; + char *zNew; + char zBuf[200]; + sMprintf.nChar = 0; + sMprintf.zText = zBuf; + sMprintf.nAlloc = sizeof(zBuf); + sMprintf.zBase = zBuf; + vxprintf(mout,&sMprintf,zFormat,ap); + sMprintf.zText[sMprintf.nChar] = 0; + zNew = malloc( sMprintf.nChar+1 ); + if( zNew ) strcpy(zNew,sMprintf.zText); + if( sMprintf.zText!=sMprintf.zBase ){ + sqliteFree(sMprintf.zText); + } + return zNew; +} + +/* +** The following four routines implement the varargs versions of the +** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h +** header files for a more detailed description of how these interfaces +** work. +** +** These routines are all just simple wrappers. +*/ +int sqlite_exec_printf( + sqlite *db, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + sqlite_callback xCallback, /* Callback function */ + void *pArg, /* 1st argument to callback function */ + char **errmsg, /* Error msg written here */ + ... /* Arguments to the format string. */ +){ + va_list ap; + int rc; + + va_start(ap, errmsg); + rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap); + va_end(ap); + return rc; +} +int sqlite_exec_vprintf( + sqlite *db, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + sqlite_callback xCallback, /* Callback function */ + void *pArg, /* 1st argument to callback function */ + char **errmsg, /* Error msg written here */ + va_list ap /* Arguments to the format string. */ +){ + char *zSql; + int rc; + + zSql = sqlite_vmprintf(sqlFormat, ap); + rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg); + free(zSql); + return rc; +} +int sqlite_get_table_printf( + sqlite *db, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncol, /* Number of result columns written here */ + char **errmsg, /* Error msg written here */ + ... /* Arguments to the format string */ +){ + va_list ap; + int rc; + + va_start(ap, errmsg); + rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap); + va_end(ap); + return rc; +} +int sqlite_get_table_vprintf( + sqlite *db, /* An open database */ + const char *sqlFormat, /* printf-style format string for the SQL */ + char ***resultp, /* Result written to a char *[] that this points to */ + int *nrow, /* Number of result rows written here */ + int *ncolumn, /* Number of result columns written here */ + char **errmsg, /* Error msg written here */ + va_list ap /* Arguments to the format string */ +){ + char *zSql; + int rc; + + zSql = sqlite_vmprintf(sqlFormat, ap); + rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg); + free(zSql); + return rc; +} diff --git a/ext/sqlite/libsqlite/src/table.c b/ext/sqlite/libsqlite/src/table.c new file mode 100644 index 0000000000..71f0b59a3a --- /dev/null +++ b/ext/sqlite/libsqlite/src/table.c @@ -0,0 +1,202 @@ +/* +** 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. +** +************************************************************************* +** This file contains the sqlite_get_table() and sqlite_free_table() +** interface routines. These are just wrappers around the main +** interface routine of sqlite_exec(). +** +** These routines are in a separate files so that they will not be linked +** if they are not used. +*/ +#include +#include +#include "sqliteInt.h" + +/* +** This structure is used to pass data from sqlite_get_table() through +** to the callback function is uses to build the result. +*/ +typedef struct TabResult { + char **azResult; + char *zErrMsg; + int nResult; + int nAlloc; + int nRow; + int nColumn; + int nData; + int rc; +} TabResult; + +/* +** This routine is called once for each row in the result table. Its job +** is to fill in the TabResult structure appropriately, allocating new +** memory as necessary. +*/ +static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ + TabResult *p = (TabResult*)pArg; + int need; + int i; + char *z; + + /* Make sure there is enough space in p->azResult to hold everything + ** we need to remember from this invocation of the callback. + */ + if( p->nRow==0 && argv!=0 ){ + need = nCol*2; + }else{ + need = nCol; + } + if( p->nData + need >= p->nAlloc ){ + char **azNew; + p->nAlloc = p->nAlloc*2 + need + 1; + azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc ); + if( azNew==0 ){ + p->rc = SQLITE_NOMEM; + return 1; + } + p->azResult = azNew; + } + + /* If this is the first row, then generate an extra row containing + ** the names of all columns. + */ + if( p->nRow==0 ){ + p->nColumn = nCol; + for(i=0; irc = SQLITE_NOMEM; + return 1; + } + strcpy(z, colv[i]); + } + p->azResult[p->nData++] = z; + } + }else if( p->nColumn!=nCol ){ + sqliteSetString(&p->zErrMsg, + "sqlite_get_table() called with two or more incompatible queries", 0); + p->rc = SQLITE_ERROR; + return 1; + } + + /* Copy over the row data + */ + if( argv!=0 ){ + for(i=0; irc = SQLITE_NOMEM; + return 1; + } + strcpy(z, argv[i]); + } + p->azResult[p->nData++] = z; + } + p->nRow++; + } + return 0; +} + +/* +** Query the database. But instead of invoking a callback for each row, +** malloc() for space to hold the result and return the entire results +** at the conclusion of the call. +** +** The result that is written to ***pazResult is held in memory obtained +** from malloc(). But the caller cannot free this memory directly. +** Instead, the entire table should be passed to sqlite_free_table() when +** the calling procedure is finished using it. +*/ +int sqlite_get_table( + sqlite *db, /* The database on which the SQL executes */ + const char *zSql, /* The SQL to be executed */ + char ***pazResult, /* Write the result table here */ + int *pnRow, /* Write the number of rows in the result here */ + int *pnColumn, /* Write the number of columns of result here */ + char **pzErrMsg /* Write error messages here */ +){ + int rc; + TabResult res; + if( pazResult==0 ){ return SQLITE_ERROR; } + *pazResult = 0; + if( pnColumn ) *pnColumn = 0; + if( pnRow ) *pnRow = 0; + res.zErrMsg = 0; + res.nResult = 0; + res.nRow = 0; + res.nColumn = 0; + res.nData = 1; + res.nAlloc = 20; + res.rc = SQLITE_OK; + res.azResult = malloc( sizeof(char*)*res.nAlloc ); + if( res.azResult==0 ){ + return SQLITE_NOMEM; + } + res.azResult[0] = 0; + rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg); + if( res.azResult ){ + res.azResult[0] = (char*)res.nData; + } + if( rc==SQLITE_ABORT ){ + sqlite_free_table(&res.azResult[1]); + if( res.zErrMsg ){ + if( pzErrMsg ){ + free(*pzErrMsg); + *pzErrMsg = res.zErrMsg; + sqliteStrRealloc(pzErrMsg); + }else{ + sqliteFree(res.zErrMsg); + } + } + return res.rc; + } + sqliteFree(res.zErrMsg); + if( rc!=SQLITE_OK ){ + sqlite_free_table(&res.azResult[1]); + return rc; + } + if( res.nAlloc>res.nData ){ + char **azNew; + azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) ); + if( azNew==0 ){ + sqlite_free_table(&res.azResult[1]); + return SQLITE_NOMEM; + } + res.nAlloc = res.nData+1; + res.azResult = azNew; + } + *pazResult = &res.azResult[1]; + if( pnColumn ) *pnColumn = res.nColumn; + if( pnRow ) *pnRow = res.nRow; + return rc; +} + +/* +** This routine frees the space the sqlite_get_table() malloced. +*/ +void sqlite_free_table( + char **azResult /* Result returned from from sqlite_get_table() */ +){ + if( azResult ){ + int i, n; + azResult--; + if( azResult==0 ) return; + n = (int)azResult[0]; + for(i=1; i +--EXPECT-- +float(1.001E+10) +float(1.001E+10)