wasCSharpSQLite – Blame information for rev 2

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 #if WINDOWS_MOBILE
680 //alxwest: Tryparse doesn't exist on Windows Moble and what will Tryparsing a double do?
681 if ( Double.IsNaN( realvalue ))
682 #else
683 if ( Double.IsNaN( realvalue ) || !( Double.TryParse( Convert.ToString( realvalue ), out d ) ) )//if( sqlite3IsNaN((double)realvalue) )
684 #endif
685 {
686 buf[0] = 'N';
687 buf[1] = 'a';
688 buf[2] = 'N';// "NaN"
689 length = 3;
690 break;
691 }
692 if ( realvalue > 0.0 )
693 {
694 while ( realvalue >= 1e32 && exp <= 350 )
695 {
696 realvalue *= 1e-32;
697 exp += 32;
698 }
699 while ( realvalue >= 1e8 && exp <= 350 )
700 {
701 realvalue *= 1e-8;
702 exp += 8;
703 }
704 while ( realvalue >= 10.0 && exp <= 350 )
705 {
706 realvalue *= 0.1;
707 exp++;
708 }
709 while ( realvalue < 1e-8 )
710 {
711 realvalue *= 1e8;
712 exp -= 8;
713 }
714 while ( realvalue < 1.0 )
715 {
716 realvalue *= 10.0;
717 exp--;
718 }
719 if ( exp > 350 )
720 {
721 if ( prefix == '-' )
722 {
723 buf[0] = '-';
724 buf[1] = 'I';
725 buf[2] = 'n';
726 buf[3] = 'f';// "-Inf"
727 bufpt = 4;
728 }
729 else if ( prefix == '+' )
730 {
731 buf[0] = '+';
732 buf[1] = 'I';
733 buf[2] = 'n';
734 buf[3] = 'f';// "+Inf"
735 bufpt = 4;
736 }
737 else
738 {
739 buf[0] = 'I';
740 buf[1] = 'n';
741 buf[2] = 'f';// "Inf"
742 bufpt = 3;
743 }
744 length = sqlite3Strlen30( bufpt );// sqlite3Strlen30(bufpt);
745 bufpt = 0;
746 break;
747 }
748 }
749 bufpt = 0;
750 /*
751 ** If the field type is etGENERIC, then convert to either etEXP
752 ** or etFLOAT, as appropriate.
753 */
754 flag_exp = xtype == etEXP;
755 if ( xtype != etFLOAT )
756 {
757 realvalue += rounder;
758 if ( realvalue >= 10.0 )
759 {
760 realvalue *= 0.1;
761 exp++;
762 }
763 }
764 if ( xtype == etGENERIC )
765 {
766 flag_rtz = !flag_alternateform;
767 if ( exp < -4 || exp > precision )
768 {
769 xtype = etEXP;
770 }
771 else
772 {
773 precision = precision - exp;
774 xtype = etFLOAT;
775 }
776 }
777 else
778 {
779 flag_rtz = false;
780 }
781 if ( xtype == etEXP )
782 {
783 e2 = 0;
784 }
785 else
786 {
787 e2 = exp;
788 }
789 nsd = 0;
790 flag_dp = ( precision > 0 ? true : false ) | flag_alternateform | flag_altform2;
791 /* The sign in front of the number */
792 if ( prefix != '\0' )
793 {
794 buf[bufpt++] = prefix;
795 }
796 /* Digits prior to the decimal point */
797 if ( e2 < 0 )
798 {
799 buf[bufpt++] = '0';
800 }
801 else
802 {
803 for ( ; e2 >= 0; e2-- )
804 {
805 buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(ref realvalue, ref nsd);
806 }
807  
808 }
809 /* The decimal point */
810 if ( flag_dp )
811 {
812 buf[bufpt++] = '.';
813 }
814 /* "0" digits after the decimal point but before the first
815 ** significant digit of the number */
816 for ( e2++; e2 < 0; precision--, e2++ )
817 {
818 Debug.Assert( precision > 0 );
819 buf[bufpt++] = '0';
820 }
821 /* Significant digits after the decimal point */
822 while ( ( precision-- ) > 0 )
823 {
824 buf[bufpt++] = (char)( et_getdigit( ref realvalue, ref nsd ) + '0' ); // *(bufpt++) = et_getdigit(&realvalue, nsd);
825 }
826 /* Remove trailing zeros and the "." if no digits follow the "." */
827 if ( flag_rtz && flag_dp )
828 {
829 while ( buf[bufpt - 1] == '0' )
830 buf[--bufpt] = '\0';
831 Debug.Assert( bufpt > 0 );
832 if ( buf[bufpt - 1] == '.' )
833 {
834 if ( flag_altform2 )
835 {
836 buf[( bufpt++ )] = '0';
837 }
838 else
839 {
840 buf[( --bufpt )] = '0';
841 }
842 }
843 }
844 /* Add the "eNNN" suffix */
845 if ( flag_exp || xtype == etEXP )
846 {
847 buf[bufpt++] = aDigits[infop.charset];
848 if ( exp < 0 )
849 {
850 buf[bufpt++] = '-';
851 exp = -exp;
852 }
853 else
854 {
855 buf[bufpt++] = '+';
856 }
857 if ( exp >= 100 )
858 {
859 buf[bufpt++] = (char)( exp / 100 + '0' ); /* 100's digit */
860 exp %= 100;
861 }
862 buf[bufpt++] = (char)( exp / 10 + '0' ); /* 10's digit */
863 buf[bufpt++] = (char)( exp % 10 + '0' ); /* 1's digit */
864 }
865 //bufpt = 0;
866  
867 /* The converted number is in buf[] and zero terminated. Output it.
868 ** Note that the number is in the usual order, not reversed as with
869 ** integer conversions. */
870 length = bufpt;//length = (int)(bufpt-buf);
871 bufpt = 0;
872  
873 /* Special case: Add leading zeros if the flag_zeropad flag is
874 ** set and we are not left justified */
875 if ( flag_zeropad && !flag_leftjustify && length < width )
876 {
877 int i;
878 int nPad = width - length;
879 for ( i = width; i >= nPad; i-- )
880 {
881 buf[bufpt + i] = buf[bufpt + i - nPad];
882 }
883 i = ( prefix != '\0' ? 1 : 0 );
884 while ( nPad-- != 0 )
885 buf[( bufpt++ ) + i] = '0';
886 length = width;
887 bufpt = 0;
888 }
889 #endif //* !defined(SQLITE_OMIT_FLOATING_POINT) */
890 break;
891 case etSIZE:
892 ap[0] = pAccum.nChar; // *(va_arg(ap,int)) = pAccum.nChar;
893 length = width = 0;
894 break;
895 case etPERCENT:
896 buf[0] = '%';
897 bufpt = 0;
898 length = 1;
899 break;
900 case etCHARX:
901 c = va_arg( ap, (Char) 0);
902 buf[0] = (char)c;
903 if ( precision >= 0 )
904 {
905 for ( idx = 1; idx < precision; idx++ )
906 buf[idx] = (char)c;
907 length = precision;
908 }
909 else
910 {
911 length = 1;
912 }
913 bufpt = 0;
914 break;
915 case etSTRING:
916 case etDYNSTRING:
917 bufpt = 0;//
918 string bufStr = (string)va_arg( ap, "string" );
919 if ( bufStr.Length > buf.Length )
920 buf = new char[bufStr.Length];
921 bufStr.ToCharArray().CopyTo( buf, 0 );
922 bufpt = bufStr.Length;
923 if ( bufpt == 0 )
924 {
925 buf[0] = '\0';
926 }
927 else if ( xtype == etDYNSTRING )
928 {
929 // zExtra = bufpt;
930 }
931 if ( precision >= 0 )
932 {
933 for ( length = 0; length < precision && length < bufStr.Length && buf[length] != 0; length++ )
934 {
935 }
936 //length += precision;
937 }
938 else
939 {
940 length = sqlite3Strlen30( bufpt );
941 }
942 bufpt = 0;
943 break;
944 case etSQLESCAPE:
945 case etSQLESCAPE2:
946 case etSQLESCAPE3:
947 {
948 int i;
949 int j;
950 int k;
951 int n;
952 bool needQuote;
953 char ch;
954 char q = ( ( xtype == etSQLESCAPE3 ) ? '"' : '\'' ); /* Quote character */
955 string escarg = (string)va_arg( ap, "char*" ) + '\0';
956 bool isnull = ( escarg.Length == 0 || escarg == "NULL\0" );
957 if ( isnull )
958 escarg = ( xtype == etSQLESCAPE2 ) ? "NULL\0" : "(NULL)\0";
959 k = precision;
960 for ( i = n = 0; k != 0 && ( ch = escarg[i] ) != 0; i++, k-- )
961 {
962 if ( ch == q )
963 n++;
964 }
965 needQuote = !isnull && ( xtype == etSQLESCAPE2 );
966 n += i + 1 + ( needQuote ? 2 : 0 );
967 if ( n > etBUFSIZE )
968 {
969 buf = new char[n];//bufpt = zExtra = sqlite3Malloc(n);
970 //if ( bufpt == 0 )
971 //{
972 // pAccum->mallocFailed = 1;
973 // return;
974 //}
975 bufpt = 0; //Start of Buffer
976 }
977 else
978 {
979 //bufpt = buf;
980 bufpt = 0; //Start of Buffer
981 }
982 j = 0;
983 if ( needQuote )
984 buf[bufpt + j++] = q;
985 k = i;
986 for ( i = 0; i < k; i++ )
987 {
988 buf[bufpt + j++] = ch = escarg[i];
989 if ( ch == q )
990 buf[bufpt + j++] = ch;
991 }
992 if ( needQuote )
993 buf[bufpt + j++] = q;
994 buf[bufpt + j] = '\0';
995 length = j;
996 /* The precision in %q and %Q means how many input characters to
997 ** consume, not the length of the output...
998 ** if( precision>=0 && precision<length ) length = precision; */
999 break;
1000 }
1001 case etTOKEN:
1002 {
1003 Token pToken;
1004 if ( ap[vaNEXT] is String )
1005 {
1006 pToken = new Token();
1007 pToken.z = va_arg( ap, ( String ) null);
1008 pToken.n = pToken.z.Length;
1009 }
1010 else
1011 pToken = va_arg( ap, (Token) null );
1012 if ( pToken != null )
1013 {
1014 sqlite3StrAccumAppend( pAccum, pToken.z.ToString(), (int)pToken.n );
1015 }
1016 length = width = 0;
1017 break;
1018 }
1019 case etSRCLIST:
1020 {
1021 SrcList pSrc = va_arg( ap, ( SrcList )null );
1022 int k = va_arg( ap, ( Int32 ) 0 );
1023 SrcList_item pItem = pSrc.a[k];
1024 Debug.Assert( k >= 0 && k < pSrc.nSrc );
1025 if ( pItem.zDatabase != null )
1026 {
1027 sqlite3StrAccumAppend( pAccum, pItem.zDatabase, -1 );
1028 sqlite3StrAccumAppend( pAccum, ".", 1 );
1029 }
1030 sqlite3StrAccumAppend( pAccum, pItem.zName, -1 );
1031 length = width = 0;
1032 break;
1033 }
1034 default:
1035 {
1036 Debug.Assert( xtype == etINVALID );
1037 return;
1038 }
1039 }/* End switch over the format type */
1040 /*
1041 ** The text of the conversion is pointed to by "bufpt" and is
1042 ** "length" characters long. The field width is "width". Do
1043 ** the output.
1044 */
1045 if ( !flag_leftjustify )
1046 {
1047 int nspace;
1048 nspace = width - length;// -2;
1049 if ( nspace > 0 )
1050 {
1051 appendSpace( pAccum, nspace );
1052 }
1053 }
1054 if ( length > 0 )
1055 {
1056 sqlite3StrAccumAppend( pAccum, new string( buf, bufpt, length ), length );
1057 }
1058 if ( flag_leftjustify )
1059 {
1060 int nspace;
1061 nspace = width - length;
1062 if ( nspace > 0 )
1063 {
1064 appendSpace( pAccum, nspace );
1065 }
1066 }
1067 //if( zExtra ){
1068 // sqlite3DbFree(db,ref zExtra);
1069 //}
1070 }/* End for loop over the format string */
1071 } /* End of function */
1072  
1073 /*
1074 ** Append N bytes of text from z to the StrAccum object.
1075 */
1076  
1077 static void sqlite3StrAccumAppend( StrAccum p, string z, int N )
1078 {
1079 Debug.Assert( z != null || N == 0 );
1080 if ( p.tooBig )//|| p.mallocFailed != 0 )
1081 {
1082 testcase( p.tooBig );
1083 //testcase( p.mallocFailed );
1084 return;
1085 }
1086 if ( N < 0 )
1087 {
1088 N = sqlite3Strlen30( z );
1089 }
1090 if ( N == 0 || NEVER( z == null ) )
1091 {
1092 return;
1093 }
1094 //if( p->nChar+N >= p->nAlloc ){
1095 // string zNew;
1096 // if( null==p->useMalloc ){
1097 // p->tooBig = 1;
1098 // N = p->nAlloc - p->nChar - 1;
1099 // if( N<=0 ){
1100 // return;
1101 // }
1102 // }else{
1103 // string zOld = (p->zText==p->zBase ? 0 : p->zText);
1104 // i64 szNew = p->nChar;
1105 // szNew += N + 1;
1106 // if( szNew > p->mxAlloc ){
1107 // sqlite3StrAccumReset(p);
1108 // p->tooBig = 1;
1109 // return;
1110 // }else{
1111 // p->nAlloc = (int)szNew;
1112 // }
1113 // if( p->useMalloc==1 ){
1114 // zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
1115 // }else{
1116 // zNew = sqlite3_realloc(zOld, p->nAlloc);
1117 // }
1118 // if( zNew ){
1119 // if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
1120 // p->zText = zNew;
1121 // }else{
1122 // p->mallocFailed = 1;
1123 // sqlite3StrAccumReset(p);
1124 // return;
1125 // }
1126 // }
1127 //}
1128 //memcpy(&p->zText[p->nChar], z, N);
1129 p.zText.Append( z.Substring( 0, N <= z.Length ? N : z.Length ) );
1130 //p.nChar += N;
1131 }
1132  
1133 /*
1134 ** Finish off a string by making sure it is zero-terminated.
1135 ** Return a pointer to the resulting string. Return a NULL
1136 ** pointer if any kind of error was encountered.
1137 */
1138 static string sqlite3StrAccumFinish( StrAccum p )
1139 {
1140 //if ( p->zText )
1141 //{
1142 // p->zText[p->nChar] = 0;
1143 // if ( p->useMalloc && p->zText == p->zBase )
1144 // {
1145 // if ( p->useMalloc == 1 )
1146 // {
1147 // p->zText = sqlite3DbMallocRaw( p->db, p->nChar + 1 );
1148 // }
1149 // else
1150 // {
1151 // p->zText = sqlite3_malloc( p->nChar + 1 );
1152 // }
1153 // if ( p->zText )
1154 // {
1155 // memcpy( p->zText, p->zBase, p->nChar + 1 );
1156 // }
1157 // else
1158 // {
1159 // p->mallocFailed = 1;
1160 // }
1161 // }
1162 //}
1163 return p.zText.ToString();
1164 }
1165  
1166 /*
1167 ** Reset an StrAccum string. Reclaim all malloced memory.
1168 */
1169 static void sqlite3StrAccumReset( StrAccum p )
1170 {
1171 //if ( p.zText.ToString() != p.zBase.ToString() )
1172 //{
1173 // if ( p.useMalloc == 1 )
1174 // {
1175 // sqlite3DbFree( p.db, ref p.zText );
1176 // }
1177 // else
1178 // {
1179 // sqlite3_free( ref p.zText );
1180 // }
1181 //}
1182 p.zText.Length = 0;
1183 }
1184  
1185 /*
1186 ** Initialize a string accumulator
1187 */
1188 static void sqlite3StrAccumInit( StrAccum p, StringBuilder zBase, int n, int mx )
1189 {
1190 //p.zBase.Length = 0;
1191 //if ( p.zBase.Capacity < n )
1192 // p.zBase.Capacity = n;
1193 p.zText.Length = 0;
1194 if ( p.zText.Capacity < n )
1195 p.zText.Capacity = n;
1196 p.db = null;
1197 //p.nChar = 0;
1198 //p.nAlloc = n;
1199 p.mxAlloc = mx;
1200 //p.useMalloc = 1;
1201 //p.tooBig = 0;
1202 //p.mallocFailed = 0;
1203 }
1204 /*
1205 ** Print into memory obtained from sqliteMalloc(). Use the internal
1206 ** %-conversion extensions.
1207 */
1208 static StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1209 static string sqlite3VMPrintf( sqlite3 db, string zFormat, params va_list[] ap )
1210 {
1211 if ( zFormat == null )
1212 return null;
1213 if ( ap.Length == 0 )
1214 return zFormat;
1215 //string z;
1216 Debug.Assert( db != null );
1217 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE,
1218 db.aLimit[SQLITE_LIMIT_LENGTH] );
1219 acc.db = db;
1220 acc.zText.Length = 0;
1221 sqlite3VXPrintf( acc, 1, zFormat, ap );
1222 // if ( acc.mallocFailed != 0 )
1223 // {
1224 ////// db.mallocFailed = 1;
1225 // }
1226 return sqlite3StrAccumFinish( acc );
1227 }
1228  
1229 /*
1230 ** Print into memory obtained from sqliteMalloc(). Use the internal
1231 ** %-conversion extensions.
1232 */
1233 static string sqlite3MPrintf( sqlite3 db, string zFormat, params va_list[] ap )
1234 {
1235 string z;
1236 //va_list ap;
1237 lock ( lock_va_list )
1238 {
1239 va_start( ap, zFormat );
1240 z = sqlite3VMPrintf( db, zFormat, ap );
1241 va_end( ref ap );
1242 }
1243 return z;
1244 }
1245  
1246 /*
1247 ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
1248 ** the string and before returnning. This routine is intended to be used
1249 ** to modify an existing string. For example:
1250 **
1251 ** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
1252 **
1253 */
1254 static string sqlite3MAppendf( sqlite3 db, string zStr, string zFormat, params va_list[] ap )
1255 {
1256 string z;
1257 //va_list ap;
1258 lock ( lock_va_list )
1259 {
1260 va_start( ap, zFormat );
1261 z = sqlite3VMPrintf( db, zFormat, ap );
1262 va_end( ref ap );
1263 sqlite3DbFree( db, ref zStr );
1264 }
1265 return z;
1266 }
1267  
1268 /*
1269 ** Print into memory obtained from sqlite3Malloc(). Omit the internal
1270 ** %-conversion extensions.
1271 */
1272 static string sqlite3_vmprintf( string zFormat, params va_list[] ap )
1273 {
1274 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1275 #if !SQLITE_OMIT_AUTOINIT
1276 if ( sqlite3_initialize() != 0 )
1277 return string.Empty;
1278 #endif
1279 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE, SQLITE_PRINT_BUF_SIZE );//zBase).Length;
1280 //acc.useMalloc = 2;
1281 sqlite3VXPrintf( acc, 0, zFormat, ap );
1282 return sqlite3StrAccumFinish( acc );
1283 }
1284  
1285 /*
1286 ** Print into memory obtained from sqlite3Malloc()(). Omit the internal
1287 ** %-conversion extensions.
1288 */
1289 static public string sqlite3_mprintf( string zFormat, params va_list[] ap )
1290 { //, ...){
1291 string z;
1292 #if !SQLITE_OMIT_AUTOINIT
1293 if ( sqlite3_initialize() != 0 )
1294 return string.Empty;
1295 #endif
1296 //va_list ap;
1297 lock ( lock_va_list )
1298 {
1299 va_start( ap, zFormat );
1300 z = sqlite3_vmprintf( zFormat, ap );
1301 va_end( ref ap );
1302 }
1303 return z;
1304 }
1305  
1306 /*
1307 ** sqlite3_snprintf() works like snprintf() except that it ignores the
1308 ** current locale settings. This is important for SQLite because we
1309 ** are not able to use a "," as the decimal point in place of "." as
1310 ** specified by some locales.
1311 **
1312 ** Oops: The first two arguments of sqlite3_snprintf() are backwards
1313 ** from the snprintf() standard. Unfortunately, it is too late to change
1314 ** this without breaking compatibility, so we just have to live with the
1315 ** mistake.
1316 **
1317 ** sqlite3_vsnprintf() is the varargs version.
1318 */
1319 static public void sqlite3_vsnprintf( int n, StringBuilder zBuf, string zFormat, params va_list[] ap )
1320 {
1321 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1322 if ( n <= 0 )
1323 return;
1324 sqlite3StrAccumInit( acc, null, n, 0 );
1325 //acc.useMalloc = 0;
1326 sqlite3VXPrintf( acc, 0, zFormat, ap );
1327 zBuf.Length = 0;
1328 if ( n > 1 && n <= acc.zText.Length )
1329 acc.zText.Length = n - 1;
1330 zBuf.Append( sqlite3StrAccumFinish( acc ) );
1331 return;
1332 }
1333  
1334 static public void sqlite3_snprintf( int n, StringBuilder zBuf, string zFormat, params va_list[] ap )
1335 {
1336 //string z;
1337 //va_list ap;
1338 lock ( lock_va_list )
1339 {//StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1340 zBuf.EnsureCapacity( SQLITE_PRINT_BUF_SIZE );
1341 va_start( ap, zFormat );
1342 sqlite3_vsnprintf( n, zBuf, zFormat, ap );
1343 va_end( ref ap );
1344 }
1345 return;
1346 }
1347  
1348 //static public string sqlite3_snprintf( int n, ref string zBuf, string zFormat, params va_list[] ap )
1349 //{
1350 // string z;
1351 // //va_list ap;
1352 // StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1353  
1354 // if ( n <= 0 )
1355 // {
1356 // return zBuf;
1357 // }
1358 // sqlite3StrAccumInit( acc, null, n, 0 );
1359 // //acc.useMalloc = 0;
1360 // va_start( ap, zFormat );
1361 // sqlite3VXPrintf( acc, 0, zFormat, ap );
1362 // va_end( ap );
1363 // z = sqlite3StrAccumFinish( acc );
1364 // return ( zBuf = z );
1365 //}
1366  
1367 /*
1368 ** This is the routine that actually formats the sqlite3_log() message.
1369 ** We house it in a separate routine from sqlite3_log() to avoid using
1370 ** stack space on small-stack systems when logging is disabled.
1371 **
1372 ** sqlite3_log() must render into a static buffer. It cannot dynamically
1373 ** allocate memory because it might be called while the memory allocator
1374 ** mutex is held.
1375 */
1376 static void renderLogMsg( int iErrCode, string zFormat, params object[] ap )
1377 {
1378 //StrAccum acc; /* String accumulator */
1379 //char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */
1380  
1381 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE * 3, 0 );
1382 //acc.useMalloc = 0;
1383 sqlite3VXPrintf( acc, 0, zFormat, ap );
1384 sqlite3GlobalConfig.xLog( sqlite3GlobalConfig.pLogArg, iErrCode,
1385 sqlite3StrAccumFinish( acc ) );
1386 }
1387  
1388 /*
1389 ** Format and write a message to the log if logging is enabled.
1390 */
1391 static void sqlite3_log( int iErrCode, string zFormat, params va_list[] ap )
1392 {
1393 if ( sqlite3GlobalConfig.xLog != null )
1394 {
1395 //va_list ap; /* Vararg list */
1396 lock ( lock_va_list )
1397 {
1398 va_start( ap, zFormat );
1399 renderLogMsg( iErrCode, zFormat, ap );
1400 va_end( ref ap );
1401 }
1402 }
1403 }
1404  
1405 #if SQLITE_DEBUG || DEBUG || TRACE
1406 /*
1407 ** A version of printf() that understands %lld. Used for debugging.
1408 ** The printf() built into some versions of windows does not understand %lld
1409 ** and segfaults if you give it a long long int.
1410 */
1411 static void sqlite3DebugPrintf( string zFormat, params va_list[] ap )
1412 {
1413 //va_list ap;
1414 lock ( lock_va_list )
1415 {
1416 //StrAccum acc = new StrAccum( SQLITE_PRINT_BUF_SIZE );
1417 sqlite3StrAccumInit( acc, null, SQLITE_PRINT_BUF_SIZE, 0 );
1418 //acc.useMalloc = 0;
1419 va_start( ap, zFormat );
1420 sqlite3VXPrintf( acc, 0, zFormat, ap );
1421 va_end( ref ap );
1422 }
1423 Console.Write( sqlite3StrAccumFinish( acc ) );
1424 //fflush(stdout);
1425 }
1426 #endif
1427 #if !SQLITE_OMIT_TRACE
1428 /*
1429 ** variable-argument wrapper around sqlite3VXPrintf().
1430 */
1431 static void sqlite3XPrintf( StrAccum p, string zFormat, params object[] ap )
1432 {
1433 //va_list ap;
1434 lock ( lock_va_list )
1435 {
1436 va_start( ap, zFormat );
1437 sqlite3VXPrintf( p, 1, zFormat, ap );
1438 va_end( ref ap );
1439 }
1440 }
1441 #endif
1442  
1443 }
1444 }