wasCSharpSQLite – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3 using System.Runtime.InteropServices;
4 using System.Text;
5  
6 namespace Community.CsharpSqlite
7 {
8 using etByte = System.Boolean;
9 using i64 = System.Int64;
10 using u64 = System.UInt64;
11 using LONGDOUBLE_TYPE = System.Double;
12 using sqlite_u3264 = System.UInt64;
13 using va_list = System.Object;
14  
15 public partial class Sqlite3
16 {
17 /*
18 ** The "printf" code that follows dates from the 1980's. It is in
19 ** the public domain. The original comments are included here for
20 ** completeness. They are very out-of-date but might be useful as
21 ** an historical reference. Most of the "enhancements" have been backed
22 ** out so that the functionality is now the same as standard printf().
23 **
24 **************************************************************************
25 **
26 ** The following modules is an enhanced replacement for the "printf" subroutines
27 ** found in the standard C library. The following enhancements are
28 ** supported:
29 **
30 ** + Additional functions. The standard set of "printf" functions
31 ** includes printf, fprintf, sprintf, vprintf, vfprintf, and
32 ** vsprintf. This module adds the following:
33 **
34 ** * snprintf -- Works like sprintf, but has an extra argument
35 ** which is the size of the buffer written to.
36 **
37 ** * mprintf -- Similar to sprintf. Writes output to memory
38 ** obtained from malloc.
39 **
40 ** * xprintf -- Calls a function to dispose of output.
41 **
42 ** * nprintf -- No output, but returns the number of characters
43 ** that would have been output by printf.
44 **
45 ** * A v- version (ex: vsnprintf) of every function is also
46 ** supplied.
47 **
48 ** + A few extensions to the formatting notation are supported:
49 **
50 ** * The "=" flag (similar to "-") causes the output to be
51 ** be centered in the appropriately sized field.
52 **
53 ** * The %b field outputs an integer in binary notation.
54 **
55 ** * The %c field now accepts a precision. The character output
56 ** is repeated by the number of times the precision specifies.
57 **
58 ** * The %' field works like %c, but takes as its character the
59 ** next character of the format string, instead of the next
60 ** argument. For example, printf("%.78'-") prints 78 minus
61 ** signs, the same as printf("%.78c",'-').
62 **
63 ** + When compiled using GCC on a SPARC, this version of printf is
64 ** faster than the library printf for SUN OS 4.1.
65 **
66 ** + All functions are fully reentrant.
67 **
68 *************************************************************************
69 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
70 ** C#-SQLite is an independent reimplementation of the SQLite software library
71 **
72 ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e
73 **
74 *************************************************************************
75 */
76 //#include "sqliteInt.h"
77  
78 /*
79 ** Conversion types fall into various categories as defined by the
80 ** following enumeration.
81 */
82 //#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
83 //#define etFLOAT 2 /* Floating point. %f */
84 //#define etEXP 3 /* Exponentional notation. %e and %E */
85 //#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
86 //#define etSIZE 5 /* Return number of characters processed so far. %n */
87 //#define etSTRING 6 /* Strings. %s */
88 //#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
89 //#define etPERCENT 8 /* Percent symbol. %% */
90 //#define etCHARX 9 /* Characters. %c */
91 ///* The rest are extensions, not normally found in printf() */
92 //#define etSQLESCAPE 10 /* Strings with '\'' doubled. %q */
93 //#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
94 // NULL pointers replaced by SQL NULL. %Q */
95 //#define etTOKEN 12 /* a pointer to a Token structure */
96 //#define etSRCLIST 13 /* a pointer to a SrcList */
97 //#define etPOINTER 14 /* The %p conversion */
98 //#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
99 //#define etORDINAL 16 /* %r -> 1st, 2nd, 3rd, 4th, etc. English only */
100  
101 //#define etINVALID 0 /* Any unrecognized conversion type */
102  
103 const int etRADIX = 1; /* Integer types. %d, %x, %o, and so forth */
104 const int etFLOAT = 2; /* Floating point. %f */
105 const int etEXP = 3; /* Exponentional notation. %e and %E */
106 const int etGENERIC = 4; /* Floating or exponential, depending on exponent. %g */
107 const int etSIZE = 5; /* Return number of characters processed so far. %n */
108 const int etSTRING = 6; /* Strings. %s */
109 const int etDYNSTRING = 7; /* Dynamically allocated strings. %z */
110 const int etPERCENT = 8; /* Percent symbol. %% */
111 const int etCHARX = 9; /* Characters. %c */
112 /* The rest are extensions, not normally found in printf() */
113 const int etSQLESCAPE = 10; /* Strings with '\'' doubled. %q */
114 const int etSQLESCAPE2 = 11; /* Strings with '\'' doubled and enclosed in '',
115 NULL pointers replaced by SQL NULL. %Q */
116 const int etTOKEN = 12; /* a pointer to a Token structure */
117 const int etSRCLIST = 13; /* a pointer to a SrcList */
118 const int etPOINTER = 14; /* The %p conversion */
119 const int etSQLESCAPE3 = 15; /* %w . Strings with '\"' doubled */
120 const int etORDINAL = 16; /* %r . 1st, 2nd, 3rd, 4th, etc. English only */
121 const int etINVALID = 0; /* Any unrecognized conversion type */
122  
123 /*
124 ** An "etByte" is an 8-bit unsigned value.
125 */
126 //typedef unsigned char etByte;
127  
128 /*
129 ** Each builtin conversion character (ex: the 'd' in "%d") is described
130 ** by an instance of the following structure
131 */
132 public class et_info
133 { /* Information about each format field */
134 public char fmttype; /* The format field code letter */
135 public byte _base; /* The _base for radix conversion */
136 public byte flags; /* One or more of FLAG_ constants below */
137 public byte type; /* Conversion paradigm */
138 public byte charset; /* Offset into aDigits[] of the digits string */
139 public byte prefix; /* Offset into aPrefix[] of the prefix string */
140 /*
141 * Constructor
142 */
143 public et_info( char fmttype,
144 byte _base,
145 byte flags,
146 byte type,
147 byte charset,
148 byte prefix
149 )
150 {
151 this.fmttype = fmttype;
152 this._base = _base;
153 this.flags = flags;
154 this.type = type;
155 this.charset = charset;
156 this.prefix = prefix;
157 }
158  
159 }
160  
161 /*
162 ** Allowed values for et_info.flags
163 */
164 const byte FLAG_SIGNED = 1; /* True if the value to convert is signed */
165 const byte FLAG_INTERN = 2; /* True if for internal use only */
166 const byte FLAG_STRING = 4; /* Allow infinity precision */
167  
168  
169 /*
170 ** The following table is searched linearly, so it is good to put the
171 ** most frequently used conversion types first.
172 */
173 static string aDigits = "0123456789ABCDEF0123456789abcdef";
174 static string aPrefix = "-x0\000X0";
175 static et_info[] fmtinfo = new et_info[] {
176 new et_info( 'd', 10, 1, etRADIX, 0, 0 ),
177 new et_info( 's', 0, 4, etSTRING, 0, 0 ),
178 new et_info( 'g', 0, 1, etGENERIC, 30, 0 ),
179 new et_info( 'z', 0, 4, etDYNSTRING, 0, 0 ),
180 new et_info( 'q', 0, 4, etSQLESCAPE, 0, 0 ),
181 new et_info( 'Q', 0, 4, etSQLESCAPE2, 0, 0 ),
182 new et_info( 'w', 0, 4, etSQLESCAPE3, 0, 0 ),
183 new et_info( 'c', 0, 0, etCHARX, 0, 0 ),
184 new et_info( 'o', 8, 0, etRADIX, 0, 2 ),
185 new et_info( 'u', 10, 0, etRADIX, 0, 0 ),
186 new et_info( 'x', 16, 0, etRADIX, 16, 1 ),
187 new et_info( 'X', 16, 0, etRADIX, 0, 4 ),
188 #if !SQLITE_OMIT_FLOATING_POINT
189 new et_info( 'f', 0, 1, etFLOAT, 0, 0 ),
190 new et_info( 'e', 0, 1, etEXP, 30, 0 ),
191 new et_info( 'E', 0, 1, etEXP, 14, 0 ),
192 new et_info( 'G', 0, 1, etGENERIC, 14, 0 ),
193 #endif
194 new et_info( 'i', 10, 1, etRADIX, 0, 0 ),
195 new et_info( 'n', 0, 0, etSIZE, 0, 0 ),
196 new et_info( '%', 0, 0, etPERCENT, 0, 0 ),
197 new et_info( 'p', 16, 0, etPOINTER, 0, 1 ),
198  
199 /* All the rest have the FLAG_INTERN bit set and are thus for internal
200 ** use only */
201 new et_info( 'T', 0, 2, etTOKEN, 0, 0 ),
202 new et_info( 'S', 0, 2, etSRCLIST, 0, 0 ),
203 new et_info( 'r', 10, 3, etORDINAL, 0, 0 ),
204 };
205 /*
206 ** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point
207 ** conversions will work.
208 */
209 #if !SQLITE_OMIT_FLOATING_POINT
210 /*
211 ** "*val" is a double such that 0.1 <= *val < 10.0
212 ** Return the ascii code for the leading digit of *val, then
213 ** multiply "*val" by 10.0 to renormalize.
214 **
215 ** Example:
216 ** input: *val = 3.14159
217 ** output: *val = 1.4159 function return = '3'
218 **
219 ** The counter *cnt is incremented each time. After counter exceeds
220 ** 16 (the number of significant digits in a 64-bit float) '0' is
221 ** always returned.
222 */
223 static char et_getdigit( ref LONGDOUBLE_TYPE val, ref int cnt )
224 {
225 int digit;
226 LONGDOUBLE_TYPE d;
227 if ( cnt++ >= 16 )
228 return '\0';
229 digit = (int)val;
230 d = digit;
231 //digit += '0';
232 val = ( val - d ) * 10.0;
233 return (char)digit;
234 }
235 #endif // * SQLITE_OMIT_FLOATING_POINT */
236  
237 /*
238 ** Append N space characters to the given string buffer.
239 */
240 static void appendSpace( StrAccum pAccum, int N )
241 {
242 //static const char zSpaces[] = " ";
243 //while( N>=zSpaces.Length-1 ){
244 // sqlite3StrAccumAppend(pAccum, zSpaces, zSpaces.Length-1);
245 // N -= zSpaces.Length-1;
246 //}
247 //if( N>0 ){
248 // sqlite3StrAccumAppend(pAccum, zSpaces, N);
249 //}
250 pAccum.zText.AppendFormat( "{0," + N + "}", string.Empty );
251 }
252  
253 /*
254 ** On machines with a small stack size, you can redefine the
255 ** SQLITE_PRINT_BUF_SIZE to be less than 350.
256 */
257 #if !SQLITE_PRINT_BUF_SIZE
258 # if (SQLITE_SMALL_STACK)
259 const int SQLITE_PRINT_BUF_SIZE = 50;
260 # else
261 const int SQLITE_PRINT_BUF_SIZE = 350;
262 #endif
263 #endif
264 const int etBUFSIZE = SQLITE_PRINT_BUF_SIZE; /* Size of the output buffer */
265  
266 /*
267 ** The root program. All variations call this core.
268 **
269 ** INPUTS:
270 ** func This is a pointer to a function taking three arguments
271 ** 1. A pointer to anything. Same as the "arg" parameter.
272 ** 2. A pointer to the list of characters to be output
273 ** (Note, this list is NOT null terminated.)
274 ** 3. An integer number of characters to be output.
275 ** (Note: This number might be zero.)
276 **
277 ** arg This is the pointer to anything which will be passed as the
278 ** first argument to "func". Use it for whatever you like.
279 **
280 ** fmt This is the format string, as in the usual print.
281 **
282 ** ap This is a pointer to a list of arguments. Same as in
283 ** vfprint.
284 **
285 ** OUTPUTS:
286 ** The return value is the total number of characters sent to
287 ** the function "func". Returns -1 on a error.
288 **
289 ** Note that the order in which automatic variables are declared below
290 ** seems to make a big difference in determining how fast this beast
291 ** will run.
292 */
293 static char[] buf = new char[etBUFSIZE]; /* Conversion buffer */
294 static void sqlite3VXPrintf(
295 StrAccum pAccum, /* Accumulate results here */
296 int useExtended, /* Allow extended %-conversions */
297 string fmt, /* Format string */
298 va_list[] ap /* arguments */
299 )
300 {
301 int c; /* Next character in the format string */
302 int bufpt; /* Pointer to the conversion buffer */
303 int precision; /* Precision of the current field */
304 int length; /* Length of the field */
305 int idx; /* A general purpose loop counter */
306 int width; /* Width of the current field */
307 etByte flag_leftjustify; /* True if "-" flag is present */
308 etByte flag_plussign; /* True if "+" flag is present */
309 etByte flag_blanksign; /* True if " " flag is present */
310 etByte flag_alternateform; /* True if "#" flag is present */
311 etByte flag_altform2; /* True if "!" flag is present */
312 etByte flag_zeropad; /* True if field width constant starts with zero */
313 etByte flag_long; /* True if "l" flag is present */
314 etByte flag_longlong; /* True if the "ll" flag is present */
315 etByte done; /* Loop termination flag */
316 i64 longvalue;
317 LONGDOUBLE_TYPE realvalue; /* Value for real types */
318 et_info infop; /* Pointer to the appropriate info structure */
319 char[] buf = new char[etBUFSIZE]; /* Conversion buffer */
320 char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
321 byte xtype = 0; /* Conversion paradigm */
322 // Not used in C# -- string zExtra; /* Extra memory used for etTCLESCAPE conversions */
323 #if !SQLITE_OMIT_FLOATING_POINT
324 int exp, e2; /* exponent of real numbers */
325 double rounder; /* Used for rounding floating point values */
326 etByte flag_dp; /* True if decimal point should be shown */
327 etByte flag_rtz; /* True if trailing zeros should be removed */
328 etByte flag_exp; /* True to force display of the exponent */
329 int nsd; /* Number of significant digits returned */
330 #endif
331 length = 0;
332 bufpt = 0;
333 int _fmt = 0; // Work around string pointer
334 fmt += '\0';
335  
336 for ( ; _fmt <= fmt.Length && ( c = fmt[_fmt] ) != 0; ++_fmt )
337 {
338 if ( c != '%' )
339 {
340 int amt;
341 bufpt = _fmt;
342 amt = 1;
343 while ( _fmt < fmt.Length && ( c = ( fmt[++_fmt] ) ) != '%' && c != 0 )
344 amt++;
345 sqlite3StrAccumAppend( pAccum, fmt.Substring( bufpt, amt ), amt );
346 if ( c == 0 )
347 break;
348 }
349 if ( _fmt < fmt.Length && ( c = ( fmt[++_fmt] ) ) == 0 )
350 {
351 sqlite3StrAccumAppend( pAccum, "%", 1 );
352 break;
353 }
354 /* Find out what flags are present */
355 flag_leftjustify = flag_plussign = flag_blanksign =
356 flag_alternateform = flag_altform2 = flag_zeropad = false;
357 done = false;
358 do
359 {
360 switch ( c )
361 {
362 case '-':
363 flag_leftjustify = true;
364 break;
365 case '+':
366 flag_plussign = true;
367 break;
368 case ' ':
369 flag_blanksign = true;
370 break;
371 case '#':
372 flag_alternateform = true;
373 break;
374 case '!':
375 flag_altform2 = true;
376 break;
377 case '0':
378 flag_zeropad = true;
379 break;
380 default:
381 done = true;
382 break;
383 }
384 } while ( !done && _fmt < fmt.Length - 1 && ( c = ( fmt[++_fmt] ) ) != 0 );
385 /* Get the field width */
386 width = 0;
387 if ( c == '*' )
388 {
389 width = va_arg( ap, (Int32)0 );
390 if ( width < 0 )
391 {
392 flag_leftjustify = true;
393 width = -width;
394 }
395 c = fmt[++_fmt];
396 }
397 else
398 {
399 while ( c >= '0' && c <= '9' )
400 {
401 width = width * 10 + c - '0';
402 c = fmt[++_fmt];
403 }
404 }
405 if ( width > etBUFSIZE - 10 )
406 {
407 width = etBUFSIZE - 12;
408 }
409 /* Get the precision */
410 if ( c == '.' )
411 {
412 precision = 0;
413 c = fmt[++_fmt];
414 if ( c == '*' )
415 {
416 precision = va_arg( ap, (Int32)0 );
417 if ( precision < 0 )
418 precision = -precision;
419 c = fmt[++_fmt];
420 }
421 else
422 {
423 while ( c >= '0' && c <= '9' )
424 {
425 precision = precision * 10 + c - '0';
426 c = fmt[++_fmt];
427 }
428 }
429 }
430 else
431 {
432 precision = -1;
433 }
434 /* Get the conversion type modifier */
435 if ( c == 'l' )
436 {
437 flag_long = true;
438 c = fmt[++_fmt];
439 if ( c == 'l' )
440 {
441 flag_longlong = true;
442 c = fmt[++_fmt];
443 }
444 else
445 {
446 flag_longlong = false;
447 }
448 }
449 else
450 {
451 flag_long = flag_longlong = false;
452 }
453 /* Fetch the info entry for the field */
454 infop = fmtinfo[0];
455 xtype = etINVALID;
456 for ( idx = 0; idx < ArraySize( fmtinfo ); idx++ )
457 {
458 if ( c == fmtinfo[idx].fmttype )
459 {
460 infop = fmtinfo[idx];
461 if ( useExtended != 0 || ( infop.flags & FLAG_INTERN ) == 0 )
462 {
463 xtype = infop.type;
464 }
465 else
466 {
467 return;
468 }
469 break;
470 }
471 }
472 //zExtra = null;
473  
474 /* Limit the precision to prevent overflowing buf[] during conversion */
475 if ( precision > etBUFSIZE - 40 && ( infop.flags & FLAG_STRING ) == 0 )
476 {
477 precision = etBUFSIZE - 40;
478 }
479  
480 /*
481 ** At this point, variables are initialized as follows:
482 **
483 ** flag_alternateform TRUE if a '#' is present.
484 ** flag_altform2 TRUE if a '!' is present.
485 ** flag_plussign TRUE if a '+' is present.
486 ** flag_leftjustify TRUE if a '-' is present or if the
487 ** field width was negative.
488 ** flag_zeropad TRUE if the width began with 0.
489 ** flag_long TRUE if the letter 'l' (ell) prefixed
490 ** the conversion character.
491 ** flag_longlong TRUE if the letter 'll' (ell ell) prefixed
492 ** the conversion character.
493 ** flag_blanksign TRUE if a ' ' is present.
494 ** width The specified field width. This is
495 ** always non-negative. Zero is the default.
496 ** precision The specified precision. The default
497 ** is -1.
498 ** xtype The class of the conversion.
499 ** infop Pointer to the appropriate info struct.
500 */
501 switch ( xtype )
502 {
503 case etPOINTER:
504 flag_longlong = true;// char*.Length == sizeof(i64);
505 flag_long = false;// char*.Length == sizeof(long);
506 /* Fall through into the next case */
507 goto case etRADIX;
508 case etORDINAL:
509 case etRADIX:
510 if ( ( infop.flags & FLAG_SIGNED ) != 0 )
511 {
512 i64 v;
513 if ( flag_longlong )
514 {
515 v = (Int64)va_arg( ap, (Int64)0 );
516 }
517 else if ( flag_long )
518 {
519 v = (Int64)va_arg( ap, (Int64)0 );
520 }
521 else
522 {
523 v = (Int32)va_arg( ap, (Int32)0 );
524 }
525 if ( v < 0 )
526 {
527 if ( v == SMALLEST_INT64 )
528 {
529 longvalue = ( (long)( (u64)1 ) << 63 );
530 }
531 else
532 {
533 longvalue = -v;
534 }
535 prefix = '-';
536 }
537 else
538 {
539 longvalue = v;
540 if ( flag_plussign )
541 prefix = '+';
542 else if ( flag_blanksign )
543 prefix = ' ';
544 else
545 prefix = '\0';
546 }
547 }
548 else
549 {
550 if ( flag_longlong )
551 {
552 longvalue = va_arg( ap, (Int64)0 );
553 }
554 else if ( flag_long )
555 {
556 longvalue = va_arg( ap, (Int64)0 );
557 }
558 else
559 {
560 longvalue = va_arg( ap, (Int64)0 );
561 }
562 prefix = '\0';
563 }
564 if ( longvalue == 0 )
565 flag_alternateform = false;
566 if ( flag_zeropad && precision < width - ( ( prefix != '\0' ) ? 1 : 0 ) )
567 {
568 precision = width - ( ( prefix != '\0' ) ? 1 : 0 );
569 }
570 bufpt = buf.Length;//[etBUFSIZE-1];
571 char[] _bufOrd = null;
572 if ( xtype == etORDINAL )
573 {
574 char[] zOrd = "thstndrd".ToCharArray();
575 int x = (int)( longvalue % 10 );
576 if ( x >= 4 || ( longvalue / 10 ) % 10 == 1 )
577 {
578 x = 0;
579 }
580 _bufOrd = new char[2];
581 _bufOrd[0] = zOrd[x * 2];
582 _bufOrd[1] = zOrd[x * 2 + 1];
583 //bufpt -= 2;
584 }
585 {
586  
587 char[] _buf;
588 switch ( infop._base )
589 {
590 case 16:
591 _buf = longvalue.ToString( "x" ).ToCharArray();
592 break;
593 case 8:
594 _buf = Convert.ToString( (long)longvalue, 8 ).ToCharArray();
595 break;
596 default:
597 {
598 if ( flag_zeropad )
599 _buf = longvalue.ToString( new string( '0', width - ( ( prefix != '\0' ) ? 1 : 0 ) ) ).ToCharArray();
600 else
601 _buf = longvalue.ToString().ToCharArray();
602 }
603 break;
604 }
605 bufpt = buf.Length - _buf.Length - ( _bufOrd == null ? 0 : 2 );
606 Array.Copy( _buf, 0, buf, bufpt, _buf.Length );
607 if ( _bufOrd != null )
608 {
609 buf[buf.Length - 1] = _bufOrd[1];
610 buf[buf.Length - 2] = _bufOrd[0];
611 }
612 //char* cset; /* Use registers for speed */
613 //int _base;
614 //cset = aDigits[infop.charset];
615 //_base = infop._base;
616 //do
617 //{ /* Convert to ascii */
618 // *(--bufpt) = cset[longvalue % (ulong)_base];
619 // longvalue = longvalue / (ulong)_base;
620 //} while (longvalue > 0);
621 }
622 length = buf.Length - bufpt;//length = (int)(&buf[etBUFSIZE-1]-bufpt);
623 for ( idx = precision - length; idx > 0; idx-- )
624 {
625 buf[( --bufpt )] = '0'; /* Zero pad */
626 }
627 if ( prefix != '\0' )
628 buf[--bufpt] = prefix; /* Add sign */
629 if ( flag_alternateform && infop.prefix != 0 )
630 { /* Add "0" or "0x" */
631 int pre;
632 char x;
633 pre = infop.prefix;
634 for ( ; ( x = aPrefix[pre] ) != 0; pre++ )
635 buf[--bufpt] = x;
636 }
637 length = buf.Length - bufpt;//length = (int)(&buf[etBUFSIZE-1]-bufpt);
638 break;
639 case etFLOAT:
640 case etEXP:
641 case etGENERIC:
642 realvalue = va_arg( ap, (Double)0 );
643 #if SQLITE_OMIT_FLOATING_POINT
644 length = 0;
645 #else
646 if ( precision < 0 )
647 precision = 6; /* Set default precision */
648 if ( precision > etBUFSIZE / 2 - 10 )
649 precision = etBUFSIZE / 2 - 10;
650 if ( realvalue < 0.0 )
651 {
652 realvalue = -realvalue;
653 prefix = '-';
654 }
655 else
656 {
657 if ( flag_plussign )
658 prefix = '+';
659 else if ( flag_blanksign )
660 prefix = ' ';
661 else
662 prefix = '\0';
663 }
664 if ( xtype == etGENERIC && precision > 0 )
665 precision--;
666 #if FALSE
667 /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
668 for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
669 #else
670 /* It makes more sense to use 0.5 */
671 for ( idx = precision, rounder = 0.5; idx > 0; idx--, rounder *= 0.1 )
672 {
673 }
674 #endif
675 if ( xtype == etFLOAT )
676 realvalue += rounder;
677 /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
678 exp = 0;
679 double d = 0;
680 #if WINDOWS_MOBILE
681 //alxwest: Tryparse doesn't exist on Windows Moble and what will Tryparsing a double do?
682 if ( Double.IsNaN( realvalue ))
683 #else
684 if ( Double.IsNaN( realvalue ) || !( Double.TryParse( Convert.ToString( realvalue ), out d ) ) )//if( sqlite3IsNaN((double)realvalue) )
685 #endif
686 {
687 buf[0] = 'N';
688 buf[1] = 'a';
689 buf[2] = 'N';// "NaN"
690 length = 3;
691 break;
692 }
693 if ( realvalue > 0.0 )
694 {
695 while ( realvalue >= 1e32 && exp <= 350 )
696 {
697 realvalue *= 1e-32;
698 exp += 32;
699 }
700 while ( realvalue >= 1e8 && exp <= 350 )
701 {
702 realvalue *= 1e-8;
703 exp += 8;
704 }
705 while ( realvalue >= 10.0 && exp <= 350 )
706 {
707 realvalue *= 0.1;
708 exp++;
709 }
710 while ( realvalue < 1e-8 )
711 {
712 realvalue *= 1e8;
713 exp -= 8;
714 }
715 while ( realvalue < 1.0 )
716 {
717 realvalue *= 10.0;
718 exp--;
719 }
720 if ( exp > 350 )
721 {
722 if ( prefix == '-' )
723 {
724 buf[0] = '-';
725 buf[1] = 'I';
726 buf[2] = 'n';
727 buf[3] = 'f';// "-Inf"
728 bufpt = 4;
729 }
730 else if ( prefix == '+' )
731 {
732 buf[0] = '+';
733 buf[1] = 'I';
734 buf[2] = 'n';
735 buf[3] = 'f';// "+Inf"
736 bufpt = 4;
737 }
738 else
739 {
740 buf[0] = 'I';
741 buf[1] = 'n';
742 buf[2] = 'f';// "Inf"
743 bufpt = 3;
744 }
745 length = sqlite3Strlen30( bufpt );// sqlite3Strlen30(bufpt);
746 bufpt = 0;
747 break;
748 }
749 }
750 bufpt = 0;
751 /*
752 ** If the field type is etGENERIC, then convert to either etEXP
753 ** or etFLOAT, as appropriate.
754 */
755 flag_exp = xtype == etEXP;
756 if ( xtype != etFLOAT )
757 {
758 realvalue += rounder;
759 if ( realvalue >= 10.0 )
760 {
761 realvalue *= 0.1;
762 exp++;
763 }
764 }
765 if ( xtype == etGENERIC )
766 {
767 flag_rtz = !flag_alternateform;
768 if ( exp < -4 || exp > precision )
769 {
770 xtype = etEXP;
771 }
772 else
773 {
774 precision = precision - exp;
775 xtype = etFLOAT;
776 }
777 }
778 else
779 {
780 flag_rtz = false;
781 }
782 if ( xtype == etEXP )
783 {
784 e2 = 0;
785 }
786 else
787 {
788 e2 = exp;
789 }
790 nsd = 0;
791 flag_dp = ( precision > 0 ? true : false ) | flag_alternateform | flag_altform2;
792 /* The sign in front of the number */
793 if ( prefix != '\0' )
794 {
795 buf[bufpt++] = prefix;
796 }
797 /* Digits prior to the decimal point */
798 if ( e2 < 0 )
799 {
800 buf[bufpt++] = '0';
801 }
802 else
803 {
804 for ( ; e2 >= 0; e2-- )
805 {
806 buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(ref realvalue, ref nsd);
807 }
808  
809 }
810 /* The decimal point */
811 if ( flag_dp )
812 {
813 buf[bufpt++] = '.';
814 }
815 /* "0" digits after the decimal point but before the first
816 ** significant digit of the number */
817 for ( e2++; e2 < 0; precision--, e2++ )
818 {
819 Debug.Assert( precision > 0 );
820 buf[bufpt++] = '0';
821 }
822 /* Significant digits after the decimal point */
823 while ( ( precision-- ) > 0 )
824 {
825 buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(&realvalue, nsd);
826 }
827 /* Remove trailing zeros and the "." if no digits follow the "." */
828 if ( flag_rtz && flag_dp )
829 {
830 while ( buf[bufpt - 1] == '0' )
831 buf[--bufpt] = '\0';
832 Debug.Assert( bufpt > 0 );
833 if ( buf[bufpt - 1] == '.' )
834 {
835 if ( flag_altform2 )
836 {
837 buf[( bufpt++ )] = '0';
838 }
839 else
840 {
841 buf[( --bufpt )] = '0';
842 }
843 }
844 }
845 /* Add the "eNNN" suffix */
846 if ( flag_exp || xtype == etEXP )
847 {
848 buf[bufpt++] = aDigits[infop.charset];
849 if ( exp < 0 )
850 {
851 buf[bufpt++] = '-';
852 exp = -exp;
853 }
854 else
855 {
856 buf[bufpt++] = '+';
857 }
858 if ( exp >= 100 )
859 {
860 buf[bufpt++] = (char)( exp / 100 + '0' ); /* 100's digit */
861 exp %= 100;
862 }
863 buf[bufpt++] = (char)( exp / 10 + '0' ); /* 10's digit */
864 buf[bufpt++] = (char)( exp % 10 + '0' ); /* 1's digit */
865 }
866 //bufpt = 0;
867  
868 /* The converted number is in buf[] and zero terminated. Output it.
869 ** Note that the number is in the usual order, not reversed as with
870 ** integer conversions. */
871 length = bufpt;//length = (int)(bufpt-buf);
872 bufpt = 0;
873  
874 /* Special case: Add leading zeros if the flag_zeropad flag is
875 ** set and we are not left justified */
876 if ( flag_zeropad && !flag_leftjustify && length < width )
877 {
878 int i;
879 int nPad = width - length;
880 for ( i = width; i >= nPad; i-- )
881 {
882 buf[bufpt + i] = buf[bufpt + i - nPad];
883 }
884 i = ( prefix != '\0' ? 1 : 0 );
885 while ( nPad-- != 0 )
886 buf[( bufpt++ ) + i] = '0';
887 length = width;
888 bufpt = 0;
889 }
890 #endif //* !defined(SQLITE_OMIT_FLOATING_POINT) */
891 break;
892 case etSIZE:
893 ap[0] = pAccum.nChar; // *(va_arg(ap,int)) = pAccum.nChar;
894 length = width = 0;
895 break;
896 case etPERCENT:
897 buf[0] = '%';
898 bufpt = 0;
899 length = 1;
900 break;
901 case etCHARX:
902 c = va_arg( ap, (Char) 0);
903 buf[0] = (char)c;
904 if ( precision >= 0 )
905 {
906 for ( idx = 1; idx < precision; idx++ )
907 buf[idx] = (char)c;
908 length = precision;
909 }
910 else
911 {
912 length = 1;
913 }
914 bufpt = 0;
915 break;
916 case etSTRING:
917 case etDYNSTRING:
918 bufpt = 0;//
919 string bufStr = (string)va_arg( ap, "string" );
920 if ( bufStr.Length > buf.Length )
921 buf = new char[bufStr.Length];
922 bufStr.ToCharArray().CopyTo( buf, 0 );
923 bufpt = bufStr.Length;
924 if ( bufpt == 0 )
925 {
926 buf[0] = '\0';
927 }
928 else if ( xtype == etDYNSTRING )
929 {
930 // zExtra = bufpt;
931 }
932 if ( precision >= 0 )
933 {
934 for ( length = 0; length < precision && length < bufStr.Length && buf[length] != 0; length++ )
935 {
936 }
937 //length += precision;
938 }
939 else
940 {
941 length = sqlite3Strlen30( bufpt );
942 }
943 bufpt = 0;
944 break;
945 case etSQLESCAPE:
946 case etSQLESCAPE2:
947 case etSQLESCAPE3:
948 {
949 int i;
950 int j;
951 int k;
952 int n;
953 bool needQuote;
954 char ch;
955 char q = ( ( xtype == etSQLESCAPE3 ) ? '"' : '\'' ); /* Quote character */
956 string escarg = (string)va_arg( ap, "char*" ) + '\0';
957 bool isnull = ( escarg.Length == 0 || escarg == "NULL\0" );
958 if ( isnull )
959 escarg = ( xtype == etSQLESCAPE2 ) ? "NULL\0" : "(NULL)\0";
960 k = precision;
961 for ( i = n = 0; k != 0 && ( ch = escarg[i] ) != 0; i++, k-- )
962 {
963 if ( ch == q )
964 n++;
965 }
966 needQuote = !isnull && ( xtype == etSQLESCAPE2 );
967 n += i + 1 + ( needQuote ? 2 : 0 );
968 if ( n > etBUFSIZE )
969 {
970 buf = new char[n];//bufpt = zExtra = sqlite3Malloc(n);
971 //if ( bufpt == 0 )
972 //{
973 // pAccum->mallocFailed = 1;
974 // return;
975 //}
976 bufpt = 0; //Start of Buffer
977 }
978 else
979 {
980 //bufpt = buf;
981 bufpt = 0; //Start of Buffer
982 }
983 j = 0;
984 if ( needQuote )
985 buf[bufpt + j++] = q;
986 k = i;
987 for ( i = 0; i < k; i++ )
988 {
989 buf[bufpt + j++] = ch = escarg[i];
990 if ( ch == q )
991 buf[bufpt + j++] = ch;
992 }
993 if ( needQuote )
994 buf[bufpt + j++] = q;
995 buf[bufpt + j] = '\0';
996 length = j;
997 /* The precision in %q and %Q means how many input characters to
998 ** consume, not the length of the output...
999 ** if( precision>=0 && precision<length ) length = precision; */
1000 break;
1001 }
1002 case etTOKEN:
1003 {
1004 Token pToken;
1005 if ( ap[vaNEXT] is String )
1006 {
1007 pToken = new Token();
1008 pToken.z = va_arg( ap, ( String ) null);
1009 pToken.n = pToken.z.Length;
1010 }
1011 else
1012 pToken = va_arg( ap, (Token) null );
1013 if ( pToken != null )
1014 {
1015 sqlite3StrAccumAppend( pAccum, pToken.z.ToString(), (int)pToken.n );
1016 }
1017 length = width = 0;
1018 break;
1019 }
1020 case etSRCLIST:
1021 {
1022 SrcList pSrc = va_arg( ap, ( SrcList )null );
1023 int k = va_arg( ap, ( Int32 ) 0 );
1024 SrcList_item pItem = pSrc.a[k];
1025 Debug.Assert( k >= 0 && k < pSrc.nSrc );
1026 if ( pItem.zDatabase != null )
1027 {
1028 sqlite3StrAccumAppend( pAccum, pItem.zDatabase, -1 );
1029 sqlite3StrAccumAppend( pAccum, ".", 1 );
1030 }
1031 sqlite3StrAccumAppend( pAccum, pItem.zName, -1 );
1032 length = width = 0;
1033 break;
1034 }
1035 default:
1036 {
1037 Debug.Assert( xtype == etINVALID );
1038 return;
1039 }
1040 }/* End switch over the format type */
1041 /*
1042 ** The text of the conversion is pointed to by "bufpt" and is
1043 ** "length" characters long. The field width is "width". Do
1044 ** the output.
1045 */
1046 if ( !flag_leftjustify )
1047 {
1048 int nspace;
1049 nspace = width - length;// -2;
1050 if ( nspace > 0 )
1051 {
1052 appendSpace( pAccum, nspace );
1053 }
1054 }
1055 if ( length > 0 )
1056 {
1057 sqlite3StrAccumAppend( pAccum, new string( buf, bufpt, length ), length );
1058 }
1059 if ( flag_leftjustify )
1060 {
1061 int nspace;
1062 nspace = width - length;
1063 if ( nspace > 0 )
1064 {
1065 appendSpace( pAccum, nspace );
1066 }
1067 }
1068 //if( zExtra ){
1069 // sqlite3DbFree(db,ref zExtra);
1070 //}
1071 }/* End for loop over the format string */
1072 } /* End of function */
1073  
1074 /*
1075 ** Append N bytes of text from z to the StrAccum object.
1076 */
1077  
1078 static void sqlite3StrAccumAppend( StrAccum p, string z, int N )
1079 {
1080 Debug.Assert( z != null || N == 0 );
1081 if ( p.tooBig )//|| p.mallocFailed != 0 )
1082 {
1083 testcase( p.tooBig );
1084 //testcase( p.mallocFailed );
1085 return;
1086 }
1087 if ( N < 0 )
1088 {
1089 N = sqlite3Strlen30( z );
1090 }
1091 if ( N == 0 || NEVER( z == null ) )
1092 {
1093 return;
1094 }
1095 //if( p->nChar+N >= p->nAlloc ){
1096 // string zNew;
1097 // if( null==p->useMalloc ){
1098 // p->tooBig = 1;
1099 // N = p->nAlloc - p->nChar - 1;
1100 // if( N<=0 ){
1101 // return;
1102 // }
1103 // }else{
1104 // string zOld = (p->zText==p->zBase ? 0 : p->zText);
1105 // i64 szNew = p->nChar;
1106 // szNew += N + 1;
1107 // if( szNew > p->mxAlloc ){
1108 // sqlite3StrAccumReset(p);
1109 // p->tooBig = 1;
1110 // return;
1111 // }else{
1112 // p->nAlloc = (int)szNew;
1113 // }
1114 // if( p->useMalloc==1 ){
1115 // zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
1116 // }else{
1117 // zNew = sqlite3_realloc(zOld, p->nAlloc);
1118 // }
1119 // if( zNew ){
1120 // if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
1121 // p->zText = zNew;
1122 // }else{
1123 // p->mallocFailed = 1;
1124 // sqlite3StrAccumReset(p);
1125 // return;
1126 // }
1127 // }
1128 //}
1129 //memcpy(&p->zText[p->nChar], z, N);
1130 p.zText.Append( z.Substring( 0, N <= z.Length ? N : z.Length ) );
1131 //p.nChar += N;
1132 }
1133  
1134 /*
1135 ** Finish off a string by making sure it is zero-terminated.
1136 ** Return a pointer to the resulting string. Return a NULL
1137 ** pointer if any kind of error was encountered.
1138 */
1139 static string sqlite3StrAccumFinish( StrAccum p )
1140 {
1141 //if ( p->zText )
1142 //{
1143 // p->zText[p->nChar] = 0;
1144 // if ( p->useMalloc && p->zText == p->zBase )
1145 // {
1146 // if ( p->useMalloc == 1 )
1147 // {
1148 // p->zText = sqlite3DbMallocRaw( p->db, p->nChar + 1 );
1149 // }
1150 // else
1151 // {
1152 // p->zText = sqlite3_malloc( p->nChar + 1 );
1153 // }
1154 // if ( p->zText )
1155 // {
1156 // memcpy( p->zText, p->zBase, p->nChar + 1 );
1157 // }
1158 // else
1159 // {
1160 // p->mallocFailed = 1;
1161 // }
1162 // }
1163 //}
1164 return p.zText.ToString();
1165 }
1166  
1167 /*
1168 ** Reset an StrAccum string. Reclaim all malloced memory.
1169 */
1170 static void sqlite3StrAccumReset( StrAccum p )
1171 {
1172 //if ( p.zText.ToString() != p.zBase.ToString() )
1173 //{
1174 // if ( p.useMalloc == 1 )
1175 // {
1176 // sqlite3DbFree( p.db, ref p.zText );
1177 // }
1178 // else
1179 // {
1180 // sqlite3_free( ref p.zText );
1181 // }
1182 //}
1183 p.zText.Length = 0;
1184 }
1185  
1186 /*
1187 ** Initialize a string accumulator
1188 */
1189 static void sqlite3StrAccumInit( StrAccum p, StringBuilder zBase, int n, int mx )
1190 {
1191 //p.zBase.Length = 0;
1192 //if ( p.zBase.Capacity < n )
1193 // p.zBase.Capacity = n;
1194 p.zText.Length = 0;
1195 if ( p.zText.Capacity < n )
1196 p.zText.Capacity = n;
1197 p.db = null;
1198 //p.nChar = 0;
1199 //p.nAlloc = n;
1200 p.mxAlloc = mx;
1201 //p.useMalloc = 1;
1202 //p.tooBig = 0;
1203 //p.mallocFailed = 0;
1204 }
1205 /*
1206 ** Print into memory obtained from sqliteMalloc(). Use the internal
1207 ** %-conversion extensions.
1208 */
1209 static StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1210 static string sqlite3VMPrintf( sqlite3 db, string zFormat, params va_list[] ap )
1211 {
1212 if ( zFormat == null )
1213 return null;
1214 if ( ap.Length == 0 )
1215 return zFormat;
1216 //string z;
1217 Debug.Assert( db != null );
1218 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE,
1219 db.aLimit[SQLITE_LIMIT_LENGTH] );
1220 acc.db = db;
1221 acc.zText.Length = 0;
1222 sqlite3VXPrintf( acc, 1, zFormat, ap );
1223 // if ( acc.mallocFailed != 0 )
1224 // {
1225 ////// db.mallocFailed = 1;
1226 // }
1227 return sqlite3StrAccumFinish( acc );
1228 }
1229  
1230 /*
1231 ** Print into memory obtained from sqliteMalloc(). Use the internal
1232 ** %-conversion extensions.
1233 */
1234 static string sqlite3MPrintf( sqlite3 db, string zFormat, params va_list[] ap )
1235 {
1236 string z;
1237 //va_list ap;
1238 lock ( lock_va_list )
1239 {
1240 va_start( ap, zFormat );
1241 z = sqlite3VMPrintf( db, zFormat, ap );
1242 va_end( ref ap );
1243 }
1244 return z;
1245 }
1246  
1247 /*
1248 ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
1249 ** the string and before returnning. This routine is intended to be used
1250 ** to modify an existing string. For example:
1251 **
1252 ** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
1253 **
1254 */
1255 static string sqlite3MAppendf( sqlite3 db, string zStr, string zFormat, params va_list[] ap )
1256 {
1257 string z;
1258 //va_list ap;
1259 lock ( lock_va_list )
1260 {
1261 va_start( ap, zFormat );
1262 z = sqlite3VMPrintf( db, zFormat, ap );
1263 va_end( ref ap );
1264 sqlite3DbFree( db, ref zStr );
1265 }
1266 return z;
1267 }
1268  
1269 /*
1270 ** Print into memory obtained from sqlite3Malloc(). Omit the internal
1271 ** %-conversion extensions.
1272 */
1273 static string sqlite3_vmprintf( string zFormat, params va_list[] ap )
1274 {
1275 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1276 #if !SQLITE_OMIT_AUTOINIT
1277 if ( sqlite3_initialize() != 0 )
1278 return string.Empty;
1279 #endif
1280 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE, SQLITE_PRINT_BUF_SIZE );//zBase).Length;
1281 //acc.useMalloc = 2;
1282 sqlite3VXPrintf( acc, 0, zFormat, ap );
1283 return sqlite3StrAccumFinish( acc );
1284 }
1285  
1286 /*
1287 ** Print into memory obtained from sqlite3Malloc()(). Omit the internal
1288 ** %-conversion extensions.
1289 */
1290 static public string sqlite3_mprintf( string zFormat, params va_list[] ap )
1291 { //, ...){
1292 string z;
1293 #if !SQLITE_OMIT_AUTOINIT
1294 if ( sqlite3_initialize() != 0 )
1295 return string.Empty;
1296 #endif
1297 //va_list ap;
1298 lock ( lock_va_list )
1299 {
1300 va_start( ap, zFormat );
1301 z = sqlite3_vmprintf( zFormat, ap );
1302 va_end( ref ap );
1303 }
1304 return z;
1305 }
1306  
1307 /*
1308 ** sqlite3_snprintf() works like snprintf() except that it ignores the
1309 ** current locale settings. This is important for SQLite because we
1310 ** are not able to use a "," as the decimal point in place of "." as
1311 ** specified by some locales.
1312 **
1313 ** Oops: The first two arguments of sqlite3_snprintf() are backwards
1314 ** from the snprintf() standard. Unfortunately, it is too late to change
1315 ** this without breaking compatibility, so we just have to live with the
1316 ** mistake.
1317 **
1318 ** sqlite3_vsnprintf() is the varargs version.
1319 */
1320 static public void sqlite3_vsnprintf( int n, StringBuilder zBuf, string zFormat, params va_list[] ap )
1321 {
1322 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1323 if ( n <= 0 )
1324 return;
1325 sqlite3StrAccumInit( acc, null, n, 0 );
1326 //acc.useMalloc = 0;
1327 sqlite3VXPrintf( acc, 0, zFormat, ap );
1328 zBuf.Length = 0;
1329 if ( n > 1 && n <= acc.zText.Length )
1330 acc.zText.Length = n - 1;
1331 zBuf.Append( sqlite3StrAccumFinish( acc ) );
1332 return;
1333 }
1334  
1335 static public void sqlite3_snprintf( int n, StringBuilder zBuf, string zFormat, params va_list[] ap )
1336 {
1337 //string z;
1338 //va_list ap;
1339 lock ( lock_va_list )
1340 {//StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1341 zBuf.EnsureCapacity( SQLITE_PRINT_BUF_SIZE );
1342 va_start( ap, zFormat );
1343 sqlite3_vsnprintf( n, zBuf, zFormat, ap );
1344 va_end( ref ap );
1345 }
1346 return;
1347 }
1348  
1349 //static public string sqlite3_snprintf( int n, ref string zBuf, string zFormat, params va_list[] ap )
1350 //{
1351 // string z;
1352 // //va_list ap;
1353 // StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1354  
1355 // if ( n <= 0 )
1356 // {
1357 // return zBuf;
1358 // }
1359 // sqlite3StrAccumInit( acc, null, n, 0 );
1360 // //acc.useMalloc = 0;
1361 // va_start( ap, zFormat );
1362 // sqlite3VXPrintf( acc, 0, zFormat, ap );
1363 // va_end( ap );
1364 // z = sqlite3StrAccumFinish( acc );
1365 // return ( zBuf = z );
1366 //}
1367  
1368 /*
1369 ** This is the routine that actually formats the sqlite3_log() message.
1370 ** We house it in a separate routine from sqlite3_log() to avoid using
1371 ** stack space on small-stack systems when logging is disabled.
1372 **
1373 ** sqlite3_log() must render into a static buffer. It cannot dynamically
1374 ** allocate memory because it might be called while the memory allocator
1375 ** mutex is held.
1376 */
1377 static void renderLogMsg( int iErrCode, string zFormat, params object[] ap )
1378 {
1379 //StrAccum acc; /* String accumulator */
1380 //char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
1381  
1382 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE * 3, 0 );
1383 //acc.useMalloc = 0;
1384 sqlite3VXPrintf( acc, 0, zFormat, ap );
1385 sqlite3GlobalConfig.xLog( sqlite3GlobalConfig.pLogArg, iErrCode,
1386 sqlite3StrAccumFinish( acc ) );
1387 }
1388  
1389 /*
1390 ** Format and write a message to the log if logging is enabled.
1391 */
1392 static void sqlite3_log( int iErrCode, string zFormat, params va_list[] ap )
1393 {
1394 if ( sqlite3GlobalConfig.xLog != null )
1395 {
1396 //va_list ap; /* Vararg list */
1397 lock ( lock_va_list )
1398 {
1399 va_start( ap, zFormat );
1400 renderLogMsg( iErrCode, zFormat, ap );
1401 va_end( ref ap );
1402 }
1403 }
1404 }
1405  
1406 #if SQLITE_DEBUG || DEBUG || TRACE
1407 /*
1408 ** A version of printf() that understands %lld. Used for debugging.
1409 ** The printf() built into some versions of windows does not understand %lld
1410 ** and segfaults if you give it a long long int.
1411 */
1412 static void sqlite3DebugPrintf( string zFormat, params va_list[] ap )
1413 {
1414 //va_list ap;
1415 lock ( lock_va_list )
1416 {
1417 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1418 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE, 0 );
1419 //acc.useMalloc = 0;
1420 va_start( ap, zFormat );
1421 sqlite3VXPrintf( acc, 0, zFormat, ap );
1422 va_end( ref ap );
1423 }
1424 Console.Write( sqlite3StrAccumFinish( acc ) );
1425 //fflush(stdout);
1426 }
1427 #endif
1428 #if !SQLITE_OMIT_TRACE
1429 /*
1430 ** variable-argument wrapper around sqlite3VXPrintf().
1431 */
1432 static void sqlite3XPrintf( StrAccum p, string zFormat, params object[] ap )
1433 {
1434 //va_list ap;
1435 lock ( lock_va_list )
1436 {
1437 va_start( ap, zFormat );
1438 sqlite3VXPrintf( p, 1, zFormat, ap );
1439 va_end( ref ap );
1440 }
1441 }
1442 #endif
1443  
1444 }
1445 }