| | @@ -208,12 +208,10 @@ |
| 208 | 208 | # define unlink _unlink |
| 209 | 209 | # endif |
| 210 | 210 | # ifndef strdup |
| 211 | 211 | # define strdup _strdup |
| 212 | 212 | # endif |
| 213 | | -# undef popen |
| 214 | | -# define popen _popen |
| 215 | 213 | # undef pclose |
| 216 | 214 | # define pclose _pclose |
| 217 | 215 | # endif |
| 218 | 216 | #else |
| 219 | 217 | /* Make sure isatty() has a prototype. */ |
| | @@ -253,10 +251,283 @@ |
| 253 | 251 | /* string conversion routines only needed on Win32 */ |
| 254 | 252 | extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); |
| 255 | 253 | extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); |
| 256 | 254 | #endif |
| 257 | 255 | |
| 256 | +/************************* Begin ../ext/misc/sqlite3_stdio.h ******************/ |
| 257 | +/* |
| 258 | +** 2024-09-24 |
| 259 | +** |
| 260 | +** The author disclaims copyright to this source code. In place of |
| 261 | +** a legal notice, here is a blessing: |
| 262 | +** |
| 263 | +** May you do good and not evil. |
| 264 | +** May you find forgiveness for yourself and forgive others. |
| 265 | +** May you share freely, never taking more than you give. |
| 266 | +** |
| 267 | +************************************************************************* |
| 268 | +** |
| 269 | +** This header file contains definitions of interfaces that provide |
| 270 | +** cross-platform I/O for UTF-8 content. |
| 271 | +** |
| 272 | +** On most platforms, the interfaces definitions in this file are |
| 273 | +** just #defines. For example sqlite3_fopen() is a macro that resolves |
| 274 | +** to the standard fopen() in the C-library. |
| 275 | +** |
| 276 | +** But Windows does not have a standard C-library, at least not one that |
| 277 | +** can handle UTF-8. So for windows build, the interfaces resolve to new |
| 278 | +** C-language routines contained in the separate sqlite3_stdio.c source file. |
| 279 | +** |
| 280 | +** So on all non-Windows platforms, simply #include this header file and |
| 281 | +** use the interfaces defined herein. Then to run your application on Windows, |
| 282 | +** also link in the accompanying sqlite3_stdio.c source file when compiling |
| 283 | +** to get compatible interfaces. |
| 284 | +*/ |
| 285 | +#ifndef _SQLITE3_STDIO_H_ |
| 286 | +#define _SQLITE3_STDIO_H_ 1 |
| 287 | +#ifdef _WIN32 |
| 288 | +/**** Definitions For Windows ****/ |
| 289 | +#include <stdio.h> |
| 290 | +#include <windows.h> |
| 291 | + |
| 292 | +FILE *sqlite3_fopen(const char *zFilename, const char *zMode); |
| 293 | +FILE *sqlite3_popen(const char *zCommand, const char *type); |
| 294 | +char *sqlite3_fgets(char *s, int size, FILE *stream); |
| 295 | +int sqlite3_fputs(const char *s, FILE *stream); |
| 296 | +int sqlite3_fprintf(FILE *stream, const char *format, ...); |
| 297 | +void sqlite3_fsetmode(FILE *stream, int mode); |
| 298 | + |
| 299 | + |
| 300 | +#else |
| 301 | +/**** Definitions For All Other Platforms ****/ |
| 302 | +#include <stdio.h> |
| 303 | +#define sqlite3_fopen fopen |
| 304 | +#define sqlite3_popen popen |
| 305 | +#define sqlite3_fgets fgets |
| 306 | +#define sqlite3_fputs fputs |
| 307 | +#define sqlite3_fprintf fprintf |
| 308 | +#define sqlite3_fsetmode(F,X) /*no-op*/ |
| 309 | + |
| 310 | +#endif |
| 311 | +#endif /* _SQLITE3_STDIO_H_ */ |
| 312 | + |
| 313 | +/************************* End ../ext/misc/sqlite3_stdio.h ********************/ |
| 314 | +/************************* Begin ../ext/misc/sqlite3_stdio.c ******************/ |
| 315 | +/* |
| 316 | +** 2024-09-24 |
| 317 | +** |
| 318 | +** The author disclaims copyright to this source code. In place of |
| 319 | +** a legal notice, here is a blessing: |
| 320 | +** |
| 321 | +** May you do good and not evil. |
| 322 | +** May you find forgiveness for yourself and forgive others. |
| 323 | +** May you share freely, never taking more than you give. |
| 324 | +** |
| 325 | +************************************************************************* |
| 326 | +** |
| 327 | +** Implementation of standard I/O interfaces for UTF-8 that are missing |
| 328 | +** on Windows. |
| 329 | +*/ |
| 330 | +#ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ |
| 331 | +#ifndef _SQLITE3_STDIO_H_ |
| 332 | +/* #include "sqlite3_stdio.h" */ |
| 333 | +#endif |
| 334 | +#undef WIN32_LEAN_AND_MEAN |
| 335 | +#define WIN32_LEAN_AND_MEAN |
| 336 | +#include <windows.h> |
| 337 | +#include <stdlib.h> |
| 338 | +#include <string.h> |
| 339 | +#include <stdio.h> |
| 340 | +#include <assert.h> |
| 341 | +/* #include "sqlite3.h" */ |
| 342 | +#include <ctype.h> |
| 343 | +#include <stdarg.h> |
| 344 | +#include <io.h> |
| 345 | +#include <fcntl.h> |
| 346 | + |
| 347 | +/* |
| 348 | +** If the SQLITE_U8TEXT_ONLY option is defined, then only use |
| 349 | +** _O_U8TEXT, _O_WTEXT, and similar together with the UTF-16 |
| 350 | +** interfaces to the Windows CRT. The use of ANSI-only routines |
| 351 | +** like fputs() and ANSI modes like _O_TEXT and _O_BINARY is |
| 352 | +** avoided. |
| 353 | +** |
| 354 | +** The downside of using SQLITE_U8TEXT_ONLY is that it becomes |
| 355 | +** impossible to output a bare newline character (0x0a) - that is, |
| 356 | +** a newline that is not preceded by a carriage return (0x0d). |
| 357 | +** And without that capability, sometimes the output will be slightly |
| 358 | +** incorrect, as extra 0x0d characters will have been inserted where |
| 359 | +** they do not belong. |
| 360 | +** |
| 361 | +** The SQLITE_U8TEXT_STDIO compile-time option is a compromise. |
| 362 | +** It always enables _O_WTEXT or similar for stdin, stdout, stderr, |
| 363 | +** but allows other streams to be _O_TEXT and/or O_BINARY. The |
| 364 | +** SQLITE_U8TEXT_STDIO option has the same downside as SQLITE_U8TEXT_ONLY |
| 365 | +** in that stray 0x0d characters might appear where they ought not, but |
| 366 | +** at least with this option those characters only appear on standard |
| 367 | +** I/O streams, and not on new streams that might be created by the |
| 368 | +** application using sqlite3_fopen() or sqlite3_popen(). |
| 369 | +*/ |
| 370 | +#if defined(SQLITE_U8TEXT_ONLY) |
| 371 | +# define UseWtextForOutput(fd) 1 |
| 372 | +# define UseWtextForInput(fd) 1 |
| 373 | +# define IsConsole(fd) _isatty(_fileno(fd)) |
| 374 | +#elif defined(SQLITE_U8TEXT_STDIO) |
| 375 | +# define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) |
| 376 | +# define UseWtextForInput(fd) ((fd)==stdin) |
| 377 | +# define IsConsole(fd) _isatty(_fileno(fd)) |
| 378 | +#else |
| 379 | +# define UseWtextForOutput(fd) _isatty(_fileno(fd)) |
| 380 | +# define UseWtextForInput(fd) _isatty(_fileno(fd)) |
| 381 | +# define IsConsole(fd) 1 |
| 382 | +#endif |
| 383 | + |
| 384 | +/* |
| 385 | +** Work-alike for the fopen() routine from the standard C library. |
| 386 | +*/ |
| 387 | +FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ |
| 388 | + FILE *fp = 0; |
| 389 | + wchar_t *b1, *b2; |
| 390 | + int sz1, sz2; |
| 391 | + |
| 392 | + sz1 = (int)strlen(zFilename); |
| 393 | + sz2 = (int)strlen(zMode); |
| 394 | + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); |
| 395 | + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); |
| 396 | + if( b1 && b2 ){ |
| 397 | + sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); |
| 398 | + b1[sz1] = 0; |
| 399 | + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); |
| 400 | + b2[sz2] = 0; |
| 401 | + fp = _wfopen(b1, b2); |
| 402 | + } |
| 403 | + free(b1); |
| 404 | + free(b2); |
| 405 | + return fp; |
| 406 | +} |
| 407 | + |
| 408 | + |
| 409 | +/* |
| 410 | +** Work-alike for the popen() routine from the standard C library. |
| 411 | +*/ |
| 412 | +FILE *sqlite3_popen(const char *zCommand, const char *zMode){ |
| 413 | + FILE *fp = 0; |
| 414 | + wchar_t *b1, *b2; |
| 415 | + int sz1, sz2; |
| 416 | + |
| 417 | + sz1 = (int)strlen(zCommand); |
| 418 | + sz2 = (int)strlen(zMode); |
| 419 | + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); |
| 420 | + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); |
| 421 | + if( b1 && b2 ){ |
| 422 | + sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); |
| 423 | + b1[sz1] = 0; |
| 424 | + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); |
| 425 | + b2[sz2] = 0; |
| 426 | + fp = _wpopen(b1, b2); |
| 427 | + } |
| 428 | + free(b1); |
| 429 | + free(b2); |
| 430 | + return fp; |
| 431 | +} |
| 432 | + |
| 433 | +/* |
| 434 | +** Work-alike for fgets() from the standard C library. |
| 435 | +*/ |
| 436 | +char *sqlite3_fgets(char *buf, int sz, FILE *in){ |
| 437 | + if( UseWtextForInput(in) ){ |
| 438 | + /* When reading from the command-prompt in Windows, it is necessary |
| 439 | + ** to use _O_WTEXT input mode to read UTF-16 characters, then translate |
| 440 | + ** that into UTF-8. Otherwise, non-ASCII characters all get translated |
| 441 | + ** into '?'. |
| 442 | + */ |
| 443 | + wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); |
| 444 | + if( b1==0 ) return 0; |
| 445 | + _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); |
| 446 | + if( fgetws(b1, sz/4, in)==0 ){ |
| 447 | + sqlite3_free(b1); |
| 448 | + return 0; |
| 449 | + } |
| 450 | + WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); |
| 451 | + sqlite3_free(b1); |
| 452 | + return buf; |
| 453 | + }else{ |
| 454 | + /* Reading from a file or other input source, just read bytes without |
| 455 | + ** any translation. */ |
| 456 | + return fgets(buf, sz, in); |
| 457 | + } |
| 458 | +} |
| 459 | + |
| 460 | +/* |
| 461 | +** Work-alike for fputs() from the standard C library. |
| 462 | +*/ |
| 463 | +int sqlite3_fputs(const char *z, FILE *out){ |
| 464 | + if( UseWtextForOutput(out) ){ |
| 465 | + /* When writing to the command-prompt in Windows, it is necessary |
| 466 | + ** to use _O_WTEXT input mode and write UTF-16 characters. |
| 467 | + */ |
| 468 | + int sz = (int)strlen(z); |
| 469 | + wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); |
| 470 | + if( b1==0 ) return 0; |
| 471 | + sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); |
| 472 | + b1[sz] = 0; |
| 473 | + _setmode(_fileno(out), _O_U8TEXT); |
| 474 | + fputws(b1, out); |
| 475 | + sqlite3_free(b1); |
| 476 | + return 0; |
| 477 | + }else{ |
| 478 | + /* Writing to a file or other destination, just write bytes without |
| 479 | + ** any translation. */ |
| 480 | + return fputs(z, out); |
| 481 | + } |
| 482 | +} |
| 483 | + |
| 484 | + |
| 485 | +/* |
| 486 | +** Work-alike for fprintf() from the standard C library. |
| 487 | +*/ |
| 488 | +int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ |
| 489 | + int rc; |
| 490 | + if( UseWtextForOutput(out) ){ |
| 491 | + /* When writing to the command-prompt in Windows, it is necessary |
| 492 | + ** to use _O_WTEXT input mode and write UTF-16 characters. |
| 493 | + */ |
| 494 | + char *z; |
| 495 | + va_list ap; |
| 496 | + |
| 497 | + va_start(ap, zFormat); |
| 498 | + z = sqlite3_vmprintf(zFormat, ap); |
| 499 | + va_end(ap); |
| 500 | + sqlite3_fputs(z, out); |
| 501 | + rc = (int)strlen(z); |
| 502 | + sqlite3_free(z); |
| 503 | + }else{ |
| 504 | + /* Writing to a file or other destination, just write bytes without |
| 505 | + ** any translation. */ |
| 506 | + va_list ap; |
| 507 | + va_start(ap, zFormat); |
| 508 | + rc = vfprintf(out, zFormat, ap); |
| 509 | + va_end(ap); |
| 510 | + } |
| 511 | + return rc; |
| 512 | +} |
| 513 | + |
| 514 | +/* |
| 515 | +** Set the mode for an output stream. mode argument is typically _O_BINARY or |
| 516 | +** _O_TEXT. |
| 517 | +*/ |
| 518 | +void sqlite3_fsetmode(FILE *fp, int mode){ |
| 519 | + if( !UseWtextForOutput(fp) ){ |
| 520 | + fflush(fp); |
| 521 | + _setmode(_fileno(fp), mode); |
| 522 | + } |
| 523 | +} |
| 524 | + |
| 525 | +#endif /* defined(_WIN32) */ |
| 526 | + |
| 527 | +/************************* End ../ext/misc/sqlite3_stdio.c ********************/ |
| 528 | + |
| 258 | 529 | /* Use console I/O package as a direct INCLUDE. */ |
| 259 | 530 | #define SQLITE_INTERNAL_LINKAGE static |
| 260 | 531 | |
| 261 | 532 | #ifdef SQLITE_SHELL_FIDDLE |
| 262 | 533 | /* Deselect most features from the console I/O package for Fiddle. */ |
| | @@ -264,1125 +535,13 @@ |
| 264 | 535 | # define SQLITE_CIO_NO_CLASSIFY |
| 265 | 536 | # define SQLITE_CIO_NO_TRANSLATE |
| 266 | 537 | # define SQLITE_CIO_NO_SETMODE |
| 267 | 538 | # define SQLITE_CIO_NO_FLUSH |
| 268 | 539 | #endif |
| 269 | | -/************************* Begin ../ext/consio/console_io.h ******************/ |
| 270 | | -/* |
| 271 | | -** 2023 November 1 |
| 272 | | -** |
| 273 | | -** The author disclaims copyright to this source code. In place of |
| 274 | | -** a legal notice, here is a blessing: |
| 275 | | -** |
| 276 | | -** May you do good and not evil. |
| 277 | | -** May you find forgiveness for yourself and forgive others. |
| 278 | | -** May you share freely, never taking more than you give. |
| 279 | | -** |
| 280 | | -******************************************************************************** |
| 281 | | -** This file exposes various interfaces used for console and other I/O |
| 282 | | -** by the SQLite project command-line tools. These interfaces are used |
| 283 | | -** at either source conglomeration time, compilation time, or run time. |
| 284 | | -** This source provides for either inclusion into conglomerated, |
| 285 | | -** "single-source" forms or separate compilation then linking. |
| 286 | | -** |
| 287 | | -** Platform dependencies are "hidden" here by various stratagems so |
| 288 | | -** that, provided certain conditions are met, the programs using this |
| 289 | | -** source or object code compiled from it need no explicit conditional |
| 290 | | -** compilation in their source for their console and stream I/O. |
| 291 | | -** |
| 292 | | -** The symbols and functionality exposed here are not a public API. |
| 293 | | -** This code may change in tandem with other project code as needed. |
| 294 | | -** |
| 295 | | -** When this .h file and its companion .c are directly incorporated into |
| 296 | | -** a source conglomeration (such as shell.c), the preprocessor symbol |
| 297 | | -** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O |
| 298 | | -** translation for Windows is effected for the build. |
| 299 | | -*/ |
| 300 | | -#define HAVE_CONSOLE_IO_H 1 |
| 301 | | -#ifndef SQLITE_INTERNAL_LINKAGE |
| 302 | | -# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */ |
| 303 | | -# include <stdio.h> |
| 304 | | -#else |
| 305 | | -# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */ |
| 306 | | -#endif |
| 307 | | - |
| 308 | | -#ifndef SQLITE3_H |
| 309 | | -/* # include "sqlite3.h" */ |
| 310 | | -#endif |
| 311 | | - |
| 312 | | -#ifndef SQLITE_CIO_NO_CLASSIFY |
| 313 | | - |
| 314 | | -/* Define enum for use with following function. */ |
| 315 | | -typedef enum StreamsAreConsole { |
| 316 | | - SAC_NoConsole = 0, |
| 317 | | - SAC_InConsole = 1, SAC_OutConsole = 2, SAC_ErrConsole = 4, |
| 318 | | - SAC_AnyConsole = 0x7 |
| 319 | | -} StreamsAreConsole; |
| 320 | | - |
| 321 | | -/* |
| 322 | | -** Classify the three standard I/O streams according to whether |
| 323 | | -** they are connected to a console attached to the process. |
| 324 | | -** |
| 325 | | -** Returns the bit-wise OR of SAC_{In,Out,Err}Console values, |
| 326 | | -** or SAC_NoConsole if none of the streams reaches a console. |
| 327 | | -** |
| 328 | | -** This function should be called before any I/O is done with |
| 329 | | -** the given streams. As a side-effect, the given inputs are |
| 330 | | -** recorded so that later I/O operations on them may be done |
| 331 | | -** differently than the C library FILE* I/O would be done, |
| 332 | | -** iff the stream is used for the I/O functions that follow, |
| 333 | | -** and to support the ones that use an implicit stream. |
| 334 | | -** |
| 335 | | -** On some platforms, stream or console mode alteration (aka |
| 336 | | -** "Setup") may be made which is undone by consoleRestore(). |
| 337 | | -*/ |
| 338 | | -SQLITE_INTERNAL_LINKAGE StreamsAreConsole |
| 339 | | -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ); |
| 340 | | -/* A usual call for convenience: */ |
| 341 | | -#define SQLITE_STD_CONSOLE_INIT() consoleClassifySetup(stdin,stdout,stderr) |
| 342 | | - |
| 343 | | -/* |
| 344 | | -** After an initial call to consoleClassifySetup(...), renew |
| 345 | | -** the same setup it effected. (A call not after is an error.) |
| 346 | | -** This will restore state altered by consoleRestore(); |
| 347 | | -** |
| 348 | | -** Applications which run an inferior (child) process which |
| 349 | | -** inherits the same I/O streams may call this function after |
| 350 | | -** such a process exits to guard against console mode changes. |
| 351 | | -*/ |
| 352 | | -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void); |
| 353 | | - |
| 354 | | -/* |
| 355 | | -** Undo any side-effects left by consoleClassifySetup(...). |
| 356 | | -** |
| 357 | | -** This should be called after consoleClassifySetup() and |
| 358 | | -** before the process terminates normally. It is suitable |
| 359 | | -** for use with the atexit() C library procedure. After |
| 360 | | -** this call, no console I/O should be done until one of |
| 361 | | -** console{Classify or Renew}Setup(...) is called again. |
| 362 | | -** |
| 363 | | -** Applications which run an inferior (child) process that |
| 364 | | -** inherits the same I/O streams might call this procedure |
| 365 | | -** before so that said process will have a console setup |
| 366 | | -** however users have configured it or come to expect. |
| 367 | | -*/ |
| 368 | | -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ); |
| 369 | | - |
| 370 | | -#else /* defined(SQLITE_CIO_NO_CLASSIFY) */ |
| 371 | | -# define consoleClassifySetup(i,o,e) |
| 372 | | -# define consoleRenewSetup() |
| 373 | | -# define consoleRestore() |
| 374 | | -#endif /* defined(SQLITE_CIO_NO_CLASSIFY) */ |
| 375 | | - |
| 376 | | -#ifndef SQLITE_CIO_NO_REDIRECT |
| 377 | | -/* |
| 378 | | -** Set stream to be used for the functions below which write |
| 379 | | -** to "the designated X stream", where X is Output or Error. |
| 380 | | -** Returns the previous value. |
| 381 | | -** |
| 382 | | -** Alternatively, pass the special value, invalidFileStream, |
| 383 | | -** to get the designated stream value without setting it. |
| 384 | | -** |
| 385 | | -** Before the designated streams are set, they default to |
| 386 | | -** those passed to consoleClassifySetup(...), and before |
| 387 | | -** that is called they default to stdout and stderr. |
| 388 | | -** |
| 389 | | -** It is error to close a stream so designated, then, without |
| 390 | | -** designating another, use the corresponding {o,e}Emit(...). |
| 391 | | -*/ |
| 392 | | -SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream; |
| 393 | | -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf); |
| 394 | | -# ifdef CONSIO_SET_ERROR_STREAM |
| 395 | | -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf); |
| 396 | | -# endif |
| 397 | | -#else |
| 398 | | -# define setOutputStream(pf) |
| 399 | | -# define setErrorStream(pf) |
| 400 | | -#endif /* !defined(SQLITE_CIO_NO_REDIRECT) */ |
| 401 | | - |
| 402 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 403 | | -/* |
| 404 | | -** Emit output like fprintf(). If the output is going to the |
| 405 | | -** console and translation from UTF-8 is necessary, perform |
| 406 | | -** the needed translation. Otherwise, write formatted output |
| 407 | | -** to the provided stream almost as-is, possibly with newline |
| 408 | | -** translation as specified by set{Binary,Text}Mode(). |
| 409 | | -*/ |
| 410 | | -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...); |
| 411 | | -/* Like fPrintfUtf8 except stream is always the designated output. */ |
| 412 | | -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...); |
| 413 | | -/* Like fPrintfUtf8 except stream is always the designated error. */ |
| 414 | | -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...); |
| 415 | | - |
| 416 | | -/* |
| 417 | | -** Emit output like fputs(). If the output is going to the |
| 418 | | -** console and translation from UTF-8 is necessary, perform |
| 419 | | -** the needed translation. Otherwise, write given text to the |
| 420 | | -** provided stream almost as-is, possibly with newline |
| 421 | | -** translation as specified by set{Binary,Text}Mode(). |
| 422 | | -*/ |
| 423 | | -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO); |
| 424 | | -/* Like fPutsUtf8 except stream is always the designated output. */ |
| 425 | | -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z); |
| 426 | | -/* Like fPutsUtf8 except stream is always the designated error. */ |
| 427 | | -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z); |
| 428 | | - |
| 429 | | -/* |
| 430 | | -** Emit output like fPutsUtf8(), except that the length of the |
| 431 | | -** accepted char or character sequence is limited by nAccept. |
| 432 | | -** |
| 433 | | -** Returns the number of accepted char values. |
| 434 | | -*/ |
| 435 | | -#ifdef CONSIO_SPUTB |
| 436 | | -SQLITE_INTERNAL_LINKAGE int |
| 437 | | -fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept); |
| 438 | | -/* Like fPutbUtf8 except stream is always the designated output. */ |
| 439 | | -#endif |
| 440 | | -SQLITE_INTERNAL_LINKAGE int |
| 441 | | -oPutbUtf8(const char *cBuf, int nAccept); |
| 442 | | -/* Like fPutbUtf8 except stream is always the designated error. */ |
| 443 | | -#ifdef CONSIO_EPUTB |
| 444 | | -SQLITE_INTERNAL_LINKAGE int |
| 445 | | -ePutbUtf8(const char *cBuf, int nAccept); |
| 446 | | -#endif |
| 447 | | - |
| 448 | | -/* |
| 449 | | -** Flush the given output stream. Return non-zero for success, else 0. |
| 450 | | -*/ |
| 451 | | -#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE) |
| 452 | | -SQLITE_INTERNAL_LINKAGE int |
| 453 | | -fFlushBuffer(FILE *pfOut); |
| 454 | | -#endif |
| 455 | | - |
| 456 | | -/* |
| 457 | | -** Collect input like fgets(...) with special provisions for input |
| 458 | | -** from the console on such platforms as require same. Newline |
| 459 | | -** translation may be done as set by set{Binary,Text}Mode(). |
| 460 | | -** As a convenience, pfIn==NULL is treated as stdin. |
| 461 | | -*/ |
| 462 | | -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn); |
| 463 | | -/* Like fGetsUtf8 except stream is always the designated input. */ |
| 464 | | -/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */ |
| 465 | | - |
| 466 | | -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ |
| 467 | | - |
| 468 | | -#ifndef SQLITE_CIO_NO_SETMODE |
| 469 | | -/* |
| 470 | | -** Set given stream for binary mode, where newline translation is |
| 471 | | -** not done, or for text mode where, for some platforms, newlines |
| 472 | | -** are translated to the platform's conventional char sequence. |
| 473 | | -** If bFlush true, flush the stream. |
| 474 | | -** |
| 475 | | -** An additional side-effect is that if the stream is one passed |
| 476 | | -** to consoleClassifySetup() as an output, it is flushed first. |
| 477 | | -** |
| 478 | | -** Note that binary/text mode has no effect on console I/O |
| 479 | | -** translation. On all platforms, newline to the console starts |
| 480 | | -** a new line and CR,LF chars from the console become a newline. |
| 481 | | -*/ |
| 482 | | -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *, short bFlush); |
| 483 | | -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *, short bFlush); |
| 484 | | -#endif |
| 485 | | - |
| 486 | | -#ifdef SQLITE_CIO_PROMPTED_IN |
| 487 | | -typedef struct Prompts { |
| 488 | | - int numPrompts; |
| 489 | | - const char **azPrompts; |
| 490 | | -} Prompts; |
| 491 | | - |
| 492 | | -/* |
| 493 | | -** Macros for use of a line editor. |
| 494 | | -** |
| 495 | | -** The following macros define operations involving use of a |
| 496 | | -** line-editing library or simple console interaction. |
| 497 | | -** A "T" argument is a text (char *) buffer or filename. |
| 498 | | -** A "N" argument is an integer. |
| 499 | | -** |
| 500 | | -** SHELL_ADD_HISTORY(T) // Record text as line(s) of history. |
| 501 | | -** SHELL_READ_HISTORY(T) // Read history from file named by T. |
| 502 | | -** SHELL_WRITE_HISTORY(T) // Write history to file named by T. |
| 503 | | -** SHELL_STIFLE_HISTORY(N) // Limit history to N entries. |
| 504 | | -** |
| 505 | | -** A console program which does interactive console input is |
| 506 | | -** expected to call: |
| 507 | | -** SHELL_READ_HISTORY(T) before collecting such input; |
| 508 | | -** SHELL_ADD_HISTORY(T) as record-worthy input is taken; |
| 509 | | -** SHELL_STIFLE_HISTORY(N) after console input ceases; then |
| 510 | | -** SHELL_WRITE_HISTORY(T) before the program exits. |
| 511 | | -*/ |
| 512 | | - |
| 513 | | -/* |
| 514 | | -** Retrieve a single line of input text from an input stream. |
| 515 | | -** |
| 516 | | -** If pfIn is the input stream passed to consoleClassifySetup(), |
| 517 | | -** and azPrompt is not NULL, then a prompt is issued before the |
| 518 | | -** line is collected, as selected by the isContinuation flag. |
| 519 | | -** Array azPrompt[{0,1}] holds the {main,continuation} prompt. |
| 520 | | -** |
| 521 | | -** If zBufPrior is not NULL then it is a buffer from a prior |
| 522 | | -** call to this routine that can be reused, or will be freed. |
| 523 | | -** |
| 524 | | -** The result is stored in space obtained from malloc() and |
| 525 | | -** must either be freed by the caller or else passed back to |
| 526 | | -** this function as zBufPrior for reuse. |
| 527 | | -** |
| 528 | | -** This function may call upon services of a line-editing |
| 529 | | -** library to interactively collect line edited input. |
| 530 | | -*/ |
| 531 | | -SQLITE_INTERNAL_LINKAGE char * |
| 532 | | -shellGetLine(FILE *pfIn, char *zBufPrior, int nLen, |
| 533 | | - short isContinuation, Prompts azPrompt); |
| 534 | | -#endif /* defined(SQLITE_CIO_PROMPTED_IN) */ |
| 535 | | -/* |
| 536 | | -** TBD: Define an interface for application(s) to generate |
| 537 | | -** completion candidates for use by the line-editor. |
| 538 | | -** |
| 539 | | -** This may be premature; the CLI is the only application |
| 540 | | -** that does this. Yet, getting line-editing melded into |
| 541 | | -** console I/O is desirable because a line-editing library |
| 542 | | -** may have to establish console operating mode, possibly |
| 543 | | -** in a way that interferes with the above functionality. |
| 544 | | -*/ |
| 545 | | - |
| 546 | | -#if !(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE)) |
| 547 | | -/* Skip over as much z[] input char sequence as is valid UTF-8, |
| 548 | | -** limited per nAccept char's or whole characters and containing |
| 549 | | -** no char cn such that ((1<<cn) & ccm)!=0. On return, the |
| 550 | | -** sequence z:return (inclusive:exclusive) is validated UTF-8. |
| 551 | | -** Limit: nAccept>=0 => char count, nAccept<0 => character |
| 552 | | - */ |
| 553 | | -SQLITE_INTERNAL_LINKAGE const char* |
| 554 | | -zSkipValidUtf8(const char *z, int nAccept, long ccm); |
| 555 | | - |
| 556 | | -#endif |
| 557 | | - |
| 558 | | -/************************* End ../ext/consio/console_io.h ********************/ |
| 559 | | -/************************* Begin ../ext/consio/console_io.c ******************/ |
| 560 | | -/* |
| 561 | | -** 2023 November 4 |
| 562 | | -** |
| 563 | | -** The author disclaims copyright to this source code. In place of |
| 564 | | -** a legal notice, here is a blessing: |
| 565 | | -** |
| 566 | | -** May you do good and not evil. |
| 567 | | -** May you find forgiveness for yourself and forgive others. |
| 568 | | -** May you share freely, never taking more than you give. |
| 569 | | -** |
| 570 | | -******************************************************************************** |
| 571 | | -** This file implements various interfaces used for console and stream I/O |
| 572 | | -** by the SQLite project command-line tools, as explained in console_io.h . |
| 573 | | -** Functions prefixed by "SQLITE_INTERNAL_LINKAGE" behave as described there. |
| 574 | | -*/ |
| 575 | | - |
| 576 | | -#ifndef SQLITE_CDECL |
| 577 | | -# define SQLITE_CDECL |
| 578 | | -#endif |
| 579 | | - |
| 580 | | -#ifndef SHELL_NO_SYSINC |
| 581 | | -# include <stdarg.h> |
| 582 | | -# include <string.h> |
| 583 | | -# include <stdlib.h> |
| 584 | | -# include <limits.h> |
| 585 | | -# include <assert.h> |
| 586 | | -/* # include "sqlite3.h" */ |
| 587 | | -#endif |
| 588 | | -#ifndef HAVE_CONSOLE_IO_H |
| 589 | | -# include "console_io.h" |
| 590 | | -#endif |
| 591 | | -#if defined(_MSC_VER) |
| 592 | | -# pragma warning(disable : 4204) |
| 593 | | -#endif |
| 594 | | - |
| 595 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 596 | | -# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT |
| 597 | | -# ifndef SHELL_NO_SYSINC |
| 598 | | -# include <io.h> |
| 599 | | -# include <fcntl.h> |
| 600 | | -# undef WIN32_LEAN_AND_MEAN |
| 601 | | -# define WIN32_LEAN_AND_MEAN |
| 602 | | -# include <windows.h> |
| 603 | | -# endif |
| 604 | | -# define CIO_WIN_WC_XLATE 1 /* Use WCHAR Windows APIs for console I/O */ |
| 605 | | -# else |
| 606 | | -# ifndef SHELL_NO_SYSINC |
| 607 | | -# include <unistd.h> |
| 608 | | -# endif |
| 609 | | -# define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ |
| 610 | | -# endif |
| 611 | | -#else |
| 612 | | -# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ |
| 613 | | -#endif |
| 614 | | - |
| 615 | | -#if CIO_WIN_WC_XLATE |
| 616 | | -static HANDLE handleOfFile(FILE *pf){ |
| 617 | | - int fileDesc = _fileno(pf); |
| 618 | | - union { intptr_t osfh; HANDLE fh; } fid = { |
| 619 | | - (fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE |
| 620 | | - }; |
| 621 | | - return fid.fh; |
| 622 | | -} |
| 623 | | -#endif |
| 624 | | - |
| 625 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 626 | | -typedef struct PerStreamTags { |
| 627 | | -# if CIO_WIN_WC_XLATE |
| 628 | | - HANDLE hx; |
| 629 | | - DWORD consMode; |
| 630 | | - char acIncomplete[4]; |
| 631 | | -# else |
| 632 | | - short reachesConsole; |
| 633 | | -# endif |
| 634 | | - FILE *pf; |
| 635 | | -} PerStreamTags; |
| 636 | | - |
| 637 | | -/* Define NULL-like value for things which can validly be 0. */ |
| 638 | | -# define SHELL_INVALID_FILE_PTR ((FILE *)~0) |
| 639 | | -# if CIO_WIN_WC_XLATE |
| 640 | | -# define SHELL_INVALID_CONS_MODE 0xFFFF0000 |
| 641 | | -# endif |
| 642 | | - |
| 643 | | -# if CIO_WIN_WC_XLATE |
| 644 | | -# define PST_INITIALIZER { INVALID_HANDLE_VALUE, SHELL_INVALID_CONS_MODE, \ |
| 645 | | - {0,0,0,0}, SHELL_INVALID_FILE_PTR } |
| 646 | | -# else |
| 647 | | -# define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR } |
| 648 | | -# endif |
| 649 | | - |
| 650 | | -/* Quickly say whether a known output is going to the console. */ |
| 651 | | -# if CIO_WIN_WC_XLATE |
| 652 | | -static short pstReachesConsole(PerStreamTags *ppst){ |
| 653 | | - return (ppst->hx != INVALID_HANDLE_VALUE); |
| 654 | | -} |
| 655 | | -# else |
| 656 | | -# define pstReachesConsole(ppst) 0 |
| 657 | | -# endif |
| 658 | | - |
| 659 | | -# if CIO_WIN_WC_XLATE |
| 660 | | -static void restoreConsoleArb(PerStreamTags *ppst){ |
| 661 | | - if( pstReachesConsole(ppst) ) SetConsoleMode(ppst->hx, ppst->consMode); |
| 662 | | -} |
| 663 | | -# else |
| 664 | | -# define restoreConsoleArb(ppst) |
| 665 | | -# endif |
| 666 | | - |
| 667 | | -/* Say whether FILE* appears to be a console, collect associated info. */ |
| 668 | | -static short streamOfConsole(FILE *pf, /* out */ PerStreamTags *ppst){ |
| 669 | | -# if CIO_WIN_WC_XLATE |
| 670 | | - short rv = 0; |
| 671 | | - DWORD dwCM = SHELL_INVALID_CONS_MODE; |
| 672 | | - HANDLE fh = handleOfFile(pf); |
| 673 | | - ppst->pf = pf; |
| 674 | | - if( INVALID_HANDLE_VALUE != fh ){ |
| 675 | | - rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwCM)); |
| 676 | | - } |
| 677 | | - ppst->hx = (rv)? fh : INVALID_HANDLE_VALUE; |
| 678 | | - ppst->consMode = dwCM; |
| 679 | | - return rv; |
| 680 | | -# else |
| 681 | | - ppst->pf = pf; |
| 682 | | - ppst->reachesConsole = ( (short)isatty(fileno(pf)) ); |
| 683 | | - return ppst->reachesConsole; |
| 684 | | -# endif |
| 685 | | -} |
| 686 | | - |
| 687 | | -# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING |
| 688 | | -# define ENABLE_VIRTUAL_TERMINAL_PROCESSING (0x4) |
| 689 | | -# endif |
| 690 | | - |
| 691 | | -# if CIO_WIN_WC_XLATE |
| 692 | | -/* Define console modes for use with the Windows Console API. */ |
| 693 | | -# define SHELL_CONI_MODE \ |
| 694 | | - (ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \ |
| 695 | | - | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT) |
| 696 | | -# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \ |
| 697 | | - | ENABLE_VIRTUAL_TERMINAL_PROCESSING) |
| 698 | | -# endif |
| 699 | | - |
| 700 | | -typedef struct ConsoleInfo { |
| 701 | | - PerStreamTags pstSetup[3]; |
| 702 | | - PerStreamTags pstDesignated[3]; |
| 703 | | - StreamsAreConsole sacSetup; |
| 704 | | -} ConsoleInfo; |
| 705 | | - |
| 706 | | -static short isValidStreamInfo(PerStreamTags *ppst){ |
| 707 | | - return (ppst->pf != SHELL_INVALID_FILE_PTR); |
| 708 | | -} |
| 709 | | - |
| 710 | | -static ConsoleInfo consoleInfo = { |
| 711 | | - { /* pstSetup */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, |
| 712 | | - { /* pstDesignated[] */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, |
| 713 | | - SAC_NoConsole /* sacSetup */ |
| 714 | | -}; |
| 715 | | - |
| 716 | | -SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0; |
| 717 | | - |
| 718 | | -# if CIO_WIN_WC_XLATE |
| 719 | | -static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){ |
| 720 | | - if( pstReachesConsole(ppst) ){ |
| 721 | | - DWORD cm = odir? SHELL_CONO_MODE : SHELL_CONI_MODE; |
| 722 | | - SetConsoleMode(ppst->hx, cm); |
| 723 | | - } |
| 724 | | -} |
| 725 | | -# else |
| 726 | | -# define maybeSetupAsConsole(ppst,odir) |
| 727 | | -# endif |
| 728 | | - |
| 729 | | -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void){ |
| 730 | | -# if CIO_WIN_WC_XLATE |
| 731 | | - int ix = 0; |
| 732 | | - while( ix < 6 ){ |
| 733 | | - PerStreamTags *ppst = (ix<3)? |
| 734 | | - &consoleInfo.pstSetup[ix] : &consoleInfo.pstDesignated[ix-3]; |
| 735 | | - maybeSetupAsConsole(ppst, (ix % 3)>0); |
| 736 | | - ++ix; |
| 737 | | - } |
| 738 | | -# endif |
| 739 | | -} |
| 740 | | - |
| 741 | | -SQLITE_INTERNAL_LINKAGE StreamsAreConsole |
| 742 | | -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){ |
| 743 | | - StreamsAreConsole rv = SAC_NoConsole; |
| 744 | | - FILE* apf[3] = { pfIn, pfOut, pfErr }; |
| 745 | | - int ix; |
| 746 | | - for( ix = 2; ix >= 0; --ix ){ |
| 747 | | - PerStreamTags *ppst = &consoleInfo.pstSetup[ix]; |
| 748 | | - if( streamOfConsole(apf[ix], ppst) ){ |
| 749 | | - rv |= (SAC_InConsole<<ix); |
| 750 | | - } |
| 751 | | - consoleInfo.pstDesignated[ix] = *ppst; |
| 752 | | - if( ix > 0 ) fflush(apf[ix]); |
| 753 | | - } |
| 754 | | - consoleInfo.sacSetup = rv; |
| 755 | | - consoleRenewSetup(); |
| 756 | | - return rv; |
| 757 | | -} |
| 758 | | - |
| 759 | | -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ){ |
| 760 | | -# if CIO_WIN_WC_XLATE |
| 761 | | - static ConsoleInfo *pci = &consoleInfo; |
| 762 | | - if( pci->sacSetup ){ |
| 763 | | - int ix; |
| 764 | | - for( ix=0; ix<3; ++ix ){ |
| 765 | | - if( pci->sacSetup & (SAC_InConsole<<ix) ){ |
| 766 | | - PerStreamTags *ppst = &pci->pstSetup[ix]; |
| 767 | | - SetConsoleMode(ppst->hx, ppst->consMode); |
| 768 | | - } |
| 769 | | - } |
| 770 | | - } |
| 771 | | -# endif |
| 772 | | -} |
| 773 | | -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ |
| 774 | | - |
| 775 | | -#ifdef SQLITE_CIO_INPUT_REDIR |
| 776 | | -/* Say whether given FILE* is among those known, via either |
| 777 | | -** consoleClassifySetup() or set{Output,Error}Stream, as |
| 778 | | -** readable, and return an associated PerStreamTags pointer |
| 779 | | -** if so. Otherwise, return 0. |
| 780 | | -*/ |
| 781 | | -static PerStreamTags * isKnownReadable(FILE *pf){ |
| 782 | | - static PerStreamTags *apst[] = { |
| 783 | | - &consoleInfo.pstDesignated[0], &consoleInfo.pstSetup[0], 0 |
| 784 | | - }; |
| 785 | | - int ix = 0; |
| 786 | | - do { |
| 787 | | - if( apst[ix]->pf == pf ) break; |
| 788 | | - } while( apst[++ix] != 0 ); |
| 789 | | - return apst[ix]; |
| 790 | | -} |
| 791 | | -#endif |
| 792 | | - |
| 793 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 794 | | -/* Say whether given FILE* is among those known, via either |
| 795 | | -** consoleClassifySetup() or set{Output,Error}Stream, as |
| 796 | | -** writable, and return an associated PerStreamTags pointer |
| 797 | | -** if so. Otherwise, return 0. |
| 798 | | -*/ |
| 799 | | -static PerStreamTags * isKnownWritable(FILE *pf){ |
| 800 | | - static PerStreamTags *apst[] = { |
| 801 | | - &consoleInfo.pstDesignated[1], &consoleInfo.pstDesignated[2], |
| 802 | | - &consoleInfo.pstSetup[1], &consoleInfo.pstSetup[2], 0 |
| 803 | | - }; |
| 804 | | - int ix = 0; |
| 805 | | - do { |
| 806 | | - if( apst[ix]->pf == pf ) break; |
| 807 | | - } while( apst[++ix] != 0 ); |
| 808 | | - return apst[ix]; |
| 809 | | -} |
| 810 | | - |
| 811 | | -static FILE *designateEmitStream(FILE *pf, unsigned chix){ |
| 812 | | - FILE *rv = consoleInfo.pstDesignated[chix].pf; |
| 813 | | - if( pf == invalidFileStream ) return rv; |
| 814 | | - else{ |
| 815 | | - /* Setting a possibly new output stream. */ |
| 816 | | - PerStreamTags *ppst = isKnownWritable(pf); |
| 817 | | - if( ppst != 0 ){ |
| 818 | | - PerStreamTags pst = *ppst; |
| 819 | | - consoleInfo.pstDesignated[chix] = pst; |
| 820 | | - }else streamOfConsole(pf, &consoleInfo.pstDesignated[chix]); |
| 821 | | - } |
| 822 | | - return rv; |
| 823 | | -} |
| 824 | | - |
| 825 | | -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf){ |
| 826 | | - return designateEmitStream(pf, 1); |
| 827 | | -} |
| 828 | | -# ifdef CONSIO_SET_ERROR_STREAM |
| 829 | | -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf){ |
| 830 | | - return designateEmitStream(pf, 2); |
| 831 | | -} |
| 832 | | -# endif |
| 833 | | -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ |
| 834 | | - |
| 835 | | -#ifndef SQLITE_CIO_NO_SETMODE |
| 836 | | -# if CIO_WIN_WC_XLATE |
| 837 | | -static void setModeFlushQ(FILE *pf, short bFlush, int mode){ |
| 838 | | - if( bFlush ) fflush(pf); |
| 839 | | - _setmode(_fileno(pf), mode); |
| 840 | | -} |
| 841 | | -# else |
| 842 | | -# define setModeFlushQ(f, b, m) if(b) fflush(f) |
| 843 | | -# endif |
| 844 | | - |
| 845 | | -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *pf, short bFlush){ |
| 846 | | - setModeFlushQ(pf, bFlush, _O_BINARY); |
| 847 | | -} |
| 848 | | -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){ |
| 849 | | - setModeFlushQ(pf, bFlush, _O_TEXT); |
| 850 | | -} |
| 851 | | -# undef setModeFlushQ |
| 852 | | - |
| 853 | | -#else /* defined(SQLITE_CIO_NO_SETMODE) */ |
| 854 | | -# define setBinaryMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) |
| 855 | | -# define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) |
| 856 | | -#endif /* defined(SQLITE_CIO_NO_SETMODE) */ |
| 857 | | - |
| 858 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 859 | | -# if CIO_WIN_WC_XLATE |
| 860 | | -/* Write buffer cBuf as output to stream known to reach console, |
| 861 | | -** limited to ncTake char's. Return ncTake on success, else 0. */ |
| 862 | | -static int conZstrEmit(PerStreamTags *ppst, const char *z, int ncTake){ |
| 863 | | - int rv = 0; |
| 864 | | - if( z!=NULL ){ |
| 865 | | - int nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, 0,0); |
| 866 | | - if( nwc > 0 ){ |
| 867 | | - WCHAR *zw = sqlite3_malloc64(nwc*sizeof(WCHAR)); |
| 868 | | - if( zw!=NULL ){ |
| 869 | | - nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, zw,nwc); |
| 870 | | - if( nwc > 0 ){ |
| 871 | | - /* Translation from UTF-8 to UTF-16, then WCHARs out. */ |
| 872 | | - if( WriteConsoleW(ppst->hx, zw,nwc, 0, NULL) ){ |
| 873 | | - rv = ncTake; |
| 874 | | - } |
| 875 | | - } |
| 876 | | - sqlite3_free(zw); |
| 877 | | - } |
| 878 | | - } |
| 879 | | - } |
| 880 | | - return rv; |
| 881 | | -} |
| 882 | | - |
| 883 | | -/* For {f,o,e}PrintfUtf8() when stream is known to reach console. */ |
| 884 | | -static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){ |
| 885 | | - char *z = sqlite3_vmprintf(zFormat, ap); |
| 886 | | - if( z ){ |
| 887 | | - int rv = conZstrEmit(ppst, z, (int)strlen(z)); |
| 888 | | - sqlite3_free(z); |
| 889 | | - return rv; |
| 890 | | - }else return 0; |
| 891 | | -} |
| 892 | | -# endif /* CIO_WIN_WC_XLATE */ |
| 893 | | - |
| 894 | | -# ifdef CONSIO_GET_EMIT_STREAM |
| 895 | | -static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix, |
| 896 | | - PerStreamTags *ppst){ |
| 897 | | - PerStreamTags *rv = isKnownWritable(pf); |
| 898 | | - short isValid = (rv!=0)? isValidStreamInfo(rv) : 0; |
| 899 | | - if( rv != 0 && isValid ) return rv; |
| 900 | | - streamOfConsole(pf, ppst); |
| 901 | | - return ppst; |
| 902 | | -} |
| 903 | | -# endif |
| 904 | | - |
| 905 | | -/* Get stream info, either for designated output or error stream when |
| 906 | | -** chix equals 1 or 2, or for an arbitrary stream when chix == 0. |
| 907 | | -** In either case, ppst references a caller-owned PerStreamTags |
| 908 | | -** struct which may be filled in if none of the known writable |
| 909 | | -** streams is being held by consoleInfo. The ppf parameter is a |
| 910 | | -** byref output when chix!=0 and a byref input when chix==0. |
| 911 | | - */ |
| 912 | | -static PerStreamTags * |
| 913 | | -getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, |
| 914 | | - /* in/out */ FILE **ppf){ |
| 915 | | - PerStreamTags *ppstTry; |
| 916 | | - FILE *pfEmit; |
| 917 | | - if( chix > 0 ){ |
| 918 | | - ppstTry = &consoleInfo.pstDesignated[chix]; |
| 919 | | - if( !isValidStreamInfo(ppstTry) ){ |
| 920 | | - ppstTry = &consoleInfo.pstSetup[chix]; |
| 921 | | - pfEmit = ppst->pf; |
| 922 | | - }else pfEmit = ppstTry->pf; |
| 923 | | - if( !isValidStreamInfo(ppstTry) ){ |
| 924 | | - pfEmit = (chix > 1)? stderr : stdout; |
| 925 | | - ppstTry = ppst; |
| 926 | | - streamOfConsole(pfEmit, ppstTry); |
| 927 | | - } |
| 928 | | - *ppf = pfEmit; |
| 929 | | - }else{ |
| 930 | | - ppstTry = isKnownWritable(*ppf); |
| 931 | | - if( ppstTry != 0 ) return ppstTry; |
| 932 | | - streamOfConsole(*ppf, ppst); |
| 933 | | - return ppst; |
| 934 | | - } |
| 935 | | - return ppstTry; |
| 936 | | -} |
| 937 | | - |
| 938 | | -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){ |
| 939 | | - va_list ap; |
| 940 | | - int rv; |
| 941 | | - FILE *pfOut; |
| 942 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 943 | | -# if CIO_WIN_WC_XLATE |
| 944 | | - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); |
| 945 | | -# else |
| 946 | | - getEmitStreamInfo(1, &pst, &pfOut); |
| 947 | | -# endif |
| 948 | | - assert(zFormat!=0); |
| 949 | | - va_start(ap, zFormat); |
| 950 | | -# if CIO_WIN_WC_XLATE |
| 951 | | - if( pstReachesConsole(ppst) ){ |
| 952 | | - rv = conioVmPrintf(ppst, zFormat, ap); |
| 953 | | - }else{ |
| 954 | | -# endif |
| 955 | | - rv = vfprintf(pfOut, zFormat, ap); |
| 956 | | -# if CIO_WIN_WC_XLATE |
| 957 | | - } |
| 958 | | -# endif |
| 959 | | - va_end(ap); |
| 960 | | - return rv; |
| 961 | | -} |
| 962 | | - |
| 963 | | -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){ |
| 964 | | - va_list ap; |
| 965 | | - int rv; |
| 966 | | - FILE *pfErr; |
| 967 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 968 | | -# if CIO_WIN_WC_XLATE |
| 969 | | - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); |
| 970 | | -# else |
| 971 | | - getEmitStreamInfo(2, &pst, &pfErr); |
| 972 | | -# endif |
| 973 | | - assert(zFormat!=0); |
| 974 | | - va_start(ap, zFormat); |
| 975 | | -# if CIO_WIN_WC_XLATE |
| 976 | | - if( pstReachesConsole(ppst) ){ |
| 977 | | - rv = conioVmPrintf(ppst, zFormat, ap); |
| 978 | | - }else{ |
| 979 | | -# endif |
| 980 | | - rv = vfprintf(pfErr, zFormat, ap); |
| 981 | | -# if CIO_WIN_WC_XLATE |
| 982 | | - } |
| 983 | | -# endif |
| 984 | | - va_end(ap); |
| 985 | | - return rv; |
| 986 | | -} |
| 987 | | - |
| 988 | | -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){ |
| 989 | | - va_list ap; |
| 990 | | - int rv; |
| 991 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 992 | | -# if CIO_WIN_WC_XLATE |
| 993 | | - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); |
| 994 | | -# else |
| 995 | | - getEmitStreamInfo(0, &pst, &pfO); |
| 996 | | -# endif |
| 997 | | - assert(zFormat!=0); |
| 998 | | - va_start(ap, zFormat); |
| 999 | | -# if CIO_WIN_WC_XLATE |
| 1000 | | - if( pstReachesConsole(ppst) ){ |
| 1001 | | - maybeSetupAsConsole(ppst, 1); |
| 1002 | | - rv = conioVmPrintf(ppst, zFormat, ap); |
| 1003 | | - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); |
| 1004 | | - }else{ |
| 1005 | | -# endif |
| 1006 | | - rv = vfprintf(pfO, zFormat, ap); |
| 1007 | | -# if CIO_WIN_WC_XLATE |
| 1008 | | - } |
| 1009 | | -# endif |
| 1010 | | - va_end(ap); |
| 1011 | | - return rv; |
| 1012 | | -} |
| 1013 | | - |
| 1014 | | -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){ |
| 1015 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1016 | | -# if CIO_WIN_WC_XLATE |
| 1017 | | - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); |
| 1018 | | -# else |
| 1019 | | - getEmitStreamInfo(0, &pst, &pfO); |
| 1020 | | -# endif |
| 1021 | | - assert(z!=0); |
| 1022 | | -# if CIO_WIN_WC_XLATE |
| 1023 | | - if( pstReachesConsole(ppst) ){ |
| 1024 | | - int rv; |
| 1025 | | - maybeSetupAsConsole(ppst, 1); |
| 1026 | | - rv = conZstrEmit(ppst, z, (int)strlen(z)); |
| 1027 | | - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); |
| 1028 | | - return rv; |
| 1029 | | - }else { |
| 1030 | | -# endif |
| 1031 | | - return (fputs(z, pfO)<0)? 0 : (int)strlen(z); |
| 1032 | | -# if CIO_WIN_WC_XLATE |
| 1033 | | - } |
| 1034 | | -# endif |
| 1035 | | -} |
| 1036 | | - |
| 1037 | | -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){ |
| 1038 | | - FILE *pfErr; |
| 1039 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1040 | | -# if CIO_WIN_WC_XLATE |
| 1041 | | - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); |
| 1042 | | -# else |
| 1043 | | - getEmitStreamInfo(2, &pst, &pfErr); |
| 1044 | | -# endif |
| 1045 | | - assert(z!=0); |
| 1046 | | -# if CIO_WIN_WC_XLATE |
| 1047 | | - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); |
| 1048 | | - else { |
| 1049 | | -# endif |
| 1050 | | - return (fputs(z, pfErr)<0)? 0 : (int)strlen(z); |
| 1051 | | -# if CIO_WIN_WC_XLATE |
| 1052 | | - } |
| 1053 | | -# endif |
| 1054 | | -} |
| 1055 | | - |
| 1056 | | -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){ |
| 1057 | | - FILE *pfOut; |
| 1058 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1059 | | -# if CIO_WIN_WC_XLATE |
| 1060 | | - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); |
| 1061 | | -# else |
| 1062 | | - getEmitStreamInfo(1, &pst, &pfOut); |
| 1063 | | -# endif |
| 1064 | | - assert(z!=0); |
| 1065 | | -# if CIO_WIN_WC_XLATE |
| 1066 | | - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); |
| 1067 | | - else { |
| 1068 | | -# endif |
| 1069 | | - return (fputs(z, pfOut)<0)? 0 : (int)strlen(z); |
| 1070 | | -# if CIO_WIN_WC_XLATE |
| 1071 | | - } |
| 1072 | | -# endif |
| 1073 | | -} |
| 1074 | | - |
| 1075 | | -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ |
| 1076 | | - |
| 1077 | | -#if !(defined(SQLITE_CIO_NO_UTF8SCAN) && defined(SQLITE_CIO_NO_TRANSLATE)) |
| 1078 | | -/* Skip over as much z[] input char sequence as is valid UTF-8, |
| 1079 | | -** limited per nAccept char's or whole characters and containing |
| 1080 | | -** no char cn such that ((1<<cn) & ccm)!=0. On return, the |
| 1081 | | -** sequence z:return (inclusive:exclusive) is validated UTF-8. |
| 1082 | | -** Limit: nAccept>=0 => char count, nAccept<0 => character |
| 1083 | | - */ |
| 1084 | | -SQLITE_INTERNAL_LINKAGE const char* |
| 1085 | | -zSkipValidUtf8(const char *z, int nAccept, long ccm){ |
| 1086 | | - int ng = (nAccept<0)? -nAccept : 0; |
| 1087 | | - const char *pcLimit = (nAccept>=0)? z+nAccept : 0; |
| 1088 | | - assert(z!=0); |
| 1089 | | - while( (pcLimit)? (z<pcLimit) : (ng-- != 0) ){ |
| 1090 | | - char c = *z; |
| 1091 | | - if( (c & 0x80) == 0 ){ |
| 1092 | | - if( ccm != 0L && c < 0x20 && ((1L<<c) & ccm) != 0 ) return z; |
| 1093 | | - ++z; /* ASCII */ |
| 1094 | | - }else if( (c & 0xC0) != 0xC0 ) return z; /* not a lead byte */ |
| 1095 | | - else{ |
| 1096 | | - const char *zt = z+1; /* Got lead byte, look at trail bytes.*/ |
| 1097 | | - do{ |
| 1098 | | - if( pcLimit && zt >= pcLimit ) return z; |
| 1099 | | - else{ |
| 1100 | | - char ct = *zt++; |
| 1101 | | - if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ |
| 1102 | | - /* Trailing bytes are too few, too many, or invalid. */ |
| 1103 | | - return z; |
| 1104 | | - } |
| 1105 | | - } |
| 1106 | | - } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ |
| 1107 | | - z = zt; |
| 1108 | | - } |
| 1109 | | - } |
| 1110 | | - return z; |
| 1111 | | -} |
| 1112 | | -#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/ |
| 1113 | | - |
| 1114 | | -#ifndef SQLITE_CIO_NO_TRANSLATE |
| 1115 | | -# ifdef CONSIO_SPUTB |
| 1116 | | -SQLITE_INTERNAL_LINKAGE int |
| 1117 | | -fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){ |
| 1118 | | - assert(pfO!=0); |
| 1119 | | -# if CIO_WIN_WC_XLATE |
| 1120 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1121 | | - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); |
| 1122 | | - if( pstReachesConsole(ppst) ){ |
| 1123 | | - int rv; |
| 1124 | | - maybeSetupAsConsole(ppst, 1); |
| 1125 | | - rv = conZstrEmit(ppst, cBuf, nAccept); |
| 1126 | | - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); |
| 1127 | | - return rv; |
| 1128 | | - }else { |
| 1129 | | -# endif |
| 1130 | | - return (int)fwrite(cBuf, 1, nAccept, pfO); |
| 1131 | | -# if CIO_WIN_WC_XLATE |
| 1132 | | - } |
| 1133 | | -# endif |
| 1134 | | -} |
| 1135 | | -# endif |
| 1136 | | - |
| 1137 | | -SQLITE_INTERNAL_LINKAGE int |
| 1138 | | -oPutbUtf8(const char *cBuf, int nAccept){ |
| 1139 | | - FILE *pfOut; |
| 1140 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1141 | | -# if CIO_WIN_WC_XLATE |
| 1142 | | - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); |
| 1143 | | -# else |
| 1144 | | - getEmitStreamInfo(1, &pst, &pfOut); |
| 1145 | | -# endif |
| 1146 | | -# if CIO_WIN_WC_XLATE |
| 1147 | | - if( pstReachesConsole(ppst) ){ |
| 1148 | | - return conZstrEmit(ppst, cBuf, nAccept); |
| 1149 | | - }else { |
| 1150 | | -# endif |
| 1151 | | - return (int)fwrite(cBuf, 1, nAccept, pfOut); |
| 1152 | | -# if CIO_WIN_WC_XLATE |
| 1153 | | - } |
| 1154 | | -# endif |
| 1155 | | -} |
| 1156 | | - |
| 1157 | | -/* |
| 1158 | | -** Flush the given output stream. Return non-zero for success, else 0. |
| 1159 | | -*/ |
| 1160 | | -#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE) |
| 1161 | | -SQLITE_INTERNAL_LINKAGE int |
| 1162 | | -fFlushBuffer(FILE *pfOut){ |
| 1163 | | -# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE) |
| 1164 | | - return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0; |
| 1165 | | -# else |
| 1166 | | - return fflush(pfOut); |
| 1167 | | -# endif |
| 1168 | | -} |
| 1169 | | -#endif |
| 1170 | | - |
| 1171 | | -#if CIO_WIN_WC_XLATE \ |
| 1172 | | - && !defined(SHELL_OMIT_FIO_DUPE) \ |
| 1173 | | - && defined(SQLITE_USE_ONLY_WIN32) |
| 1174 | | -static struct FileAltIds { |
| 1175 | | - int fd; |
| 1176 | | - HANDLE fh; |
| 1177 | | -} altIdsOfFile(FILE *pf){ |
| 1178 | | - struct FileAltIds rv = { _fileno(pf) }; |
| 1179 | | - union { intptr_t osfh; HANDLE fh; } fid = { |
| 1180 | | - (rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE |
| 1181 | | - }; |
| 1182 | | - rv.fh = fid.fh; |
| 1183 | | - return rv; |
| 1184 | | -} |
| 1185 | | - |
| 1186 | | -SQLITE_INTERNAL_LINKAGE size_t |
| 1187 | | -cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){ |
| 1188 | | - size_t rv = 0; |
| 1189 | | - struct FileAltIds fai = altIdsOfFile(pf); |
| 1190 | | - int fmode = _setmode(fai.fd, _O_BINARY); |
| 1191 | | - _setmode(fai.fd, fmode); |
| 1192 | | - while( rv < ocnt ){ |
| 1193 | | - size_t nbo = osz; |
| 1194 | | - while( nbo > 0 ){ |
| 1195 | | - DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo; |
| 1196 | | - BOOL wrc = TRUE; |
| 1197 | | - BOOL genCR = (fmode & _O_TEXT)!=0; |
| 1198 | | - if( genCR ){ |
| 1199 | | - const char *pnl = (const char*)memchr(buf, '\n', nbo); |
| 1200 | | - if( pnl ) nbo = pnl - (const char*)buf; |
| 1201 | | - else genCR = 0; |
| 1202 | | - } |
| 1203 | | - if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0); |
| 1204 | | - if( genCR && wrc ){ |
| 1205 | | - wrc = WriteFile(fai.fh, "\r\n", 2, 0,0); |
| 1206 | | - ++dwno; /* Skip over the LF */ |
| 1207 | | - } |
| 1208 | | - if( !wrc ) return rv; |
| 1209 | | - buf = (const char*)buf + dwno; |
| 1210 | | - nbo += dwno; |
| 1211 | | - } |
| 1212 | | - ++rv; |
| 1213 | | - } |
| 1214 | | - return rv; |
| 1215 | | -} |
| 1216 | | - |
| 1217 | | -/* An fgets() equivalent, using Win32 file API for actual input. |
| 1218 | | -** Input ends when given buffer is filled or a newline is read. |
| 1219 | | -** If the FILE object is in text mode, swallows 0x0D. (ASCII CR) |
| 1220 | | -*/ |
| 1221 | | -SQLITE_INTERNAL_LINKAGE char * |
| 1222 | | -cfGets(char *cBuf, int n, FILE *pf){ |
| 1223 | | - int nci = 0; |
| 1224 | | - struct FileAltIds fai = altIdsOfFile(pf); |
| 1225 | | - int fmode = _setmode(fai.fd, _O_BINARY); |
| 1226 | | - BOOL eatCR = (fmode & _O_TEXT)!=0; |
| 1227 | | - _setmode(fai.fd, fmode); |
| 1228 | | - while( nci < n-1 ){ |
| 1229 | | - DWORD nr; |
| 1230 | | - if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break; |
| 1231 | | - if( nr>0 && (!eatCR || cBuf[nci]!='\r') ){ |
| 1232 | | - nci += nr; |
| 1233 | | - if( cBuf[nci-nr]=='\n' ) break; |
| 1234 | | - } |
| 1235 | | - } |
| 1236 | | - if( nci < n ) cBuf[nci] = 0; |
| 1237 | | - return (nci>0)? cBuf : 0; |
| 1238 | | -} |
| 1239 | | -# else |
| 1240 | | -# define cfWrite(b,os,no,f) fwrite(b,os,no,f) |
| 1241 | | -# define cfGets(b,n,f) fgets(b,n,f) |
| 1242 | | -# endif |
| 1243 | | - |
| 1244 | | -# ifdef CONSIO_EPUTB |
| 1245 | | -SQLITE_INTERNAL_LINKAGE int |
| 1246 | | -ePutbUtf8(const char *cBuf, int nAccept){ |
| 1247 | | - FILE *pfErr; |
| 1248 | | - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ |
| 1249 | | - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); |
| 1250 | | -# if CIO_WIN_WC_XLATE |
| 1251 | | - if( pstReachesConsole(ppst) ){ |
| 1252 | | - return conZstrEmit(ppst, cBuf, nAccept); |
| 1253 | | - }else { |
| 1254 | | -# endif |
| 1255 | | - return (int)cfWrite(cBuf, 1, nAccept, pfErr); |
| 1256 | | -# if CIO_WIN_WC_XLATE |
| 1257 | | - } |
| 1258 | | -# endif |
| 1259 | | -} |
| 1260 | | -# endif /* defined(CONSIO_EPUTB) */ |
| 1261 | | - |
| 1262 | | -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){ |
| 1263 | | - if( pfIn==0 ) pfIn = stdin; |
| 1264 | | -# if CIO_WIN_WC_XLATE |
| 1265 | | - if( pfIn == consoleInfo.pstSetup[0].pf |
| 1266 | | - && (consoleInfo.sacSetup & SAC_InConsole)!=0 ){ |
| 1267 | | -# if CIO_WIN_WC_XLATE==1 |
| 1268 | | -# define SHELL_GULP 150 /* Count of WCHARS to be gulped at a time */ |
| 1269 | | - WCHAR wcBuf[SHELL_GULP+1]; |
| 1270 | | - int lend = 0, noc = 0; |
| 1271 | | - if( ncMax > 0 ) cBuf[0] = 0; |
| 1272 | | - while( noc < ncMax-8-1 && !lend ){ |
| 1273 | | - /* There is room for at least 2 more characters and a 0-terminator. */ |
| 1274 | | - int na = (ncMax > SHELL_GULP*4+1 + noc)? SHELL_GULP : (ncMax-1 - noc)/4; |
| 1275 | | -# undef SHELL_GULP |
| 1276 | | - DWORD nbr = 0; |
| 1277 | | - BOOL bRC = ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf, na, &nbr, 0); |
| 1278 | | - if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){ |
| 1279 | | - /* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */ |
| 1280 | | - DWORD nbrx; |
| 1281 | | - bRC &= ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf+nbr, 1, &nbrx, 0); |
| 1282 | | - if( bRC ) nbr += nbrx; |
| 1283 | | - } |
| 1284 | | - if( !bRC || (noc==0 && nbr==0) ) return 0; |
| 1285 | | - if( nbr > 0 ){ |
| 1286 | | - int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0); |
| 1287 | | - if( nmb != 0 && noc+nmb <= ncMax ){ |
| 1288 | | - int iseg = noc; |
| 1289 | | - nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0); |
| 1290 | | - noc += nmb; |
| 1291 | | - /* Fixup line-ends as coded by Windows for CR (or "Enter".) |
| 1292 | | - ** This is done without regard for any setMode{Text,Binary}() |
| 1293 | | - ** call that might have been done on the interactive input. |
| 1294 | | - */ |
| 1295 | | - if( noc > 0 ){ |
| 1296 | | - if( cBuf[noc-1]=='\n' ){ |
| 1297 | | - lend = 1; |
| 1298 | | - if( noc > 1 && cBuf[noc-2]=='\r' ) cBuf[--noc-1] = '\n'; |
| 1299 | | - } |
| 1300 | | - } |
| 1301 | | - /* Check for ^Z (anywhere in line) too, to act as EOF. */ |
| 1302 | | - while( iseg < noc ){ |
| 1303 | | - if( cBuf[iseg]=='\x1a' ){ |
| 1304 | | - noc = iseg; /* Chop ^Z and anything following. */ |
| 1305 | | - lend = 1; /* Counts as end of line too. */ |
| 1306 | | - break; |
| 1307 | | - } |
| 1308 | | - ++iseg; |
| 1309 | | - } |
| 1310 | | - }else break; /* Drop apparent garbage in. (Could assert.) */ |
| 1311 | | - }else break; |
| 1312 | | - } |
| 1313 | | - /* If got nothing, (after ^Z chop), must be at end-of-file. */ |
| 1314 | | - if( noc > 0 ){ |
| 1315 | | - cBuf[noc] = 0; |
| 1316 | | - return cBuf; |
| 1317 | | - }else return 0; |
| 1318 | | -# endif |
| 1319 | | - }else{ |
| 1320 | | -# endif |
| 1321 | | - return cfGets(cBuf, ncMax, pfIn); |
| 1322 | | -# if CIO_WIN_WC_XLATE |
| 1323 | | - } |
| 1324 | | -# endif |
| 1325 | | -} |
| 1326 | | -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ |
| 1327 | | - |
| 1328 | | -#if defined(_MSC_VER) |
| 1329 | | -# pragma warning(default : 4204) |
| 1330 | | -#endif |
| 1331 | | - |
| 1332 | | -#undef SHELL_INVALID_FILE_PTR |
| 1333 | | - |
| 1334 | | -/************************* End ../ext/consio/console_io.c ********************/ |
| 1335 | | - |
| 1336 | | -#ifndef SQLITE_SHELL_FIDDLE |
| 1337 | | - |
| 1338 | | -/* From here onward, fgets() is redirected to the console_io library. */ |
| 1339 | | -# define fgets(b,n,f) fGetsUtf8(b,n,f) |
| 1340 | | -/* |
| 1341 | | - * Define macros for emitting output text in various ways: |
| 1342 | | - * sputz(s, z) => emit 0-terminated string z to given stream s |
| 1343 | | - * sputf(s, f, ...) => emit varargs per format f to given stream s |
| 1344 | | - * oputz(z) => emit 0-terminated string z to default stream |
| 1345 | | - * oputf(f, ...) => emit varargs per format f to default stream |
| 1346 | | - * eputz(z) => emit 0-terminated string z to error stream |
| 1347 | | - * eputf(f, ...) => emit varargs per format f to error stream |
| 1348 | | - * oputb(b, n) => emit char buffer b[0..n-1] to default stream |
| 1349 | | - * |
| 1350 | | - * Note that the default stream is whatever has been last set via: |
| 1351 | | - * setOutputStream(FILE *pf) |
| 1352 | | - * This is normally the stream that CLI normal output goes to. |
| 1353 | | - * For the stand-alone CLI, it is stdout with no .output redirect. |
| 1354 | | - * |
| 1355 | | - * The ?putz(z) forms are required for the Fiddle builds for string literal |
| 1356 | | - * output, in aid of enforcing format string to argument correspondence. |
| 1357 | | - */ |
| 1358 | | -# define sputz(s,z) fPutsUtf8(z,s) |
| 1359 | | -# define sputf fPrintfUtf8 |
| 1360 | | -# define oputz(z) oPutsUtf8(z) |
| 1361 | | -# define oputf oPrintfUtf8 |
| 1362 | | -# define eputz(z) ePutsUtf8(z) |
| 1363 | | -# define eputf ePrintfUtf8 |
| 1364 | | -# define oputb(buf,na) oPutbUtf8(buf,na) |
| 1365 | | -# define fflush(s) fFlushBuffer(s); |
| 1366 | | - |
| 1367 | | -#else |
| 1368 | | -/* For Fiddle, all console handling and emit redirection is omitted. */ |
| 1369 | | -/* These next 3 macros are for emitting formatted output. When complaints |
| 1370 | | - * from the WASM build are issued for non-formatted output, when a mere |
| 1371 | | - * string literal is to be emitted, the ?putz(z) forms should be used. |
| 1372 | | - * (This permits compile-time checking of format string / argument mismatch.) |
| 1373 | | - */ |
| 1374 | | -# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) |
| 1375 | | -# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) |
| 1376 | | -# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) |
| 1377 | | -/* These next 3 macros are for emitting simple string literals. */ |
| 1378 | | -# define oputz(z) fputs(z,stdout) |
| 1379 | | -# define eputz(z) fputs(z,stderr) |
| 1380 | | -# define sputz(fp,z) fputs(z,fp) |
| 1381 | | -# define oputb(buf,na) fwrite(buf,1,na,stdout) |
| 1382 | | -# undef fflush |
| 1383 | | -#endif |
| 540 | + |
| 541 | +#define eputz(z) sqlite3_fputs(z,stderr) |
| 542 | +#define sputz(fp,z) sqlite3_fputs(z,fp) |
| 1384 | 543 | |
| 1385 | 544 | /* True if the timer is enabled */ |
| 1386 | 545 | static int enableTimer = 0; |
| 1387 | 546 | |
| 1388 | 547 | /* A version of strcmp() that works with NULL values */ |
| | @@ -1423,10 +582,11 @@ |
| 1423 | 582 | struct timeval ru_utime; /* user CPU time used */ |
| 1424 | 583 | struct timeval ru_stime; /* system CPU time used */ |
| 1425 | 584 | }; |
| 1426 | 585 | #define getrusage(A,B) memset(B,0,sizeof(*B)) |
| 1427 | 586 | #endif |
| 587 | + |
| 1428 | 588 | |
| 1429 | 589 | /* Saved resource information for the beginning of an operation */ |
| 1430 | 590 | static struct rusage sBegin; /* CPU time at start */ |
| 1431 | 591 | static sqlite3_int64 iBegin; /* Wall-clock time at start */ |
| 1432 | 592 | |
| | @@ -1447,24 +607,24 @@ |
| 1447 | 607 | } |
| 1448 | 608 | |
| 1449 | 609 | /* |
| 1450 | 610 | ** Print the timing results. |
| 1451 | 611 | */ |
| 1452 | | -static void endTimer(void){ |
| 612 | +static void endTimer(FILE *out){ |
| 1453 | 613 | if( enableTimer ){ |
| 1454 | 614 | sqlite3_int64 iEnd = timeOfDay(); |
| 1455 | 615 | struct rusage sEnd; |
| 1456 | 616 | getrusage(RUSAGE_SELF, &sEnd); |
| 1457 | | - sputf(stdout, "Run Time: real %.3f user %f sys %f\n", |
| 617 | + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", |
| 1458 | 618 | (iEnd - iBegin)*0.001, |
| 1459 | 619 | timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), |
| 1460 | 620 | timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); |
| 1461 | 621 | } |
| 1462 | 622 | } |
| 1463 | 623 | |
| 1464 | 624 | #define BEGIN_TIMER beginTimer() |
| 1465 | | -#define END_TIMER endTimer() |
| 625 | +#define END_TIMER(X) endTimer(X) |
| 1466 | 626 | #define HAS_TIMER 1 |
| 1467 | 627 | |
| 1468 | 628 | #elif (defined(_WIN32) || defined(WIN32)) |
| 1469 | 629 | |
| 1470 | 630 | /* Saved resource information for the beginning of an operation */ |
| | @@ -1526,29 +686,29 @@ |
| 1526 | 686 | } |
| 1527 | 687 | |
| 1528 | 688 | /* |
| 1529 | 689 | ** Print the timing results. |
| 1530 | 690 | */ |
| 1531 | | -static void endTimer(void){ |
| 691 | +static void endTimer(FILE *out){ |
| 1532 | 692 | if( enableTimer && getProcessTimesAddr){ |
| 1533 | 693 | FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; |
| 1534 | 694 | sqlite3_int64 ftWallEnd = timeOfDay(); |
| 1535 | 695 | getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); |
| 1536 | | - sputf(stdout, "Run Time: real %.3f user %f sys %f\n", |
| 696 | + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", |
| 1537 | 697 | (ftWallEnd - ftWallBegin)*0.001, |
| 1538 | 698 | timeDiff(&ftUserBegin, &ftUserEnd), |
| 1539 | 699 | timeDiff(&ftKernelBegin, &ftKernelEnd)); |
| 1540 | 700 | } |
| 1541 | 701 | } |
| 1542 | 702 | |
| 1543 | 703 | #define BEGIN_TIMER beginTimer() |
| 1544 | | -#define END_TIMER endTimer() |
| 704 | +#define END_TIMER(X) endTimer(X) |
| 1545 | 705 | #define HAS_TIMER hasTimer() |
| 1546 | 706 | |
| 1547 | 707 | #else |
| 1548 | 708 | #define BEGIN_TIMER |
| 1549 | | -#define END_TIMER |
| 709 | +#define END_TIMER(X) /*no-op*/ |
| 1550 | 710 | #define HAS_TIMER 0 |
| 1551 | 711 | #endif |
| 1552 | 712 | |
| 1553 | 713 | /* |
| 1554 | 714 | ** Used to prevent warnings about unused parameters |
| | @@ -1745,41 +905,219 @@ |
| 1745 | 905 | char *z; |
| 1746 | 906 | if( iotrace==0 ) return; |
| 1747 | 907 | va_start(ap, zFormat); |
| 1748 | 908 | z = sqlite3_vmprintf(zFormat, ap); |
| 1749 | 909 | va_end(ap); |
| 1750 | | - sputf(iotrace, "%s", z); |
| 910 | + sqlite3_fprintf(iotrace, "%s", z); |
| 1751 | 911 | sqlite3_free(z); |
| 1752 | 912 | } |
| 1753 | 913 | #endif |
| 1754 | 914 | |
| 915 | +/* Lookup table to estimate the number of columns consumed by a Unicode |
| 916 | +** character. |
| 917 | +*/ |
| 918 | +static const struct { |
| 919 | + unsigned char w; /* Width of the character in columns */ |
| 920 | + int iFirst; /* First character in a span having this width */ |
| 921 | +} aUWidth[] = { |
| 922 | + /* {0, 0x00000}, {1, 0x00020}, {0, 0x0007f}, {1, 0x000a0}, */ |
| 923 | + {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488}, |
| 924 | + {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0}, |
| 925 | + {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7}, |
| 926 | + {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616}, |
| 927 | + {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6}, |
| 928 | + {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee}, |
| 929 | + {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730}, |
| 930 | + {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4}, |
| 931 | + {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941}, |
| 932 | + {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955}, |
| 933 | + {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc}, |
| 934 | + {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce}, |
| 935 | + {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c}, |
| 936 | + {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49}, |
| 937 | + {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81}, |
| 938 | + {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6}, |
| 939 | + {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2}, |
| 940 | + {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d}, |
| 941 | + {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d}, |
| 942 | + {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83}, |
| 943 | + {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e}, |
| 944 | + {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e}, |
| 945 | + {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf}, |
| 946 | + {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce}, |
| 947 | + {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d}, |
| 948 | + {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5}, |
| 949 | + {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34}, |
| 950 | + {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2}, |
| 951 | + {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8}, |
| 952 | + {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36}, |
| 953 | + {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71}, |
| 954 | + {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88}, |
| 955 | + {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6}, |
| 956 | + {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033}, |
| 957 | + {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058}, |
| 958 | + {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f}, |
| 959 | + {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735}, |
| 960 | + {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4}, |
| 961 | + {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7}, |
| 962 | + {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b}, |
| 963 | + {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923}, |
| 964 | + {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939}, |
| 965 | + {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04}, |
| 966 | + {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c}, |
| 967 | + {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74}, |
| 968 | + {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b}, |
| 969 | + {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064}, |
| 970 | + {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329}, |
| 971 | + {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f}, |
| 972 | + {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806}, |
| 973 | + {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827}, |
| 974 | + {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e}, |
| 975 | + {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20}, |
| 976 | + {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00}, |
| 977 | + {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc}, |
| 978 | + {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c}, |
| 979 | + {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40}, |
| 980 | + {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185}, |
| 981 | + {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245}, |
| 982 | + {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001}, |
| 983 | + {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0} |
| 984 | +}; |
| 985 | + |
| 1755 | 986 | /* |
| 1756 | | -** Output string zUtf to Out stream as w characters. If w is negative, |
| 987 | +** Return an estimate of the width, in columns, for the single Unicode |
| 988 | +** character c. For normal characters, the answer is always 1. But the |
| 989 | +** estimate might be 0 or 2 for zero-width and double-width characters. |
| 990 | +** |
| 991 | +** Different display devices display unicode using different widths. So |
| 992 | +** it is impossible to know that true display width with 100% accuracy. |
| 993 | +** Inaccuracies in the width estimates might cause columns to be misaligned. |
| 994 | +** Unfortunately, there is nothing we can do about that. |
| 995 | +*/ |
| 996 | +int cli_wcwidth(int c){ |
| 997 | + int iFirst, iLast; |
| 998 | + |
| 999 | + /* Fast path for common characters */ |
| 1000 | + if( c<0x20 ) return 0; |
| 1001 | + if( c<0x7f ) return 1; |
| 1002 | + if( c<0xa0 ) return 0; |
| 1003 | + if( c<=0x300 ) return 1; |
| 1004 | + |
| 1005 | + /* The general case */ |
| 1006 | + iFirst = 0; |
| 1007 | + iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1; |
| 1008 | + while( iFirst<iLast-1 ){ |
| 1009 | + int iMid = (iFirst+iLast)/2; |
| 1010 | + int cMid = aUWidth[iMid].iFirst; |
| 1011 | + if( cMid < c ){ |
| 1012 | + iFirst = iMid; |
| 1013 | + }else if( cMid > c ){ |
| 1014 | + iLast = iMid - 1; |
| 1015 | + }else{ |
| 1016 | + return aUWidth[iMid].w; |
| 1017 | + } |
| 1018 | + } |
| 1019 | + if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w; |
| 1020 | + return aUWidth[iLast].w; |
| 1021 | +} |
| 1022 | + |
| 1023 | +/* |
| 1024 | +** Compute the value and length of a multi-byte UTF-8 character that |
| 1025 | +** begins at z[0]. Return the length. Write the Unicode value into *pU. |
| 1026 | +** |
| 1027 | +** This routine only works for *multi-byte* UTF-8 characters. |
| 1028 | +*/ |
| 1029 | +static int decodeUtf8(const unsigned char *z, int *pU){ |
| 1030 | + if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){ |
| 1031 | + *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f); |
| 1032 | + return 2; |
| 1033 | + } |
| 1034 | + if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){ |
| 1035 | + *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f); |
| 1036 | + return 3; |
| 1037 | + } |
| 1038 | + if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 |
| 1039 | + && (z[3] & 0xc0)==0x80 |
| 1040 | + ){ |
| 1041 | + *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 |
| 1042 | + | (z[4] & 0x3f); |
| 1043 | + return 4; |
| 1044 | + } |
| 1045 | + *pU = 0; |
| 1046 | + return 1; |
| 1047 | +} |
| 1048 | + |
| 1049 | + |
| 1050 | +#if 0 /* NOT USED */ |
| 1051 | +/* |
| 1052 | +** Return the width, in display columns, of a UTF-8 string. |
| 1053 | +** |
| 1054 | +** Each normal character counts as 1. Zero-width characters count |
| 1055 | +** as zero, and double-width characters count as 2. |
| 1056 | +*/ |
| 1057 | +int cli_wcswidth(const char *z){ |
| 1058 | + const unsigned char *a = (const unsigned char*)z; |
| 1059 | + int n = 0; |
| 1060 | + int i = 0; |
| 1061 | + unsigned char c; |
| 1062 | + while( (c = a[i])!=0 ){ |
| 1063 | + if( c>=0xc0 ){ |
| 1064 | + int u; |
| 1065 | + int len = decodeUtf8(&a[i], &u); |
| 1066 | + i += len; |
| 1067 | + n += cli_wcwidth(u); |
| 1068 | + }else if( c>=' ' ){ |
| 1069 | + n++; |
| 1070 | + i++; |
| 1071 | + }else{ |
| 1072 | + i++; |
| 1073 | + } |
| 1074 | + } |
| 1075 | + return n; |
| 1076 | +} |
| 1077 | +#endif |
| 1078 | + |
| 1079 | +/* |
| 1080 | +** Output string zUtf to stdout as w characters. If w is negative, |
| 1757 | 1081 | ** then right-justify the text. W is the width in UTF-8 characters, not |
| 1758 | 1082 | ** in bytes. This is different from the %*.*s specification in printf |
| 1759 | 1083 | ** since with %*.*s the width is measured in bytes, not characters. |
| 1084 | +** |
| 1085 | +** Take into account zero-width and double-width Unicode characters. |
| 1086 | +** In other words, a zero-width character does not count toward the |
| 1087 | +** the w limit. A double-width character counts as two. |
| 1760 | 1088 | */ |
| 1761 | | -static void utf8_width_print(int w, const char *zUtf){ |
| 1762 | | - int i; |
| 1763 | | - int n; |
| 1089 | +static void utf8_width_print(FILE *out, int w, const char *zUtf){ |
| 1090 | + const unsigned char *a = (const unsigned char*)zUtf; |
| 1091 | + unsigned char c; |
| 1092 | + int i = 0; |
| 1093 | + int n = 0; |
| 1764 | 1094 | int aw = w<0 ? -w : w; |
| 1765 | 1095 | if( zUtf==0 ) zUtf = ""; |
| 1766 | | - for(i=n=0; zUtf[i]; i++){ |
| 1767 | | - if( (zUtf[i]&0xc0)!=0x80 ){ |
| 1096 | + while( (c = a[i])!=0 ){ |
| 1097 | + if( (c&0xc0)==0xc0 ){ |
| 1098 | + int u; |
| 1099 | + int len = decodeUtf8(a+i, &u); |
| 1100 | + int x = cli_wcwidth(u); |
| 1101 | + if( x+n>aw ){ |
| 1102 | + break; |
| 1103 | + } |
| 1104 | + i += len; |
| 1105 | + n += x; |
| 1106 | + }else if( n>=aw ){ |
| 1107 | + break; |
| 1108 | + }else{ |
| 1768 | 1109 | n++; |
| 1769 | | - if( n==aw ){ |
| 1770 | | - do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); |
| 1771 | | - break; |
| 1772 | | - } |
| 1110 | + i++; |
| 1773 | 1111 | } |
| 1774 | 1112 | } |
| 1775 | 1113 | if( n>=aw ){ |
| 1776 | | - oputf("%.*s", i, zUtf); |
| 1114 | + sqlite3_fprintf(out, "%.*s", i, zUtf); |
| 1777 | 1115 | }else if( w<0 ){ |
| 1778 | | - oputf("%*s%s", aw-n, "", zUtf); |
| 1116 | + sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf); |
| 1779 | 1117 | }else{ |
| 1780 | | - oputf("%s%*s", zUtf, aw-n, ""); |
| 1118 | + sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, ""); |
| 1781 | 1119 | } |
| 1782 | 1120 | } |
| 1783 | 1121 | |
| 1784 | 1122 | |
| 1785 | 1123 | /* |
| | @@ -1841,11 +1179,11 @@ |
| 1841 | 1179 | struct __stat64 x = {0}; |
| 1842 | 1180 | # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) |
| 1843 | 1181 | /* On Windows, open first, then check the stream nature. This order |
| 1844 | 1182 | ** is necessary because _stat() and sibs, when checking a named pipe, |
| 1845 | 1183 | ** effectively break the pipe as its supplier sees it. */ |
| 1846 | | - FILE *rv = fopen(zFile, "rb"); |
| 1184 | + FILE *rv = sqlite3_fopen(zFile, "rb"); |
| 1847 | 1185 | if( rv==0 ) return 0; |
| 1848 | 1186 | if( _fstat64(_fileno(rv), &x) != 0 |
| 1849 | 1187 | || !STAT_CHR_SRC(x.st_mode)){ |
| 1850 | 1188 | fclose(rv); |
| 1851 | 1189 | rv = 0; |
| | @@ -1855,11 +1193,11 @@ |
| 1855 | 1193 | struct stat x = {0}; |
| 1856 | 1194 | int rc = stat(zFile, &x); |
| 1857 | 1195 | # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) |
| 1858 | 1196 | if( rc!=0 ) return 0; |
| 1859 | 1197 | if( STAT_CHR_SRC(x.st_mode) ){ |
| 1860 | | - return fopen(zFile, "rb"); |
| 1198 | + return sqlite3_fopen(zFile, "rb"); |
| 1861 | 1199 | }else{ |
| 1862 | 1200 | return 0; |
| 1863 | 1201 | } |
| 1864 | 1202 | #endif |
| 1865 | 1203 | #undef STAT_CHR_SRC |
| | @@ -1882,11 +1220,11 @@ |
| 1882 | 1220 | if( n+100>nLine ){ |
| 1883 | 1221 | nLine = nLine*2 + 100; |
| 1884 | 1222 | zLine = realloc(zLine, nLine); |
| 1885 | 1223 | shell_check_oom(zLine); |
| 1886 | 1224 | } |
| 1887 | | - if( fgets(&zLine[n], nLine - n, in)==0 ){ |
| 1225 | + if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ |
| 1888 | 1226 | if( n==0 ){ |
| 1889 | 1227 | free(zLine); |
| 1890 | 1228 | return 0; |
| 1891 | 1229 | } |
| 1892 | 1230 | zLine[n] = 0; |
| | @@ -8604,10 +7942,17 @@ |
| 8604 | 7942 | # define lstat(path,buf) stat(path,buf) |
| 8605 | 7943 | #endif |
| 8606 | 7944 | #include <time.h> |
| 8607 | 7945 | #include <errno.h> |
| 8608 | 7946 | |
| 7947 | +/* When used as part of the CLI, the sqlite3_stdio.h module will have |
| 7948 | +** been included before this one. In that case use the sqlite3_stdio.h |
| 7949 | +** #defines. If not, create our own for fopen(). |
| 7950 | +*/ |
| 7951 | +#ifndef _SQLITE3_STDIO_H_ |
| 7952 | +# define sqlite3_fopen fopen |
| 7953 | +#endif |
| 8609 | 7954 | |
| 8610 | 7955 | /* |
| 8611 | 7956 | ** Structure of the fsdir() table-valued function |
| 8612 | 7957 | */ |
| 8613 | 7958 | /* 0 1 2 3 4 5 */ |
| | @@ -8636,11 +7981,11 @@ |
| 8636 | 7981 | sqlite3_int64 nIn; |
| 8637 | 7982 | void *pBuf; |
| 8638 | 7983 | sqlite3 *db; |
| 8639 | 7984 | int mxBlob; |
| 8640 | 7985 | |
| 8641 | | - in = fopen(zName, "rb"); |
| 7986 | + in = sqlite3_fopen(zName, "rb"); |
| 8642 | 7987 | if( in==0 ){ |
| 8643 | 7988 | /* File does not exist or is unreadable. Leave the result set to NULL. */ |
| 8644 | 7989 | return; |
| 8645 | 7990 | } |
| 8646 | 7991 | fseek(in, 0, SEEK_END); |
| | @@ -8891,11 +8236,11 @@ |
| 8891 | 8236 | } |
| 8892 | 8237 | }else{ |
| 8893 | 8238 | sqlite3_int64 nWrite = 0; |
| 8894 | 8239 | const char *z; |
| 8895 | 8240 | int rc = 0; |
| 8896 | | - FILE *out = fopen(zFile, "wb"); |
| 8241 | + FILE *out = sqlite3_fopen(zFile, "wb"); |
| 8897 | 8242 | if( out==0 ) return 1; |
| 8898 | 8243 | z = (const char*)sqlite3_value_blob(pData); |
| 8899 | 8244 | if( z ){ |
| 8900 | 8245 | sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); |
| 8901 | 8246 | nWrite = sqlite3_value_bytes(pData); |
| | @@ -10752,10 +10097,18 @@ |
| 10752 | 10097 | #ifndef SQLITE_NO_STDINT |
| 10753 | 10098 | # include <stdint.h> |
| 10754 | 10099 | #endif |
| 10755 | 10100 | |
| 10756 | 10101 | #include <zlib.h> |
| 10102 | + |
| 10103 | +/* When used as part of the CLI, the sqlite3_stdio.h module will have |
| 10104 | +** been included before this one. In that case use the sqlite3_stdio.h |
| 10105 | +** #defines. If not, create our own for fopen(). |
| 10106 | +*/ |
| 10107 | +#ifndef _SQLITE3_STDIO_H_ |
| 10108 | +# define sqlite3_fopen fopen |
| 10109 | +#endif |
| 10757 | 10110 | |
| 10758 | 10111 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 10759 | 10112 | |
| 10760 | 10113 | #ifndef SQLITE_AMALGAMATION |
| 10761 | 10114 | |
| | @@ -12009,11 +11362,11 @@ |
| 12009 | 11362 | }else{ |
| 12010 | 11363 | zFile = (const char*)sqlite3_value_text(argv[0]); |
| 12011 | 11364 | } |
| 12012 | 11365 | |
| 12013 | 11366 | if( 0==pTab->pWriteFd && 0==bInMemory ){ |
| 12014 | | - pCsr->pFile = zFile ? fopen(zFile, "rb") : 0; |
| 11367 | + pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0; |
| 12015 | 11368 | if( pCsr->pFile==0 ){ |
| 12016 | 11369 | zipfileCursorErr(pCsr, "cannot open file: %s", zFile); |
| 12017 | 11370 | rc = SQLITE_ERROR; |
| 12018 | 11371 | }else{ |
| 12019 | 11372 | rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); |
| | @@ -12199,11 +11552,11 @@ |
| 12199 | 11552 | |
| 12200 | 11553 | /* Open a write fd on the file. Also load the entire central directory |
| 12201 | 11554 | ** structure into memory. During the transaction any new file data is |
| 12202 | 11555 | ** appended to the archive file, but the central directory is accumulated |
| 12203 | 11556 | ** in main-memory until the transaction is committed. */ |
| 12204 | | - pTab->pWriteFd = fopen(pTab->zFile, "ab+"); |
| 11557 | + pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+"); |
| 12205 | 11558 | if( pTab->pWriteFd==0 ){ |
| 12206 | 11559 | pTab->base.zErrMsg = sqlite3_mprintf( |
| 12207 | 11560 | "zipfile: failed to open file %s for writing", pTab->zFile |
| 12208 | 11561 | ); |
| 12209 | 11562 | rc = SQLITE_ERROR; |
| | @@ -14883,10 +14236,16 @@ |
| 14883 | 14236 | sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); |
| 14884 | 14237 | while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ |
| 14885 | 14238 | const char *zComma = zCols==0 ? "" : ", "; |
| 14886 | 14239 | const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); |
| 14887 | 14240 | const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); |
| 14241 | + if( zName==0 ){ |
| 14242 | + /* This index contains an expression. Ignore it. */ |
| 14243 | + sqlite3_free(zCols); |
| 14244 | + sqlite3_free(zOrder); |
| 14245 | + return sqlite3_reset(pIndexXInfo); |
| 14246 | + } |
| 14888 | 14247 | zCols = idxAppendText(&rc, zCols, |
| 14889 | 14248 | "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s", |
| 14890 | 14249 | zComma, zName, nCol, zName, zColl |
| 14891 | 14250 | ); |
| 14892 | 14251 | zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); |
| | @@ -21991,10 +21350,11 @@ |
| 21991 | 21350 | #define MODE_Table 15 /* MySQL-style table formatting */ |
| 21992 | 21351 | #define MODE_Box 16 /* Unicode box-drawing characters */ |
| 21993 | 21352 | #define MODE_Count 17 /* Output only a count of the rows of output */ |
| 21994 | 21353 | #define MODE_Off 18 /* No query output shown */ |
| 21995 | 21354 | #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */ |
| 21355 | +#define MODE_Www 20 /* Full web-page output */ |
| 21996 | 21356 | |
| 21997 | 21357 | static const char *modeDescr[] = { |
| 21998 | 21358 | "line", |
| 21999 | 21359 | "column", |
| 22000 | 21360 | "list", |
| | @@ -22011,11 +21371,13 @@ |
| 22011 | 21371 | "json", |
| 22012 | 21372 | "markdown", |
| 22013 | 21373 | "table", |
| 22014 | 21374 | "box", |
| 22015 | 21375 | "count", |
| 22016 | | - "off" |
| 21376 | + "off", |
| 21377 | + "scanexp", |
| 21378 | + "www", |
| 22017 | 21379 | }; |
| 22018 | 21380 | |
| 22019 | 21381 | /* |
| 22020 | 21382 | ** These are the column/row/line separators used by the various |
| 22021 | 21383 | ** import/export modes. |
| | @@ -22023,11 +21385,17 @@ |
| 22023 | 21385 | #define SEP_Column "|" |
| 22024 | 21386 | #define SEP_Row "\n" |
| 22025 | 21387 | #define SEP_Tab "\t" |
| 22026 | 21388 | #define SEP_Space " " |
| 22027 | 21389 | #define SEP_Comma "," |
| 22028 | | -#define SEP_CrLf "\r\n" |
| 21390 | +#ifdef SQLITE_U8TEXT_ONLY |
| 21391 | + /* With the SQLITE_U8TEXT_ONLY option, the output will always be in |
| 21392 | + ** text mode. The \r will be inserted automatically. */ |
| 21393 | +# define SEP_CrLf "\n" |
| 21394 | +#else |
| 21395 | +# define SEP_CrLf "\r\n" |
| 21396 | +#endif |
| 22029 | 21397 | #define SEP_Unit "\x1F" |
| 22030 | 21398 | #define SEP_Record "\x1E" |
| 22031 | 21399 | |
| 22032 | 21400 | /* |
| 22033 | 21401 | ** Limit input nesting via .read or any other input redirect. |
| | @@ -22039,11 +21407,11 @@ |
| 22039 | 21407 | ** A callback for the sqlite3_log() interface. |
| 22040 | 21408 | */ |
| 22041 | 21409 | static void shellLog(void *pArg, int iErrCode, const char *zMsg){ |
| 22042 | 21410 | ShellState *p = (ShellState*)pArg; |
| 22043 | 21411 | if( p->pLog==0 ) return; |
| 22044 | | - sputf(p->pLog, "(%d) %s\n", iErrCode, zMsg); |
| 21412 | + sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); |
| 22045 | 21413 | fflush(p->pLog); |
| 22046 | 21414 | } |
| 22047 | 21415 | |
| 22048 | 21416 | /* |
| 22049 | 21417 | ** SQL function: shell_putsnl(X) |
| | @@ -22054,13 +21422,13 @@ |
| 22054 | 21422 | static void shellPutsFunc( |
| 22055 | 21423 | sqlite3_context *pCtx, |
| 22056 | 21424 | int nVal, |
| 22057 | 21425 | sqlite3_value **apVal |
| 22058 | 21426 | ){ |
| 22059 | | - /* Unused: (ShellState*)sqlite3_user_data(pCtx); */ |
| 21427 | + ShellState *p = (ShellState*)sqlite3_user_data(pCtx); |
| 22060 | 21428 | (void)nVal; |
| 22061 | | - oputf("%s\n", sqlite3_value_text(apVal[0])); |
| 21429 | + sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0])); |
| 22062 | 21430 | sqlite3_result_value(pCtx, apVal[0]); |
| 22063 | 21431 | } |
| 22064 | 21432 | |
| 22065 | 21433 | /* |
| 22066 | 21434 | ** If in safe mode, print an error message described by the arguments |
| | @@ -22075,11 +21443,11 @@ |
| 22075 | 21443 | va_list ap; |
| 22076 | 21444 | char *zMsg; |
| 22077 | 21445 | va_start(ap, zErrMsg); |
| 22078 | 21446 | zMsg = sqlite3_vmprintf(zErrMsg, ap); |
| 22079 | 21447 | va_end(ap); |
| 22080 | | - eputf("line %d: %s\n", p->lineno, zMsg); |
| 21448 | + sqlite3_fprintf(stderr, "line %d: %s\n", p->lineno, zMsg); |
| 22081 | 21449 | exit(1); |
| 22082 | 21450 | } |
| 22083 | 21451 | } |
| 22084 | 21452 | |
| 22085 | 21453 | /* |
| | @@ -22142,11 +21510,11 @@ |
| 22142 | 21510 | } |
| 22143 | 21511 | } |
| 22144 | 21512 | bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; |
| 22145 | 21513 | /* When writing the file to be edited, do \n to \r\n conversions on systems |
| 22146 | 21514 | ** that want \r\n line endings */ |
| 22147 | | - f = fopen(zTempFile, bBin ? "wb" : "w"); |
| 21515 | + f = sqlite3_fopen(zTempFile, bBin ? "wb" : "w"); |
| 22148 | 21516 | if( f==0 ){ |
| 22149 | 21517 | sqlite3_result_error(context, "edit() cannot open temp file", -1); |
| 22150 | 21518 | goto edit_func_end; |
| 22151 | 21519 | } |
| 22152 | 21520 | sz = sqlite3_value_bytes(argv[0]); |
| | @@ -22173,11 +21541,11 @@ |
| 22173 | 21541 | sqlite3_free(zCmd); |
| 22174 | 21542 | if( rc ){ |
| 22175 | 21543 | sqlite3_result_error(context, "EDITOR returned non-zero", -1); |
| 22176 | 21544 | goto edit_func_end; |
| 22177 | 21545 | } |
| 22178 | | - f = fopen(zTempFile, "rb"); |
| 21546 | + f = sqlite3_fopen(zTempFile, "rb"); |
| 22179 | 21547 | if( f==0 ){ |
| 22180 | 21548 | sqlite3_result_error(context, |
| 22181 | 21549 | "edit() cannot reopen temp file after edit", -1); |
| 22182 | 21550 | goto edit_func_end; |
| 22183 | 21551 | } |
| | @@ -22243,11 +21611,11 @@ |
| 22243 | 21611 | } |
| 22244 | 21612 | |
| 22245 | 21613 | /* |
| 22246 | 21614 | ** Output the given string as a hex-encoded blob (eg. X'1234' ) |
| 22247 | 21615 | */ |
| 22248 | | -static void output_hex_blob(const void *pBlob, int nBlob){ |
| 21616 | +static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ |
| 22249 | 21617 | int i; |
| 22250 | 21618 | unsigned char *aBlob = (unsigned char*)pBlob; |
| 22251 | 21619 | |
| 22252 | 21620 | char *zStr = sqlite3_malloc(nBlob*2 + 1); |
| 22253 | 21621 | shell_check_oom(zStr); |
| | @@ -22260,11 +21628,11 @@ |
| 22260 | 21628 | zStr[i*2] = aHex[ (aBlob[i] >> 4) ]; |
| 22261 | 21629 | zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ]; |
| 22262 | 21630 | } |
| 22263 | 21631 | zStr[i*2] = '\0'; |
| 22264 | 21632 | |
| 22265 | | - oputf("X'%s'", zStr); |
| 21633 | + sqlite3_fprintf(out, "X'%s'", zStr); |
| 22266 | 21634 | sqlite3_free(zStr); |
| 22267 | 21635 | } |
| 22268 | 21636 | |
| 22269 | 21637 | /* |
| 22270 | 21638 | ** Find a string that is not found anywhere in z[]. Return a pointer |
| | @@ -22290,46 +21658,39 @@ |
| 22290 | 21658 | /* |
| 22291 | 21659 | ** Output the given string as a quoted string using SQL quoting conventions. |
| 22292 | 21660 | ** |
| 22293 | 21661 | ** See also: output_quoted_escaped_string() |
| 22294 | 21662 | */ |
| 22295 | | -static void output_quoted_string(const char *z){ |
| 21663 | +static void output_quoted_string(FILE *out, const char *z){ |
| 22296 | 21664 | int i; |
| 22297 | 21665 | char c; |
| 22298 | | -#ifndef SQLITE_SHELL_FIDDLE |
| 22299 | | - FILE *pfO = setOutputStream(invalidFileStream); |
| 22300 | | - setBinaryMode(pfO, 1); |
| 22301 | | -#endif |
| 21666 | + sqlite3_fsetmode(out, _O_BINARY); |
| 22302 | 21667 | if( z==0 ) return; |
| 22303 | 21668 | for(i=0; (c = z[i])!=0 && c!='\''; i++){} |
| 22304 | 21669 | if( c==0 ){ |
| 22305 | | - oputf("'%s'",z); |
| 21670 | + sqlite3_fprintf(out, "'%s'",z); |
| 22306 | 21671 | }else{ |
| 22307 | | - oputz("'"); |
| 21672 | + sqlite3_fputs("'", out); |
| 22308 | 21673 | while( *z ){ |
| 22309 | 21674 | for(i=0; (c = z[i])!=0 && c!='\''; i++){} |
| 22310 | 21675 | if( c=='\'' ) i++; |
| 22311 | 21676 | if( i ){ |
| 22312 | | - oputf("%.*s", i, z); |
| 21677 | + sqlite3_fprintf(out, "%.*s", i, z); |
| 22313 | 21678 | z += i; |
| 22314 | 21679 | } |
| 22315 | 21680 | if( c=='\'' ){ |
| 22316 | | - oputz("'"); |
| 21681 | + sqlite3_fputs("'", out); |
| 22317 | 21682 | continue; |
| 22318 | 21683 | } |
| 22319 | 21684 | if( c==0 ){ |
| 22320 | 21685 | break; |
| 22321 | 21686 | } |
| 22322 | 21687 | z++; |
| 22323 | 21688 | } |
| 22324 | | - oputz("'"); |
| 21689 | + sqlite3_fputs("'", out); |
| 22325 | 21690 | } |
| 22326 | | -#ifndef SQLITE_SHELL_FIDDLE |
| 22327 | | - setTextMode(pfO, 1); |
| 22328 | | -#else |
| 22329 | | - setTextMode(stdout, 1); |
| 22330 | | -#endif |
| 21691 | + sqlite3_fsetmode(out, _O_TEXT); |
| 22331 | 21692 | } |
| 22332 | 21693 | |
| 22333 | 21694 | /* |
| 22334 | 21695 | ** Output the given string as a quoted string using SQL quoting conventions. |
| 22335 | 21696 | ** Additionallly , escape the "\n" and "\r" characters so that they do not |
| | @@ -22337,20 +21698,17 @@ |
| 22337 | 21698 | ** systems. |
| 22338 | 21699 | ** |
| 22339 | 21700 | ** This is like output_quoted_string() but with the addition of the \r\n |
| 22340 | 21701 | ** escape mechanism. |
| 22341 | 21702 | */ |
| 22342 | | -static void output_quoted_escaped_string(const char *z){ |
| 21703 | +static void output_quoted_escaped_string(FILE *out, const char *z){ |
| 22343 | 21704 | int i; |
| 22344 | 21705 | char c; |
| 22345 | | -#ifndef SQLITE_SHELL_FIDDLE |
| 22346 | | - FILE *pfO = setOutputStream(invalidFileStream); |
| 22347 | | - setBinaryMode(pfO, 1); |
| 22348 | | -#endif |
| 21706 | + sqlite3_fsetmode(out, _O_BINARY); |
| 22349 | 21707 | for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){} |
| 22350 | 21708 | if( c==0 ){ |
| 22351 | | - oputf("'%s'",z); |
| 21709 | + sqlite3_fprintf(out, "'%s'",z); |
| 22352 | 21710 | }else{ |
| 22353 | 21711 | const char *zNL = 0; |
| 22354 | 21712 | const char *zCR = 0; |
| 22355 | 21713 | int nNL = 0; |
| 22356 | 21714 | int nCR = 0; |
| | @@ -22358,52 +21716,48 @@ |
| 22358 | 21716 | for(i=0; z[i]; i++){ |
| 22359 | 21717 | if( z[i]=='\n' ) nNL++; |
| 22360 | 21718 | if( z[i]=='\r' ) nCR++; |
| 22361 | 21719 | } |
| 22362 | 21720 | if( nNL ){ |
| 22363 | | - oputz("replace("); |
| 21721 | + sqlite3_fputs("replace(", out); |
| 22364 | 21722 | zNL = unused_string(z, "\\n", "\\012", zBuf1); |
| 22365 | 21723 | } |
| 22366 | 21724 | if( nCR ){ |
| 22367 | | - oputz("replace("); |
| 21725 | + sqlite3_fputs("replace(", out); |
| 22368 | 21726 | zCR = unused_string(z, "\\r", "\\015", zBuf2); |
| 22369 | 21727 | } |
| 22370 | | - oputz("'"); |
| 21728 | + sqlite3_fputs("'", out); |
| 22371 | 21729 | while( *z ){ |
| 22372 | 21730 | for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){} |
| 22373 | 21731 | if( c=='\'' ) i++; |
| 22374 | 21732 | if( i ){ |
| 22375 | | - oputf("%.*s", i, z); |
| 21733 | + sqlite3_fprintf(out, "%.*s", i, z); |
| 22376 | 21734 | z += i; |
| 22377 | 21735 | } |
| 22378 | 21736 | if( c=='\'' ){ |
| 22379 | | - oputz("'"); |
| 21737 | + sqlite3_fputs("'", out); |
| 22380 | 21738 | continue; |
| 22381 | 21739 | } |
| 22382 | 21740 | if( c==0 ){ |
| 22383 | 21741 | break; |
| 22384 | 21742 | } |
| 22385 | 21743 | z++; |
| 22386 | 21744 | if( c=='\n' ){ |
| 22387 | | - oputz(zNL); |
| 21745 | + sqlite3_fputs(zNL, out); |
| 22388 | 21746 | continue; |
| 22389 | 21747 | } |
| 22390 | | - oputz(zCR); |
| 21748 | + sqlite3_fputs(zCR, out); |
| 22391 | 21749 | } |
| 22392 | | - oputz("'"); |
| 21750 | + sqlite3_fputs("'", out); |
| 22393 | 21751 | if( nCR ){ |
| 22394 | | - oputf(",'%s',char(13))", zCR); |
| 21752 | + sqlite3_fprintf(out, ",'%s',char(13))", zCR); |
| 22395 | 21753 | } |
| 22396 | 21754 | if( nNL ){ |
| 22397 | | - oputf(",'%s',char(10))", zNL); |
| 21755 | + sqlite3_fprintf(out, ",'%s',char(10))", zNL); |
| 22398 | 21756 | } |
| 22399 | 21757 | } |
| 22400 | | -#ifndef SQLITE_SHELL_FIDDLE |
| 22401 | | - setTextMode(pfO, 1); |
| 22402 | | -#else |
| 22403 | | - setTextMode(stdout, 1); |
| 22404 | | -#endif |
| 21758 | + sqlite3_fsetmode(stdout, _O_TEXT); |
| 22405 | 21759 | } |
| 22406 | 21760 | |
| 22407 | 21761 | /* |
| 22408 | 21762 | ** Find earliest of chars within s specified in zAny. |
| 22409 | 21763 | ** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated. |
| | @@ -22419,26 +21773,64 @@ |
| 22419 | 21773 | } |
| 22420 | 21774 | ++zAny; |
| 22421 | 21775 | } |
| 22422 | 21776 | return pcFirst; |
| 22423 | 21777 | } |
| 21778 | + |
| 21779 | +/* Skip over as much z[] input char sequence as is valid UTF-8, |
| 21780 | +** limited per nAccept char's or whole characters and containing |
| 21781 | +** no char cn such that ((1<<cn) & ccm)!=0. On return, the |
| 21782 | +** sequence z:return (inclusive:exclusive) is validated UTF-8. |
| 21783 | +** Limit: nAccept>=0 => char count, nAccept<0 => character |
| 21784 | + */ |
| 21785 | +const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ |
| 21786 | + int ng = (nAccept<0)? -nAccept : 0; |
| 21787 | + const char *pcLimit = (nAccept>=0)? z+nAccept : 0; |
| 21788 | + assert(z!=0); |
| 21789 | + while( (pcLimit)? (z<pcLimit) : (ng-- != 0) ){ |
| 21790 | + char c = *z; |
| 21791 | + if( (c & 0x80) == 0 ){ |
| 21792 | + if( ccm != 0L && c < 0x20 && ((1L<<c) & ccm) != 0 ) return z; |
| 21793 | + ++z; /* ASCII */ |
| 21794 | + }else if( (c & 0xC0) != 0xC0 ) return z; /* not a lead byte */ |
| 21795 | + else{ |
| 21796 | + const char *zt = z+1; /* Got lead byte, look at trail bytes.*/ |
| 21797 | + do{ |
| 21798 | + if( pcLimit && zt >= pcLimit ) return z; |
| 21799 | + else{ |
| 21800 | + char ct = *zt++; |
| 21801 | + if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ |
| 21802 | + /* Trailing bytes are too few, too many, or invalid. */ |
| 21803 | + return z; |
| 21804 | + } |
| 21805 | + } |
| 21806 | + } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ |
| 21807 | + z = zt; |
| 21808 | + } |
| 21809 | + } |
| 21810 | + return z; |
| 21811 | +} |
| 21812 | + |
| 21813 | + |
| 22424 | 21814 | /* |
| 22425 | 21815 | ** Output the given string as a quoted according to C or TCL quoting rules. |
| 22426 | 21816 | */ |
| 22427 | | -static void output_c_string(const char *z){ |
| 21817 | +static void output_c_string(FILE *out, const char *z){ |
| 22428 | 21818 | char c; |
| 22429 | 21819 | static const char *zq = "\""; |
| 22430 | 21820 | static long ctrlMask = ~0L; |
| 22431 | 21821 | static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */ |
| 22432 | 21822 | char ace[3] = "\\?"; |
| 22433 | 21823 | char cbsSay; |
| 22434 | | - oputz(zq); |
| 21824 | + sqlite3_fputs(zq, out); |
| 22435 | 21825 | while( *z!=0 ){ |
| 22436 | 21826 | const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0); |
| 22437 | 21827 | const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask); |
| 22438 | 21828 | const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast; |
| 22439 | | - if( pcEnd > z ) oputb(z, (int)(pcEnd-z)); |
| 21829 | + if( pcEnd > z ){ |
| 21830 | + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); |
| 21831 | + } |
| 22440 | 21832 | if( (c = *pcEnd)==0 ) break; |
| 22441 | 21833 | ++pcEnd; |
| 22442 | 21834 | switch( c ){ |
| 22443 | 21835 | case '\\': case '"': |
| 22444 | 21836 | cbsSay = (char)c; |
| | @@ -22449,26 +21841,26 @@ |
| 22449 | 21841 | case '\f': cbsSay = 'f'; break; |
| 22450 | 21842 | default: cbsSay = 0; break; |
| 22451 | 21843 | } |
| 22452 | 21844 | if( cbsSay ){ |
| 22453 | 21845 | ace[1] = cbsSay; |
| 22454 | | - oputz(ace); |
| 21846 | + sqlite3_fputs(ace, out); |
| 22455 | 21847 | }else if( !isprint(c&0xff) ){ |
| 22456 | | - oputf("\\%03o", c&0xff); |
| 21848 | + sqlite3_fprintf(out, "\\%03o", c&0xff); |
| 22457 | 21849 | }else{ |
| 22458 | 21850 | ace[1] = (char)c; |
| 22459 | | - oputz(ace+1); |
| 21851 | + sqlite3_fputs(ace+1, out); |
| 22460 | 21852 | } |
| 22461 | 21853 | z = pcEnd; |
| 22462 | 21854 | } |
| 22463 | | - oputz(zq); |
| 21855 | + sqlite3_fputs(zq, out); |
| 22464 | 21856 | } |
| 22465 | 21857 | |
| 22466 | 21858 | /* |
| 22467 | 21859 | ** Output the given string as a quoted according to JSON quoting rules. |
| 22468 | 21860 | */ |
| 22469 | | -static void output_json_string(const char *z, i64 n){ |
| 21861 | +static void output_json_string(FILE *out, const char *z, i64 n){ |
| 22470 | 21862 | char c; |
| 22471 | 21863 | static const char *zq = "\""; |
| 22472 | 21864 | static long ctrlMask = ~0L; |
| 22473 | 21865 | static const char *zDQBS = "\"\\"; |
| 22474 | 21866 | const char *pcLimit; |
| | @@ -22475,17 +21867,17 @@ |
| 22475 | 21867 | char ace[3] = "\\?"; |
| 22476 | 21868 | char cbsSay; |
| 22477 | 21869 | |
| 22478 | 21870 | if( z==0 ) z = ""; |
| 22479 | 21871 | pcLimit = z + ((n<0)? strlen(z) : (size_t)n); |
| 22480 | | - oputz(zq); |
| 21872 | + sqlite3_fputs(zq, out); |
| 22481 | 21873 | while( z < pcLimit ){ |
| 22482 | 21874 | const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z); |
| 22483 | 21875 | const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask); |
| 22484 | 21876 | const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast; |
| 22485 | 21877 | if( pcEnd > z ){ |
| 22486 | | - oputb(z, (int)(pcEnd-z)); |
| 21878 | + sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); |
| 22487 | 21879 | z = pcEnd; |
| 22488 | 21880 | } |
| 22489 | 21881 | if( z >= pcLimit ) break; |
| 22490 | 21882 | c = *(z++); |
| 22491 | 21883 | switch( c ){ |
| | @@ -22499,26 +21891,26 @@ |
| 22499 | 21891 | case '\t': cbsSay = 't'; break; |
| 22500 | 21892 | default: cbsSay = 0; break; |
| 22501 | 21893 | } |
| 22502 | 21894 | if( cbsSay ){ |
| 22503 | 21895 | ace[1] = cbsSay; |
| 22504 | | - oputz(ace); |
| 21896 | + sqlite3_fputs(ace, out); |
| 22505 | 21897 | }else if( c<=0x1f ){ |
| 22506 | | - oputf("u%04x", c); |
| 21898 | + sqlite3_fprintf(out, "u%04x", c); |
| 22507 | 21899 | }else{ |
| 22508 | 21900 | ace[1] = (char)c; |
| 22509 | | - oputz(ace+1); |
| 21901 | + sqlite3_fputs(ace+1, out); |
| 22510 | 21902 | } |
| 22511 | 21903 | } |
| 22512 | | - oputz(zq); |
| 21904 | + sqlite3_fputs(zq, out); |
| 22513 | 21905 | } |
| 22514 | 21906 | |
| 22515 | 21907 | /* |
| 22516 | 21908 | ** Output the given string with characters that are special to |
| 22517 | 21909 | ** HTML escaped. |
| 22518 | 21910 | */ |
| 22519 | | -static void output_html_string(const char *z){ |
| 21911 | +static void output_html_string(FILE *out, const char *z){ |
| 22520 | 21912 | int i; |
| 22521 | 21913 | if( z==0 ) z = ""; |
| 22522 | 21914 | while( *z ){ |
| 22523 | 21915 | for(i=0; z[i] |
| 22524 | 21916 | && z[i]!='<' |
| | @@ -22526,22 +21918,22 @@ |
| 22526 | 21918 | && z[i]!='>' |
| 22527 | 21919 | && z[i]!='\"' |
| 22528 | 21920 | && z[i]!='\''; |
| 22529 | 21921 | i++){} |
| 22530 | 21922 | if( i>0 ){ |
| 22531 | | - oputf("%.*s",i,z); |
| 21923 | + sqlite3_fprintf(out, "%.*s",i,z); |
| 22532 | 21924 | } |
| 22533 | 21925 | if( z[i]=='<' ){ |
| 22534 | | - oputz("<"); |
| 21926 | + sqlite3_fputs("<", out); |
| 22535 | 21927 | }else if( z[i]=='&' ){ |
| 22536 | | - oputz("&"); |
| 21928 | + sqlite3_fputs("&", out); |
| 22537 | 21929 | }else if( z[i]=='>' ){ |
| 22538 | | - oputz(">"); |
| 21930 | + sqlite3_fputs(">", out); |
| 22539 | 21931 | }else if( z[i]=='\"' ){ |
| 22540 | | - oputz("""); |
| 21932 | + sqlite3_fputs(""", out); |
| 22541 | 21933 | }else if( z[i]=='\'' ){ |
| 22542 | | - oputz("'"); |
| 21934 | + sqlite3_fputs("'", out); |
| 22543 | 21935 | }else{ |
| 22544 | 21936 | break; |
| 22545 | 21937 | } |
| 22546 | 21938 | z += i + 1; |
| 22547 | 21939 | } |
| | @@ -22576,11 +21968,11 @@ |
| 22576 | 21968 | ** the null value. Strings are quoted if necessary. The separator |
| 22577 | 21969 | ** is only issued if bSep is true. |
| 22578 | 21970 | */ |
| 22579 | 21971 | static void output_csv(ShellState *p, const char *z, int bSep){ |
| 22580 | 21972 | if( z==0 ){ |
| 22581 | | - oputf("%s",p->nullValue); |
| 21973 | + sqlite3_fprintf(p->out, "%s",p->nullValue); |
| 22582 | 21974 | }else{ |
| 22583 | 21975 | unsigned i; |
| 22584 | 21976 | for(i=0; z[i]; i++){ |
| 22585 | 21977 | if( needCsvQuote[((unsigned char*)z)[i]] ){ |
| 22586 | 21978 | i = 0; |
| | @@ -22588,18 +21980,18 @@ |
| 22588 | 21980 | } |
| 22589 | 21981 | } |
| 22590 | 21982 | if( i==0 || strstr(z, p->colSeparator)!=0 ){ |
| 22591 | 21983 | char *zQuoted = sqlite3_mprintf("\"%w\"", z); |
| 22592 | 21984 | shell_check_oom(zQuoted); |
| 22593 | | - oputz(zQuoted); |
| 21985 | + sqlite3_fputs(zQuoted, p->out); |
| 22594 | 21986 | sqlite3_free(zQuoted); |
| 22595 | 21987 | }else{ |
| 22596 | | - oputz(z); |
| 21988 | + sqlite3_fputs(z, p->out); |
| 22597 | 21989 | } |
| 22598 | 21990 | } |
| 22599 | 21991 | if( bSep ){ |
| 22600 | | - oputz(p->colSeparator); |
| 21992 | + sqlite3_fputs(p->colSeparator, p->out); |
| 22601 | 21993 | } |
| 22602 | 21994 | } |
| 22603 | 21995 | |
| 22604 | 21996 | /* |
| 22605 | 21997 | ** This routine runs when the user presses Ctrl-C |
| | @@ -22703,20 +22095,20 @@ |
| 22703 | 22095 | const char *az[4]; |
| 22704 | 22096 | az[0] = zA1; |
| 22705 | 22097 | az[1] = zA2; |
| 22706 | 22098 | az[2] = zA3; |
| 22707 | 22099 | az[3] = zA4; |
| 22708 | | - oputf("authorizer: %s", azAction[op]); |
| 22100 | + sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]); |
| 22709 | 22101 | for(i=0; i<4; i++){ |
| 22710 | | - oputz(" "); |
| 22102 | + sqlite3_fputs(" ", p->out); |
| 22711 | 22103 | if( az[i] ){ |
| 22712 | | - output_c_string(az[i]); |
| 22104 | + output_c_string(p->out, az[i]); |
| 22713 | 22105 | }else{ |
| 22714 | | - oputz("NULL"); |
| 22106 | + sqlite3_fputs("NULL", p->out); |
| 22715 | 22107 | } |
| 22716 | 22108 | } |
| 22717 | | - oputz("\n"); |
| 22109 | + sqlite3_fputs("\n", p->out); |
| 22718 | 22110 | if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4); |
| 22719 | 22111 | return SQLITE_OK; |
| 22720 | 22112 | } |
| 22721 | 22113 | #endif |
| 22722 | 22114 | |
| | @@ -22728,11 +22120,11 @@ |
| 22728 | 22120 | ** |
| 22729 | 22121 | ** If the schema statement in z[] contains a start-of-comment and if |
| 22730 | 22122 | ** sqlite3_complete() returns false, try to terminate the comment before |
| 22731 | 22123 | ** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c |
| 22732 | 22124 | */ |
| 22733 | | -static void printSchemaLine(const char *z, const char *zTail){ |
| 22125 | +static void printSchemaLine(FILE *out, const char *z, const char *zTail){ |
| 22734 | 22126 | char *zToFree = 0; |
| 22735 | 22127 | if( z==0 ) return; |
| 22736 | 22128 | if( zTail==0 ) return; |
| 22737 | 22129 | if( zTail[0]==';' && (strstr(z, "/*")!=0 || strstr(z,"--")!=0) ){ |
| 22738 | 22130 | const char *zOrig = z; |
| | @@ -22750,20 +22142,20 @@ |
| 22750 | 22142 | } |
| 22751 | 22143 | sqlite3_free(zNew); |
| 22752 | 22144 | } |
| 22753 | 22145 | } |
| 22754 | 22146 | if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ |
| 22755 | | - oputf("CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); |
| 22147 | + sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); |
| 22756 | 22148 | }else{ |
| 22757 | | - oputf("%s%s", z, zTail); |
| 22149 | + sqlite3_fprintf(out, "%s%s", z, zTail); |
| 22758 | 22150 | } |
| 22759 | 22151 | sqlite3_free(zToFree); |
| 22760 | 22152 | } |
| 22761 | | -static void printSchemaLineN(char *z, int n, const char *zTail){ |
| 22153 | +static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ |
| 22762 | 22154 | char c = z[n]; |
| 22763 | 22155 | z[n] = 0; |
| 22764 | | - printSchemaLine(z, zTail); |
| 22156 | + printSchemaLine(out, z, zTail); |
| 22765 | 22157 | z[n] = c; |
| 22766 | 22158 | } |
| 22767 | 22159 | |
| 22768 | 22160 | /* |
| 22769 | 22161 | ** Return true if string z[] has nothing but whitespace and comments to the |
| | @@ -22787,11 +22179,11 @@ |
| 22787 | 22179 | EQPGraphRow *pNew; |
| 22788 | 22180 | i64 nText; |
| 22789 | 22181 | if( zText==0 ) return; |
| 22790 | 22182 | nText = strlen(zText); |
| 22791 | 22183 | if( p->autoEQPtest ){ |
| 22792 | | - oputf("%d,%d,%s\n", iEqpId, p2, zText); |
| 22184 | + sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); |
| 22793 | 22185 | } |
| 22794 | 22186 | pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); |
| 22795 | 22187 | shell_check_oom(pNew); |
| 22796 | 22188 | pNew->iEqpId = iEqpId; |
| 22797 | 22189 | pNew->iParentId = p2; |
| | @@ -22835,11 +22227,12 @@ |
| 22835 | 22227 | i64 n = strlen(p->sGraph.zPrefix); |
| 22836 | 22228 | char *z; |
| 22837 | 22229 | for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ |
| 22838 | 22230 | pNext = eqp_next_row(p, iEqpId, pRow); |
| 22839 | 22231 | z = pRow->zText; |
| 22840 | | - oputf("%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); |
| 22232 | + sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix, |
| 22233 | + pNext ? "|--" : "`--", z); |
| 22841 | 22234 | if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){ |
| 22842 | 22235 | memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); |
| 22843 | 22236 | eqp_render_level(p, pRow->iEqpId); |
| 22844 | 22237 | p->sGraph.zPrefix[n] = 0; |
| 22845 | 22238 | } |
| | @@ -22855,17 +22248,17 @@ |
| 22855 | 22248 | if( pRow->zText[0]=='-' ){ |
| 22856 | 22249 | if( pRow->pNext==0 ){ |
| 22857 | 22250 | eqp_reset(p); |
| 22858 | 22251 | return; |
| 22859 | 22252 | } |
| 22860 | | - oputf("%s\n", pRow->zText+3); |
| 22253 | + sqlite3_fprintf(p->out, "%s\n", pRow->zText+3); |
| 22861 | 22254 | p->sGraph.pRow = pRow->pNext; |
| 22862 | 22255 | sqlite3_free(pRow); |
| 22863 | 22256 | }else if( nCycle>0 ){ |
| 22864 | | - oputf("QUERY PLAN (cycles=%lld [100%%])\n", nCycle); |
| 22257 | + sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle); |
| 22865 | 22258 | }else{ |
| 22866 | | - oputz("QUERY PLAN\n"); |
| 22259 | + sqlite3_fputs("QUERY PLAN\n", p->out); |
| 22867 | 22260 | } |
| 22868 | 22261 | p->sGraph.zPrefix[0] = 0; |
| 22869 | 22262 | eqp_render_level(p, 0); |
| 22870 | 22263 | eqp_reset(p); |
| 22871 | 22264 | } |
| | @@ -22877,33 +22270,33 @@ |
| 22877 | 22270 | */ |
| 22878 | 22271 | static int progress_handler(void *pClientData) { |
| 22879 | 22272 | ShellState *p = (ShellState*)pClientData; |
| 22880 | 22273 | p->nProgress++; |
| 22881 | 22274 | if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){ |
| 22882 | | - oputf("Progress limit reached (%u)\n", p->nProgress); |
| 22275 | + sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress); |
| 22883 | 22276 | if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; |
| 22884 | 22277 | if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0; |
| 22885 | 22278 | return 1; |
| 22886 | 22279 | } |
| 22887 | 22280 | if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){ |
| 22888 | | - oputf("Progress %u\n", p->nProgress); |
| 22281 | + sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress); |
| 22889 | 22282 | } |
| 22890 | 22283 | return 0; |
| 22891 | 22284 | } |
| 22892 | 22285 | #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */ |
| 22893 | 22286 | |
| 22894 | 22287 | /* |
| 22895 | 22288 | ** Print N dashes |
| 22896 | 22289 | */ |
| 22897 | | -static void print_dashes(int N){ |
| 22290 | +static void print_dashes(FILE *out, int N){ |
| 22898 | 22291 | const char zDash[] = "--------------------------------------------------"; |
| 22899 | 22292 | const int nDash = sizeof(zDash) - 1; |
| 22900 | 22293 | while( N>nDash ){ |
| 22901 | | - oputz(zDash); |
| 22294 | + sqlite3_fputs(zDash, out); |
| 22902 | 22295 | N -= nDash; |
| 22903 | 22296 | } |
| 22904 | | - oputf("%.*s", N, zDash); |
| 22297 | + sqlite3_fprintf(out, "%.*s", N, zDash); |
| 22905 | 22298 | } |
| 22906 | 22299 | |
| 22907 | 22300 | /* |
| 22908 | 22301 | ** Print a markdown or table-style row separator using ascii-art |
| 22909 | 22302 | */ |
| | @@ -22912,19 +22305,19 @@ |
| 22912 | 22305 | int nArg, |
| 22913 | 22306 | const char *zSep |
| 22914 | 22307 | ){ |
| 22915 | 22308 | int i; |
| 22916 | 22309 | if( nArg>0 ){ |
| 22917 | | - oputz(zSep); |
| 22918 | | - print_dashes(p->actualWidth[0]+2); |
| 22310 | + sqlite3_fputs(zSep, p->out); |
| 22311 | + print_dashes(p->out, p->actualWidth[0]+2); |
| 22919 | 22312 | for(i=1; i<nArg; i++){ |
| 22920 | | - oputz(zSep); |
| 22921 | | - print_dashes(p->actualWidth[i]+2); |
| 22313 | + sqlite3_fputs(zSep, p->out); |
| 22314 | + print_dashes(p->out, p->actualWidth[i]+2); |
| 22922 | 22315 | } |
| 22923 | | - oputz(zSep); |
| 22316 | + sqlite3_fputs(zSep, p->out); |
| 22924 | 22317 | } |
| 22925 | | - oputz("\n"); |
| 22318 | + sqlite3_fputs("\n", p->out); |
| 22926 | 22319 | } |
| 22927 | 22320 | |
| 22928 | 22321 | /* |
| 22929 | 22322 | ** This is the callback routine that the shell |
| 22930 | 22323 | ** invokes for each row of a query result. |
| | @@ -22950,13 +22343,13 @@ |
| 22950 | 22343 | if( azArg==0 ) break; |
| 22951 | 22344 | for(i=0; i<nArg; i++){ |
| 22952 | 22345 | int len = strlen30(azCol[i] ? azCol[i] : ""); |
| 22953 | 22346 | if( len>w ) w = len; |
| 22954 | 22347 | } |
| 22955 | | - if( p->cnt++>0 ) oputz(p->rowSeparator); |
| 22348 | + if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out); |
| 22956 | 22349 | for(i=0; i<nArg; i++){ |
| 22957 | | - oputf("%*s = %s%s", w, azCol[i], |
| 22350 | + sqlite3_fprintf(p->out, "%*s = %s%s", w, azCol[i], |
| 22958 | 22351 | azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator); |
| 22959 | 22352 | } |
| 22960 | 22353 | break; |
| 22961 | 22354 | } |
| 22962 | 22355 | case MODE_ScanExp: |
| | @@ -22980,16 +22373,16 @@ |
| 22980 | 22373 | if( nArg>nWidth ) nArg = nWidth; |
| 22981 | 22374 | |
| 22982 | 22375 | /* If this is the first row seen, print out the headers */ |
| 22983 | 22376 | if( p->cnt++==0 ){ |
| 22984 | 22377 | for(i=0; i<nArg; i++){ |
| 22985 | | - utf8_width_print(aWidth[i], azCol[ aMap[i] ]); |
| 22986 | | - oputz(i==nArg-1 ? "\n" : " "); |
| 22378 | + utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]); |
| 22379 | + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); |
| 22987 | 22380 | } |
| 22988 | 22381 | for(i=0; i<nArg; i++){ |
| 22989 | | - print_dashes(aWidth[i]); |
| 22990 | | - oputz(i==nArg-1 ? "\n" : " "); |
| 22382 | + print_dashes(p->out, aWidth[i]); |
| 22383 | + sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); |
| 22991 | 22384 | } |
| 22992 | 22385 | } |
| 22993 | 22386 | |
| 22994 | 22387 | /* If there is no data, exit early. */ |
| 22995 | 22388 | if( azArg==0 ) break; |
| | @@ -23003,21 +22396,21 @@ |
| 23003 | 22396 | w = strlenChar(zVal); |
| 23004 | 22397 | zSep = " "; |
| 23005 | 22398 | } |
| 23006 | 22399 | if( i==iIndent && p->aiIndent && p->pStmt ){ |
| 23007 | 22400 | if( p->iIndent<p->nIndent ){ |
| 23008 | | - oputf("%*.s", p->aiIndent[p->iIndent], ""); |
| 22401 | + sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); |
| 23009 | 22402 | } |
| 23010 | 22403 | p->iIndent++; |
| 23011 | 22404 | } |
| 23012 | | - utf8_width_print(w, zVal ? zVal : p->nullValue); |
| 23013 | | - oputz(i==nArg-1 ? "\n" : zSep); |
| 22405 | + utf8_width_print(p->out, w, zVal ? zVal : p->nullValue); |
| 22406 | + sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out); |
| 23014 | 22407 | } |
| 23015 | 22408 | break; |
| 23016 | 22409 | } |
| 23017 | 22410 | case MODE_Semi: { /* .schema and .fullschema output */ |
| 23018 | | - printSchemaLine(azArg[0], ";\n"); |
| 22411 | + printSchemaLine(p->out, azArg[0], ";\n"); |
| 23019 | 22412 | break; |
| 23020 | 22413 | } |
| 23021 | 22414 | case MODE_Pretty: { /* .schema and .fullschema with --indent */ |
| 23022 | 22415 | char *z; |
| 23023 | 22416 | int j; |
| | @@ -23028,11 +22421,11 @@ |
| 23028 | 22421 | assert( nArg==1 ); |
| 23029 | 22422 | if( azArg[0]==0 ) break; |
| 23030 | 22423 | if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 |
| 23031 | 22424 | || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 |
| 23032 | 22425 | ){ |
| 23033 | | - oputf("%s;\n", azArg[0]); |
| 22426 | + sqlite3_fprintf(p->out, "%s;\n", azArg[0]); |
| 23034 | 22427 | break; |
| 23035 | 22428 | } |
| 23036 | 22429 | z = sqlite3_mprintf("%s", azArg[0]); |
| 23037 | 22430 | shell_check_oom(z); |
| 23038 | 22431 | j = 0; |
| | @@ -23061,255 +22454,265 @@ |
| 23061 | 22454 | }else if( c=='(' ){ |
| 23062 | 22455 | nParen++; |
| 23063 | 22456 | }else if( c==')' ){ |
| 23064 | 22457 | nParen--; |
| 23065 | 22458 | if( nLine>0 && nParen==0 && j>0 ){ |
| 23066 | | - printSchemaLineN(z, j, "\n"); |
| 22459 | + printSchemaLineN(p->out, z, j, "\n"); |
| 23067 | 22460 | j = 0; |
| 23068 | 22461 | } |
| 23069 | 22462 | } |
| 23070 | 22463 | z[j++] = c; |
| 23071 | 22464 | if( nParen==1 && cEnd==0 |
| 23072 | 22465 | && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) |
| 23073 | 22466 | ){ |
| 23074 | 22467 | if( c=='\n' ) j--; |
| 23075 | | - printSchemaLineN(z, j, "\n "); |
| 22468 | + printSchemaLineN(p->out, z, j, "\n "); |
| 23076 | 22469 | j = 0; |
| 23077 | 22470 | nLine++; |
| 23078 | 22471 | while( IsSpace(z[i+1]) ){ i++; } |
| 23079 | 22472 | } |
| 23080 | 22473 | } |
| 23081 | 22474 | z[j] = 0; |
| 23082 | 22475 | } |
| 23083 | | - printSchemaLine(z, ";\n"); |
| 22476 | + printSchemaLine(p->out, z, ";\n"); |
| 23084 | 22477 | sqlite3_free(z); |
| 23085 | 22478 | break; |
| 23086 | 22479 | } |
| 23087 | 22480 | case MODE_List: { |
| 23088 | 22481 | if( p->cnt++==0 && p->showHeader ){ |
| 23089 | 22482 | for(i=0; i<nArg; i++){ |
| 23090 | | - oputf("%s%s",azCol[i], i==nArg-1 ? p->rowSeparator : p->colSeparator); |
| 22483 | + sqlite3_fprintf(p->out, "%s%s", azCol[i], |
| 22484 | + i==nArg-1 ? p->rowSeparator : p->colSeparator); |
| 23091 | 22485 | } |
| 23092 | 22486 | } |
| 23093 | 22487 | if( azArg==0 ) break; |
| 23094 | 22488 | for(i=0; i<nArg; i++){ |
| 23095 | 22489 | char *z = azArg[i]; |
| 23096 | 22490 | if( z==0 ) z = p->nullValue; |
| 23097 | | - oputz(z); |
| 23098 | | - oputz((i<nArg-1)? p->colSeparator : p->rowSeparator); |
| 22491 | + sqlite3_fputs(z, p->out); |
| 22492 | + sqlite3_fputs((i<nArg-1)? p->colSeparator : p->rowSeparator, p->out); |
| 23099 | 22493 | } |
| 23100 | 22494 | break; |
| 23101 | 22495 | } |
| 22496 | + case MODE_Www: |
| 23102 | 22497 | case MODE_Html: { |
| 23103 | | - if( p->cnt++==0 && p->showHeader ){ |
| 23104 | | - oputz("<TR>"); |
| 22498 | + if( p->cnt==0 && p->cMode==MODE_Www ){ |
| 22499 | + sqlite3_fputs( |
| 22500 | + "</PRE>\n" |
| 22501 | + "<TABLE border='1' cellspacing='0' cellpadding='2'>\n" |
| 22502 | + ,p->out |
| 22503 | + ); |
| 22504 | + } |
| 22505 | + if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){ |
| 22506 | + sqlite3_fputs("<TR>", p->out); |
| 23105 | 22507 | for(i=0; i<nArg; i++){ |
| 23106 | | - oputz("<TH>"); |
| 23107 | | - output_html_string(azCol[i]); |
| 23108 | | - oputz("</TH>\n"); |
| 22508 | + sqlite3_fputs("<TH>", p->out); |
| 22509 | + output_html_string(p->out, azCol[i]); |
| 22510 | + sqlite3_fputs("</TH>\n", p->out); |
| 23109 | 22511 | } |
| 23110 | | - oputz("</TR>\n"); |
| 22512 | + sqlite3_fputs("</TR>\n", p->out); |
| 23111 | 22513 | } |
| 22514 | + p->cnt++; |
| 23112 | 22515 | if( azArg==0 ) break; |
| 23113 | | - oputz("<TR>"); |
| 22516 | + sqlite3_fputs("<TR>", p->out); |
| 23114 | 22517 | for(i=0; i<nArg; i++){ |
| 23115 | | - oputz("<TD>"); |
| 23116 | | - output_html_string(azArg[i] ? azArg[i] : p->nullValue); |
| 23117 | | - oputz("</TD>\n"); |
| 22518 | + sqlite3_fputs("<TD>", p->out); |
| 22519 | + output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
| 22520 | + sqlite3_fputs("</TD>\n", p->out); |
| 23118 | 22521 | } |
| 23119 | | - oputz("</TR>\n"); |
| 22522 | + sqlite3_fputs("</TR>\n", p->out); |
| 23120 | 22523 | break; |
| 23121 | 22524 | } |
| 23122 | 22525 | case MODE_Tcl: { |
| 23123 | 22526 | if( p->cnt++==0 && p->showHeader ){ |
| 23124 | 22527 | for(i=0; i<nArg; i++){ |
| 23125 | | - output_c_string(azCol[i] ? azCol[i] : ""); |
| 23126 | | - if(i<nArg-1) oputz(p->colSeparator); |
| 22528 | + output_c_string(p->out, azCol[i] ? azCol[i] : ""); |
| 22529 | + if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out); |
| 23127 | 22530 | } |
| 23128 | | - oputz(p->rowSeparator); |
| 22531 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23129 | 22532 | } |
| 23130 | 22533 | if( azArg==0 ) break; |
| 23131 | 22534 | for(i=0; i<nArg; i++){ |
| 23132 | | - output_c_string(azArg[i] ? azArg[i] : p->nullValue); |
| 23133 | | - if(i<nArg-1) oputz(p->colSeparator); |
| 22535 | + output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); |
| 22536 | + if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out); |
| 23134 | 22537 | } |
| 23135 | | - oputz(p->rowSeparator); |
| 22538 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23136 | 22539 | break; |
| 23137 | 22540 | } |
| 23138 | 22541 | case MODE_Csv: { |
| 23139 | | - setBinaryMode(p->out, 1); |
| 22542 | + sqlite3_fsetmode(p->out, _O_BINARY); |
| 23140 | 22543 | if( p->cnt++==0 && p->showHeader ){ |
| 23141 | 22544 | for(i=0; i<nArg; i++){ |
| 23142 | 22545 | output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); |
| 23143 | 22546 | } |
| 23144 | | - oputz(p->rowSeparator); |
| 22547 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23145 | 22548 | } |
| 23146 | 22549 | if( nArg>0 ){ |
| 23147 | 22550 | for(i=0; i<nArg; i++){ |
| 23148 | 22551 | output_csv(p, azArg[i], i<nArg-1); |
| 23149 | 22552 | } |
| 23150 | | - oputz(p->rowSeparator); |
| 22553 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23151 | 22554 | } |
| 23152 | | - setTextMode(p->out, 1); |
| 22555 | + sqlite3_fsetmode(p->out, _O_TEXT); |
| 23153 | 22556 | break; |
| 23154 | 22557 | } |
| 23155 | 22558 | case MODE_Insert: { |
| 23156 | 22559 | if( azArg==0 ) break; |
| 23157 | | - oputf("INSERT INTO %s",p->zDestTable); |
| 22560 | + sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable); |
| 23158 | 22561 | if( p->showHeader ){ |
| 23159 | | - oputz("("); |
| 22562 | + sqlite3_fputs("(", p->out); |
| 23160 | 22563 | for(i=0; i<nArg; i++){ |
| 23161 | | - if( i>0 ) oputz(","); |
| 22564 | + if( i>0 ) sqlite3_fputs(",", p->out); |
| 23162 | 22565 | if( quoteChar(azCol[i]) ){ |
| 23163 | 22566 | char *z = sqlite3_mprintf("\"%w\"", azCol[i]); |
| 23164 | 22567 | shell_check_oom(z); |
| 23165 | | - oputz(z); |
| 22568 | + sqlite3_fputs(z, p->out); |
| 23166 | 22569 | sqlite3_free(z); |
| 23167 | 22570 | }else{ |
| 23168 | | - oputf("%s", azCol[i]); |
| 22571 | + sqlite3_fprintf(p->out, "%s", azCol[i]); |
| 23169 | 22572 | } |
| 23170 | 22573 | } |
| 23171 | | - oputz(")"); |
| 22574 | + sqlite3_fputs(")", p->out); |
| 23172 | 22575 | } |
| 23173 | 22576 | p->cnt++; |
| 23174 | 22577 | for(i=0; i<nArg; i++){ |
| 23175 | | - oputz(i>0 ? "," : " VALUES("); |
| 22578 | + sqlite3_fputs(i>0 ? "," : " VALUES(", p->out); |
| 23176 | 22579 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
| 23177 | | - oputz("NULL"); |
| 22580 | + sqlite3_fputs("NULL", p->out); |
| 23178 | 22581 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
| 23179 | 22582 | if( ShellHasFlag(p, SHFLG_Newlines) ){ |
| 23180 | | - output_quoted_string(azArg[i]); |
| 22583 | + output_quoted_string(p->out, azArg[i]); |
| 23181 | 22584 | }else{ |
| 23182 | | - output_quoted_escaped_string(azArg[i]); |
| 22585 | + output_quoted_escaped_string(p->out, azArg[i]); |
| 23183 | 22586 | } |
| 23184 | 22587 | }else if( aiType && aiType[i]==SQLITE_INTEGER ){ |
| 23185 | | - oputz(azArg[i]); |
| 22588 | + sqlite3_fputs(azArg[i], p->out); |
| 23186 | 22589 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
| 23187 | 22590 | char z[50]; |
| 23188 | 22591 | double r = sqlite3_column_double(p->pStmt, i); |
| 23189 | 22592 | sqlite3_uint64 ur; |
| 23190 | 22593 | memcpy(&ur,&r,sizeof(r)); |
| 23191 | 22594 | if( ur==0x7ff0000000000000LL ){ |
| 23192 | | - oputz("9.0e+999"); |
| 22595 | + sqlite3_fputs("9.0e+999", p->out); |
| 23193 | 22596 | }else if( ur==0xfff0000000000000LL ){ |
| 23194 | | - oputz("-9.0e+999"); |
| 22597 | + sqlite3_fputs("-9.0e+999", p->out); |
| 23195 | 22598 | }else{ |
| 23196 | 22599 | sqlite3_int64 ir = (sqlite3_int64)r; |
| 23197 | 22600 | if( r==(double)ir ){ |
| 23198 | 22601 | sqlite3_snprintf(50,z,"%lld.0", ir); |
| 23199 | 22602 | }else{ |
| 23200 | 22603 | sqlite3_snprintf(50,z,"%!.20g", r); |
| 23201 | 22604 | } |
| 23202 | | - oputz(z); |
| 22605 | + sqlite3_fputs(z, p->out); |
| 23203 | 22606 | } |
| 23204 | 22607 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
| 23205 | 22608 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
| 23206 | 22609 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
| 23207 | | - output_hex_blob(pBlob, nBlob); |
| 22610 | + output_hex_blob(p->out, pBlob, nBlob); |
| 23208 | 22611 | }else if( isNumber(azArg[i], 0) ){ |
| 23209 | | - oputz(azArg[i]); |
| 22612 | + sqlite3_fputs(azArg[i], p->out); |
| 23210 | 22613 | }else if( ShellHasFlag(p, SHFLG_Newlines) ){ |
| 23211 | | - output_quoted_string(azArg[i]); |
| 22614 | + output_quoted_string(p->out, azArg[i]); |
| 23212 | 22615 | }else{ |
| 23213 | | - output_quoted_escaped_string(azArg[i]); |
| 22616 | + output_quoted_escaped_string(p->out, azArg[i]); |
| 23214 | 22617 | } |
| 23215 | 22618 | } |
| 23216 | | - oputz(");\n"); |
| 22619 | + sqlite3_fputs(");\n", p->out); |
| 23217 | 22620 | break; |
| 23218 | 22621 | } |
| 23219 | 22622 | case MODE_Json: { |
| 23220 | 22623 | if( azArg==0 ) break; |
| 23221 | 22624 | if( p->cnt==0 ){ |
| 23222 | | - fputs("[{", p->out); |
| 22625 | + sqlite3_fputs("[{", p->out); |
| 23223 | 22626 | }else{ |
| 23224 | | - fputs(",\n{", p->out); |
| 22627 | + sqlite3_fputs(",\n{", p->out); |
| 23225 | 22628 | } |
| 23226 | 22629 | p->cnt++; |
| 23227 | 22630 | for(i=0; i<nArg; i++){ |
| 23228 | | - output_json_string(azCol[i], -1); |
| 23229 | | - oputz(":"); |
| 22631 | + output_json_string(p->out, azCol[i], -1); |
| 22632 | + sqlite3_fputs(":", p->out); |
| 23230 | 22633 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
| 23231 | | - oputz("null"); |
| 22634 | + sqlite3_fputs("null", p->out); |
| 23232 | 22635 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
| 23233 | 22636 | char z[50]; |
| 23234 | 22637 | double r = sqlite3_column_double(p->pStmt, i); |
| 23235 | 22638 | sqlite3_uint64 ur; |
| 23236 | 22639 | memcpy(&ur,&r,sizeof(r)); |
| 23237 | 22640 | if( ur==0x7ff0000000000000LL ){ |
| 23238 | | - oputz("9.0e+999"); |
| 22641 | + sqlite3_fputs("9.0e+999", p->out); |
| 23239 | 22642 | }else if( ur==0xfff0000000000000LL ){ |
| 23240 | | - oputz("-9.0e+999"); |
| 22643 | + sqlite3_fputs("-9.0e+999", p->out); |
| 23241 | 22644 | }else{ |
| 23242 | 22645 | sqlite3_snprintf(50,z,"%!.20g", r); |
| 23243 | | - oputz(z); |
| 22646 | + sqlite3_fputs(z, p->out); |
| 23244 | 22647 | } |
| 23245 | 22648 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
| 23246 | 22649 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
| 23247 | 22650 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
| 23248 | | - output_json_string(pBlob, nBlob); |
| 22651 | + output_json_string(p->out, pBlob, nBlob); |
| 23249 | 22652 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
| 23250 | | - output_json_string(azArg[i], -1); |
| 22653 | + output_json_string(p->out, azArg[i], -1); |
| 23251 | 22654 | }else{ |
| 23252 | | - oputz(azArg[i]); |
| 22655 | + sqlite3_fputs(azArg[i], p->out); |
| 23253 | 22656 | } |
| 23254 | 22657 | if( i<nArg-1 ){ |
| 23255 | | - oputz(","); |
| 22658 | + sqlite3_fputs(",", p->out); |
| 23256 | 22659 | } |
| 23257 | 22660 | } |
| 23258 | | - oputz("}"); |
| 22661 | + sqlite3_fputs("}", p->out); |
| 23259 | 22662 | break; |
| 23260 | 22663 | } |
| 23261 | 22664 | case MODE_Quote: { |
| 23262 | 22665 | if( azArg==0 ) break; |
| 23263 | 22666 | if( p->cnt==0 && p->showHeader ){ |
| 23264 | 22667 | for(i=0; i<nArg; i++){ |
| 23265 | | - if( i>0 ) fputs(p->colSeparator, p->out); |
| 23266 | | - output_quoted_string(azCol[i]); |
| 22668 | + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); |
| 22669 | + output_quoted_string(p->out, azCol[i]); |
| 23267 | 22670 | } |
| 23268 | | - fputs(p->rowSeparator, p->out); |
| 22671 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23269 | 22672 | } |
| 23270 | 22673 | p->cnt++; |
| 23271 | 22674 | for(i=0; i<nArg; i++){ |
| 23272 | | - if( i>0 ) fputs(p->colSeparator, p->out); |
| 22675 | + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); |
| 23273 | 22676 | if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ |
| 23274 | | - oputz("NULL"); |
| 22677 | + sqlite3_fputs("NULL", p->out); |
| 23275 | 22678 | }else if( aiType && aiType[i]==SQLITE_TEXT ){ |
| 23276 | | - output_quoted_string(azArg[i]); |
| 22679 | + output_quoted_string(p->out, azArg[i]); |
| 23277 | 22680 | }else if( aiType && aiType[i]==SQLITE_INTEGER ){ |
| 23278 | | - oputz(azArg[i]); |
| 22681 | + sqlite3_fputs(azArg[i], p->out); |
| 23279 | 22682 | }else if( aiType && aiType[i]==SQLITE_FLOAT ){ |
| 23280 | 22683 | char z[50]; |
| 23281 | 22684 | double r = sqlite3_column_double(p->pStmt, i); |
| 23282 | 22685 | sqlite3_snprintf(50,z,"%!.20g", r); |
| 23283 | | - oputz(z); |
| 22686 | + sqlite3_fputs(z, p->out); |
| 23284 | 22687 | }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ |
| 23285 | 22688 | const void *pBlob = sqlite3_column_blob(p->pStmt, i); |
| 23286 | 22689 | int nBlob = sqlite3_column_bytes(p->pStmt, i); |
| 23287 | | - output_hex_blob(pBlob, nBlob); |
| 22690 | + output_hex_blob(p->out, pBlob, nBlob); |
| 23288 | 22691 | }else if( isNumber(azArg[i], 0) ){ |
| 23289 | | - oputz(azArg[i]); |
| 22692 | + sqlite3_fputs(azArg[i], p->out); |
| 23290 | 22693 | }else{ |
| 23291 | | - output_quoted_string(azArg[i]); |
| 22694 | + output_quoted_string(p->out, azArg[i]); |
| 23292 | 22695 | } |
| 23293 | 22696 | } |
| 23294 | | - fputs(p->rowSeparator, p->out); |
| 22697 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23295 | 22698 | break; |
| 23296 | 22699 | } |
| 23297 | 22700 | case MODE_Ascii: { |
| 23298 | 22701 | if( p->cnt++==0 && p->showHeader ){ |
| 23299 | 22702 | for(i=0; i<nArg; i++){ |
| 23300 | | - if( i>0 ) oputz(p->colSeparator); |
| 23301 | | - oputz(azCol[i] ? azCol[i] : ""); |
| 22703 | + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); |
| 22704 | + sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out); |
| 23302 | 22705 | } |
| 23303 | | - oputz(p->rowSeparator); |
| 22706 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23304 | 22707 | } |
| 23305 | 22708 | if( azArg==0 ) break; |
| 23306 | 22709 | for(i=0; i<nArg; i++){ |
| 23307 | | - if( i>0 ) oputz(p->colSeparator); |
| 23308 | | - oputz(azArg[i] ? azArg[i] : p->nullValue); |
| 22710 | + if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); |
| 22711 | + sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out); |
| 23309 | 22712 | } |
| 23310 | | - oputz(p->rowSeparator); |
| 22713 | + sqlite3_fputs(p->rowSeparator, p->out); |
| 23311 | 22714 | break; |
| 23312 | 22715 | } |
| 23313 | 22716 | case MODE_EQP: { |
| 23314 | 22717 | eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]); |
| 23315 | 22718 | break; |
| | @@ -23384,11 +22787,11 @@ |
| 23384 | 22787 | "INSERT INTO selftest(tno,op,cmd,ans)" |
| 23385 | 22788 | " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" |
| 23386 | 22789 | "DROP TABLE [_shell$self];" |
| 23387 | 22790 | ,0,0,&zErrMsg); |
| 23388 | 22791 | if( zErrMsg ){ |
| 23389 | | - eputf("SELFTEST initialization failure: %s\n", zErrMsg); |
| 22792 | + sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); |
| 23390 | 22793 | sqlite3_free(zErrMsg); |
| 23391 | 22794 | } |
| 23392 | 22795 | sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); |
| 23393 | 22796 | } |
| 23394 | 22797 | |
| | @@ -23487,36 +22890,37 @@ |
| 23487 | 22890 | int i; |
| 23488 | 22891 | const char *z; |
| 23489 | 22892 | rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); |
| 23490 | 22893 | if( rc!=SQLITE_OK || !pSelect ){ |
| 23491 | 22894 | char *zContext = shell_error_context(zSelect, p->db); |
| 23492 | | - oputf("/**** ERROR: (%d) %s *****/\n%s", |
| 22895 | + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s", |
| 23493 | 22896 | rc, sqlite3_errmsg(p->db), zContext); |
| 23494 | 22897 | sqlite3_free(zContext); |
| 23495 | 22898 | if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; |
| 23496 | 22899 | return rc; |
| 23497 | 22900 | } |
| 23498 | 22901 | rc = sqlite3_step(pSelect); |
| 23499 | 22902 | nResult = sqlite3_column_count(pSelect); |
| 23500 | 22903 | while( rc==SQLITE_ROW ){ |
| 23501 | 22904 | z = (const char*)sqlite3_column_text(pSelect, 0); |
| 23502 | | - oputf("%s", z); |
| 22905 | + sqlite3_fprintf(p->out, "%s", z); |
| 23503 | 22906 | for(i=1; i<nResult; i++){ |
| 23504 | | - oputf(",%s", sqlite3_column_text(pSelect, i)); |
| 22907 | + sqlite3_fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i)); |
| 23505 | 22908 | } |
| 23506 | 22909 | if( z==0 ) z = ""; |
| 23507 | 22910 | while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; |
| 23508 | 22911 | if( z[0] ){ |
| 23509 | | - oputz("\n;\n"); |
| 22912 | + sqlite3_fputs("\n;\n", p->out); |
| 23510 | 22913 | }else{ |
| 23511 | | - oputz(";\n"); |
| 22914 | + sqlite3_fputs(";\n", p->out); |
| 23512 | 22915 | } |
| 23513 | 22916 | rc = sqlite3_step(pSelect); |
| 23514 | 22917 | } |
| 23515 | 22918 | rc = sqlite3_finalize(pSelect); |
| 23516 | 22919 | if( rc!=SQLITE_OK ){ |
| 23517 | | - oputf("/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); |
| 22920 | + sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", |
| 22921 | + rc, sqlite3_errmsg(p->db)); |
| 23518 | 22922 | if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; |
| 23519 | 22923 | } |
| 23520 | 22924 | return rc; |
| 23521 | 22925 | } |
| 23522 | 22926 | |
| | @@ -23548,17 +22952,17 @@ |
| 23548 | 22952 | |
| 23549 | 22953 | #ifdef __linux__ |
| 23550 | 22954 | /* |
| 23551 | 22955 | ** Attempt to display I/O stats on Linux using /proc/PID/io |
| 23552 | 22956 | */ |
| 23553 | | -static void displayLinuxIoStats(void){ |
| 22957 | +static void displayLinuxIoStats(FILE *out){ |
| 23554 | 22958 | FILE *in; |
| 23555 | 22959 | char z[200]; |
| 23556 | 22960 | sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); |
| 23557 | | - in = fopen(z, "rb"); |
| 22961 | + in = sqlite3_fopen(z, "rb"); |
| 23558 | 22962 | if( in==0 ) return; |
| 23559 | | - while( fgets(z, sizeof(z), in)!=0 ){ |
| 22963 | + while( sqlite3_fgets(z, sizeof(z), in)!=0 ){ |
| 23560 | 22964 | static const struct { |
| 23561 | 22965 | const char *zPattern; |
| 23562 | 22966 | const char *zDesc; |
| 23563 | 22967 | } aTrans[] = { |
| 23564 | 22968 | { "rchar: ", "Bytes received by read():" }, |
| | @@ -23571,11 +22975,11 @@ |
| 23571 | 22975 | }; |
| 23572 | 22976 | int i; |
| 23573 | 22977 | for(i=0; i<ArraySize(aTrans); i++){ |
| 23574 | 22978 | int n = strlen30(aTrans[i].zPattern); |
| 23575 | 22979 | if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){ |
| 23576 | | - oputf("%-36s %s", aTrans[i].zDesc, &z[n]); |
| 22980 | + sqlite3_fprintf(out, "%-36s %s", aTrans[i].zDesc, &z[n]); |
| 23577 | 22981 | break; |
| 23578 | 22982 | } |
| 23579 | 22983 | } |
| 23580 | 22984 | } |
| 23581 | 22985 | fclose(in); |
| | @@ -23584,10 +22988,11 @@ |
| 23584 | 22988 | |
| 23585 | 22989 | /* |
| 23586 | 22990 | ** Display a single line of status using 64-bit values. |
| 23587 | 22991 | */ |
| 23588 | 22992 | static void displayStatLine( |
| 22993 | + FILE *out, /* Write to this channel */ |
| 23589 | 22994 | char *zLabel, /* Label for this one line */ |
| 23590 | 22995 | char *zFormat, /* Format for the result */ |
| 23591 | 22996 | int iStatusCtrl, /* Which status to display */ |
| 23592 | 22997 | int bReset /* True to reset the stats */ |
| 23593 | 22998 | ){ |
| | @@ -23602,11 +23007,11 @@ |
| 23602 | 23007 | if( nPercent>1 ){ |
| 23603 | 23008 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); |
| 23604 | 23009 | }else{ |
| 23605 | 23010 | sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); |
| 23606 | 23011 | } |
| 23607 | | - oputf("%-36s %s\n", zLabel, zLine); |
| 23012 | + sqlite3_fprintf(out, "%-36s %s\n", zLabel, zLine); |
| 23608 | 23013 | } |
| 23609 | 23014 | |
| 23610 | 23015 | /* |
| 23611 | 23016 | ** Display memory stats. |
| 23612 | 23017 | */ |
| | @@ -23615,130 +23020,152 @@ |
| 23615 | 23020 | ShellState *pArg, /* Pointer to ShellState */ |
| 23616 | 23021 | int bReset /* True to reset the stats */ |
| 23617 | 23022 | ){ |
| 23618 | 23023 | int iCur; |
| 23619 | 23024 | int iHiwtr; |
| 23025 | + FILE *out; |
| 23620 | 23026 | if( pArg==0 || pArg->out==0 ) return 0; |
| 23027 | + out = pArg->out; |
| 23621 | 23028 | |
| 23622 | 23029 | if( pArg->pStmt && pArg->statsOn==2 ){ |
| 23623 | 23030 | int nCol, i, x; |
| 23624 | 23031 | sqlite3_stmt *pStmt = pArg->pStmt; |
| 23625 | 23032 | char z[100]; |
| 23626 | 23033 | nCol = sqlite3_column_count(pStmt); |
| 23627 | | - oputf("%-36s %d\n", "Number of output columns:", nCol); |
| 23034 | + sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol); |
| 23628 | 23035 | for(i=0; i<nCol; i++){ |
| 23629 | 23036 | sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x); |
| 23630 | | - oputf("%-36s %s\n", z, sqlite3_column_name(pStmt,i)); |
| 23037 | + sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i)); |
| 23631 | 23038 | #ifndef SQLITE_OMIT_DECLTYPE |
| 23632 | 23039 | sqlite3_snprintf(30, z+x, "declared type:"); |
| 23633 | | - oputf("%-36s %s\n", z, sqlite3_column_decltype(pStmt, i)); |
| 23040 | + sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i)); |
| 23634 | 23041 | #endif |
| 23635 | 23042 | #ifdef SQLITE_ENABLE_COLUMN_METADATA |
| 23636 | 23043 | sqlite3_snprintf(30, z+x, "database name:"); |
| 23637 | | - oputf("%-36s %s\n", z, sqlite3_column_database_name(pStmt,i)); |
| 23044 | + sqlite3_fprintf(out, "%-36s %s\n", z, |
| 23045 | + sqlite3_column_database_name(pStmt,i)); |
| 23638 | 23046 | sqlite3_snprintf(30, z+x, "table name:"); |
| 23639 | | - oputf("%-36s %s\n", z, sqlite3_column_table_name(pStmt,i)); |
| 23047 | + sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i)); |
| 23640 | 23048 | sqlite3_snprintf(30, z+x, "origin name:"); |
| 23641 | | - oputf("%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i)); |
| 23049 | + sqlite3_fprintf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i)); |
| 23642 | 23050 | #endif |
| 23643 | 23051 | } |
| 23644 | 23052 | } |
| 23645 | 23053 | |
| 23646 | 23054 | if( pArg->statsOn==3 ){ |
| 23647 | 23055 | if( pArg->pStmt ){ |
| 23648 | 23056 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset); |
| 23649 | | - oputf("VM-steps: %d\n", iCur); |
| 23057 | + sqlite3_fprintf(out, "VM-steps: %d\n", iCur); |
| 23650 | 23058 | } |
| 23651 | 23059 | return 0; |
| 23652 | 23060 | } |
| 23653 | 23061 | |
| 23654 | | - displayStatLine("Memory Used:", |
| 23062 | + displayStatLine(out, "Memory Used:", |
| 23655 | 23063 | "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); |
| 23656 | | - displayStatLine("Number of Outstanding Allocations:", |
| 23064 | + displayStatLine(out, "Number of Outstanding Allocations:", |
| 23657 | 23065 | "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); |
| 23658 | 23066 | if( pArg->shellFlgs & SHFLG_Pagecache ){ |
| 23659 | | - displayStatLine("Number of Pcache Pages Used:", |
| 23067 | + displayStatLine(out, "Number of Pcache Pages Used:", |
| 23660 | 23068 | "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); |
| 23661 | 23069 | } |
| 23662 | | - displayStatLine("Number of Pcache Overflow Bytes:", |
| 23070 | + displayStatLine(out, "Number of Pcache Overflow Bytes:", |
| 23663 | 23071 | "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); |
| 23664 | | - displayStatLine("Largest Allocation:", |
| 23072 | + displayStatLine(out, "Largest Allocation:", |
| 23665 | 23073 | "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); |
| 23666 | | - displayStatLine("Largest Pcache Allocation:", |
| 23074 | + displayStatLine(out, "Largest Pcache Allocation:", |
| 23667 | 23075 | "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); |
| 23668 | 23076 | #ifdef YYTRACKMAXSTACKDEPTH |
| 23669 | | - displayStatLine("Deepest Parser Stack:", |
| 23077 | + displayStatLine(out, "Deepest Parser Stack:", |
| 23670 | 23078 | "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); |
| 23671 | 23079 | #endif |
| 23672 | 23080 | |
| 23673 | 23081 | if( db ){ |
| 23674 | 23082 | if( pArg->shellFlgs & SHFLG_Lookaside ){ |
| 23675 | 23083 | iHiwtr = iCur = -1; |
| 23676 | 23084 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, |
| 23677 | 23085 | &iCur, &iHiwtr, bReset); |
| 23678 | | - oputf("Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); |
| 23086 | + sqlite3_fprintf(out, |
| 23087 | + "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); |
| 23679 | 23088 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, |
| 23680 | 23089 | &iCur, &iHiwtr, bReset); |
| 23681 | | - oputf("Successful lookaside attempts: %d\n", iHiwtr); |
| 23090 | + sqlite3_fprintf(out, |
| 23091 | + "Successful lookaside attempts: %d\n", iHiwtr); |
| 23682 | 23092 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, |
| 23683 | 23093 | &iCur, &iHiwtr, bReset); |
| 23684 | | - oputf("Lookaside failures due to size: %d\n", iHiwtr); |
| 23094 | + sqlite3_fprintf(out, |
| 23095 | + "Lookaside failures due to size: %d\n", iHiwtr); |
| 23685 | 23096 | sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, |
| 23686 | 23097 | &iCur, &iHiwtr, bReset); |
| 23687 | | - oputf("Lookaside failures due to OOM: %d\n", iHiwtr); |
| 23098 | + sqlite3_fprintf(out, |
| 23099 | + "Lookaside failures due to OOM: %d\n", iHiwtr); |
| 23688 | 23100 | } |
| 23689 | 23101 | iHiwtr = iCur = -1; |
| 23690 | 23102 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); |
| 23691 | | - oputf("Pager Heap Usage: %d bytes\n", iCur); |
| 23103 | + sqlite3_fprintf(out, |
| 23104 | + "Pager Heap Usage: %d bytes\n", iCur); |
| 23692 | 23105 | iHiwtr = iCur = -1; |
| 23693 | 23106 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); |
| 23694 | | - oputf("Page cache hits: %d\n", iCur); |
| 23107 | + sqlite3_fprintf(out, |
| 23108 | + "Page cache hits: %d\n", iCur); |
| 23695 | 23109 | iHiwtr = iCur = -1; |
| 23696 | 23110 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); |
| 23697 | | - oputf("Page cache misses: %d\n", iCur); |
| 23111 | + sqlite3_fprintf(out, |
| 23112 | + "Page cache misses: %d\n", iCur); |
| 23698 | 23113 | iHiwtr = iCur = -1; |
| 23699 | 23114 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); |
| 23700 | | - oputf("Page cache writes: %d\n", iCur); |
| 23115 | + sqlite3_fprintf(out, |
| 23116 | + "Page cache writes: %d\n", iCur); |
| 23701 | 23117 | iHiwtr = iCur = -1; |
| 23702 | 23118 | sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); |
| 23703 | | - oputf("Page cache spills: %d\n", iCur); |
| 23119 | + sqlite3_fprintf(out, |
| 23120 | + "Page cache spills: %d\n", iCur); |
| 23704 | 23121 | iHiwtr = iCur = -1; |
| 23705 | 23122 | sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); |
| 23706 | | - oputf("Schema Heap Usage: %d bytes\n", iCur); |
| 23123 | + sqlite3_fprintf(out, |
| 23124 | + "Schema Heap Usage: %d bytes\n", iCur); |
| 23707 | 23125 | iHiwtr = iCur = -1; |
| 23708 | 23126 | sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); |
| 23709 | | - oputf("Statement Heap/Lookaside Usage: %d bytes\n", iCur); |
| 23127 | + sqlite3_fprintf(out, |
| 23128 | + "Statement Heap/Lookaside Usage: %d bytes\n", iCur); |
| 23710 | 23129 | } |
| 23711 | 23130 | |
| 23712 | 23131 | if( pArg->pStmt ){ |
| 23713 | 23132 | int iHit, iMiss; |
| 23714 | 23133 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, |
| 23715 | 23134 | bReset); |
| 23716 | | - oputf("Fullscan Steps: %d\n", iCur); |
| 23135 | + sqlite3_fprintf(out, |
| 23136 | + "Fullscan Steps: %d\n", iCur); |
| 23717 | 23137 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); |
| 23718 | | - oputf("Sort Operations: %d\n", iCur); |
| 23138 | + sqlite3_fprintf(out, |
| 23139 | + "Sort Operations: %d\n", iCur); |
| 23719 | 23140 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); |
| 23720 | | - oputf("Autoindex Inserts: %d\n", iCur); |
| 23141 | + sqlite3_fprintf(out, |
| 23142 | + "Autoindex Inserts: %d\n", iCur); |
| 23721 | 23143 | iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, |
| 23722 | 23144 | bReset); |
| 23723 | 23145 | iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, |
| 23724 | 23146 | bReset); |
| 23725 | 23147 | if( iHit || iMiss ){ |
| 23726 | | - oputf("Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); |
| 23148 | + sqlite3_fprintf(out, |
| 23149 | + "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); |
| 23727 | 23150 | } |
| 23728 | 23151 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); |
| 23729 | | - oputf("Virtual Machine Steps: %d\n", iCur); |
| 23152 | + sqlite3_fprintf(out, |
| 23153 | + "Virtual Machine Steps: %d\n", iCur); |
| 23730 | 23154 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); |
| 23731 | | - oputf("Reprepare operations: %d\n", iCur); |
| 23155 | + sqlite3_fprintf(out, |
| 23156 | + "Reprepare operations: %d\n", iCur); |
| 23732 | 23157 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); |
| 23733 | | - oputf("Number of times run: %d\n", iCur); |
| 23158 | + sqlite3_fprintf(out, |
| 23159 | + "Number of times run: %d\n", iCur); |
| 23734 | 23160 | iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); |
| 23735 | | - oputf("Memory used by prepared stmt: %d\n", iCur); |
| 23161 | + sqlite3_fprintf(out, |
| 23162 | + "Memory used by prepared stmt: %d\n", iCur); |
| 23736 | 23163 | } |
| 23737 | 23164 | |
| 23738 | 23165 | #ifdef __linux__ |
| 23739 | | - displayLinuxIoStats(); |
| 23166 | + displayLinuxIoStats(pArg->out); |
| 23740 | 23167 | #endif |
| 23741 | 23168 | |
| 23742 | 23169 | /* Do not remove this machine readable comment: extra-stats-output-here */ |
| 23743 | 23170 | |
| 23744 | 23171 | return 0; |
| | @@ -24130,21 +23557,21 @@ |
| 24130 | 23557 | #define BOX_1234 "\342\224\274" /* U+253c -|- */ |
| 24131 | 23558 | |
| 24132 | 23559 | /* Draw horizontal line N characters long using unicode box |
| 24133 | 23560 | ** characters |
| 24134 | 23561 | */ |
| 24135 | | -static void print_box_line(int N){ |
| 23562 | +static void print_box_line(FILE *out, int N){ |
| 24136 | 23563 | const char zDash[] = |
| 24137 | 23564 | BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 |
| 24138 | 23565 | BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; |
| 24139 | 23566 | const int nDash = sizeof(zDash) - 1; |
| 24140 | 23567 | N *= 3; |
| 24141 | 23568 | while( N>nDash ){ |
| 24142 | | - oputz(zDash); |
| 23569 | + sqlite3_fputs(zDash, out); |
| 24143 | 23570 | N -= nDash; |
| 24144 | 23571 | } |
| 24145 | | - oputf("%.*s", N, zDash); |
| 23572 | + sqlite3_fprintf(out, "%.*s", N, zDash); |
| 24146 | 23573 | } |
| 24147 | 23574 | |
| 24148 | 23575 | /* |
| 24149 | 23576 | ** Draw a horizontal separator for a MODE_Box table. |
| 24150 | 23577 | */ |
| | @@ -24155,19 +23582,19 @@ |
| 24155 | 23582 | const char *zSep2, |
| 24156 | 23583 | const char *zSep3 |
| 24157 | 23584 | ){ |
| 24158 | 23585 | int i; |
| 24159 | 23586 | if( nArg>0 ){ |
| 24160 | | - oputz(zSep1); |
| 24161 | | - print_box_line(p->actualWidth[0]+2); |
| 23587 | + sqlite3_fputs(zSep1, p->out); |
| 23588 | + print_box_line(p->out, p->actualWidth[0]+2); |
| 24162 | 23589 | for(i=1; i<nArg; i++){ |
| 24163 | | - oputz(zSep2); |
| 24164 | | - print_box_line(p->actualWidth[i]+2); |
| 23590 | + sqlite3_fputs(zSep2, p->out); |
| 23591 | + print_box_line(p->out, p->actualWidth[i]+2); |
| 24165 | 23592 | } |
| 24166 | | - oputz(zSep3); |
| 23593 | + sqlite3_fputs(zSep3, p->out); |
| 24167 | 23594 | } |
| 24168 | | - oputz("\n"); |
| 23595 | + sqlite3_fputs("\n", p->out); |
| 24169 | 23596 | } |
| 24170 | 23597 | |
| 24171 | 23598 | /* |
| 24172 | 23599 | ** z[] is a line of text that is to be displayed the .mode box or table or |
| 24173 | 23600 | ** similar tabular formats. z[] might contain control characters such |
| | @@ -24197,16 +23624,26 @@ |
| 24197 | 23624 | } |
| 24198 | 23625 | if( mxWidth<0 ) mxWidth = -mxWidth; |
| 24199 | 23626 | if( mxWidth==0 ) mxWidth = 1000000; |
| 24200 | 23627 | i = j = n = 0; |
| 24201 | 23628 | while( n<mxWidth ){ |
| 24202 | | - if( z[i]>=' ' ){ |
| 23629 | + unsigned char c = z[i]; |
| 23630 | + if( c>=0xc0 ){ |
| 23631 | + int u; |
| 23632 | + int len = decodeUtf8(&z[i], &u); |
| 23633 | + i += len; |
| 23634 | + j += len; |
| 23635 | + n += cli_wcwidth(u); |
| 23636 | + continue; |
| 23637 | + } |
| 23638 | + if( c>=' ' ){ |
| 24203 | 23639 | n++; |
| 24204 | | - do{ i++; j++; }while( (z[i]&0xc0)==0x80 ); |
| 23640 | + i++; |
| 23641 | + j++; |
| 24205 | 23642 | continue; |
| 24206 | 23643 | } |
| 24207 | | - if( z[i]=='\t' ){ |
| 23644 | + if( c=='\t' ){ |
| 24208 | 23645 | do{ |
| 24209 | 23646 | n++; |
| 24210 | 23647 | j++; |
| 24211 | 23648 | }while( (n&7)!=0 && n<mxWidth ); |
| 24212 | 23649 | i++; |
| | @@ -24244,13 +23681,21 @@ |
| 24244 | 23681 | } |
| 24245 | 23682 | zOut = malloc( j+1 ); |
| 24246 | 23683 | shell_check_oom(zOut); |
| 24247 | 23684 | i = j = n = 0; |
| 24248 | 23685 | while( i<k ){ |
| 24249 | | - if( z[i]>=' ' ){ |
| 23686 | + unsigned char c = z[i]; |
| 23687 | + if( c>=0xc0 ){ |
| 23688 | + int u; |
| 23689 | + int len = decodeUtf8(&z[i], &u); |
| 23690 | + do{ zOut[j++] = z[i++]; }while( (--len)>0 ); |
| 23691 | + n += cli_wcwidth(u); |
| 23692 | + continue; |
| 23693 | + } |
| 23694 | + if( c>=' ' ){ |
| 24250 | 23695 | n++; |
| 24251 | | - do{ zOut[j++] = z[i++]; }while( (z[i]&0xc0)==0x80 ); |
| 23696 | + zOut[j++] = z[i++]; |
| 24252 | 23697 | continue; |
| 24253 | 23698 | } |
| 24254 | 23699 | if( z[i]=='\t' ){ |
| 24255 | 23700 | do{ |
| 24256 | 23701 | n++; |
| | @@ -24426,97 +23871,99 @@ |
| 24426 | 23871 | rowSep = "\n"; |
| 24427 | 23872 | if( p->showHeader ){ |
| 24428 | 23873 | for(i=0; i<nColumn; i++){ |
| 24429 | 23874 | w = p->actualWidth[i]; |
| 24430 | 23875 | if( p->colWidth[i]<0 ) w = -w; |
| 24431 | | - utf8_width_print(w, azData[i]); |
| 24432 | | - fputs(i==nColumn-1?"\n":" ", p->out); |
| 23876 | + utf8_width_print(p->out, w, azData[i]); |
| 23877 | + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); |
| 24433 | 23878 | } |
| 24434 | 23879 | for(i=0; i<nColumn; i++){ |
| 24435 | | - print_dashes(p->actualWidth[i]); |
| 24436 | | - fputs(i==nColumn-1?"\n":" ", p->out); |
| 23880 | + print_dashes(p->out, p->actualWidth[i]); |
| 23881 | + sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); |
| 24437 | 23882 | } |
| 24438 | 23883 | } |
| 24439 | 23884 | break; |
| 24440 | 23885 | } |
| 24441 | 23886 | case MODE_Table: { |
| 24442 | 23887 | colSep = " | "; |
| 24443 | 23888 | rowSep = " |\n"; |
| 24444 | 23889 | print_row_separator(p, nColumn, "+"); |
| 24445 | | - fputs("| ", p->out); |
| 23890 | + sqlite3_fputs("| ", p->out); |
| 24446 | 23891 | for(i=0; i<nColumn; i++){ |
| 24447 | 23892 | w = p->actualWidth[i]; |
| 24448 | 23893 | n = strlenChar(azData[i]); |
| 24449 | | - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); |
| 24450 | | - oputz(i==nColumn-1?" |\n":" | "); |
| 23894 | + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", |
| 23895 | + azData[i], (w-n+1)/2, ""); |
| 23896 | + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); |
| 24451 | 23897 | } |
| 24452 | 23898 | print_row_separator(p, nColumn, "+"); |
| 24453 | 23899 | break; |
| 24454 | 23900 | } |
| 24455 | 23901 | case MODE_Markdown: { |
| 24456 | 23902 | colSep = " | "; |
| 24457 | 23903 | rowSep = " |\n"; |
| 24458 | | - fputs("| ", p->out); |
| 23904 | + sqlite3_fputs("| ", p->out); |
| 24459 | 23905 | for(i=0; i<nColumn; i++){ |
| 24460 | 23906 | w = p->actualWidth[i]; |
| 24461 | 23907 | n = strlenChar(azData[i]); |
| 24462 | | - oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, ""); |
| 24463 | | - oputz(i==nColumn-1?" |\n":" | "); |
| 23908 | + sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", |
| 23909 | + azData[i], (w-n+1)/2, ""); |
| 23910 | + sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); |
| 24464 | 23911 | } |
| 24465 | 23912 | print_row_separator(p, nColumn, "|"); |
| 24466 | 23913 | break; |
| 24467 | 23914 | } |
| 24468 | 23915 | case MODE_Box: { |
| 24469 | 23916 | colSep = " " BOX_13 " "; |
| 24470 | 23917 | rowSep = " " BOX_13 "\n"; |
| 24471 | 23918 | print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34); |
| 24472 | | - oputz(BOX_13 " "); |
| 23919 | + sqlite3_fputs(BOX_13 " ", p->out); |
| 24473 | 23920 | for(i=0; i<nColumn; i++){ |
| 24474 | 23921 | w = p->actualWidth[i]; |
| 24475 | 23922 | n = strlenChar(azData[i]); |
| 24476 | | - oputf("%*s%s%*s%s", |
| 23923 | + sqlite3_fprintf(p->out, "%*s%s%*s%s", |
| 24477 | 23924 | (w-n)/2, "", azData[i], (w-n+1)/2, "", |
| 24478 | 23925 | i==nColumn-1?" "BOX_13"\n":" "BOX_13" "); |
| 24479 | 23926 | } |
| 24480 | 23927 | print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); |
| 24481 | 23928 | break; |
| 24482 | 23929 | } |
| 24483 | 23930 | } |
| 24484 | 23931 | for(i=nColumn, j=0; i<nTotal; i++, j++){ |
| 24485 | 23932 | if( j==0 && p->cMode!=MODE_Column ){ |
| 24486 | | - oputz(p->cMode==MODE_Box?BOX_13" ":"| "); |
| 23933 | + sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out); |
| 24487 | 23934 | } |
| 24488 | 23935 | z = azData[i]; |
| 24489 | 23936 | if( z==0 ) z = p->nullValue; |
| 24490 | 23937 | w = p->actualWidth[j]; |
| 24491 | 23938 | if( p->colWidth[j]<0 ) w = -w; |
| 24492 | | - utf8_width_print(w, z); |
| 23939 | + utf8_width_print(p->out, w, z); |
| 24493 | 23940 | if( j==nColumn-1 ){ |
| 24494 | | - oputz(rowSep); |
| 23941 | + sqlite3_fputs(rowSep, p->out); |
| 24495 | 23942 | if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){ |
| 24496 | 23943 | if( p->cMode==MODE_Table ){ |
| 24497 | 23944 | print_row_separator(p, nColumn, "+"); |
| 24498 | 23945 | }else if( p->cMode==MODE_Box ){ |
| 24499 | 23946 | print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); |
| 24500 | 23947 | }else if( p->cMode==MODE_Column ){ |
| 24501 | | - oputz("\n"); |
| 23948 | + sqlite3_fputs("\n", p->out); |
| 24502 | 23949 | } |
| 24503 | 23950 | } |
| 24504 | 23951 | j = -1; |
| 24505 | 23952 | if( seenInterrupt ) goto columnar_end; |
| 24506 | 23953 | }else{ |
| 24507 | | - oputz(colSep); |
| 23954 | + sqlite3_fputs(colSep, p->out); |
| 24508 | 23955 | } |
| 24509 | 23956 | } |
| 24510 | 23957 | if( p->cMode==MODE_Table ){ |
| 24511 | 23958 | print_row_separator(p, nColumn, "+"); |
| 24512 | 23959 | }else if( p->cMode==MODE_Box ){ |
| 24513 | 23960 | print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14); |
| 24514 | 23961 | } |
| 24515 | 23962 | columnar_end: |
| 24516 | 23963 | if( seenInterrupt ){ |
| 24517 | | - oputz("Interrupt\n"); |
| 23964 | + sqlite3_fputs("Interrupt\n", p->out); |
| 24518 | 23965 | } |
| 24519 | 23966 | nData = (nRow+1)*nColumn; |
| 24520 | 23967 | for(i=0; i<nData; i++){ |
| 24521 | 23968 | z = azData[i]; |
| 24522 | 23969 | if( z!=zEmpty && z!=zShowNull ) free(azData[i]); |
| | @@ -24599,11 +24046,13 @@ |
| 24599 | 24046 | } |
| 24600 | 24047 | } |
| 24601 | 24048 | } while( SQLITE_ROW == rc ); |
| 24602 | 24049 | sqlite3_free(pData); |
| 24603 | 24050 | if( pArg->cMode==MODE_Json ){ |
| 24604 | | - fputs("]\n", pArg->out); |
| 24051 | + sqlite3_fputs("]\n", pArg->out); |
| 24052 | + }else if( pArg->cMode==MODE_Www ){ |
| 24053 | + sqlite3_fputs("</TABLE>\n<PRE>\n", pArg->out); |
| 24605 | 24054 | }else if( pArg->cMode==MODE_Count ){ |
| 24606 | 24055 | char zBuf[200]; |
| 24607 | 24056 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n", |
| 24608 | 24057 | nRow, nRow!=1 ? "s" : ""); |
| 24609 | 24058 | printf("%s", zBuf); |
| | @@ -24648,10 +24097,11 @@ |
| 24648 | 24097 | int bCancel, |
| 24649 | 24098 | char **pzErr |
| 24650 | 24099 | ){ |
| 24651 | 24100 | int rc = SQLITE_OK; |
| 24652 | 24101 | sqlite3expert *p = pState->expert.pExpert; |
| 24102 | + FILE *out = pState->out; |
| 24653 | 24103 | assert( p ); |
| 24654 | 24104 | assert( bCancel || pzErr==0 || *pzErr==0 ); |
| 24655 | 24105 | if( bCancel==0 ){ |
| 24656 | 24106 | int bVerbose = pState->expert.bVerbose; |
| 24657 | 24107 | |
| | @@ -24660,24 +24110,25 @@ |
| 24660 | 24110 | int nQuery = sqlite3_expert_count(p); |
| 24661 | 24111 | int i; |
| 24662 | 24112 | |
| 24663 | 24113 | if( bVerbose ){ |
| 24664 | 24114 | const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); |
| 24665 | | - oputz("-- Candidates -----------------------------\n"); |
| 24666 | | - oputf("%s\n", zCand); |
| 24115 | + sqlite3_fputs("-- Candidates -----------------------------\n", out); |
| 24116 | + sqlite3_fprintf(out, "%s\n", zCand); |
| 24667 | 24117 | } |
| 24668 | 24118 | for(i=0; i<nQuery; i++){ |
| 24669 | 24119 | const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL); |
| 24670 | 24120 | const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES); |
| 24671 | 24121 | const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN); |
| 24672 | 24122 | if( zIdx==0 ) zIdx = "(no new indexes)\n"; |
| 24673 | 24123 | if( bVerbose ){ |
| 24674 | | - oputf("-- Query %d --------------------------------\n",i+1); |
| 24675 | | - oputf("%s\n\n", zSql); |
| 24124 | + sqlite3_fprintf(out, |
| 24125 | + "-- Query %d --------------------------------\n" |
| 24126 | + "%s\n\n" |
| 24127 | + ,i+1, zSql); |
| 24676 | 24128 | } |
| 24677 | | - oputf("%s\n", zIdx); |
| 24678 | | - oputf("%s\n", zEQP); |
| 24129 | + sqlite3_fprintf(out, "%s\n%s\n", zIdx, zEQP); |
| 24679 | 24130 | } |
| 24680 | 24131 | } |
| 24681 | 24132 | } |
| 24682 | 24133 | sqlite3_expert_destroy(p); |
| 24683 | 24134 | pState->expert.pExpert = 0; |
| | @@ -24708,30 +24159,31 @@ |
| 24708 | 24159 | if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){ |
| 24709 | 24160 | pState->expert.bVerbose = 1; |
| 24710 | 24161 | } |
| 24711 | 24162 | else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){ |
| 24712 | 24163 | if( i==(nArg-1) ){ |
| 24713 | | - eputf("option requires an argument: %s\n", z); |
| 24164 | + sqlite3_fprintf(stderr, "option requires an argument: %s\n", z); |
| 24714 | 24165 | rc = SQLITE_ERROR; |
| 24715 | 24166 | }else{ |
| 24716 | 24167 | iSample = (int)integerValue(azArg[++i]); |
| 24717 | 24168 | if( iSample<0 || iSample>100 ){ |
| 24718 | | - eputf("value out of range: %s\n", azArg[i]); |
| 24169 | + sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]); |
| 24719 | 24170 | rc = SQLITE_ERROR; |
| 24720 | 24171 | } |
| 24721 | 24172 | } |
| 24722 | 24173 | } |
| 24723 | 24174 | else{ |
| 24724 | | - eputf("unknown option: %s\n", z); |
| 24175 | + sqlite3_fprintf(stderr,"unknown option: %s\n", z); |
| 24725 | 24176 | rc = SQLITE_ERROR; |
| 24726 | 24177 | } |
| 24727 | 24178 | } |
| 24728 | 24179 | |
| 24729 | 24180 | if( rc==SQLITE_OK ){ |
| 24730 | 24181 | pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); |
| 24731 | 24182 | if( pState->expert.pExpert==0 ){ |
| 24732 | | - eputf("sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); |
| 24183 | + sqlite3_fprintf(stderr, |
| 24184 | + "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); |
| 24733 | 24185 | rc = SQLITE_ERROR; |
| 24734 | 24186 | }else{ |
| 24735 | 24187 | sqlite3_expert_config( |
| 24736 | 24188 | pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample |
| 24737 | 24189 | ); |
| | @@ -25056,33 +24508,33 @@ |
| 25056 | 24508 | if( zType==0 ) return 0; |
| 25057 | 24509 | dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0; |
| 25058 | 24510 | noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0; |
| 25059 | 24511 | |
| 25060 | 24512 | if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){ |
| 25061 | | - if( !dataOnly ) oputz("DELETE FROM sqlite_sequence;\n"); |
| 24513 | + if( !dataOnly ) sqlite3_fputs("DELETE FROM sqlite_sequence;\n", p->out); |
| 25062 | 24514 | }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){ |
| 25063 | | - if( !dataOnly ) oputz("ANALYZE sqlite_schema;\n"); |
| 24515 | + if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); |
| 25064 | 24516 | }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){ |
| 25065 | 24517 | return 0; |
| 25066 | 24518 | }else if( dataOnly ){ |
| 25067 | 24519 | /* no-op */ |
| 25068 | 24520 | }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ |
| 25069 | 24521 | char *zIns; |
| 25070 | 24522 | if( !p->writableSchema ){ |
| 25071 | | - oputz("PRAGMA writable_schema=ON;\n"); |
| 24523 | + sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out); |
| 25072 | 24524 | p->writableSchema = 1; |
| 25073 | 24525 | } |
| 25074 | 24526 | zIns = sqlite3_mprintf( |
| 25075 | 24527 | "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)" |
| 25076 | 24528 | "VALUES('table','%q','%q',0,'%q');", |
| 25077 | 24529 | zTable, zTable, zSql); |
| 25078 | 24530 | shell_check_oom(zIns); |
| 25079 | | - oputf("%s\n", zIns); |
| 24531 | + sqlite3_fprintf(p->out, "%s\n", zIns); |
| 25080 | 24532 | sqlite3_free(zIns); |
| 25081 | 24533 | return 0; |
| 25082 | 24534 | }else{ |
| 25083 | | - printSchemaLine(zSql, ";\n"); |
| 24535 | + printSchemaLine(p->out, zSql, ";\n"); |
| 25084 | 24536 | } |
| 25085 | 24537 | |
| 25086 | 24538 | if( cli_strcmp(zType, "table")==0 ){ |
| 25087 | 24539 | ShellText sSelect; |
| 25088 | 24540 | ShellText sTable; |
| | @@ -25136,11 +24588,11 @@ |
| 25136 | 24588 | savedMode = p->mode; |
| 25137 | 24589 | p->zDestTable = sTable.z; |
| 25138 | 24590 | p->mode = p->cMode = MODE_Insert; |
| 25139 | 24591 | rc = shell_exec(p, sSelect.z, 0); |
| 25140 | 24592 | if( (rc&0xff)==SQLITE_CORRUPT ){ |
| 25141 | | - oputz("/****** CORRUPTION ERROR *******/\n"); |
| 24593 | + sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); |
| 25142 | 24594 | toggleSelectOrder(p->db); |
| 25143 | 24595 | shell_exec(p, sSelect.z, 0); |
| 25144 | 24596 | toggleSelectOrder(p->db); |
| 25145 | 24597 | } |
| 25146 | 24598 | p->zDestTable = savedDestTable; |
| | @@ -25167,22 +24619,22 @@ |
| 25167 | 24619 | char *zErr = 0; |
| 25168 | 24620 | rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); |
| 25169 | 24621 | if( rc==SQLITE_CORRUPT ){ |
| 25170 | 24622 | char *zQ2; |
| 25171 | 24623 | int len = strlen30(zQuery); |
| 25172 | | - oputz("/****** CORRUPTION ERROR *******/\n"); |
| 24624 | + sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); |
| 25173 | 24625 | if( zErr ){ |
| 25174 | | - oputf("/****** %s ******/\n", zErr); |
| 24626 | + sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr); |
| 25175 | 24627 | sqlite3_free(zErr); |
| 25176 | 24628 | zErr = 0; |
| 25177 | 24629 | } |
| 25178 | 24630 | zQ2 = malloc( len+100 ); |
| 25179 | 24631 | if( zQ2==0 ) return rc; |
| 25180 | 24632 | sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); |
| 25181 | 24633 | rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); |
| 25182 | 24634 | if( rc ){ |
| 25183 | | - oputf("/****** ERROR: %s ******/\n", zErr); |
| 24635 | + sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); |
| 25184 | 24636 | }else{ |
| 25185 | 24637 | rc = SQLITE_CORRUPT; |
| 25186 | 24638 | } |
| 25187 | 24639 | sqlite3_free(zErr); |
| 25188 | 24640 | free(zQ2); |
| | @@ -25241,13 +24693,14 @@ |
| 25241 | 24693 | #ifndef SQLITE_SHELL_FIDDLE |
| 25242 | 24694 | ".check GLOB Fail if output since .testcase does not match", |
| 25243 | 24695 | ".clone NEWDB Clone data into NEWDB from the existing database", |
| 25244 | 24696 | #endif |
| 25245 | 24697 | ".connection [close] [#] Open or close an auxiliary database connection", |
| 25246 | | -#if defined(_WIN32) || defined(WIN32) |
| 24698 | +#if defined(_WIN32) && !defined(SQLITE_U8TEXT_ONLY) \ |
| 24699 | + && !defined(SQLITE_U8TEXT_STDIO) |
| 25247 | 24700 | ".crnl on|off Translate \\n to \\r\\n. Default ON", |
| 25248 | | -#endif |
| 24701 | +#endif /* _WIN32 && U8TEXT_ONLY && U8TEXT_STDIO */ |
| 25249 | 24702 | ".databases List names and files of attached databases", |
| 25250 | 24703 | ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", |
| 25251 | 24704 | #if SQLITE_SHELL_HAVE_RECOVER |
| 25252 | 24705 | ".dbinfo ?DB? Show status information about the database", |
| 25253 | 24706 | #endif |
| | @@ -25349,13 +24802,15 @@ |
| 25349 | 24802 | #endif |
| 25350 | 24803 | ".nullvalue STRING Use STRING in place of NULL values", |
| 25351 | 24804 | #ifndef SQLITE_SHELL_FIDDLE |
| 25352 | 24805 | ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE", |
| 25353 | 24806 | " If FILE begins with '|' then open as a pipe", |
| 25354 | | - " --bom Put a UTF8 byte-order mark at the beginning", |
| 25355 | | - " -e Send output to the system text editor", |
| 25356 | | - " -x Send output as CSV to a spreadsheet (same as \".excel\")", |
| 24807 | + " --bom Put a UTF8 byte-order mark at the beginning", |
| 24808 | + " -e Send output to the system text editor", |
| 24809 | + " --plain Use text/plain output instead of HTML for -w option", |
| 24810 | + " -w Send output as HTML to a web browser (same as \".www\")", |
| 24811 | + " -x Send output as CSV to a spreadsheet (same as \".excel\")", |
| 25357 | 24812 | /* Note that .open is (partially) available in WASM builds but is |
| 25358 | 24813 | ** currently only intended to be used by the fiddle tool, not |
| 25359 | 24814 | ** end users, so is "undocumented." */ |
| 25360 | 24815 | ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", |
| 25361 | 24816 | " Options:", |
| | @@ -25374,10 +24829,12 @@ |
| 25374 | 24829 | ".output ?FILE? Send output to FILE or stdout if FILE is omitted", |
| 25375 | 24830 | " If FILE begins with '|' then open it as a pipe.", |
| 25376 | 24831 | " Options:", |
| 25377 | 24832 | " --bom Prefix output with a UTF8 byte-order mark", |
| 25378 | 24833 | " -e Send output to the system text editor", |
| 24834 | + " --plain Use text/plain for -w option", |
| 24835 | + " -w Send output to a web browser", |
| 25379 | 24836 | " -x Send output as CSV to a spreadsheet", |
| 25380 | 24837 | #endif |
| 25381 | 24838 | ".parameter CMD ... Manage SQL parameter bindings", |
| 25382 | 24839 | " clear Erase all bindings", |
| 25383 | 24840 | " init Initialize the TEMP table that holds bindings", |
| | @@ -25487,10 +24944,14 @@ |
| 25487 | 24944 | ".vfsinfo ?AUX? Information about the top-level VFS", |
| 25488 | 24945 | ".vfslist List all available VFSes", |
| 25489 | 24946 | ".vfsname ?AUX? Print the name of the VFS stack", |
| 25490 | 24947 | ".width NUM1 NUM2 ... Set minimum column widths for columnar output", |
| 25491 | 24948 | " Negative values right-justify", |
| 24949 | +#ifndef SQLITE_SHELL_FIDDLE |
| 24950 | + ".www Display output of the next command in web browser", |
| 24951 | + " --plain Show results as text/plain, not as HTML", |
| 24952 | +#endif |
| 25492 | 24953 | }; |
| 25493 | 24954 | |
| 25494 | 24955 | /* |
| 25495 | 24956 | ** Output help text. |
| 25496 | 24957 | ** |
| | @@ -25535,24 +24996,24 @@ |
| 25535 | 24996 | hh &= ~HH_Summary; |
| 25536 | 24997 | break; |
| 25537 | 24998 | } |
| 25538 | 24999 | if( ((hw^hh)&HH_Undoc)==0 ){ |
| 25539 | 25000 | if( (hh&HH_Summary)!=0 ){ |
| 25540 | | - sputf(out, ".%s\n", azHelp[i]+1); |
| 25001 | + sqlite3_fprintf(out, ".%s\n", azHelp[i]+1); |
| 25541 | 25002 | ++n; |
| 25542 | 25003 | }else if( (hw&HW_SummaryOnly)==0 ){ |
| 25543 | | - sputf(out, "%s\n", azHelp[i]); |
| 25004 | + sqlite3_fprintf(out, "%s\n", azHelp[i]); |
| 25544 | 25005 | } |
| 25545 | 25006 | } |
| 25546 | 25007 | } |
| 25547 | 25008 | }else{ |
| 25548 | 25009 | /* Seek documented commands for which zPattern is an exact prefix */ |
| 25549 | 25010 | zPat = sqlite3_mprintf(".%s*", zPattern); |
| 25550 | 25011 | shell_check_oom(zPat); |
| 25551 | 25012 | for(i=0; i<ArraySize(azHelp); i++){ |
| 25552 | 25013 | if( sqlite3_strglob(zPat, azHelp[i])==0 ){ |
| 25553 | | - sputf(out, "%s\n", azHelp[i]); |
| 25014 | + sqlite3_fprintf(out, "%s\n", azHelp[i]); |
| 25554 | 25015 | j = i+1; |
| 25555 | 25016 | n++; |
| 25556 | 25017 | } |
| 25557 | 25018 | } |
| 25558 | 25019 | sqlite3_free(zPat); |
| | @@ -25559,11 +25020,11 @@ |
| 25559 | 25020 | if( n ){ |
| 25560 | 25021 | if( n==1 ){ |
| 25561 | 25022 | /* when zPattern is a prefix of exactly one command, then include |
| 25562 | 25023 | ** the details of that command, which should begin at offset j */ |
| 25563 | 25024 | while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){ |
| 25564 | | - sputf(out, "%s\n", azHelp[j]); |
| 25025 | + sqlite3_fprintf(out, "%s\n", azHelp[j]); |
| 25565 | 25026 | j++; |
| 25566 | 25027 | } |
| 25567 | 25028 | } |
| 25568 | 25029 | return n; |
| 25569 | 25030 | } |
| | @@ -25576,14 +25037,14 @@ |
| 25576 | 25037 | while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i; |
| 25577 | 25038 | continue; |
| 25578 | 25039 | } |
| 25579 | 25040 | if( azHelp[i][0]=='.' ) j = i; |
| 25580 | 25041 | if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){ |
| 25581 | | - sputf(out, "%s\n", azHelp[j]); |
| 25042 | + sqlite3_fprintf(out, "%s\n", azHelp[j]); |
| 25582 | 25043 | while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){ |
| 25583 | 25044 | j++; |
| 25584 | | - sputf(out, "%s\n", azHelp[j]); |
| 25045 | + sqlite3_fprintf(out, "%s\n", azHelp[j]); |
| 25585 | 25046 | } |
| 25586 | 25047 | i = j; |
| 25587 | 25048 | n++; |
| 25588 | 25049 | } |
| 25589 | 25050 | } |
| | @@ -25609,35 +25070,35 @@ |
| 25609 | 25070 | ** |
| 25610 | 25071 | ** NULL is returned if any error is encountered. The final value of *pnByte |
| 25611 | 25072 | ** is undefined in this case. |
| 25612 | 25073 | */ |
| 25613 | 25074 | static char *readFile(const char *zName, int *pnByte){ |
| 25614 | | - FILE *in = fopen(zName, "rb"); |
| 25075 | + FILE *in = sqlite3_fopen(zName, "rb"); |
| 25615 | 25076 | long nIn; |
| 25616 | 25077 | size_t nRead; |
| 25617 | 25078 | char *pBuf; |
| 25618 | 25079 | int rc; |
| 25619 | 25080 | if( in==0 ) return 0; |
| 25620 | 25081 | rc = fseek(in, 0, SEEK_END); |
| 25621 | 25082 | if( rc!=0 ){ |
| 25622 | | - eputf("Error: '%s' not seekable\n", zName); |
| 25083 | + sqlite3_fprintf(stderr,"Error: '%s' not seekable\n", zName); |
| 25623 | 25084 | fclose(in); |
| 25624 | 25085 | return 0; |
| 25625 | 25086 | } |
| 25626 | 25087 | nIn = ftell(in); |
| 25627 | 25088 | rewind(in); |
| 25628 | 25089 | pBuf = sqlite3_malloc64( nIn+1 ); |
| 25629 | 25090 | if( pBuf==0 ){ |
| 25630 | | - eputz("Error: out of memory\n"); |
| 25091 | + sqlite3_fputs("Error: out of memory\n", stderr); |
| 25631 | 25092 | fclose(in); |
| 25632 | 25093 | return 0; |
| 25633 | 25094 | } |
| 25634 | 25095 | nRead = fread(pBuf, nIn, 1, in); |
| 25635 | 25096 | fclose(in); |
| 25636 | 25097 | if( nRead!=1 ){ |
| 25637 | 25098 | sqlite3_free(pBuf); |
| 25638 | | - eputf("Error: cannot read '%s'\n", zName); |
| 25099 | + sqlite3_fprintf(stderr,"Error: cannot read '%s'\n", zName); |
| 25639 | 25100 | return 0; |
| 25640 | 25101 | } |
| 25641 | 25102 | pBuf[nIn] = 0; |
| 25642 | 25103 | if( pnByte ) *pnByte = nIn; |
| 25643 | 25104 | return pBuf; |
| | @@ -25699,11 +25160,11 @@ |
| 25699 | 25160 | ** archive and the dfltZip flag is true, then assume it is a ZIP archive. |
| 25700 | 25161 | ** Otherwise, assume an ordinary database regardless of the filename if |
| 25701 | 25162 | ** the type cannot be determined from content. |
| 25702 | 25163 | */ |
| 25703 | 25164 | int deduceDatabaseType(const char *zName, int dfltZip){ |
| 25704 | | - FILE *f = fopen(zName, "rb"); |
| 25165 | + FILE *f = sqlite3_fopen(zName, "rb"); |
| 25705 | 25166 | size_t n; |
| 25706 | 25167 | int rc = SHELL_OPEN_UNSPEC; |
| 25707 | 25168 | char zBuf[100]; |
| 25708 | 25169 | if( f==0 ){ |
| 25709 | 25170 | if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ |
| | @@ -25752,13 +25213,13 @@ |
| 25752 | 25213 | FILE *in; |
| 25753 | 25214 | const char *zDbFilename = p->pAuxDb->zDbFilename; |
| 25754 | 25215 | unsigned int x[16]; |
| 25755 | 25216 | char zLine[1000]; |
| 25756 | 25217 | if( zDbFilename ){ |
| 25757 | | - in = fopen(zDbFilename, "r"); |
| 25218 | + in = sqlite3_fopen(zDbFilename, "r"); |
| 25758 | 25219 | if( in==0 ){ |
| 25759 | | - eputf("cannot open \"%s\" for reading\n", zDbFilename); |
| 25220 | + sqlite3_fprintf(stderr,"cannot open \"%s\" for reading\n", zDbFilename); |
| 25760 | 25221 | return 0; |
| 25761 | 25222 | } |
| 25762 | 25223 | nLine = 0; |
| 25763 | 25224 | }else{ |
| 25764 | 25225 | in = p->in; |
| | @@ -25765,24 +25226,24 @@ |
| 25765 | 25226 | nLine = p->lineno; |
| 25766 | 25227 | if( in==0 ) in = stdin; |
| 25767 | 25228 | } |
| 25768 | 25229 | *pnData = 0; |
| 25769 | 25230 | nLine++; |
| 25770 | | - if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
| 25231 | + if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; |
| 25771 | 25232 | rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); |
| 25772 | 25233 | if( rc!=2 ) goto readHexDb_error; |
| 25773 | 25234 | if( n<0 ) goto readHexDb_error; |
| 25774 | 25235 | if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error; |
| 25775 | 25236 | n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */ |
| 25776 | 25237 | a = sqlite3_malloc( n ? n : 1 ); |
| 25777 | 25238 | shell_check_oom(a); |
| 25778 | 25239 | memset(a, 0, n); |
| 25779 | 25240 | if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ |
| 25780 | | - eputz("invalid pagesize\n"); |
| 25241 | + sqlite3_fputs("invalid pagesize\n", stderr); |
| 25781 | 25242 | goto readHexDb_error; |
| 25782 | 25243 | } |
| 25783 | | - for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25244 | + for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ |
| 25784 | 25245 | rc = sscanf(zLine, "| page %d offset %d", &j, &k); |
| 25785 | 25246 | if( rc==2 ){ |
| 25786 | 25247 | iOffset = k; |
| 25787 | 25248 | continue; |
| 25788 | 25249 | } |
| | @@ -25810,18 +25271,18 @@ |
| 25810 | 25271 | |
| 25811 | 25272 | readHexDb_error: |
| 25812 | 25273 | if( in!=p->in ){ |
| 25813 | 25274 | fclose(in); |
| 25814 | 25275 | }else{ |
| 25815 | | - while( fgets(zLine, sizeof(zLine), p->in)!=0 ){ |
| 25276 | + while( sqlite3_fgets(zLine, sizeof(zLine), p->in)!=0 ){ |
| 25816 | 25277 | nLine++; |
| 25817 | 25278 | if(cli_strncmp(zLine, "| end ", 6)==0 ) break; |
| 25818 | 25279 | } |
| 25819 | 25280 | p->lineno = nLine; |
| 25820 | 25281 | } |
| 25821 | 25282 | sqlite3_free(a); |
| 25822 | | - eputf("Error on line %d of --hexdb input\n", nLine); |
| 25283 | + sqlite3_fprintf(stderr,"Error on line %d of --hexdb input\n", nLine); |
| 25823 | 25284 | return 0; |
| 25824 | 25285 | } |
| 25825 | 25286 | #endif /* SQLITE_OMIT_DESERIALIZE */ |
| 25826 | 25287 | |
| 25827 | 25288 | /* |
| | @@ -25892,22 +25353,24 @@ |
| 25892 | 25353 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0); |
| 25893 | 25354 | break; |
| 25894 | 25355 | } |
| 25895 | 25356 | } |
| 25896 | 25357 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 25897 | | - eputf("Error: unable to open database \"%s\": %s\n", |
| 25358 | + sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", |
| 25898 | 25359 | zDbFilename, sqlite3_errmsg(p->db)); |
| 25899 | 25360 | if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){ |
| 25900 | 25361 | exit(1); |
| 25901 | 25362 | } |
| 25902 | 25363 | sqlite3_close(p->db); |
| 25903 | 25364 | sqlite3_open(":memory:", &p->db); |
| 25904 | 25365 | if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ |
| 25905 | | - eputz("Also: unable to open substitute in-memory database.\n"); |
| 25366 | + sqlite3_fputs("Also: unable to open substitute in-memory database.\n", |
| 25367 | + stderr); |
| 25906 | 25368 | exit(1); |
| 25907 | 25369 | }else{ |
| 25908 | | - eputf("Notice: using substitute in-memory database instead of \"%s\"\n", |
| 25370 | + sqlite3_fprintf(stderr, |
| 25371 | + "Notice: using substitute in-memory database instead of \"%s\"\n", |
| 25909 | 25372 | zDbFilename); |
| 25910 | 25373 | } |
| 25911 | 25374 | } |
| 25912 | 25375 | globalDb = p->db; |
| 25913 | 25376 | sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0); |
| | @@ -26015,11 +25478,11 @@ |
| 26015 | 25478 | } |
| 26016 | 25479 | rc = sqlite3_deserialize(p->db, "main", aData, nData, nData, |
| 26017 | 25480 | SQLITE_DESERIALIZE_RESIZEABLE | |
| 26018 | 25481 | SQLITE_DESERIALIZE_FREEONCLOSE); |
| 26019 | 25482 | if( rc ){ |
| 26020 | | - eputf("Error: sqlite3_deserialize() returns %d\n", rc); |
| 25483 | + sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc); |
| 26021 | 25484 | } |
| 26022 | 25485 | if( p->szMax>0 ){ |
| 26023 | 25486 | sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax); |
| 26024 | 25487 | } |
| 26025 | 25488 | } |
| | @@ -26039,11 +25502,12 @@ |
| 26039 | 25502 | ** Attempt to close the database connection. Report errors. |
| 26040 | 25503 | */ |
| 26041 | 25504 | void close_db(sqlite3 *db){ |
| 26042 | 25505 | int rc = sqlite3_close(db); |
| 26043 | 25506 | if( rc ){ |
| 26044 | | - eputf("Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); |
| 25507 | + sqlite3_fprintf(stderr, |
| 25508 | + "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); |
| 26045 | 25509 | } |
| 26046 | 25510 | } |
| 26047 | 25511 | |
| 26048 | 25512 | #if HAVE_READLINE || HAVE_EDITLINE |
| 26049 | 25513 | /* |
| | @@ -26203,11 +25667,12 @@ |
| 26203 | 25667 | return 1; |
| 26204 | 25668 | } |
| 26205 | 25669 | if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ |
| 26206 | 25670 | return 0; |
| 26207 | 25671 | } |
| 26208 | | - eputf("ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); |
| 25672 | + sqlite3_fprintf(stderr, |
| 25673 | + "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); |
| 26209 | 25674 | return 0; |
| 26210 | 25675 | } |
| 26211 | 25676 | |
| 26212 | 25677 | /* |
| 26213 | 25678 | ** Set or clear a shell flag according to a boolean value. |
| | @@ -26239,13 +25704,13 @@ |
| 26239 | 25704 | }else if( cli_strcmp(zFile, "stderr")==0 ){ |
| 26240 | 25705 | f = stderr; |
| 26241 | 25706 | }else if( cli_strcmp(zFile, "off")==0 ){ |
| 26242 | 25707 | f = 0; |
| 26243 | 25708 | }else{ |
| 26244 | | - f = fopen(zFile, bTextMode ? "w" : "wb"); |
| 25709 | + f = sqlite3_fopen(zFile, bTextMode ? "w" : "wb"); |
| 26245 | 25710 | if( f==0 ){ |
| 26246 | | - eputf("Error: cannot open \"%s\"\n", zFile); |
| 25711 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); |
| 26247 | 25712 | } |
| 26248 | 25713 | } |
| 26249 | 25714 | return f; |
| 26250 | 25715 | } |
| 26251 | 25716 | |
| | @@ -26294,16 +25759,17 @@ |
| 26294 | 25759 | if( nSql>1000000000 ) nSql = 1000000000; |
| 26295 | 25760 | while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; } |
| 26296 | 25761 | switch( mType ){ |
| 26297 | 25762 | case SQLITE_TRACE_ROW: |
| 26298 | 25763 | case SQLITE_TRACE_STMT: { |
| 26299 | | - sputf(p->traceOut, "%.*s;\n", (int)nSql, zSql); |
| 25764 | + sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql); |
| 26300 | 25765 | break; |
| 26301 | 25766 | } |
| 26302 | 25767 | case SQLITE_TRACE_PROFILE: { |
| 26303 | 25768 | sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0; |
| 26304 | | - sputf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); |
| 25769 | + sqlite3_fprintf(p->traceOut, |
| 25770 | + "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); |
| 26305 | 25771 | break; |
| 26306 | 25772 | } |
| 26307 | 25773 | } |
| 26308 | 25774 | return 0; |
| 26309 | 25775 | } |
| | @@ -26406,14 +25872,15 @@ |
| 26406 | 25872 | do{ p->n--; }while( p->z[p->n]!=cQuote ); |
| 26407 | 25873 | p->cTerm = c; |
| 26408 | 25874 | break; |
| 26409 | 25875 | } |
| 26410 | 25876 | if( pc==cQuote && c!='\r' ){ |
| 26411 | | - eputf("%s:%d: unescaped %c character\n", p->zFile, p->nLine, cQuote); |
| 25877 | + sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n", |
| 25878 | + p->zFile, p->nLine, cQuote); |
| 26412 | 25879 | } |
| 26413 | 25880 | if( c==EOF ){ |
| 26414 | | - eputf("%s:%d: unterminated %c-quoted field\n", |
| 25881 | + sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n", |
| 26415 | 25882 | p->zFile, startLine, cQuote); |
| 26416 | 25883 | p->cTerm = c; |
| 26417 | 25884 | break; |
| 26418 | 25885 | } |
| 26419 | 25886 | import_append_char(p, c); |
| | @@ -26508,11 +25975,11 @@ |
| 26508 | 25975 | |
| 26509 | 25976 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); |
| 26510 | 25977 | shell_check_oom(zQuery); |
| 26511 | 25978 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
| 26512 | 25979 | if( rc ){ |
| 26513 | | - eputf("Error %d: %s on [%s]\n", |
| 25980 | + sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", |
| 26514 | 25981 | sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); |
| 26515 | 25982 | goto end_data_xfer; |
| 26516 | 25983 | } |
| 26517 | 25984 | n = sqlite3_column_count(pQuery); |
| 26518 | 25985 | zInsert = sqlite3_malloc64(200 + nTable + n*3); |
| | @@ -26525,11 +25992,11 @@ |
| 26525 | 25992 | i += 2; |
| 26526 | 25993 | } |
| 26527 | 25994 | memcpy(zInsert+i, ");", 3); |
| 26528 | 25995 | rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); |
| 26529 | 25996 | if( rc ){ |
| 26530 | | - eputf("Error %d: %s on [%s]\n", |
| 25997 | + sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", |
| 26531 | 25998 | sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert); |
| 26532 | 25999 | goto end_data_xfer; |
| 26533 | 26000 | } |
| 26534 | 26001 | for(k=0; k<2; k++){ |
| 26535 | 26002 | while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ |
| | @@ -26561,11 +26028,11 @@ |
| 26561 | 26028 | } |
| 26562 | 26029 | } |
| 26563 | 26030 | } /* End for */ |
| 26564 | 26031 | rc = sqlite3_step(pInsert); |
| 26565 | 26032 | if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ |
| 26566 | | - eputf("Error %d: %s\n", |
| 26033 | + sqlite3_fprintf(stderr,"Error %d: %s\n", |
| 26567 | 26034 | sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb)); |
| 26568 | 26035 | } |
| 26569 | 26036 | sqlite3_reset(pInsert); |
| 26570 | 26037 | cnt++; |
| 26571 | 26038 | if( (cnt%spinRate)==0 ){ |
| | @@ -26579,11 +26046,11 @@ |
| 26579 | 26046 | zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;", |
| 26580 | 26047 | zTable); |
| 26581 | 26048 | shell_check_oom(zQuery); |
| 26582 | 26049 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
| 26583 | 26050 | if( rc ){ |
| 26584 | | - eputf("Warning: cannot step \"%s\" backwards", zTable); |
| 26051 | + sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable); |
| 26585 | 26052 | break; |
| 26586 | 26053 | } |
| 26587 | 26054 | } /* End for(k=0...) */ |
| 26588 | 26055 | |
| 26589 | 26056 | end_data_xfer: |
| | @@ -26616,23 +26083,24 @@ |
| 26616 | 26083 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" |
| 26617 | 26084 | " WHERE %s ORDER BY rowid ASC", zWhere); |
| 26618 | 26085 | shell_check_oom(zQuery); |
| 26619 | 26086 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
| 26620 | 26087 | if( rc ){ |
| 26621 | | - eputf("Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), |
| 26088 | + sqlite3_fprintf(stderr, |
| 26089 | + "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), |
| 26622 | 26090 | sqlite3_errmsg(p->db), zQuery); |
| 26623 | 26091 | goto end_schema_xfer; |
| 26624 | 26092 | } |
| 26625 | 26093 | while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ |
| 26626 | 26094 | zName = sqlite3_column_text(pQuery, 0); |
| 26627 | 26095 | zSql = sqlite3_column_text(pQuery, 1); |
| 26628 | 26096 | if( zName==0 || zSql==0 ) continue; |
| 26629 | 26097 | if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){ |
| 26630 | | - sputf(stdout, "%s... ", zName); fflush(stdout); |
| 26098 | + sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); |
| 26631 | 26099 | sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); |
| 26632 | 26100 | if( zErrMsg ){ |
| 26633 | | - eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); |
| 26101 | + sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); |
| 26634 | 26102 | sqlite3_free(zErrMsg); |
| 26635 | 26103 | zErrMsg = 0; |
| 26636 | 26104 | } |
| 26637 | 26105 | } |
| 26638 | 26106 | if( xForEach ){ |
| | @@ -26646,23 +26114,23 @@ |
| 26646 | 26114 | zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" |
| 26647 | 26115 | " WHERE %s ORDER BY rowid DESC", zWhere); |
| 26648 | 26116 | shell_check_oom(zQuery); |
| 26649 | 26117 | rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); |
| 26650 | 26118 | if( rc ){ |
| 26651 | | - eputf("Error: (%d) %s on [%s]\n", |
| 26119 | + sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n", |
| 26652 | 26120 | sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); |
| 26653 | 26121 | goto end_schema_xfer; |
| 26654 | 26122 | } |
| 26655 | 26123 | while( sqlite3_step(pQuery)==SQLITE_ROW ){ |
| 26656 | 26124 | zName = sqlite3_column_text(pQuery, 0); |
| 26657 | 26125 | zSql = sqlite3_column_text(pQuery, 1); |
| 26658 | 26126 | if( zName==0 || zSql==0 ) continue; |
| 26659 | 26127 | if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue; |
| 26660 | | - sputf(stdout, "%s... ", zName); fflush(stdout); |
| 26128 | + sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); |
| 26661 | 26129 | sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); |
| 26662 | 26130 | if( zErrMsg ){ |
| 26663 | | - eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql); |
| 26131 | + sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); |
| 26664 | 26132 | sqlite3_free(zErrMsg); |
| 26665 | 26133 | zErrMsg = 0; |
| 26666 | 26134 | } |
| 26667 | 26135 | if( xForEach ){ |
| 26668 | 26136 | xForEach(p, newDb, (const char*)zName); |
| | @@ -26682,16 +26150,17 @@ |
| 26682 | 26150 | */ |
| 26683 | 26151 | static void tryToClone(ShellState *p, const char *zNewDb){ |
| 26684 | 26152 | int rc; |
| 26685 | 26153 | sqlite3 *newDb = 0; |
| 26686 | 26154 | if( access(zNewDb,0)==0 ){ |
| 26687 | | - eputf("File \"%s\" already exists.\n", zNewDb); |
| 26155 | + sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb); |
| 26688 | 26156 | return; |
| 26689 | 26157 | } |
| 26690 | 26158 | rc = sqlite3_open(zNewDb, &newDb); |
| 26691 | 26159 | if( rc ){ |
| 26692 | | - eputf("Cannot create output database: %s\n", sqlite3_errmsg(newDb)); |
| 26160 | + sqlite3_fprintf(stderr, |
| 26161 | + "Cannot create output database: %s\n", sqlite3_errmsg(newDb)); |
| 26693 | 26162 | }else{ |
| 26694 | 26163 | sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); |
| 26695 | 26164 | sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); |
| 26696 | 26165 | tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); |
| 26697 | 26166 | tryToCloneSchema(p, newDb, "type!='table'", 0); |
| | @@ -26704,14 +26173,21 @@ |
| 26704 | 26173 | #ifndef SQLITE_SHELL_FIDDLE |
| 26705 | 26174 | /* |
| 26706 | 26175 | ** Change the output stream (file or pipe or console) to something else. |
| 26707 | 26176 | */ |
| 26708 | 26177 | static void output_redir(ShellState *p, FILE *pfNew){ |
| 26709 | | - if( p->out != stdout ) eputz("Output already redirected.\n"); |
| 26710 | | - else{ |
| 26178 | + if( p->out != stdout ){ |
| 26179 | + sqlite3_fputs("Output already redirected.\n", stderr); |
| 26180 | + }else{ |
| 26711 | 26181 | p->out = pfNew; |
| 26712 | | - setOutputStream(pfNew); |
| 26182 | + if( p->mode==MODE_Www ){ |
| 26183 | + sqlite3_fputs( |
| 26184 | + "<!DOCTYPE html>\n" |
| 26185 | + "<HTML><BODY><PRE>\n", |
| 26186 | + p->out |
| 26187 | + ); |
| 26188 | + } |
| 26713 | 26189 | } |
| 26714 | 26190 | } |
| 26715 | 26191 | |
| 26716 | 26192 | /* |
| 26717 | 26193 | ** Change the output file back to stdout. |
| | @@ -26724,10 +26200,13 @@ |
| 26724 | 26200 | if( p->outfile[0]=='|' ){ |
| 26725 | 26201 | #ifndef SQLITE_OMIT_POPEN |
| 26726 | 26202 | pclose(p->out); |
| 26727 | 26203 | #endif |
| 26728 | 26204 | }else{ |
| 26205 | + if( p->mode==MODE_Www ){ |
| 26206 | + sqlite3_fputs("</PRE></BODY></HTML>\n", p->out); |
| 26207 | + } |
| 26729 | 26208 | output_file_close(p->out); |
| 26730 | 26209 | #ifndef SQLITE_NOHAVE_SYSTEM |
| 26731 | 26210 | if( p->doXdgOpen ){ |
| 26732 | 26211 | const char *zXdgOpenCmd = |
| 26733 | 26212 | #if defined(_WIN32) |
| | @@ -26738,11 +26217,11 @@ |
| 26738 | 26217 | "xdg-open"; |
| 26739 | 26218 | #endif |
| 26740 | 26219 | char *zCmd; |
| 26741 | 26220 | zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); |
| 26742 | 26221 | if( system(zCmd) ){ |
| 26743 | | - eputf("Failed: [%s]\n", zCmd); |
| 26222 | + sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd); |
| 26744 | 26223 | }else{ |
| 26745 | 26224 | /* Give the start/open/xdg-open command some time to get |
| 26746 | 26225 | ** going before we continue, and potential delete the |
| 26747 | 26226 | ** p->zTempFile data file out from under it */ |
| 26748 | 26227 | sqlite3_sleep(2000); |
| | @@ -26753,11 +26232,10 @@ |
| 26753 | 26232 | } |
| 26754 | 26233 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ |
| 26755 | 26234 | } |
| 26756 | 26235 | p->outfile[0] = 0; |
| 26757 | 26236 | p->out = stdout; |
| 26758 | | - setOutputStream(stdout); |
| 26759 | 26237 | } |
| 26760 | 26238 | #else |
| 26761 | 26239 | # define output_redir(SS,pfO) |
| 26762 | 26240 | # define output_reset(SS) |
| 26763 | 26241 | #endif |
| | @@ -26829,11 +26307,11 @@ |
| 26829 | 26307 | if( p->db==0 ) return 1; |
| 26830 | 26308 | rc = sqlite3_prepare_v2(p->db, |
| 26831 | 26309 | "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", |
| 26832 | 26310 | -1, &pStmt, 0); |
| 26833 | 26311 | if( rc ){ |
| 26834 | | - eputf("error: %s\n", sqlite3_errmsg(p->db)); |
| 26312 | + sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db)); |
| 26835 | 26313 | sqlite3_finalize(pStmt); |
| 26836 | 26314 | return 1; |
| 26837 | 26315 | } |
| 26838 | 26316 | sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); |
| 26839 | 26317 | if( sqlite3_step(pStmt)==SQLITE_ROW |
| | @@ -26842,32 +26320,32 @@ |
| 26842 | 26320 | const u8 *pb = sqlite3_column_blob(pStmt,0); |
| 26843 | 26321 | shell_check_oom(pb); |
| 26844 | 26322 | memcpy(aHdr, pb, 100); |
| 26845 | 26323 | sqlite3_finalize(pStmt); |
| 26846 | 26324 | }else{ |
| 26847 | | - eputz("unable to read database header\n"); |
| 26325 | + sqlite3_fputs("unable to read database header\n", stderr); |
| 26848 | 26326 | sqlite3_finalize(pStmt); |
| 26849 | 26327 | return 1; |
| 26850 | 26328 | } |
| 26851 | 26329 | i = get2byteInt(aHdr+16); |
| 26852 | 26330 | if( i==1 ) i = 65536; |
| 26853 | | - oputf("%-20s %d\n", "database page size:", i); |
| 26854 | | - oputf("%-20s %d\n", "write format:", aHdr[18]); |
| 26855 | | - oputf("%-20s %d\n", "read format:", aHdr[19]); |
| 26856 | | - oputf("%-20s %d\n", "reserved bytes:", aHdr[20]); |
| 26331 | + sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i); |
| 26332 | + sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); |
| 26333 | + sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); |
| 26334 | + sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); |
| 26857 | 26335 | for(i=0; i<ArraySize(aField); i++){ |
| 26858 | 26336 | int ofst = aField[i].ofst; |
| 26859 | 26337 | unsigned int val = get4byteInt(aHdr + ofst); |
| 26860 | | - oputf("%-20s %u", aField[i].zName, val); |
| 26338 | + sqlite3_fprintf(p->out, "%-20s %u", aField[i].zName, val); |
| 26861 | 26339 | switch( ofst ){ |
| 26862 | 26340 | case 56: { |
| 26863 | | - if( val==1 ) oputz(" (utf8)"); |
| 26864 | | - if( val==2 ) oputz(" (utf16le)"); |
| 26865 | | - if( val==3 ) oputz(" (utf16be)"); |
| 26341 | + if( val==1 ) sqlite3_fputs(" (utf8)", p->out); |
| 26342 | + if( val==2 ) sqlite3_fputs(" (utf16le)", p->out); |
| 26343 | + if( val==3 ) sqlite3_fputs(" (utf16be)", p->out); |
| 26866 | 26344 | } |
| 26867 | 26345 | } |
| 26868 | | - oputz("\n"); |
| 26346 | + sqlite3_fputs("\n", p->out); |
| 26869 | 26347 | } |
| 26870 | 26348 | if( zDb==0 ){ |
| 26871 | 26349 | zSchemaTab = sqlite3_mprintf("main.sqlite_schema"); |
| 26872 | 26350 | }else if( cli_strcmp(zDb,"temp")==0 ){ |
| 26873 | 26351 | zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema"); |
| | @@ -26876,24 +26354,24 @@ |
| 26876 | 26354 | } |
| 26877 | 26355 | for(i=0; i<ArraySize(aQuery); i++){ |
| 26878 | 26356 | char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab); |
| 26879 | 26357 | int val = db_int(p->db, zSql); |
| 26880 | 26358 | sqlite3_free(zSql); |
| 26881 | | - oputf("%-20s %d\n", aQuery[i].zName, val); |
| 26359 | + sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); |
| 26882 | 26360 | } |
| 26883 | 26361 | sqlite3_free(zSchemaTab); |
| 26884 | 26362 | sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); |
| 26885 | | - oputf("%-20s %u\n", "data version", iDataVersion); |
| 26363 | + sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion); |
| 26886 | 26364 | return 0; |
| 26887 | 26365 | } |
| 26888 | 26366 | #endif /* SQLITE_SHELL_HAVE_RECOVER */ |
| 26889 | 26367 | |
| 26890 | 26368 | /* |
| 26891 | 26369 | ** Print the given string as an error message. |
| 26892 | 26370 | */ |
| 26893 | 26371 | static void shellEmitError(const char *zErr){ |
| 26894 | | - eputf("Error: %s\n", zErr); |
| 26372 | + sqlite3_fprintf(stderr,"Error: %s\n", zErr); |
| 26895 | 26373 | } |
| 26896 | 26374 | /* |
| 26897 | 26375 | ** Print the current sqlite3_errmsg() value to stderr and return 1. |
| 26898 | 26376 | */ |
| 26899 | 26377 | static int shellDatabaseError(sqlite3 *db){ |
| | @@ -27136,10 +26614,11 @@ |
| 27136 | 26614 | int bGroupByParent = 0; /* If -groupbyparent is present */ |
| 27137 | 26615 | int i; /* To iterate through azArg[] */ |
| 27138 | 26616 | const char *zIndent = ""; /* How much to indent CREATE INDEX by */ |
| 27139 | 26617 | int rc; /* Return code */ |
| 27140 | 26618 | sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ |
| 26619 | + FILE *out = pState->out; /* Send output here */ |
| 27141 | 26620 | |
| 27142 | 26621 | /* |
| 27143 | 26622 | ** This SELECT statement returns one row for each foreign key constraint |
| 27144 | 26623 | ** in the schema of the main database. The column values are: |
| 27145 | 26624 | ** |
| | @@ -27211,11 +26690,12 @@ |
| 27211 | 26690 | else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ |
| 27212 | 26691 | bGroupByParent = 1; |
| 27213 | 26692 | zIndent = " "; |
| 27214 | 26693 | } |
| 27215 | 26694 | else{ |
| 27216 | | - eputf("Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); |
| 26695 | + sqlite3_fprintf(stderr, |
| 26696 | + "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); |
| 27217 | 26697 | return SQLITE_ERROR; |
| 27218 | 26698 | } |
| 27219 | 26699 | } |
| 27220 | 26700 | |
| 27221 | 26701 | /* Register the fkey_collate_clause() SQL function */ |
| | @@ -27255,44 +26735,45 @@ |
| 27255 | 26735 | } |
| 27256 | 26736 | rc = sqlite3_finalize(pExplain); |
| 27257 | 26737 | if( rc!=SQLITE_OK ) break; |
| 27258 | 26738 | |
| 27259 | 26739 | if( res<0 ){ |
| 27260 | | - eputz("Error: internal error"); |
| 26740 | + sqlite3_fputs("Error: internal error", stderr); |
| 27261 | 26741 | break; |
| 27262 | 26742 | }else{ |
| 27263 | 26743 | if( bGroupByParent |
| 27264 | 26744 | && (bVerbose || res==0) |
| 27265 | 26745 | && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) |
| 27266 | 26746 | ){ |
| 27267 | | - oputf("-- Parent table %s\n", zParent); |
| 26747 | + sqlite3_fprintf(out, "-- Parent table %s\n", zParent); |
| 27268 | 26748 | sqlite3_free(zPrev); |
| 27269 | 26749 | zPrev = sqlite3_mprintf("%s", zParent); |
| 27270 | 26750 | } |
| 27271 | 26751 | |
| 27272 | 26752 | if( res==0 ){ |
| 27273 | | - oputf("%s%s --> %s\n", zIndent, zCI, zTarget); |
| 26753 | + sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); |
| 27274 | 26754 | }else if( bVerbose ){ |
| 27275 | | - oputf("%s/* no extra indexes required for %s -> %s */\n", |
| 26755 | + sqlite3_fprintf(out, |
| 26756 | + "%s/* no extra indexes required for %s -> %s */\n", |
| 27276 | 26757 | zIndent, zFrom, zTarget |
| 27277 | 26758 | ); |
| 27278 | 26759 | } |
| 27279 | 26760 | } |
| 27280 | 26761 | } |
| 27281 | 26762 | sqlite3_free(zPrev); |
| 27282 | 26763 | |
| 27283 | 26764 | if( rc!=SQLITE_OK ){ |
| 27284 | | - eputf("%s\n", sqlite3_errmsg(db)); |
| 26765 | + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); |
| 27285 | 26766 | } |
| 27286 | 26767 | |
| 27287 | 26768 | rc2 = sqlite3_finalize(pSql); |
| 27288 | 26769 | if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ |
| 27289 | 26770 | rc = rc2; |
| 27290 | | - eputf("%s\n", sqlite3_errmsg(db)); |
| 26771 | + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); |
| 27291 | 26772 | } |
| 27292 | 26773 | }else{ |
| 27293 | | - eputf("%s\n", sqlite3_errmsg(db)); |
| 26774 | + sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); |
| 27294 | 26775 | } |
| 27295 | 26776 | |
| 27296 | 26777 | return rc; |
| 27297 | 26778 | } |
| 27298 | 26779 | |
| | @@ -27308,13 +26789,13 @@ |
| 27308 | 26789 | n = (nArg>=2 ? strlen30(azArg[1]) : 0); |
| 27309 | 26790 | if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; |
| 27310 | 26791 | return lintFkeyIndexes(pState, azArg, nArg); |
| 27311 | 26792 | |
| 27312 | 26793 | usage: |
| 27313 | | - eputf("Usage %s sub-command ?switches...?\n", azArg[0]); |
| 27314 | | - eputz("Where sub-commands are:\n"); |
| 27315 | | - eputz(" fkey-indexes\n"); |
| 26794 | + sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]); |
| 26795 | + sqlite3_fprintf(stderr, "Where sub-commands are:\n"); |
| 26796 | + sqlite3_fprintf(stderr, " fkey-indexes\n"); |
| 27316 | 26797 | return SQLITE_ERROR; |
| 27317 | 26798 | } |
| 27318 | 26799 | |
| 27319 | 26800 | static void shellPrepare( |
| 27320 | 26801 | sqlite3 *db, |
| | @@ -27324,11 +26805,12 @@ |
| 27324 | 26805 | ){ |
| 27325 | 26806 | *ppStmt = 0; |
| 27326 | 26807 | if( *pRc==SQLITE_OK ){ |
| 27327 | 26808 | int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); |
| 27328 | 26809 | if( rc!=SQLITE_OK ){ |
| 27329 | | - eputf("sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); |
| 26810 | + sqlite3_fprintf(stderr, |
| 26811 | + "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); |
| 27330 | 26812 | *pRc = rc; |
| 27331 | 26813 | } |
| 27332 | 26814 | } |
| 27333 | 26815 | } |
| 27334 | 26816 | |
| | @@ -27368,11 +26850,11 @@ |
| 27368 | 26850 | if( pStmt ){ |
| 27369 | 26851 | sqlite3 *db = sqlite3_db_handle(pStmt); |
| 27370 | 26852 | int rc = sqlite3_finalize(pStmt); |
| 27371 | 26853 | if( *pRc==SQLITE_OK ){ |
| 27372 | 26854 | if( rc!=SQLITE_OK ){ |
| 27373 | | - eputf("SQL error: %s\n", sqlite3_errmsg(db)); |
| 26855 | + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); |
| 27374 | 26856 | } |
| 27375 | 26857 | *pRc = rc; |
| 27376 | 26858 | } |
| 27377 | 26859 | } |
| 27378 | 26860 | } |
| | @@ -27390,11 +26872,11 @@ |
| 27390 | 26872 | ){ |
| 27391 | 26873 | int rc = sqlite3_reset(pStmt); |
| 27392 | 26874 | if( *pRc==SQLITE_OK ){ |
| 27393 | 26875 | if( rc!=SQLITE_OK ){ |
| 27394 | 26876 | sqlite3 *db = sqlite3_db_handle(pStmt); |
| 27395 | | - eputf("SQL error: %s\n", sqlite3_errmsg(db)); |
| 26877 | + sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); |
| 27396 | 26878 | } |
| 27397 | 26879 | *pRc = rc; |
| 27398 | 26880 | } |
| 27399 | 26881 | } |
| 27400 | 26882 | #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ |
| | @@ -27419,10 +26901,11 @@ |
| 27419 | 26901 | char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ |
| 27420 | 26902 | const char *zFile; /* --file argument, or NULL */ |
| 27421 | 26903 | const char *zDir; /* --directory argument, or NULL */ |
| 27422 | 26904 | char **azArg; /* Array of command arguments */ |
| 27423 | 26905 | ShellState *p; /* Shell state */ |
| 26906 | + FILE *out; /* Output to this stream */ |
| 27424 | 26907 | sqlite3 *db; /* Database containing the archive */ |
| 27425 | 26908 | }; |
| 27426 | 26909 | |
| 27427 | 26910 | /* |
| 27428 | 26911 | ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. |
| | @@ -27442,13 +26925,13 @@ |
| 27442 | 26925 | va_start(ap, zFmt); |
| 27443 | 26926 | z = sqlite3_vmprintf(zFmt, ap); |
| 27444 | 26927 | va_end(ap); |
| 27445 | 26928 | shellEmitError(z); |
| 27446 | 26929 | if( pAr->fromCmdLine ){ |
| 27447 | | - eputz("Use \"-A\" for more help\n"); |
| 26930 | + sqlite3_fputs("Use \"-A\" for more help\n", stderr); |
| 27448 | 26931 | }else{ |
| 27449 | | - eputz("Use \".archive --help\" for more help\n"); |
| 26932 | + sqlite3_fputs("Use \".archive --help\" for more help\n", stderr); |
| 27450 | 26933 | } |
| 27451 | 26934 | sqlite3_free(z); |
| 27452 | 26935 | return SQLITE_ERROR; |
| 27453 | 26936 | } |
| 27454 | 26937 | |
| | @@ -27544,11 +27027,11 @@ |
| 27544 | 27027 | }; |
| 27545 | 27028 | int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); |
| 27546 | 27029 | struct ArSwitch *pEnd = &aSwitch[nSwitch]; |
| 27547 | 27030 | |
| 27548 | 27031 | if( nArg<=1 ){ |
| 27549 | | - eputz("Wrong number of arguments. Usage:\n"); |
| 27032 | + sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n"); |
| 27550 | 27033 | return arUsage(stderr); |
| 27551 | 27034 | }else{ |
| 27552 | 27035 | char *z = azArg[1]; |
| 27553 | 27036 | if( z[0]!='-' ){ |
| 27554 | 27037 | /* Traditional style [tar] invocation */ |
| | @@ -27650,11 +27133,11 @@ |
| 27650 | 27133 | } |
| 27651 | 27134 | } |
| 27652 | 27135 | } |
| 27653 | 27136 | } |
| 27654 | 27137 | if( pAr->eCmd==0 ){ |
| 27655 | | - eputz("Required argument missing. Usage:\n"); |
| 27138 | + sqlite3_fprintf(stderr, "Required argument missing. Usage:\n"); |
| 27656 | 27139 | return arUsage(stderr); |
| 27657 | 27140 | } |
| 27658 | 27141 | return SQLITE_OK; |
| 27659 | 27142 | } |
| 27660 | 27143 | |
| | @@ -27693,11 +27176,11 @@ |
| 27693 | 27176 | if( SQLITE_ROW==sqlite3_step(pTest) ){ |
| 27694 | 27177 | bOk = 1; |
| 27695 | 27178 | } |
| 27696 | 27179 | shellReset(&rc, pTest); |
| 27697 | 27180 | if( rc==SQLITE_OK && bOk==0 ){ |
| 27698 | | - eputf("not found in archive: %s\n", z); |
| 27181 | + sqlite3_fprintf(stderr,"not found in archive: %s\n", z); |
| 27699 | 27182 | rc = SQLITE_ERROR; |
| 27700 | 27183 | } |
| 27701 | 27184 | } |
| 27702 | 27185 | shellFinalize(&rc, pTest); |
| 27703 | 27186 | } |
| | @@ -27760,19 +27243,19 @@ |
| 27760 | 27243 | arWhereClause(&rc, pAr, &zWhere); |
| 27761 | 27244 | |
| 27762 | 27245 | shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], |
| 27763 | 27246 | pAr->zSrcTable, zWhere); |
| 27764 | 27247 | if( pAr->bDryRun ){ |
| 27765 | | - oputf("%s\n", sqlite3_sql(pSql)); |
| 27248 | + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); |
| 27766 | 27249 | }else{ |
| 27767 | 27250 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
| 27768 | 27251 | if( pAr->bVerbose ){ |
| 27769 | | - oputf("%s % 10d %s %s\n", |
| 27252 | + sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n", |
| 27770 | 27253 | sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1), |
| 27771 | 27254 | sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3)); |
| 27772 | 27255 | }else{ |
| 27773 | | - oputf("%s\n", sqlite3_column_text(pSql, 0)); |
| 27256 | + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); |
| 27774 | 27257 | } |
| 27775 | 27258 | } |
| 27776 | 27259 | } |
| 27777 | 27260 | shellFinalize(&rc, pSql); |
| 27778 | 27261 | sqlite3_free(zWhere); |
| | @@ -27795,11 +27278,11 @@ |
| 27795 | 27278 | } |
| 27796 | 27279 | if( rc==SQLITE_OK ){ |
| 27797 | 27280 | zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;", |
| 27798 | 27281 | pAr->zSrcTable, zWhere); |
| 27799 | 27282 | if( pAr->bDryRun ){ |
| 27800 | | - oputf("%s\n", zSql); |
| 27283 | + sqlite3_fprintf(pAr->out, "%s\n", zSql); |
| 27801 | 27284 | }else{ |
| 27802 | 27285 | char *zErr = 0; |
| 27803 | 27286 | rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0); |
| 27804 | 27287 | if( rc==SQLITE_OK ){ |
| 27805 | 27288 | rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); |
| | @@ -27808,11 +27291,11 @@ |
| 27808 | 27291 | }else{ |
| 27809 | 27292 | rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0); |
| 27810 | 27293 | } |
| 27811 | 27294 | } |
| 27812 | 27295 | if( zErr ){ |
| 27813 | | - sputf(stdout, "ERROR: %s\n", zErr); /* stdout? */ |
| 27296 | + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */ |
| 27814 | 27297 | sqlite3_free(zErr); |
| 27815 | 27298 | } |
| 27816 | 27299 | } |
| 27817 | 27300 | } |
| 27818 | 27301 | sqlite3_free(zWhere); |
| | @@ -27872,15 +27355,15 @@ |
| 27872 | 27355 | ** populating them changes the timestamp). */ |
| 27873 | 27356 | for(i=0; i<2; i++){ |
| 27874 | 27357 | j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); |
| 27875 | 27358 | sqlite3_bind_int(pSql, j, i); |
| 27876 | 27359 | if( pAr->bDryRun ){ |
| 27877 | | - oputf("%s\n", sqlite3_sql(pSql)); |
| 27360 | + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); |
| 27878 | 27361 | }else{ |
| 27879 | 27362 | while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ |
| 27880 | 27363 | if( i==0 && pAr->bVerbose ){ |
| 27881 | | - oputf("%s\n", sqlite3_column_text(pSql, 0)); |
| 27364 | + sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); |
| 27882 | 27365 | } |
| 27883 | 27366 | } |
| 27884 | 27367 | } |
| 27885 | 27368 | shellReset(&rc, pSql); |
| 27886 | 27369 | } |
| | @@ -27896,17 +27379,17 @@ |
| 27896 | 27379 | ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. |
| 27897 | 27380 | */ |
| 27898 | 27381 | static int arExecSql(ArCommand *pAr, const char *zSql){ |
| 27899 | 27382 | int rc; |
| 27900 | 27383 | if( pAr->bDryRun ){ |
| 27901 | | - oputf("%s\n", zSql); |
| 27384 | + sqlite3_fprintf(pAr->out, "%s\n", zSql); |
| 27902 | 27385 | rc = SQLITE_OK; |
| 27903 | 27386 | }else{ |
| 27904 | 27387 | char *zErr = 0; |
| 27905 | 27388 | rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); |
| 27906 | 27389 | if( zErr ){ |
| 27907 | | - sputf(stdout, "ERROR: %s\n", zErr); |
| 27390 | + sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); |
| 27908 | 27391 | sqlite3_free(zErr); |
| 27909 | 27392 | } |
| 27910 | 27393 | } |
| 27911 | 27394 | return rc; |
| 27912 | 27395 | } |
| | @@ -28051,10 +27534,11 @@ |
| 28051 | 27534 | cmd.fromCmdLine = fromCmdLine; |
| 28052 | 27535 | rc = arParseCommand(azArg, nArg, &cmd); |
| 28053 | 27536 | if( rc==SQLITE_OK ){ |
| 28054 | 27537 | int eDbType = SHELL_OPEN_UNSPEC; |
| 28055 | 27538 | cmd.p = pState; |
| 27539 | + cmd.out = pState->out; |
| 28056 | 27540 | cmd.db = pState->db; |
| 28057 | 27541 | if( cmd.zFile ){ |
| 28058 | 27542 | eDbType = deduceDatabaseType(cmd.zFile, 1); |
| 28059 | 27543 | }else{ |
| 28060 | 27544 | eDbType = pState->openMode; |
| | @@ -28077,17 +27561,18 @@ |
| 28077 | 27561 | }else{ |
| 28078 | 27562 | flags = SQLITE_OPEN_READONLY; |
| 28079 | 27563 | } |
| 28080 | 27564 | cmd.db = 0; |
| 28081 | 27565 | if( cmd.bDryRun ){ |
| 28082 | | - oputf("-- open database '%s'%s\n", cmd.zFile, |
| 27566 | + sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile, |
| 28083 | 27567 | eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); |
| 28084 | 27568 | } |
| 28085 | 27569 | rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, |
| 28086 | 27570 | eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); |
| 28087 | 27571 | if( rc!=SQLITE_OK ){ |
| 28088 | | - eputf("cannot open file: %s (%s)\n", cmd.zFile, sqlite3_errmsg(cmd.db)); |
| 27572 | + sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n", |
| 27573 | + cmd.zFile, sqlite3_errmsg(cmd.db)); |
| 28089 | 27574 | goto end_ar_command; |
| 28090 | 27575 | } |
| 28091 | 27576 | sqlite3_fileio_init(cmd.db, 0, 0); |
| 28092 | 27577 | sqlite3_sqlar_init(cmd.db, 0, 0); |
| 28093 | 27578 | sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p, |
| | @@ -28096,11 +27581,11 @@ |
| 28096 | 27581 | } |
| 28097 | 27582 | if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){ |
| 28098 | 27583 | if( cmd.eCmd!=AR_CMD_CREATE |
| 28099 | 27584 | && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) |
| 28100 | 27585 | ){ |
| 28101 | | - eputz("database does not contain an 'sqlar' table\n"); |
| 27586 | + sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n"); |
| 28102 | 27587 | rc = SQLITE_ERROR; |
| 28103 | 27588 | goto end_ar_command; |
| 28104 | 27589 | } |
| 28105 | 27590 | cmd.zSrcTable = sqlite3_mprintf("sqlar"); |
| 28106 | 27591 | } |
| | @@ -28154,11 +27639,11 @@ |
| 28154 | 27639 | ** This function is used as a callback by the recover extension. Simply |
| 28155 | 27640 | ** print the supplied SQL statement to stdout. |
| 28156 | 27641 | */ |
| 28157 | 27642 | static int recoverSqlCb(void *pCtx, const char *zSql){ |
| 28158 | 27643 | ShellState *pState = (ShellState*)pCtx; |
| 28159 | | - sputf(pState->out, "%s;\n", zSql); |
| 27644 | + sqlite3_fprintf(pState->out, "%s;\n", zSql); |
| 28160 | 27645 | return SQLITE_OK; |
| 28161 | 27646 | } |
| 28162 | 27647 | |
| 28163 | 27648 | /* |
| 28164 | 27649 | ** This function is called to recover data from the database. A script |
| | @@ -28197,11 +27682,11 @@ |
| 28197 | 27682 | }else |
| 28198 | 27683 | if( n<=10 && memcmp("-no-rowids", z, n)==0 ){ |
| 28199 | 27684 | bRowids = 0; |
| 28200 | 27685 | } |
| 28201 | 27686 | else{ |
| 28202 | | - eputf("unexpected option: %s\n", azArg[i]); |
| 27687 | + sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]); |
| 28203 | 27688 | showHelp(pState->out, azArg[0]); |
| 28204 | 27689 | return 1; |
| 28205 | 27690 | } |
| 28206 | 27691 | } |
| 28207 | 27692 | |
| | @@ -28216,11 +27701,11 @@ |
| 28216 | 27701 | |
| 28217 | 27702 | sqlite3_recover_run(p); |
| 28218 | 27703 | if( sqlite3_recover_errcode(p)!=SQLITE_OK ){ |
| 28219 | 27704 | const char *zErr = sqlite3_recover_errmsg(p); |
| 28220 | 27705 | int errCode = sqlite3_recover_errcode(p); |
| 28221 | | - eputf("sql error: %s (%d)\n", zErr, errCode); |
| 27706 | + sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode); |
| 28222 | 27707 | } |
| 28223 | 27708 | rc = sqlite3_recover_finish(p); |
| 28224 | 27709 | return rc; |
| 28225 | 27710 | } |
| 28226 | 27711 | #endif /* SQLITE_SHELL_HAVE_RECOVER */ |
| | @@ -28238,25 +27723,25 @@ |
| 28238 | 27723 | i64 nError = 0; |
| 28239 | 27724 | const char *zErr = 0; |
| 28240 | 27725 | while( SQLITE_OK==sqlite3_intck_step(p) ){ |
| 28241 | 27726 | const char *zMsg = sqlite3_intck_message(p); |
| 28242 | 27727 | if( zMsg ){ |
| 28243 | | - oputf("%s\n", zMsg); |
| 27728 | + sqlite3_fprintf(pState->out, "%s\n", zMsg); |
| 28244 | 27729 | nError++; |
| 28245 | 27730 | } |
| 28246 | 27731 | nStep++; |
| 28247 | 27732 | if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){ |
| 28248 | 27733 | sqlite3_intck_unlock(p); |
| 28249 | 27734 | } |
| 28250 | 27735 | } |
| 28251 | 27736 | rc = sqlite3_intck_error(p, &zErr); |
| 28252 | 27737 | if( zErr ){ |
| 28253 | | - eputf("%s\n", zErr); |
| 27738 | + sqlite3_fprintf(stderr,"%s\n", zErr); |
| 28254 | 27739 | } |
| 28255 | 27740 | sqlite3_intck_close(p); |
| 28256 | 27741 | |
| 28257 | | - oputf("%lld steps, %lld errors\n", nStep, nError); |
| 27742 | + sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError); |
| 28258 | 27743 | } |
| 28259 | 27744 | |
| 28260 | 27745 | return rc; |
| 28261 | 27746 | } |
| 28262 | 27747 | |
| | @@ -28275,11 +27760,11 @@ |
| 28275 | 27760 | */ |
| 28276 | 27761 | #ifdef SHELL_DEBUG |
| 28277 | 27762 | #define rc_err_oom_die(rc) \ |
| 28278 | 27763 | if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ |
| 28279 | 27764 | else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ |
| 28280 | | - eputf("E:%d\n",rc), assert(0) |
| 27765 | + sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0) |
| 28281 | 27766 | #else |
| 28282 | 27767 | static void rc_err_oom_die(int rc){ |
| 28283 | 27768 | if( rc==SQLITE_NOMEM ) shell_check_oom(0); |
| 28284 | 27769 | assert(rc==SQLITE_OK||rc==SQLITE_DONE); |
| 28285 | 27770 | } |
| | @@ -28492,12 +27977,13 @@ |
| 28492 | 27977 | shellPreparePrintf(p->db, &rc, &pStmt, |
| 28493 | 27978 | "SELECT 1 FROM sqlite_schema o WHERE " |
| 28494 | 27979 | "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true" |
| 28495 | 27980 | ); |
| 28496 | 27981 | if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 28497 | | - oputz("/* WARNING: " |
| 28498 | | - "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n" |
| 27982 | + sqlite3_fputs("/* WARNING: " |
| 27983 | + "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n", |
| 27984 | + p->out |
| 28499 | 27985 | ); |
| 28500 | 27986 | } |
| 28501 | 27987 | shellFinalize(&rc, pStmt); |
| 28502 | 27988 | return rc; |
| 28503 | 27989 | } |
| | @@ -28524,16 +28010,18 @@ |
| 28524 | 28010 | return SQLITE_OK; |
| 28525 | 28011 | } |
| 28526 | 28012 | if( faultsim_state.iCnt ){ |
| 28527 | 28013 | if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--; |
| 28528 | 28014 | if( faultsim_state.eVerbose>=2 ){ |
| 28529 | | - oputf("FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); |
| 28015 | + sqlite3_fprintf(stdout, |
| 28016 | + "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); |
| 28530 | 28017 | } |
| 28531 | 28018 | return SQLITE_OK; |
| 28532 | 28019 | } |
| 28533 | 28020 | if( faultsim_state.eVerbose>=1 ){ |
| 28534 | | - oputf("FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); |
| 28021 | + sqlite3_fprintf(stdout, |
| 28022 | + "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); |
| 28535 | 28023 | } |
| 28536 | 28024 | faultsim_state.iCnt = faultsim_state.iInterval; |
| 28537 | 28025 | faultsim_state.nHit++; |
| 28538 | 28026 | if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){ |
| 28539 | 28027 | faultsim_state.iCnt = -1; |
| | @@ -28592,11 +28080,11 @@ |
| 28592 | 28080 | clearTempFile(p); |
| 28593 | 28081 | |
| 28594 | 28082 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 28595 | 28083 | if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){ |
| 28596 | 28084 | if( nArg!=2 ){ |
| 28597 | | - eputz("Usage: .auth ON|OFF\n"); |
| 28085 | + sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n"); |
| 28598 | 28086 | rc = 1; |
| 28599 | 28087 | goto meta_command_exit; |
| 28600 | 28088 | } |
| 28601 | 28089 | open_db(p, 0); |
| 28602 | 28090 | if( booleanValue(azArg[1]) ){ |
| | @@ -28639,32 +28127,32 @@ |
| 28639 | 28127 | }else |
| 28640 | 28128 | if( cli_strcmp(z, "-async")==0 ){ |
| 28641 | 28129 | bAsync = 1; |
| 28642 | 28130 | }else |
| 28643 | 28131 | { |
| 28644 | | - eputf("unknown option: %s\n", azArg[j]); |
| 28132 | + sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]); |
| 28645 | 28133 | return 1; |
| 28646 | 28134 | } |
| 28647 | 28135 | }else if( zDestFile==0 ){ |
| 28648 | 28136 | zDestFile = azArg[j]; |
| 28649 | 28137 | }else if( zDb==0 ){ |
| 28650 | 28138 | zDb = zDestFile; |
| 28651 | 28139 | zDestFile = azArg[j]; |
| 28652 | 28140 | }else{ |
| 28653 | | - eputz("Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); |
| 28141 | + sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); |
| 28654 | 28142 | return 1; |
| 28655 | 28143 | } |
| 28656 | 28144 | } |
| 28657 | 28145 | if( zDestFile==0 ){ |
| 28658 | | - eputz("missing FILENAME argument on .backup\n"); |
| 28146 | + sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n"); |
| 28659 | 28147 | return 1; |
| 28660 | 28148 | } |
| 28661 | 28149 | if( zDb==0 ) zDb = "main"; |
| 28662 | 28150 | rc = sqlite3_open_v2(zDestFile, &pDest, |
| 28663 | 28151 | SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); |
| 28664 | 28152 | if( rc!=SQLITE_OK ){ |
| 28665 | | - eputf("Error: cannot open \"%s\"\n", zDestFile); |
| 28153 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile); |
| 28666 | 28154 | close_db(pDest); |
| 28667 | 28155 | return 1; |
| 28668 | 28156 | } |
| 28669 | 28157 | if( bAsync ){ |
| 28670 | 28158 | sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;", |
| | @@ -28698,21 +28186,12 @@ |
| 28698 | 28186 | } |
| 28699 | 28187 | }else |
| 28700 | 28188 | |
| 28701 | 28189 | /* Undocumented. Legacy only. See "crnl" below */ |
| 28702 | 28190 | if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ |
| 28703 | | - if( nArg==2 ){ |
| 28704 | | - if( booleanValue(azArg[1]) ){ |
| 28705 | | - setBinaryMode(p->out, 1); |
| 28706 | | - }else{ |
| 28707 | | - setTextMode(p->out, 1); |
| 28708 | | - } |
| 28709 | | - }else{ |
| 28710 | | - eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n" |
| 28711 | | - "Usage: .binary on|off\n"); |
| 28712 | | - rc = 1; |
| 28713 | | - } |
| 28191 | + eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n"); |
| 28192 | + rc = 1; |
| 28714 | 28193 | }else |
| 28715 | 28194 | |
| 28716 | 28195 | /* The undocumented ".breakpoint" command causes a call to the no-op |
| 28717 | 28196 | ** routine named test_breakpoint(). |
| 28718 | 28197 | */ |
| | @@ -28730,11 +28209,11 @@ |
| 28730 | 28209 | sqlite3_free(z); |
| 28731 | 28210 | #else |
| 28732 | 28211 | rc = chdir(azArg[1]); |
| 28733 | 28212 | #endif |
| 28734 | 28213 | if( rc ){ |
| 28735 | | - eputf("Cannot change to directory \"%s\"\n", azArg[1]); |
| 28214 | + sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]); |
| 28736 | 28215 | rc = 1; |
| 28737 | 28216 | } |
| 28738 | 28217 | }else{ |
| 28739 | 28218 | eputz("Usage: .cd DIRECTORY\n"); |
| 28740 | 28219 | rc = 1; |
| | @@ -28763,15 +28242,16 @@ |
| 28763 | 28242 | eputz("Usage: .check GLOB-PATTERN\n"); |
| 28764 | 28243 | rc = 2; |
| 28765 | 28244 | }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ |
| 28766 | 28245 | rc = 2; |
| 28767 | 28246 | }else if( testcase_glob(azArg[1],zRes)==0 ){ |
| 28768 | | - eputf("testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", |
| 28247 | + sqlite3_fprintf(stderr, |
| 28248 | + "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", |
| 28769 | 28249 | p->zTestcase, azArg[1], zRes); |
| 28770 | 28250 | rc = 1; |
| 28771 | 28251 | }else{ |
| 28772 | | - oputf("testcase-%s ok\n", p->zTestcase); |
| 28252 | + sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase); |
| 28773 | 28253 | p->nCheck++; |
| 28774 | 28254 | } |
| 28775 | 28255 | sqlite3_free(zRes); |
| 28776 | 28256 | }else |
| 28777 | 28257 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
| | @@ -28800,13 +28280,13 @@ |
| 28800 | 28280 | zFile = "(memory)"; |
| 28801 | 28281 | }else if( zFile[0]==0 ){ |
| 28802 | 28282 | zFile = "(temporary-file)"; |
| 28803 | 28283 | } |
| 28804 | 28284 | if( p->pAuxDb == &p->aAuxDb[i] ){ |
| 28805 | | - sputf(stdout, "ACTIVE %d: %s\n", i, zFile); |
| 28285 | + sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile); |
| 28806 | 28286 | }else if( p->aAuxDb[i].db!=0 ){ |
| 28807 | | - sputf(stdout, " %d: %s\n", i, zFile); |
| 28287 | + sqlite3_fprintf(stdout, " %d: %s\n", i, zFile); |
| 28808 | 28288 | } |
| 28809 | 28289 | } |
| 28810 | 28290 | }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ |
| 28811 | 28291 | int i = azArg[1][0] - '0'; |
| 28812 | 28292 | if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){ |
| | @@ -28833,23 +28313,25 @@ |
| 28833 | 28313 | rc = 1; |
| 28834 | 28314 | } |
| 28835 | 28315 | }else |
| 28836 | 28316 | |
| 28837 | 28317 | if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){ |
| 28318 | +#if !defined(_WIN32) || defined(SQLITE_U8TEXT_ONLY) \ |
| 28319 | + || defined(SQLITE_U8TEXT_STDIO) |
| 28320 | + sqlite3_fputs("The \".crnl\" command is disable in this build.\n", p->out); |
| 28321 | +#else |
| 28838 | 28322 | if( nArg==2 ){ |
| 28839 | 28323 | if( booleanValue(azArg[1]) ){ |
| 28840 | | - setTextMode(p->out, 1); |
| 28841 | | - }else{ |
| 28842 | | - setBinaryMode(p->out, 1); |
| 28843 | | - } |
| 28844 | | - }else{ |
| 28845 | | -#if !defined(_WIN32) && !defined(WIN32) |
| 28846 | | - eputz("The \".crnl\" is a no-op on non-Windows machines.\n"); |
| 28847 | | -#endif |
| 28324 | + sqlite3_fsetmode(p->out, _O_TEXT); |
| 28325 | + }else{ |
| 28326 | + sqlite3_fsetmode(p->out, _O_BINARY); |
| 28327 | + } |
| 28328 | + }else{ |
| 28848 | 28329 | eputz("Usage: .crnl on|off\n"); |
| 28849 | 28330 | rc = 1; |
| 28850 | 28331 | } |
| 28332 | +#endif |
| 28851 | 28333 | }else |
| 28852 | 28334 | |
| 28853 | 28335 | if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){ |
| 28854 | 28336 | char **azName = 0; |
| 28855 | 28337 | int nName = 0; |
| | @@ -28875,11 +28357,11 @@ |
| 28875 | 28357 | sqlite3_finalize(pStmt); |
| 28876 | 28358 | for(i=0; i<nName; i++){ |
| 28877 | 28359 | int eTxn = sqlite3_txn_state(p->db, azName[i*2]); |
| 28878 | 28360 | int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]); |
| 28879 | 28361 | const char *z = azName[i*2+1]; |
| 28880 | | - oputf("%s: %s %s%s\n", |
| 28362 | + sqlite3_fprintf(p->out, "%s: %s %s%s\n", |
| 28881 | 28363 | azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w", |
| 28882 | 28364 | eTxn==SQLITE_TXN_NONE ? "" : |
| 28883 | 28365 | eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn"); |
| 28884 | 28366 | free(azName[i*2]); |
| 28885 | 28367 | free(azName[i*2+1]); |
| | @@ -28917,15 +28399,16 @@ |
| 28917 | 28399 | if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; |
| 28918 | 28400 | if( nArg>=3 ){ |
| 28919 | 28401 | sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); |
| 28920 | 28402 | } |
| 28921 | 28403 | sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); |
| 28922 | | - oputf("%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off"); |
| 28404 | + sqlite3_fprintf(p->out, "%19s %s\n", |
| 28405 | + aDbConfig[ii].zName, v ? "on" : "off"); |
| 28923 | 28406 | if( nArg>1 ) break; |
| 28924 | 28407 | } |
| 28925 | 28408 | if( nArg>1 && ii==ArraySize(aDbConfig) ){ |
| 28926 | | - eputf("Error: unknown dbconfig \"%s\"\n", azArg[1]); |
| 28409 | + sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]); |
| 28927 | 28410 | eputz("Enter \".dbconfig\" with no arguments for a list\n"); |
| 28928 | 28411 | } |
| 28929 | 28412 | }else |
| 28930 | 28413 | |
| 28931 | 28414 | #if SQLITE_SHELL_HAVE_RECOVER |
| | @@ -28971,11 +28454,12 @@ |
| 28971 | 28454 | }else |
| 28972 | 28455 | if( cli_strcmp(z,"nosys")==0 ){ |
| 28973 | 28456 | ShellSetFlag(p, SHFLG_DumpNoSys); |
| 28974 | 28457 | }else |
| 28975 | 28458 | { |
| 28976 | | - eputf("Unknown option \"%s\" on \".dump\"\n", azArg[i]); |
| 28459 | + sqlite3_fprintf(stderr, |
| 28460 | + "Unknown option \"%s\" on \".dump\"\n", azArg[i]); |
| 28977 | 28461 | rc = 1; |
| 28978 | 28462 | sqlite3_free(zLike); |
| 28979 | 28463 | goto meta_command_exit; |
| 28980 | 28464 | } |
| 28981 | 28465 | }else{ |
| | @@ -29006,12 +28490,12 @@ |
| 29006 | 28490 | outputDumpWarning(p, zLike); |
| 29007 | 28491 | if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ |
| 29008 | 28492 | /* When playing back a "dump", the content might appear in an order |
| 29009 | 28493 | ** which causes immediate foreign key constraints to be violated. |
| 29010 | 28494 | ** So disable foreign-key constraint enforcement to prevent problems. */ |
| 29011 | | - oputz("PRAGMA foreign_keys=OFF;\n"); |
| 29012 | | - oputz("BEGIN TRANSACTION;\n"); |
| 28495 | + sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out); |
| 28496 | + sqlite3_fputs("BEGIN TRANSACTION;\n", p->out); |
| 29013 | 28497 | } |
| 29014 | 28498 | p->writableSchema = 0; |
| 29015 | 28499 | p->showHeader = 0; |
| 29016 | 28500 | /* Set writable_schema=ON since doing so forces SQLite to initialize |
| 29017 | 28501 | ** as much of the schema as it can even if the sqlite_schema table is |
| | @@ -29039,17 +28523,17 @@ |
| 29039 | 28523 | run_table_dump_query(p, zSql); |
| 29040 | 28524 | sqlite3_free(zSql); |
| 29041 | 28525 | } |
| 29042 | 28526 | sqlite3_free(zLike); |
| 29043 | 28527 | if( p->writableSchema ){ |
| 29044 | | - oputz("PRAGMA writable_schema=OFF;\n"); |
| 28528 | + sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out); |
| 29045 | 28529 | p->writableSchema = 0; |
| 29046 | 28530 | } |
| 29047 | 28531 | sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); |
| 29048 | 28532 | sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); |
| 29049 | 28533 | if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ |
| 29050 | | - oputz(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n"); |
| 28534 | + sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out); |
| 29051 | 28535 | } |
| 29052 | 28536 | p->showHeader = savedShowHeader; |
| 29053 | 28537 | p->shellFlgs = savedShellFlags; |
| 29054 | 28538 | }else |
| 29055 | 28539 | |
| | @@ -29125,11 +28609,12 @@ |
| 29125 | 28609 | }else |
| 29126 | 28610 | |
| 29127 | 28611 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 29128 | 28612 | if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ |
| 29129 | 28613 | if( p->bSafeMode ){ |
| 29130 | | - eputf("Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 28614 | + sqlite3_fprintf(stderr, |
| 28615 | + "Cannot run experimental commands such as \"%s\" in safe mode\n", |
| 29131 | 28616 | azArg[0]); |
| 29132 | 28617 | rc = 1; |
| 29133 | 28618 | }else{ |
| 29134 | 28619 | open_db(p, 0); |
| 29135 | 28620 | expertDotCommand(p, azArg, nArg); |
| | @@ -29182,13 +28667,14 @@ |
| 29182 | 28667 | if( zCmd[0]=='-' && zCmd[1] ) zCmd++; |
| 29183 | 28668 | } |
| 29184 | 28669 | |
| 29185 | 28670 | /* --help lists all file-controls */ |
| 29186 | 28671 | if( cli_strcmp(zCmd,"help")==0 ){ |
| 29187 | | - oputz("Available file-controls:\n"); |
| 28672 | + sqlite3_fputs("Available file-controls:\n", p->out); |
| 29188 | 28673 | for(i=0; i<ArraySize(aCtrl); i++){ |
| 29189 | | - oputf(" .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
| 28674 | + sqlite3_fprintf(p->out, |
| 28675 | + " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
| 29190 | 28676 | } |
| 29191 | 28677 | rc = 1; |
| 29192 | 28678 | goto meta_command_exit; |
| 29193 | 28679 | } |
| 29194 | 28680 | |
| | @@ -29199,19 +28685,19 @@ |
| 29199 | 28685 | if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ |
| 29200 | 28686 | if( filectrl<0 ){ |
| 29201 | 28687 | filectrl = aCtrl[i].ctrlCode; |
| 29202 | 28688 | iCtrl = i; |
| 29203 | 28689 | }else{ |
| 29204 | | - eputf("Error: ambiguous file-control: \"%s\"\n" |
| 28690 | + sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n" |
| 29205 | 28691 | "Use \".filectrl --help\" for help\n", zCmd); |
| 29206 | 28692 | rc = 1; |
| 29207 | 28693 | goto meta_command_exit; |
| 29208 | 28694 | } |
| 29209 | 28695 | } |
| 29210 | 28696 | } |
| 29211 | 28697 | if( filectrl<0 ){ |
| 29212 | | - eputf("Error: unknown file-control: %s\n" |
| 28698 | + sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n" |
| 29213 | 28699 | "Use \".filectrl --help\" for help\n", zCmd); |
| 29214 | 28700 | }else{ |
| 29215 | 28701 | switch(filectrl){ |
| 29216 | 28702 | case SQLITE_FCNTL_SIZE_LIMIT: { |
| 29217 | 28703 | if( nArg!=2 && nArg!=3 ) break; |
| | @@ -29251,11 +28737,11 @@ |
| 29251 | 28737 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 29252 | 28738 | char *z = 0; |
| 29253 | 28739 | if( nArg!=2 ) break; |
| 29254 | 28740 | sqlite3_file_control(p->db, zSchema, filectrl, &z); |
| 29255 | 28741 | if( z ){ |
| 29256 | | - oputf("%s\n", z); |
| 28742 | + sqlite3_fprintf(p->out, "%s\n", z); |
| 29257 | 28743 | sqlite3_free(z); |
| 29258 | 28744 | } |
| 29259 | 28745 | isOk = 2; |
| 29260 | 28746 | break; |
| 29261 | 28747 | } |
| | @@ -29265,23 +28751,24 @@ |
| 29265 | 28751 | x = atoi(azArg[2]); |
| 29266 | 28752 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
| 29267 | 28753 | } |
| 29268 | 28754 | x = -1; |
| 29269 | 28755 | sqlite3_file_control(p->db, zSchema, filectrl, &x); |
| 29270 | | - oputf("%d\n", x); |
| 28756 | + sqlite3_fprintf(p->out, "%d\n", x); |
| 29271 | 28757 | isOk = 2; |
| 29272 | 28758 | break; |
| 29273 | 28759 | } |
| 29274 | 28760 | } |
| 29275 | 28761 | } |
| 29276 | 28762 | if( isOk==0 && iCtrl>=0 ){ |
| 29277 | | - oputf("Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); |
| 28763 | + sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n", |
| 28764 | + zCmd, aCtrl[iCtrl].zUsage); |
| 29278 | 28765 | rc = 1; |
| 29279 | 28766 | }else if( isOk==1 ){ |
| 29280 | 28767 | char zBuf[100]; |
| 29281 | 28768 | sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes); |
| 29282 | | - oputf("%s\n", zBuf); |
| 28769 | + sqlite3_fprintf(p->out, "%s\n", zBuf); |
| 29283 | 28770 | } |
| 29284 | 28771 | }else |
| 29285 | 28772 | |
| 29286 | 28773 | if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){ |
| 29287 | 28774 | ShellState data; |
| | @@ -29318,19 +28805,19 @@ |
| 29318 | 28805 | doStats = sqlite3_step(pStmt)==SQLITE_ROW; |
| 29319 | 28806 | sqlite3_finalize(pStmt); |
| 29320 | 28807 | } |
| 29321 | 28808 | } |
| 29322 | 28809 | if( doStats==0 ){ |
| 29323 | | - oputz("/* No STAT tables available */\n"); |
| 28810 | + sqlite3_fputs("/* No STAT tables available */\n", p->out); |
| 29324 | 28811 | }else{ |
| 29325 | | - oputz("ANALYZE sqlite_schema;\n"); |
| 28812 | + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); |
| 29326 | 28813 | data.cMode = data.mode = MODE_Insert; |
| 29327 | 28814 | data.zDestTable = "sqlite_stat1"; |
| 29328 | 28815 | shell_exec(&data, "SELECT * FROM sqlite_stat1", 0); |
| 29329 | 28816 | data.zDestTable = "sqlite_stat4"; |
| 29330 | 28817 | shell_exec(&data, "SELECT * FROM sqlite_stat4", 0); |
| 29331 | | - oputz("ANALYZE sqlite_schema;\n"); |
| 28818 | + sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); |
| 29332 | 28819 | } |
| 29333 | 28820 | }else |
| 29334 | 28821 | |
| 29335 | 28822 | if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){ |
| 29336 | 28823 | if( nArg==2 ){ |
| | @@ -29344,11 +28831,11 @@ |
| 29344 | 28831 | |
| 29345 | 28832 | if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){ |
| 29346 | 28833 | if( nArg>=2 ){ |
| 29347 | 28834 | n = showHelp(p->out, azArg[1]); |
| 29348 | 28835 | if( n==0 ){ |
| 29349 | | - oputf("Nothing matches '%s'\n", azArg[1]); |
| 28836 | + sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]); |
| 29350 | 28837 | } |
| 29351 | 28838 | }else{ |
| 29352 | 28839 | showHelp(p->out, 0); |
| 29353 | 28840 | } |
| 29354 | 28841 | }else |
| | @@ -29387,11 +28874,11 @@ |
| 29387 | 28874 | if( zFile==0 ){ |
| 29388 | 28875 | zFile = z; |
| 29389 | 28876 | }else if( zTable==0 ){ |
| 29390 | 28877 | zTable = z; |
| 29391 | 28878 | }else{ |
| 29392 | | - oputf("ERROR: extra argument: \"%s\". Usage:\n", z); |
| 28879 | + sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z); |
| 29393 | 28880 | showHelp(p->out, "import"); |
| 29394 | 28881 | goto meta_command_exit; |
| 29395 | 28882 | } |
| 29396 | 28883 | }else if( cli_strcmp(z,"-v")==0 ){ |
| 29397 | 28884 | eVerbose++; |
| | @@ -29408,17 +28895,17 @@ |
| 29408 | 28895 | sCtx.cColSep = ','; |
| 29409 | 28896 | sCtx.cRowSep = '\n'; |
| 29410 | 28897 | xRead = csv_read_one_field; |
| 29411 | 28898 | useOutputMode = 0; |
| 29412 | 28899 | }else{ |
| 29413 | | - oputf("ERROR: unknown option: \"%s\". Usage:\n", z); |
| 28900 | + sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z); |
| 29414 | 28901 | showHelp(p->out, "import"); |
| 29415 | 28902 | goto meta_command_exit; |
| 29416 | 28903 | } |
| 29417 | 28904 | } |
| 29418 | 28905 | if( zTable==0 ){ |
| 29419 | | - oputf("ERROR: missing %s argument. Usage:\n", |
| 28906 | + sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n", |
| 29420 | 28907 | zFile==0 ? "FILE" : "TABLE"); |
| 29421 | 28908 | showHelp(p->out, "import"); |
| 29422 | 28909 | goto meta_command_exit; |
| 29423 | 28910 | } |
| 29424 | 28911 | seenInterrupt = 0; |
| | @@ -29464,32 +28951,32 @@ |
| 29464 | 28951 | if( sCtx.zFile[0]=='|' ){ |
| 29465 | 28952 | #ifdef SQLITE_OMIT_POPEN |
| 29466 | 28953 | eputz("Error: pipes are not supported in this OS\n"); |
| 29467 | 28954 | goto meta_command_exit; |
| 29468 | 28955 | #else |
| 29469 | | - sCtx.in = popen(sCtx.zFile+1, "r"); |
| 28956 | + sCtx.in = sqlite3_popen(sCtx.zFile+1, "r"); |
| 29470 | 28957 | sCtx.zFile = "<pipe>"; |
| 29471 | 28958 | sCtx.xCloser = pclose; |
| 29472 | 28959 | #endif |
| 29473 | 28960 | }else{ |
| 29474 | | - sCtx.in = fopen(sCtx.zFile, "rb"); |
| 28961 | + sCtx.in = sqlite3_fopen(sCtx.zFile, "rb"); |
| 29475 | 28962 | sCtx.xCloser = fclose; |
| 29476 | 28963 | } |
| 29477 | 28964 | if( sCtx.in==0 ){ |
| 29478 | | - eputf("Error: cannot open \"%s\"\n", zFile); |
| 28965 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); |
| 29479 | 28966 | goto meta_command_exit; |
| 29480 | 28967 | } |
| 29481 | 28968 | if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ |
| 29482 | 28969 | char zSep[2]; |
| 29483 | 28970 | zSep[1] = 0; |
| 29484 | 28971 | zSep[0] = sCtx.cColSep; |
| 29485 | | - oputz("Column separator "); |
| 29486 | | - output_c_string(zSep); |
| 29487 | | - oputz(", row separator "); |
| 28972 | + sqlite3_fputs("Column separator ", p->out); |
| 28973 | + output_c_string(p->out, zSep); |
| 28974 | + sqlite3_fputs(", row separator ", p->out); |
| 29488 | 28975 | zSep[0] = sCtx.cRowSep; |
| 29489 | | - output_c_string(zSep); |
| 29490 | | - oputz("\n"); |
| 28976 | + output_c_string(p->out, zSep); |
| 28977 | + sqlite3_fputs("\n", p->out); |
| 29491 | 28978 | } |
| 29492 | 28979 | sCtx.z = sqlite3_malloc64(120); |
| 29493 | 28980 | if( sCtx.z==0 ){ |
| 29494 | 28981 | import_cleanup(&sCtx); |
| 29495 | 28982 | shell_out_of_memory(); |
| | @@ -29510,18 +28997,18 @@ |
| 29510 | 28997 | zAutoColumn(sCtx.z, &dbCols, 0); |
| 29511 | 28998 | if( sCtx.cTerm!=sCtx.cColSep ) break; |
| 29512 | 28999 | } |
| 29513 | 29000 | zColDefs = zAutoColumn(0, &dbCols, &zRenames); |
| 29514 | 29001 | if( zRenames!=0 ){ |
| 29515 | | - sputf((stdin_is_interactive && p->in==stdin)? p->out : stderr, |
| 29002 | + sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr, |
| 29516 | 29003 | "Columns renamed during .import %s due to duplicates:\n" |
| 29517 | 29004 | "%s\n", sCtx.zFile, zRenames); |
| 29518 | 29005 | sqlite3_free(zRenames); |
| 29519 | 29006 | } |
| 29520 | 29007 | assert(dbCols==0); |
| 29521 | 29008 | if( zColDefs==0 ){ |
| 29522 | | - eputf("%s: empty file\n", sCtx.zFile); |
| 29009 | + sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile); |
| 29523 | 29010 | import_cleanup(&sCtx); |
| 29524 | 29011 | rc = 1; |
| 29525 | 29012 | sqlite3_free(zCreate); |
| 29526 | 29013 | goto meta_command_exit; |
| 29527 | 29014 | } |
| | @@ -29529,17 +29016,20 @@ |
| 29529 | 29016 | if( zCreate==0 ){ |
| 29530 | 29017 | import_cleanup(&sCtx); |
| 29531 | 29018 | shell_out_of_memory(); |
| 29532 | 29019 | } |
| 29533 | 29020 | if( eVerbose>=1 ){ |
| 29534 | | - oputf("%s\n", zCreate); |
| 29021 | + sqlite3_fprintf(p->out, "%s\n", zCreate); |
| 29535 | 29022 | } |
| 29536 | 29023 | rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); |
| 29024 | + if( rc ){ |
| 29025 | + sqlite3_fprintf(stderr, |
| 29026 | + "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); |
| 29027 | + } |
| 29537 | 29028 | sqlite3_free(zCreate); |
| 29538 | 29029 | zCreate = 0; |
| 29539 | 29030 | if( rc ){ |
| 29540 | | - eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); |
| 29541 | 29031 | import_cleanup(&sCtx); |
| 29542 | 29032 | rc = 1; |
| 29543 | 29033 | goto meta_command_exit; |
| 29544 | 29034 | } |
| 29545 | 29035 | } |
| | @@ -29590,11 +29080,11 @@ |
| 29590 | 29080 | } |
| 29591 | 29081 | zSql[j++] = ')'; |
| 29592 | 29082 | zSql[j] = 0; |
| 29593 | 29083 | assert( j<nByte ); |
| 29594 | 29084 | if( eVerbose>=2 ){ |
| 29595 | | - oputf("Insert using: %s\n", zSql); |
| 29085 | + sqlite3_fprintf(p->out, "Insert using: %s\n", zSql); |
| 29596 | 29086 | } |
| 29597 | 29087 | rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 29598 | 29088 | sqlite3_free(zSql); |
| 29599 | 29089 | zSql = 0; |
| 29600 | 29090 | if( rc ){ |
| | @@ -29629,11 +29119,11 @@ |
| 29629 | 29119 | if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){ |
| 29630 | 29120 | z = ""; |
| 29631 | 29121 | } |
| 29632 | 29122 | sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); |
| 29633 | 29123 | if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ |
| 29634 | | - eputf("%s:%d: expected %d columns but found %d" |
| 29124 | + sqlite3_fprintf(stderr,"%s:%d: expected %d columns but found %d" |
| 29635 | 29125 | " - filling the rest with NULL\n", |
| 29636 | 29126 | sCtx.zFile, startLine, nCol, i+1); |
| 29637 | 29127 | i += 2; |
| 29638 | 29128 | while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } |
| 29639 | 29129 | } |
| | @@ -29641,18 +29131,19 @@ |
| 29641 | 29131 | if( sCtx.cTerm==sCtx.cColSep ){ |
| 29642 | 29132 | do{ |
| 29643 | 29133 | xRead(&sCtx); |
| 29644 | 29134 | i++; |
| 29645 | 29135 | }while( sCtx.cTerm==sCtx.cColSep ); |
| 29646 | | - eputf("%s:%d: expected %d columns but found %d - extras ignored\n", |
| 29136 | + sqlite3_fprintf(stderr, |
| 29137 | + "%s:%d: expected %d columns but found %d - extras ignored\n", |
| 29647 | 29138 | sCtx.zFile, startLine, nCol, i); |
| 29648 | 29139 | } |
| 29649 | 29140 | if( i>=nCol ){ |
| 29650 | 29141 | sqlite3_step(pStmt); |
| 29651 | 29142 | rc = sqlite3_reset(pStmt); |
| 29652 | 29143 | if( rc!=SQLITE_OK ){ |
| 29653 | | - eputf("%s:%d: INSERT failed: %s\n", |
| 29144 | + sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n", |
| 29654 | 29145 | sCtx.zFile, startLine, sqlite3_errmsg(p->db)); |
| 29655 | 29146 | sCtx.nErr++; |
| 29656 | 29147 | }else{ |
| 29657 | 29148 | sCtx.nRow++; |
| 29658 | 29149 | } |
| | @@ -29661,11 +29152,12 @@ |
| 29661 | 29152 | |
| 29662 | 29153 | import_cleanup(&sCtx); |
| 29663 | 29154 | sqlite3_finalize(pStmt); |
| 29664 | 29155 | if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); |
| 29665 | 29156 | if( eVerbose>0 ){ |
| 29666 | | - oputf("Added %d rows with %d errors using %d lines of input\n", |
| 29157 | + sqlite3_fprintf(p->out, |
| 29158 | + "Added %d rows with %d errors using %d lines of input\n", |
| 29667 | 29159 | sCtx.nRow, sCtx.nErr, sCtx.nLine-1); |
| 29668 | 29160 | } |
| 29669 | 29161 | }else |
| 29670 | 29162 | #endif /* !defined(SQLITE_SHELL_FIDDLE) */ |
| 29671 | 29163 | |
| | @@ -29677,11 +29169,11 @@ |
| 29677 | 29169 | int tnum = 0; |
| 29678 | 29170 | int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ |
| 29679 | 29171 | int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ |
| 29680 | 29172 | int i; |
| 29681 | 29173 | if( !ShellHasFlag(p,SHFLG_TestingMode) ){ |
| 29682 | | - eputf(".%s unavailable without --unsafe-testing\n", |
| 29174 | + sqlite3_fprintf(stderr,".%s unavailable without --unsafe-testing\n", |
| 29683 | 29175 | "imposter"); |
| 29684 | 29176 | rc = 1; |
| 29685 | 29177 | goto meta_command_exit; |
| 29686 | 29178 | } |
| 29687 | 29179 | if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ |
| | @@ -29743,11 +29235,11 @@ |
| 29743 | 29235 | zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); |
| 29744 | 29236 | } |
| 29745 | 29237 | } |
| 29746 | 29238 | sqlite3_finalize(pStmt); |
| 29747 | 29239 | if( i==0 || tnum==0 ){ |
| 29748 | | - eputf("no such index: \"%s\"\n", azArg[1]); |
| 29240 | + sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]); |
| 29749 | 29241 | rc = 1; |
| 29750 | 29242 | sqlite3_free(zCollist); |
| 29751 | 29243 | goto meta_command_exit; |
| 29752 | 29244 | } |
| 29753 | 29245 | if( lenPK==0 ) lenPK = 100000; |
| | @@ -29758,18 +29250,20 @@ |
| 29758 | 29250 | rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum); |
| 29759 | 29251 | if( rc==SQLITE_OK ){ |
| 29760 | 29252 | rc = sqlite3_exec(p->db, zSql, 0, 0, 0); |
| 29761 | 29253 | sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); |
| 29762 | 29254 | if( rc ){ |
| 29763 | | - eputf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); |
| 29255 | + sqlite3_fprintf(stderr, |
| 29256 | + "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); |
| 29764 | 29257 | }else{ |
| 29765 | | - sputf(stdout, "%s;\n", zSql); |
| 29766 | | - sputf(stdout, "WARNING: writing to an imposter table will corrupt" |
| 29258 | + sqlite3_fprintf(stdout, "%s;\n", zSql); |
| 29259 | + sqlite3_fprintf(stdout, |
| 29260 | + "WARNING: writing to an imposter table will corrupt" |
| 29767 | 29261 | " the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index"); |
| 29768 | 29262 | } |
| 29769 | 29263 | }else{ |
| 29770 | | - eputf("SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); |
| 29264 | + sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); |
| 29771 | 29265 | rc = 1; |
| 29772 | 29266 | } |
| 29773 | 29267 | sqlite3_free(zSql); |
| 29774 | 29268 | }else |
| 29775 | 29269 | #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ |
| | @@ -29779,11 +29273,11 @@ |
| 29779 | 29273 | if( nArg==2 ){ |
| 29780 | 29274 | iArg = integerValue(azArg[1]); |
| 29781 | 29275 | if( iArg==0 ) iArg = -1; |
| 29782 | 29276 | } |
| 29783 | 29277 | if( (nArg!=1 && nArg!=2) || iArg<0 ){ |
| 29784 | | - eputf("%s","Usage: .intck STEPS_PER_UNLOCK\n"); |
| 29278 | + sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n"); |
| 29785 | 29279 | rc = 1; |
| 29786 | 29280 | goto meta_command_exit; |
| 29787 | 29281 | } |
| 29788 | 29282 | open_db(p, 0); |
| 29789 | 29283 | rc = intckDatabaseCmd(p, iArg); |
| | @@ -29798,13 +29292,13 @@ |
| 29798 | 29292 | sqlite3IoTrace = 0; |
| 29799 | 29293 | }else if( cli_strcmp(azArg[1], "-")==0 ){ |
| 29800 | 29294 | sqlite3IoTrace = iotracePrintf; |
| 29801 | 29295 | iotrace = stdout; |
| 29802 | 29296 | }else{ |
| 29803 | | - iotrace = fopen(azArg[1], "w"); |
| 29297 | + iotrace = sqlite3_fopen(azArg[1], "w"); |
| 29804 | 29298 | if( iotrace==0 ){ |
| 29805 | | - eputf("Error: cannot open \"%s\"\n", azArg[1]); |
| 29299 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); |
| 29806 | 29300 | sqlite3IoTrace = 0; |
| 29807 | 29301 | rc = 1; |
| 29808 | 29302 | }else{ |
| 29809 | 29303 | sqlite3IoTrace = iotracePrintf; |
| 29810 | 29304 | } |
| | @@ -29832,11 +29326,11 @@ |
| 29832 | 29326 | }; |
| 29833 | 29327 | int i, n2; |
| 29834 | 29328 | open_db(p, 0); |
| 29835 | 29329 | if( nArg==1 ){ |
| 29836 | 29330 | for(i=0; i<ArraySize(aLimit); i++){ |
| 29837 | | - sputf(stdout, "%20s %d\n", aLimit[i].zLimitName, |
| 29331 | + sqlite3_fprintf(stdout, "%20s %d\n", aLimit[i].zLimitName, |
| 29838 | 29332 | sqlite3_limit(p->db, aLimit[i].limitCode, -1)); |
| 29839 | 29333 | } |
| 29840 | 29334 | }else if( nArg>3 ){ |
| 29841 | 29335 | eputz("Usage: .limit NAME ?NEW-VALUE?\n"); |
| 29842 | 29336 | rc = 1; |
| | @@ -29847,28 +29341,28 @@ |
| 29847 | 29341 | for(i=0; i<ArraySize(aLimit); i++){ |
| 29848 | 29342 | if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ |
| 29849 | 29343 | if( iLimit<0 ){ |
| 29850 | 29344 | iLimit = i; |
| 29851 | 29345 | }else{ |
| 29852 | | - eputf("ambiguous limit: \"%s\"\n", azArg[1]); |
| 29346 | + sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]); |
| 29853 | 29347 | rc = 1; |
| 29854 | 29348 | goto meta_command_exit; |
| 29855 | 29349 | } |
| 29856 | 29350 | } |
| 29857 | 29351 | } |
| 29858 | 29352 | if( iLimit<0 ){ |
| 29859 | | - eputf("unknown limit: \"%s\"\n" |
| 29353 | + sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n" |
| 29860 | 29354 | "enter \".limits\" with no arguments for a list.\n", |
| 29861 | 29355 | azArg[1]); |
| 29862 | 29356 | rc = 1; |
| 29863 | 29357 | goto meta_command_exit; |
| 29864 | 29358 | } |
| 29865 | 29359 | if( nArg==3 ){ |
| 29866 | 29360 | sqlite3_limit(p->db, aLimit[iLimit].limitCode, |
| 29867 | 29361 | (int)integerValue(azArg[2])); |
| 29868 | 29362 | } |
| 29869 | | - sputf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, |
| 29363 | + sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, |
| 29870 | 29364 | sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); |
| 29871 | 29365 | } |
| 29872 | 29366 | }else |
| 29873 | 29367 | |
| 29874 | 29368 | if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){ |
| | @@ -29947,35 +29441,37 @@ |
| 29947 | 29441 | cmOpts = cmo; |
| 29948 | 29442 | } |
| 29949 | 29443 | }else if( zTabname==0 ){ |
| 29950 | 29444 | zTabname = z; |
| 29951 | 29445 | }else if( z[0]=='-' ){ |
| 29952 | | - eputf("unknown option: %s\n", z); |
| 29446 | + sqlite3_fprintf(stderr,"unknown option: %s\n", z); |
| 29953 | 29447 | eputz("options:\n" |
| 29954 | 29448 | " --noquote\n" |
| 29955 | 29449 | " --quote\n" |
| 29956 | 29450 | " --wordwrap on/off\n" |
| 29957 | 29451 | " --wrap N\n" |
| 29958 | 29452 | " --ww\n"); |
| 29959 | 29453 | rc = 1; |
| 29960 | 29454 | goto meta_command_exit; |
| 29961 | 29455 | }else{ |
| 29962 | | - eputf("extra argument: \"%s\"\n", z); |
| 29456 | + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); |
| 29963 | 29457 | rc = 1; |
| 29964 | 29458 | goto meta_command_exit; |
| 29965 | 29459 | } |
| 29966 | 29460 | } |
| 29967 | 29461 | if( zMode==0 ){ |
| 29968 | 29462 | if( p->mode==MODE_Column |
| 29969 | 29463 | || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) |
| 29970 | 29464 | ){ |
| 29971 | | - oputf("current output mode: %s --wrap %d --wordwrap %s --%squote\n", |
| 29465 | + sqlite3_fprintf(p->out, |
| 29466 | + "current output mode: %s --wrap %d --wordwrap %s --%squote\n", |
| 29972 | 29467 | modeDescr[p->mode], p->cmOpts.iWrap, |
| 29973 | 29468 | p->cmOpts.bWordWrap ? "on" : "off", |
| 29974 | 29469 | p->cmOpts.bQuote ? "" : "no"); |
| 29975 | 29470 | }else{ |
| 29976 | | - oputf("current output mode: %s\n", modeDescr[p->mode]); |
| 29471 | + sqlite3_fprintf(p->out, |
| 29472 | + "current output mode: %s\n", modeDescr[p->mode]); |
| 29977 | 29473 | } |
| 29978 | 29474 | zMode = modeDescr[p->mode]; |
| 29979 | 29475 | } |
| 29980 | 29476 | n2 = strlen30(zMode); |
| 29981 | 29477 | if( cli_strncmp(zMode,"lines",n2)==0 ){ |
| | @@ -30044,11 +29540,11 @@ |
| 30044 | 29540 | if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){ |
| 30045 | 29541 | if( nArg!=2 ){ |
| 30046 | 29542 | eputz("Usage: .nonce NONCE\n"); |
| 30047 | 29543 | rc = 1; |
| 30048 | 29544 | }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){ |
| 30049 | | - eputf("line %d: incorrect nonce: \"%s\"\n", |
| 29545 | + sqlite3_fprintf(stderr,"line %d: incorrect nonce: \"%s\"\n", |
| 30050 | 29546 | p->lineno, azArg[1]); |
| 30051 | 29547 | exit(1); |
| 30052 | 29548 | }else{ |
| 30053 | 29549 | p->bSafeMode = 0; |
| 30054 | 29550 | return 0; /* Return immediately to bypass the safe mode reset |
| | @@ -30099,15 +29595,15 @@ |
| 30099 | 29595 | p->szMax = integerValue(azArg[++iName]); |
| 30100 | 29596 | #endif /* SQLITE_OMIT_DESERIALIZE */ |
| 30101 | 29597 | }else |
| 30102 | 29598 | #endif /* !SQLITE_SHELL_FIDDLE */ |
| 30103 | 29599 | if( z[0]=='-' ){ |
| 30104 | | - eputf("unknown option: %s\n", z); |
| 29600 | + sqlite3_fprintf(stderr,"unknown option: %s\n", z); |
| 30105 | 29601 | rc = 1; |
| 30106 | 29602 | goto meta_command_exit; |
| 30107 | 29603 | }else if( zFN ){ |
| 30108 | | - eputf("extra argument: \"%s\"\n", z); |
| 29604 | + sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); |
| 30109 | 29605 | rc = 1; |
| 30110 | 29606 | goto meta_command_exit; |
| 30111 | 29607 | }else{ |
| 30112 | 29608 | zFN = z; |
| 30113 | 29609 | } |
| | @@ -30145,11 +29641,11 @@ |
| 30145 | 29641 | zNewFilename = 0; |
| 30146 | 29642 | } |
| 30147 | 29643 | p->pAuxDb->zDbFilename = zNewFilename; |
| 30148 | 29644 | open_db(p, OPEN_DB_KEEPALIVE); |
| 30149 | 29645 | if( p->db==0 ){ |
| 30150 | | - eputf("Error: cannot open '%s'\n", zNewFilename); |
| 29646 | + sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename); |
| 30151 | 29647 | sqlite3_free(zNewFilename); |
| 30152 | 29648 | }else{ |
| 30153 | 29649 | p->pAuxDb->zFreeOnClose = zNewFilename; |
| 30154 | 29650 | } |
| 30155 | 29651 | } |
| | @@ -30163,22 +29659,27 @@ |
| 30163 | 29659 | #ifndef SQLITE_SHELL_FIDDLE |
| 30164 | 29660 | if( (c=='o' |
| 30165 | 29661 | && (cli_strncmp(azArg[0], "output", n)==0 |
| 30166 | 29662 | || cli_strncmp(azArg[0], "once", n)==0)) |
| 30167 | 29663 | || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0) |
| 29664 | + || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0) |
| 30168 | 29665 | ){ |
| 30169 | 29666 | char *zFile = 0; |
| 30170 | 29667 | int bTxtMode = 0; |
| 30171 | 29668 | int i; |
| 30172 | 29669 | int eMode = 0; |
| 30173 | | - int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ |
| 29670 | + int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */ |
| 29671 | + int bPlain = 0; /* --plain option */ |
| 30174 | 29672 | static const char *zBomUtf8 = "\xef\xbb\xbf"; |
| 30175 | 29673 | const char *zBom = 0; |
| 30176 | 29674 | |
| 30177 | 29675 | failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); |
| 30178 | 29676 | if( c=='e' ){ |
| 30179 | 29677 | eMode = 'x'; |
| 29678 | + bOnce = 2; |
| 29679 | + }else if( c=='w' ){ |
| 29680 | + eMode = 'w'; |
| 30180 | 29681 | bOnce = 2; |
| 30181 | 29682 | }else if( cli_strncmp(azArg[0],"once",n)==0 ){ |
| 30182 | 29683 | bOnce = 1; |
| 30183 | 29684 | } |
| 30184 | 29685 | for(i=1; i<nArg; i++){ |
| | @@ -30185,28 +29686,34 @@ |
| 30185 | 29686 | char *z = azArg[i]; |
| 30186 | 29687 | if( z[0]=='-' ){ |
| 30187 | 29688 | if( z[1]=='-' ) z++; |
| 30188 | 29689 | if( cli_strcmp(z,"-bom")==0 ){ |
| 30189 | 29690 | zBom = zBomUtf8; |
| 30190 | | - }else if( c!='e' && cli_strcmp(z,"-x")==0 ){ |
| 29691 | + }else if( cli_strcmp(z,"-plain")==0 ){ |
| 29692 | + bPlain = 1; |
| 29693 | + }else if( c=='o' && cli_strcmp(z,"-x")==0 ){ |
| 30191 | 29694 | eMode = 'x'; /* spreadsheet */ |
| 30192 | | - }else if( c!='e' && cli_strcmp(z,"-e")==0 ){ |
| 29695 | + }else if( c=='o' && cli_strcmp(z,"-e")==0 ){ |
| 30193 | 29696 | eMode = 'e'; /* text editor */ |
| 29697 | + }else if( c=='o' && cli_strcmp(z,"-w")==0 ){ |
| 29698 | + eMode = 'w'; /* Web browser */ |
| 30194 | 29699 | }else{ |
| 30195 | | - oputf("ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); |
| 29700 | + sqlite3_fprintf(p->out, |
| 29701 | + "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); |
| 30196 | 29702 | showHelp(p->out, azArg[0]); |
| 30197 | 29703 | rc = 1; |
| 30198 | 29704 | goto meta_command_exit; |
| 30199 | 29705 | } |
| 30200 | | - }else if( zFile==0 && eMode!='e' && eMode!='x' ){ |
| 29706 | + }else if( zFile==0 && eMode==0 ){ |
| 30201 | 29707 | zFile = sqlite3_mprintf("%s", z); |
| 30202 | 29708 | if( zFile && zFile[0]=='|' ){ |
| 30203 | 29709 | while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]); |
| 30204 | 29710 | break; |
| 30205 | 29711 | } |
| 30206 | 29712 | }else{ |
| 30207 | | - oputf("ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); |
| 29713 | + sqlite3_fprintf(p->out, |
| 29714 | + "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); |
| 30208 | 29715 | showHelp(p->out, azArg[0]); |
| 30209 | 29716 | rc = 1; |
| 30210 | 29717 | sqlite3_free(zFile); |
| 30211 | 29718 | goto meta_command_exit; |
| 30212 | 29719 | } |
| | @@ -30219,20 +29726,29 @@ |
| 30219 | 29726 | }else{ |
| 30220 | 29727 | p->outCount = 0; |
| 30221 | 29728 | } |
| 30222 | 29729 | output_reset(p); |
| 30223 | 29730 | #ifndef SQLITE_NOHAVE_SYSTEM |
| 30224 | | - if( eMode=='e' || eMode=='x' ){ |
| 29731 | + if( eMode=='e' || eMode=='x' || eMode=='w' ){ |
| 30225 | 29732 | p->doXdgOpen = 1; |
| 30226 | 29733 | outputModePush(p); |
| 30227 | 29734 | if( eMode=='x' ){ |
| 30228 | 29735 | /* spreadsheet mode. Output as CSV. */ |
| 30229 | 29736 | newTempFile(p, "csv"); |
| 30230 | 29737 | ShellClearFlag(p, SHFLG_Echo); |
| 30231 | 29738 | p->mode = MODE_Csv; |
| 30232 | 29739 | sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); |
| 30233 | 29740 | sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); |
| 29741 | +#ifdef _WIN32 |
| 29742 | + zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does |
| 29743 | + ** not work without it. */ |
| 29744 | +#endif |
| 29745 | + }else if( eMode=='w' ){ |
| 29746 | + /* web-browser mode. */ |
| 29747 | + newTempFile(p, "html"); |
| 29748 | + if( !bPlain ) p->mode = MODE_Www; |
| 29749 | + bTxtMode = 1; |
| 30234 | 29750 | }else{ |
| 30235 | 29751 | /* text editor mode */ |
| 30236 | 29752 | newTempFile(p, "txt"); |
| 30237 | 29753 | bTxtMode = 1; |
| 30238 | 29754 | } |
| | @@ -30245,30 +29761,36 @@ |
| 30245 | 29761 | #ifdef SQLITE_OMIT_POPEN |
| 30246 | 29762 | eputz("Error: pipes are not supported in this OS\n"); |
| 30247 | 29763 | rc = 1; |
| 30248 | 29764 | output_redir(p, stdout); |
| 30249 | 29765 | #else |
| 30250 | | - FILE *pfPipe = popen(zFile + 1, "w"); |
| 29766 | + FILE *pfPipe = sqlite3_popen(zFile + 1, "w"); |
| 30251 | 29767 | if( pfPipe==0 ){ |
| 30252 | | - eputf("Error: cannot open pipe \"%s\"\n", zFile + 1); |
| 29768 | + sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); |
| 30253 | 29769 | rc = 1; |
| 30254 | 29770 | }else{ |
| 30255 | 29771 | output_redir(p, pfPipe); |
| 30256 | | - if( zBom ) oputz(zBom); |
| 29772 | + if( zBom ) sqlite3_fputs(zBom, pfPipe); |
| 30257 | 29773 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); |
| 30258 | 29774 | } |
| 30259 | 29775 | #endif |
| 30260 | 29776 | }else{ |
| 30261 | 29777 | FILE *pfFile = output_file_open(zFile, bTxtMode); |
| 30262 | 29778 | if( pfFile==0 ){ |
| 30263 | 29779 | if( cli_strcmp(zFile,"off")!=0 ){ |
| 30264 | | - eputf("Error: cannot write to \"%s\"\n", zFile); |
| 29780 | + sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); |
| 30265 | 29781 | } |
| 30266 | 29782 | rc = 1; |
| 30267 | 29783 | } else { |
| 30268 | 29784 | output_redir(p, pfFile); |
| 30269 | | - if( zBom ) oputz(zBom); |
| 29785 | + if( bPlain && eMode=='w' ){ |
| 29786 | + sqlite3_fputs( |
| 29787 | + "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n", |
| 29788 | + pfFile |
| 29789 | + ); |
| 29790 | + } |
| 29791 | + if( zBom ) sqlite3_fputs(zBom, pfFile); |
| 30270 | 29792 | sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); |
| 30271 | 29793 | } |
| 30272 | 29794 | } |
| 30273 | 29795 | sqlite3_free(zFile); |
| 30274 | 29796 | }else |
| | @@ -30305,11 +29827,12 @@ |
| 30305 | 29827 | if( len ){ |
| 30306 | 29828 | rx = sqlite3_prepare_v2(p->db, |
| 30307 | 29829 | "SELECT key, quote(value) " |
| 30308 | 29830 | "FROM temp.sqlite_parameters;", -1, &pStmt, 0); |
| 30309 | 29831 | while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 30310 | | - oputf("%-*s %s\n", len, sqlite3_column_text(pStmt,0), |
| 29832 | + sqlite3_fprintf(p->out, |
| 29833 | + "%-*s %s\n", len, sqlite3_column_text(pStmt,0), |
| 30311 | 29834 | sqlite3_column_text(pStmt,1)); |
| 30312 | 29835 | } |
| 30313 | 29836 | sqlite3_finalize(pStmt); |
| 30314 | 29837 | } |
| 30315 | 29838 | }else |
| | @@ -30350,11 +29873,11 @@ |
| 30350 | 29873 | "VALUES(%Q,%Q);", zKey, zValue); |
| 30351 | 29874 | shell_check_oom(zSql); |
| 30352 | 29875 | rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); |
| 30353 | 29876 | sqlite3_free(zSql); |
| 30354 | 29877 | if( rx!=SQLITE_OK ){ |
| 30355 | | - oputf("Error: %s\n", sqlite3_errmsg(p->db)); |
| 29878 | + sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db)); |
| 30356 | 29879 | sqlite3_finalize(pStmt); |
| 30357 | 29880 | pStmt = 0; |
| 30358 | 29881 | rc = 1; |
| 30359 | 29882 | } |
| 30360 | 29883 | } |
| | @@ -30379,14 +29902,14 @@ |
| 30379 | 29902 | }else |
| 30380 | 29903 | |
| 30381 | 29904 | if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){ |
| 30382 | 29905 | int i; |
| 30383 | 29906 | for(i=1; i<nArg; i++){ |
| 30384 | | - if( i>1 ) oputz(" "); |
| 30385 | | - oputz(azArg[i]); |
| 29907 | + if( i>1 ) sqlite3_fputs(" ", p->out); |
| 29908 | + sqlite3_fputs(azArg[i], p->out); |
| 30386 | 29909 | } |
| 30387 | | - oputz("\n"); |
| 29910 | + sqlite3_fputs("\n", p->out); |
| 30388 | 29911 | }else |
| 30389 | 29912 | |
| 30390 | 29913 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 30391 | 29914 | if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){ |
| 30392 | 29915 | int i; |
| | @@ -30419,11 +29942,11 @@ |
| 30419 | 29942 | }else{ |
| 30420 | 29943 | p->mxProgress = (int)integerValue(azArg[++i]); |
| 30421 | 29944 | } |
| 30422 | 29945 | continue; |
| 30423 | 29946 | } |
| 30424 | | - eputf("Error: unknown option: \"%s\"\n", azArg[i]); |
| 29947 | + sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]); |
| 30425 | 29948 | rc = 1; |
| 30426 | 29949 | goto meta_command_exit; |
| 30427 | 29950 | }else{ |
| 30428 | 29951 | nn = (int)integerValue(z); |
| 30429 | 29952 | } |
| | @@ -30462,21 +29985,21 @@ |
| 30462 | 29985 | #ifdef SQLITE_OMIT_POPEN |
| 30463 | 29986 | eputz("Error: pipes are not supported in this OS\n"); |
| 30464 | 29987 | rc = 1; |
| 30465 | 29988 | p->out = stdout; |
| 30466 | 29989 | #else |
| 30467 | | - p->in = popen(azArg[1]+1, "r"); |
| 29990 | + p->in = sqlite3_popen(azArg[1]+1, "r"); |
| 30468 | 29991 | if( p->in==0 ){ |
| 30469 | | - eputf("Error: cannot open \"%s\"\n", azArg[1]); |
| 29992 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); |
| 30470 | 29993 | rc = 1; |
| 30471 | 29994 | }else{ |
| 30472 | 29995 | rc = process_input(p); |
| 30473 | 29996 | pclose(p->in); |
| 30474 | 29997 | } |
| 30475 | 29998 | #endif |
| 30476 | 29999 | }else if( (p->in = openChrSource(azArg[1]))==0 ){ |
| 30477 | | - eputf("Error: cannot open \"%s\"\n", azArg[1]); |
| 30000 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); |
| 30478 | 30001 | rc = 1; |
| 30479 | 30002 | }else{ |
| 30480 | 30003 | rc = process_input(p); |
| 30481 | 30004 | fclose(p->in); |
| 30482 | 30005 | } |
| | @@ -30505,11 +30028,11 @@ |
| 30505 | 30028 | rc = 1; |
| 30506 | 30029 | goto meta_command_exit; |
| 30507 | 30030 | } |
| 30508 | 30031 | rc = sqlite3_open(zSrcFile, &pSrc); |
| 30509 | 30032 | if( rc!=SQLITE_OK ){ |
| 30510 | | - eputf("Error: cannot open \"%s\"\n", zSrcFile); |
| 30033 | + sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile); |
| 30511 | 30034 | close_db(pSrc); |
| 30512 | 30035 | return 1; |
| 30513 | 30036 | } |
| 30514 | 30037 | open_db(p, 0); |
| 30515 | 30038 | pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); |
| | @@ -30588,11 +30111,11 @@ |
| 30588 | 30111 | }else if( optionMatch(azArg[ii],"debug") ){ |
| 30589 | 30112 | bDebug = 1; |
| 30590 | 30113 | }else if( optionMatch(azArg[ii],"nosys") ){ |
| 30591 | 30114 | bNoSystemTabs = 1; |
| 30592 | 30115 | }else if( azArg[ii][0]=='-' ){ |
| 30593 | | - eputf("Unknown option: \"%s\"\n", azArg[ii]); |
| 30116 | + sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]); |
| 30594 | 30117 | rc = 1; |
| 30595 | 30118 | goto meta_command_exit; |
| 30596 | 30119 | }else if( zName==0 ){ |
| 30597 | 30120 | zName = azArg[ii]; |
| 30598 | 30121 | }else{ |
| | @@ -30689,11 +30212,11 @@ |
| 30689 | 30212 | appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0); |
| 30690 | 30213 | } |
| 30691 | 30214 | appendText(&sSelect, "sql IS NOT NULL" |
| 30692 | 30215 | " ORDER BY snum, rowid", 0); |
| 30693 | 30216 | if( bDebug ){ |
| 30694 | | - oputf("SQL: %s;\n", sSelect.z); |
| 30217 | + sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z); |
| 30695 | 30218 | }else{ |
| 30696 | 30219 | rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg); |
| 30697 | 30220 | } |
| 30698 | 30221 | freeText(&sSelect); |
| 30699 | 30222 | } |
| | @@ -30750,11 +30273,12 @@ |
| 30750 | 30273 | session_not_open: |
| 30751 | 30274 | eputz("ERROR: No sessions are open\n"); |
| 30752 | 30275 | }else{ |
| 30753 | 30276 | rc = sqlite3session_attach(pSession->p, azCmd[1]); |
| 30754 | 30277 | if( rc ){ |
| 30755 | | - eputf("ERROR: sqlite3session_attach() returns %d\n",rc); |
| 30278 | + sqlite3_fprintf(stderr, |
| 30279 | + "ERROR: sqlite3session_attach() returns %d\n",rc); |
| 30756 | 30280 | rc = 0; |
| 30757 | 30281 | } |
| 30758 | 30282 | } |
| 30759 | 30283 | }else |
| 30760 | 30284 | |
| | @@ -30767,13 +30291,13 @@ |
| 30767 | 30291 | ){ |
| 30768 | 30292 | FILE *out = 0; |
| 30769 | 30293 | failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); |
| 30770 | 30294 | if( nCmd!=2 ) goto session_syntax_error; |
| 30771 | 30295 | if( pSession->p==0 ) goto session_not_open; |
| 30772 | | - out = fopen(azCmd[1], "wb"); |
| 30296 | + out = sqlite3_fopen(azCmd[1], "wb"); |
| 30773 | 30297 | if( out==0 ){ |
| 30774 | | - eputf("ERROR: cannot open \"%s\" for writing\n", |
| 30298 | + sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n", |
| 30775 | 30299 | azCmd[1]); |
| 30776 | 30300 | }else{ |
| 30777 | 30301 | int szChng; |
| 30778 | 30302 | void *pChng; |
| 30779 | 30303 | if( azCmd[0][0]=='c' ){ |
| | @@ -30780,16 +30304,17 @@ |
| 30780 | 30304 | rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); |
| 30781 | 30305 | }else{ |
| 30782 | 30306 | rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); |
| 30783 | 30307 | } |
| 30784 | 30308 | if( rc ){ |
| 30785 | | - sputf(stdout, "Error: error code %d\n", rc); |
| 30309 | + sqlite3_fprintf(stdout, "Error: error code %d\n", rc); |
| 30786 | 30310 | rc = 0; |
| 30787 | 30311 | } |
| 30788 | 30312 | if( pChng |
| 30789 | 30313 | && fwrite(pChng, szChng, 1, out)!=1 ){ |
| 30790 | | - eputf("ERROR: Failed to write entire %d-byte output\n", szChng); |
| 30314 | + sqlite3_fprintf(stderr, |
| 30315 | + "ERROR: Failed to write entire %d-byte output\n", szChng); |
| 30791 | 30316 | } |
| 30792 | 30317 | sqlite3_free(pChng); |
| 30793 | 30318 | fclose(out); |
| 30794 | 30319 | } |
| 30795 | 30320 | }else |
| | @@ -30812,11 +30337,12 @@ |
| 30812 | 30337 | int ii; |
| 30813 | 30338 | if( nCmd>2 ) goto session_syntax_error; |
| 30814 | 30339 | ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); |
| 30815 | 30340 | if( pAuxDb->nSession ){ |
| 30816 | 30341 | ii = sqlite3session_enable(pSession->p, ii); |
| 30817 | | - oputf("session %s enable flag = %d\n", pSession->zName, ii); |
| 30342 | + sqlite3_fprintf(p->out, |
| 30343 | + "session %s enable flag = %d\n", pSession->zName, ii); |
| 30818 | 30344 | } |
| 30819 | 30345 | }else |
| 30820 | 30346 | |
| 30821 | 30347 | /* .session filter GLOB .... |
| 30822 | 30348 | ** Set a list of GLOB patterns of table names to be excluded. |
| | @@ -30847,11 +30373,12 @@ |
| 30847 | 30373 | int ii; |
| 30848 | 30374 | if( nCmd>2 ) goto session_syntax_error; |
| 30849 | 30375 | ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); |
| 30850 | 30376 | if( pAuxDb->nSession ){ |
| 30851 | 30377 | ii = sqlite3session_indirect(pSession->p, ii); |
| 30852 | | - oputf("session %s indirect flag = %d\n", pSession->zName, ii); |
| 30378 | + sqlite3_fprintf(p->out, |
| 30379 | + "session %s indirect flag = %d\n", pSession->zName, ii); |
| 30853 | 30380 | } |
| 30854 | 30381 | }else |
| 30855 | 30382 | |
| 30856 | 30383 | /* .session isempty |
| 30857 | 30384 | ** Determine if the session is empty |
| | @@ -30859,20 +30386,21 @@ |
| 30859 | 30386 | if( cli_strcmp(azCmd[0], "isempty")==0 ){ |
| 30860 | 30387 | int ii; |
| 30861 | 30388 | if( nCmd!=1 ) goto session_syntax_error; |
| 30862 | 30389 | if( pAuxDb->nSession ){ |
| 30863 | 30390 | ii = sqlite3session_isempty(pSession->p); |
| 30864 | | - oputf("session %s isempty flag = %d\n", pSession->zName, ii); |
| 30391 | + sqlite3_fprintf(p->out, |
| 30392 | + "session %s isempty flag = %d\n", pSession->zName, ii); |
| 30865 | 30393 | } |
| 30866 | 30394 | }else |
| 30867 | 30395 | |
| 30868 | 30396 | /* .session list |
| 30869 | 30397 | ** List all currently open sessions |
| 30870 | 30398 | */ |
| 30871 | 30399 | if( cli_strcmp(azCmd[0],"list")==0 ){ |
| 30872 | 30400 | for(i=0; i<pAuxDb->nSession; i++){ |
| 30873 | | - oputf("%d %s\n", i, pAuxDb->aSession[i].zName); |
| 30401 | + sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName); |
| 30874 | 30402 | } |
| 30875 | 30403 | }else |
| 30876 | 30404 | |
| 30877 | 30405 | /* .session open DB NAME |
| 30878 | 30406 | ** Open a new session called NAME on the attached database DB. |
| | @@ -30883,22 +30411,23 @@ |
| 30883 | 30411 | if( nCmd!=3 ) goto session_syntax_error; |
| 30884 | 30412 | zName = azCmd[2]; |
| 30885 | 30413 | if( zName[0]==0 ) goto session_syntax_error; |
| 30886 | 30414 | for(i=0; i<pAuxDb->nSession; i++){ |
| 30887 | 30415 | if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ |
| 30888 | | - eputf("Session \"%s\" already exists\n", zName); |
| 30416 | + sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName); |
| 30889 | 30417 | goto meta_command_exit; |
| 30890 | 30418 | } |
| 30891 | 30419 | } |
| 30892 | 30420 | if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ |
| 30893 | | - eputf("Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); |
| 30421 | + sqlite3_fprintf(stderr, |
| 30422 | + "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); |
| 30894 | 30423 | goto meta_command_exit; |
| 30895 | 30424 | } |
| 30896 | 30425 | pSession = &pAuxDb->aSession[pAuxDb->nSession]; |
| 30897 | 30426 | rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); |
| 30898 | 30427 | if( rc ){ |
| 30899 | | - eputf("Cannot open session: error code=%d\n", rc); |
| 30428 | + sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc); |
| 30900 | 30429 | rc = 0; |
| 30901 | 30430 | goto meta_command_exit; |
| 30902 | 30431 | } |
| 30903 | 30432 | pSession->nFilter = 0; |
| 30904 | 30433 | sqlite3session_table_filter(pSession->p, session_filter, pSession); |
| | @@ -30918,20 +30447,20 @@ |
| 30918 | 30447 | if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){ |
| 30919 | 30448 | if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){ |
| 30920 | 30449 | int i, v; |
| 30921 | 30450 | for(i=1; i<nArg; i++){ |
| 30922 | 30451 | v = booleanValue(azArg[i]); |
| 30923 | | - oputf("%s: %d 0x%x\n", azArg[i], v, v); |
| 30452 | + sqlite3_fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); |
| 30924 | 30453 | } |
| 30925 | 30454 | } |
| 30926 | 30455 | if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){ |
| 30927 | 30456 | int i; sqlite3_int64 v; |
| 30928 | 30457 | for(i=1; i<nArg; i++){ |
| 30929 | 30458 | char zBuf[200]; |
| 30930 | 30459 | v = integerValue(azArg[i]); |
| 30931 | 30460 | sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); |
| 30932 | | - oputz(zBuf); |
| 30461 | + sqlite3_fputs(zBuf, p->out); |
| 30933 | 30462 | } |
| 30934 | 30463 | } |
| 30935 | 30464 | }else |
| 30936 | 30465 | #endif |
| 30937 | 30466 | |
| | @@ -30954,12 +30483,13 @@ |
| 30954 | 30483 | }else |
| 30955 | 30484 | if( cli_strcmp(z,"-v")==0 ){ |
| 30956 | 30485 | bVerbose++; |
| 30957 | 30486 | }else |
| 30958 | 30487 | { |
| 30959 | | - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); |
| 30960 | | - eputz("Should be one of: --init -v\n"); |
| 30488 | + sqlite3_fprintf(stderr, |
| 30489 | + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); |
| 30490 | + sqlite3_fputs("Should be one of: --init -v\n", stderr); |
| 30961 | 30491 | rc = 1; |
| 30962 | 30492 | goto meta_command_exit; |
| 30963 | 30493 | } |
| 30964 | 30494 | } |
| 30965 | 30495 | if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0) |
| | @@ -31000,46 +30530,47 @@ |
| 31000 | 30530 | if( zOp==0 ) continue; |
| 31001 | 30531 | if( zSql==0 ) continue; |
| 31002 | 30532 | if( zAns==0 ) continue; |
| 31003 | 30533 | k = 0; |
| 31004 | 30534 | if( bVerbose>0 ){ |
| 31005 | | - sputf(stdout, "%d: %s %s\n", tno, zOp, zSql); |
| 30535 | + sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql); |
| 31006 | 30536 | } |
| 31007 | 30537 | if( cli_strcmp(zOp,"memo")==0 ){ |
| 31008 | | - oputf("%s\n", zSql); |
| 30538 | + sqlite3_fprintf(p->out, "%s\n", zSql); |
| 31009 | 30539 | }else |
| 31010 | 30540 | if( cli_strcmp(zOp,"run")==0 ){ |
| 31011 | 30541 | char *zErrMsg = 0; |
| 31012 | 30542 | str.n = 0; |
| 31013 | 30543 | str.z[0] = 0; |
| 31014 | 30544 | rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); |
| 31015 | 30545 | nTest++; |
| 31016 | 30546 | if( bVerbose ){ |
| 31017 | | - oputf("Result: %s\n", str.z); |
| 30547 | + sqlite3_fprintf(p->out, "Result: %s\n", str.z); |
| 31018 | 30548 | } |
| 31019 | 30549 | if( rc || zErrMsg ){ |
| 31020 | 30550 | nErr++; |
| 31021 | 30551 | rc = 1; |
| 31022 | | - oputf("%d: error-code-%d: %s\n", tno, rc, zErrMsg); |
| 30552 | + sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); |
| 31023 | 30553 | sqlite3_free(zErrMsg); |
| 31024 | 30554 | }else if( cli_strcmp(zAns,str.z)!=0 ){ |
| 31025 | 30555 | nErr++; |
| 31026 | 30556 | rc = 1; |
| 31027 | | - oputf("%d: Expected: [%s]\n", tno, zAns); |
| 31028 | | - oputf("%d: Got: [%s]\n", tno, str.z); |
| 30557 | + sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); |
| 30558 | + sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.z); |
| 31029 | 30559 | } |
| 31030 | 30560 | } |
| 31031 | 30561 | else{ |
| 31032 | | - eputf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno); |
| 30562 | + sqlite3_fprintf(stderr, |
| 30563 | + "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); |
| 31033 | 30564 | rc = 1; |
| 31034 | 30565 | break; |
| 31035 | 30566 | } |
| 31036 | 30567 | } /* End loop over rows of content from SELFTEST */ |
| 31037 | 30568 | sqlite3_finalize(pStmt); |
| 31038 | 30569 | } /* End loop over k */ |
| 31039 | 30570 | freeText(&str); |
| 31040 | | - oputf("%d errors out of %d tests\n", nErr, nTest); |
| 30571 | + sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest); |
| 31041 | 30572 | }else |
| 31042 | 30573 | |
| 31043 | 30574 | if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){ |
| 31044 | 30575 | if( nArg<2 || nArg>3 ){ |
| 31045 | 30576 | eputz("Usage: .separator COL ?ROW?\n"); |
| | @@ -31083,11 +30614,12 @@ |
| 31083 | 30614 | }else |
| 31084 | 30615 | if( cli_strcmp(z,"debug")==0 ){ |
| 31085 | 30616 | bDebug = 1; |
| 31086 | 30617 | }else |
| 31087 | 30618 | { |
| 31088 | | - eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); |
| 30619 | + sqlite3_fprintf(stderr, |
| 30620 | + "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); |
| 31089 | 30621 | showHelp(p->out, azArg[0]); |
| 31090 | 30622 | rc = 1; |
| 31091 | 30623 | goto meta_command_exit; |
| 31092 | 30624 | } |
| 31093 | 30625 | }else if( zLike ){ |
| | @@ -31161,11 +30693,11 @@ |
| 31161 | 30693 | } |
| 31162 | 30694 | shell_check_oom(zSql); |
| 31163 | 30695 | freeText(&sQuery); |
| 31164 | 30696 | freeText(&sSql); |
| 31165 | 30697 | if( bDebug ){ |
| 31166 | | - oputf("%s\n", zSql); |
| 30698 | + sqlite3_fprintf(p->out, "%s\n", zSql); |
| 31167 | 30699 | }else{ |
| 31168 | 30700 | shell_exec(p, zSql, 0); |
| 31169 | 30701 | } |
| 31170 | 30702 | #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE) |
| 31171 | 30703 | { |
| | @@ -31191,11 +30723,11 @@ |
| 31191 | 30723 | "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n" |
| 31192 | 30724 | "|| ' AND typeof('||cname||')=''text'' ',\n" |
| 31193 | 30725 | "' OR ') as query, tname from tabcols group by tname)" |
| 31194 | 30726 | , zRevText); |
| 31195 | 30727 | shell_check_oom(zRevText); |
| 31196 | | - if( bDebug ) oputf("%s\n", zRevText); |
| 30728 | + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText); |
| 31197 | 30729 | lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0); |
| 31198 | 30730 | if( lrc!=SQLITE_OK ){ |
| 31199 | 30731 | /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the |
| 31200 | 30732 | ** user does cruel and unnatural things like ".limit expr_depth 0". */ |
| 31201 | 30733 | rc = 1; |
| | @@ -31204,19 +30736,20 @@ |
| 31204 | 30736 | lrc = SQLITE_ROW==sqlite3_step(pStmt); |
| 31205 | 30737 | if( lrc ){ |
| 31206 | 30738 | const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0); |
| 31207 | 30739 | sqlite3_stmt *pCheckStmt; |
| 31208 | 30740 | lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0); |
| 31209 | | - if( bDebug ) oputf("%s\n", zGenQuery); |
| 30741 | + if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery); |
| 31210 | 30742 | if( lrc!=SQLITE_OK ){ |
| 31211 | 30743 | rc = 1; |
| 31212 | 30744 | }else{ |
| 31213 | 30745 | if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){ |
| 31214 | 30746 | double countIrreversible = sqlite3_column_double(pCheckStmt, 0); |
| 31215 | 30747 | if( countIrreversible>0 ){ |
| 31216 | 30748 | int sz = (int)(countIrreversible + 0.5); |
| 31217 | | - eputf("Digest includes %d invalidly encoded text field%s.\n", |
| 30749 | + sqlite3_fprintf(stderr, |
| 30750 | + "Digest includes %d invalidly encoded text field%s.\n", |
| 31218 | 30751 | sz, (sz>1)? "s": ""); |
| 31219 | 30752 | } |
| 31220 | 30753 | } |
| 31221 | 30754 | sqlite3_finalize(pCheckStmt); |
| 31222 | 30755 | } |
| | @@ -31246,15 +30779,15 @@ |
| 31246 | 30779 | zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); |
| 31247 | 30780 | for(i=2; i<nArg && zCmd!=0; i++){ |
| 31248 | 30781 | zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"", |
| 31249 | 30782 | zCmd, azArg[i]); |
| 31250 | 30783 | } |
| 31251 | | - consoleRestore(); |
| 30784 | + /*consoleRestore();*/ |
| 31252 | 30785 | x = zCmd!=0 ? system(zCmd) : 1; |
| 31253 | | - consoleRenewSetup(); |
| 30786 | + /*consoleRenewSetup();*/ |
| 31254 | 30787 | sqlite3_free(zCmd); |
| 31255 | | - if( x ) eputf("System command returns %d\n", x); |
| 30788 | + if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x); |
| 31256 | 30789 | }else |
| 31257 | 30790 | #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */ |
| 31258 | 30791 | |
| 31259 | 30792 | if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){ |
| 31260 | 30793 | static const char *azBool[] = { "off", "on", "trigger", "full"}; |
| | @@ -31263,50 +30796,52 @@ |
| 31263 | 30796 | if( nArg!=1 ){ |
| 31264 | 30797 | eputz("Usage: .show\n"); |
| 31265 | 30798 | rc = 1; |
| 31266 | 30799 | goto meta_command_exit; |
| 31267 | 30800 | } |
| 31268 | | - oputf("%12.12s: %s\n","echo", |
| 30801 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","echo", |
| 31269 | 30802 | azBool[ShellHasFlag(p, SHFLG_Echo)]); |
| 31270 | | - oputf("%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); |
| 31271 | | - oputf("%12.12s: %s\n","explain", |
| 30803 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); |
| 30804 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","explain", |
| 31272 | 30805 | p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); |
| 31273 | | - oputf("%12.12s: %s\n","headers", azBool[p->showHeader!=0]); |
| 30806 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", |
| 30807 | + azBool[p->showHeader!=0]); |
| 31274 | 30808 | if( p->mode==MODE_Column |
| 31275 | 30809 | || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) |
| 31276 | 30810 | ){ |
| 31277 | | - oputf("%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", |
| 30811 | + sqlite3_fprintf(p->out, |
| 30812 | + "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", |
| 31278 | 30813 | modeDescr[p->mode], p->cmOpts.iWrap, |
| 31279 | 30814 | p->cmOpts.bWordWrap ? "on" : "off", |
| 31280 | 30815 | p->cmOpts.bQuote ? "" : "no"); |
| 31281 | 30816 | }else{ |
| 31282 | | - oputf("%12.12s: %s\n","mode", modeDescr[p->mode]); |
| 30817 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); |
| 31283 | 30818 | } |
| 31284 | | - oputf("%12.12s: ", "nullvalue"); |
| 31285 | | - output_c_string(p->nullValue); |
| 31286 | | - oputz("\n"); |
| 31287 | | - oputf("%12.12s: %s\n","output", |
| 30819 | + sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue"); |
| 30820 | + output_c_string(p->out, p->nullValue); |
| 30821 | + sqlite3_fputs("\n", p->out); |
| 30822 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","output", |
| 31288 | 30823 | strlen30(p->outfile) ? p->outfile : "stdout"); |
| 31289 | | - oputf("%12.12s: ", "colseparator"); |
| 31290 | | - output_c_string(p->colSeparator); |
| 31291 | | - oputz("\n"); |
| 31292 | | - oputf("%12.12s: ", "rowseparator"); |
| 31293 | | - output_c_string(p->rowSeparator); |
| 31294 | | - oputz("\n"); |
| 30824 | + sqlite3_fprintf(p->out, "%12.12s: ", "colseparator"); |
| 30825 | + output_c_string(p->out, p->colSeparator); |
| 30826 | + sqlite3_fputs("\n", p->out); |
| 30827 | + sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator"); |
| 30828 | + output_c_string(p->out, p->rowSeparator); |
| 30829 | + sqlite3_fputs("\n", p->out); |
| 31295 | 30830 | switch( p->statsOn ){ |
| 31296 | 30831 | case 0: zOut = "off"; break; |
| 31297 | 30832 | default: zOut = "on"; break; |
| 31298 | 30833 | case 2: zOut = "stmt"; break; |
| 31299 | 30834 | case 3: zOut = "vmstep"; break; |
| 31300 | 30835 | } |
| 31301 | | - oputf("%12.12s: %s\n","stats", zOut); |
| 31302 | | - oputf("%12.12s: ", "width"); |
| 30836 | + sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut); |
| 30837 | + sqlite3_fprintf(p->out, "%12.12s: ", "width"); |
| 31303 | 30838 | for (i=0;i<p->nWidth;i++) { |
| 31304 | | - oputf("%d ", p->colWidth[i]); |
| 30839 | + sqlite3_fprintf(p->out, "%d ", p->colWidth[i]); |
| 31305 | 30840 | } |
| 31306 | | - oputz("\n"); |
| 31307 | | - oputf("%12.12s: %s\n", "filename", |
| 30841 | + sqlite3_fputs("\n", p->out); |
| 30842 | + sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename", |
| 31308 | 30843 | p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : ""); |
| 31309 | 30844 | }else |
| 31310 | 30845 | |
| 31311 | 30846 | if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){ |
| 31312 | 30847 | if( nArg==2 ){ |
| | @@ -31420,13 +30955,14 @@ |
| 31420 | 30955 | if( nPrintCol<1 ) nPrintCol = 1; |
| 31421 | 30956 | nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; |
| 31422 | 30957 | for(i=0; i<nPrintRow; i++){ |
| 31423 | 30958 | for(j=i; j<nRow; j+=nPrintRow){ |
| 31424 | 30959 | char *zSp = j<nPrintRow ? "" : " "; |
| 31425 | | - oputf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); |
| 30960 | + sqlite3_fprintf(p->out, |
| 30961 | + "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); |
| 31426 | 30962 | } |
| 31427 | | - oputz("\n"); |
| 30963 | + sqlite3_fputs("\n", p->out); |
| 31428 | 30964 | } |
| 31429 | 30965 | } |
| 31430 | 30966 | |
| 31431 | 30967 | for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); |
| 31432 | 30968 | sqlite3_free(azResult); |
| | @@ -31498,14 +31034,14 @@ |
| 31498 | 31034 | if( zCmd[0]=='-' && zCmd[1] ) zCmd++; |
| 31499 | 31035 | } |
| 31500 | 31036 | |
| 31501 | 31037 | /* --help lists all test-controls */ |
| 31502 | 31038 | if( cli_strcmp(zCmd,"help")==0 ){ |
| 31503 | | - oputz("Available test-controls:\n"); |
| 31039 | + sqlite3_fputs("Available test-controls:\n", p->out); |
| 31504 | 31040 | for(i=0; i<ArraySize(aCtrl); i++){ |
| 31505 | 31041 | if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue; |
| 31506 | | - oputf(" .testctrl %s %s\n", |
| 31042 | + sqlite3_fprintf(p->out, " .testctrl %s %s\n", |
| 31507 | 31043 | aCtrl[i].zCtrlName, aCtrl[i].zUsage); |
| 31508 | 31044 | } |
| 31509 | 31045 | rc = 1; |
| 31510 | 31046 | goto meta_command_exit; |
| 31511 | 31047 | } |
| | @@ -31518,19 +31054,19 @@ |
| 31518 | 31054 | if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ |
| 31519 | 31055 | if( testctrl<0 ){ |
| 31520 | 31056 | testctrl = aCtrl[i].ctrlCode; |
| 31521 | 31057 | iCtrl = i; |
| 31522 | 31058 | }else{ |
| 31523 | | - eputf("Error: ambiguous test-control: \"%s\"\n" |
| 31059 | + sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n" |
| 31524 | 31060 | "Use \".testctrl --help\" for help\n", zCmd); |
| 31525 | 31061 | rc = 1; |
| 31526 | 31062 | goto meta_command_exit; |
| 31527 | 31063 | } |
| 31528 | 31064 | } |
| 31529 | 31065 | } |
| 31530 | 31066 | if( testctrl<0 ){ |
| 31531 | | - eputf("Error: unknown test-control: %s\n" |
| 31067 | + sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n" |
| 31532 | 31068 | "Use \".testctrl --help\" for help\n", zCmd); |
| 31533 | 31069 | }else{ |
| 31534 | 31070 | switch(testctrl){ |
| 31535 | 31071 | |
| 31536 | 31072 | /* Special processing for .testctrl opt MASK ... |
| | @@ -31602,16 +31138,17 @@ |
| 31602 | 31138 | int jj; |
| 31603 | 31139 | for(jj=0; jj<ArraySize(aLabel); jj++){ |
| 31604 | 31140 | if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break; |
| 31605 | 31141 | } |
| 31606 | 31142 | if( jj>=ArraySize(aLabel) ){ |
| 31607 | | - eputf("Error: no such optimization: \"%s\"\n", zLabel); |
| 31608 | | - eputz("Should be one of:"); |
| 31143 | + sqlite3_fprintf(stderr, |
| 31144 | + "Error: no such optimization: \"%s\"\n", zLabel); |
| 31145 | + sqlite3_fputs("Should be one of:", stderr); |
| 31609 | 31146 | for(jj=0; jj<ArraySize(aLabel); jj++){ |
| 31610 | | - eputf(" %s", aLabel[jj].zLabel); |
| 31147 | + sqlite3_fprintf(stderr," %s", aLabel[jj].zLabel); |
| 31611 | 31148 | } |
| 31612 | | - eputz("\n"); |
| 31149 | + sqlite3_fputs("\n", stderr); |
| 31613 | 31150 | rc = 1; |
| 31614 | 31151 | goto meta_command_exit; |
| 31615 | 31152 | } |
| 31616 | 31153 | if( useLabel=='+' ){ |
| 31617 | 31154 | newOpt &= ~aLabel[jj].mask; |
| | @@ -31624,20 +31161,20 @@ |
| 31624 | 31161 | sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt); |
| 31625 | 31162 | }else if( nArg<3 ){ |
| 31626 | 31163 | curOpt = ~newOpt; |
| 31627 | 31164 | } |
| 31628 | 31165 | if( newOpt==0 ){ |
| 31629 | | - oputz("+All\n"); |
| 31166 | + sqlite3_fputs("+All\n", p->out); |
| 31630 | 31167 | }else if( newOpt==0xffffffff ){ |
| 31631 | | - oputz("-All\n"); |
| 31168 | + sqlite3_fputs("-All\n", p->out); |
| 31632 | 31169 | }else{ |
| 31633 | 31170 | int jj; |
| 31634 | 31171 | for(jj=0; jj<ArraySize(aLabel); jj++){ |
| 31635 | 31172 | unsigned int m = aLabel[jj].mask; |
| 31636 | 31173 | if( !aLabel[jj].bDsply ) continue; |
| 31637 | 31174 | if( (curOpt&m)!=(newOpt&m) ){ |
| 31638 | | - oputf("%c%s\n", (newOpt & m)==0 ? '+' : '-', |
| 31175 | + sqlite3_fprintf(p->out, "%c%s\n", (newOpt & m)==0 ? '+' : '-', |
| 31639 | 31176 | aLabel[jj].zLabel); |
| 31640 | 31177 | } |
| 31641 | 31178 | } |
| 31642 | 31179 | } |
| 31643 | 31180 | rc2 = isOk = 3; |
| | @@ -31677,11 +31214,11 @@ |
| 31677 | 31214 | if( nArg==3 || nArg==4 ){ |
| 31678 | 31215 | int ii = (int)integerValue(azArg[2]); |
| 31679 | 31216 | sqlite3 *db; |
| 31680 | 31217 | if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){ |
| 31681 | 31218 | sqlite3_randomness(sizeof(ii),&ii); |
| 31682 | | - sputf(stdout, "-- random seed: %d\n", ii); |
| 31219 | + sqlite3_fprintf(stdout, "-- random seed: %d\n", ii); |
| 31683 | 31220 | } |
| 31684 | 31221 | if( nArg==3 ){ |
| 31685 | 31222 | db = 0; |
| 31686 | 31223 | }else{ |
| 31687 | 31224 | db = p->db; |
| | @@ -31745,11 +31282,11 @@ |
| 31745 | 31282 | break; |
| 31746 | 31283 | |
| 31747 | 31284 | case SQLITE_TESTCTRL_SEEK_COUNT: { |
| 31748 | 31285 | u64 x = 0; |
| 31749 | 31286 | rc2 = sqlite3_test_control(testctrl, p->db, &x); |
| 31750 | | - oputf("%llu\n", x); |
| 31287 | + sqlite3_fprintf(p->out, "%llu\n", x); |
| 31751 | 31288 | isOk = 3; |
| 31752 | 31289 | break; |
| 31753 | 31290 | } |
| 31754 | 31291 | |
| 31755 | 31292 | #ifdef YYCOVERAGE |
| | @@ -31776,15 +31313,15 @@ |
| 31776 | 31313 | int id = 1; |
| 31777 | 31314 | while(1){ |
| 31778 | 31315 | int val = 0; |
| 31779 | 31316 | rc2 = sqlite3_test_control(testctrl, -id, &val); |
| 31780 | 31317 | if( rc2!=SQLITE_OK ) break; |
| 31781 | | - if( id>1 ) oputz(" "); |
| 31782 | | - oputf("%d: %d", id, val); |
| 31318 | + if( id>1 ) sqlite3_fputs(" ", p->out); |
| 31319 | + sqlite3_fprintf(p->out, "%d: %d", id, val); |
| 31783 | 31320 | id++; |
| 31784 | 31321 | } |
| 31785 | | - if( id>1 ) oputz("\n"); |
| 31322 | + if( id>1 ) sqlite3_fputs("\n", p->out); |
| 31786 | 31323 | isOk = 3; |
| 31787 | 31324 | } |
| 31788 | 31325 | break; |
| 31789 | 31326 | } |
| 31790 | 31327 | #endif |
| | @@ -31822,18 +31359,26 @@ |
| 31822 | 31359 | }else if( cli_strcmp(z,"reset")==0 ){ |
| 31823 | 31360 | faultsim_state.iCnt = faultsim_state.nSkip; |
| 31824 | 31361 | faultsim_state.nHit = 0; |
| 31825 | 31362 | sqlite3_test_control(testctrl, faultsim_callback); |
| 31826 | 31363 | }else if( cli_strcmp(z,"status")==0 ){ |
| 31827 | | - oputf("faultsim.iId: %d\n", faultsim_state.iId); |
| 31828 | | - oputf("faultsim.iErr: %d\n", faultsim_state.iErr); |
| 31829 | | - oputf("faultsim.iCnt: %d\n", faultsim_state.iCnt); |
| 31830 | | - oputf("faultsim.nHit: %d\n", faultsim_state.nHit); |
| 31831 | | - oputf("faultsim.iInterval: %d\n", faultsim_state.iInterval); |
| 31832 | | - oputf("faultsim.eVerbose: %d\n", faultsim_state.eVerbose); |
| 31833 | | - oputf("faultsim.nRepeat: %d\n", faultsim_state.nRepeat); |
| 31834 | | - oputf("faultsim.nSkip: %d\n", faultsim_state.nSkip); |
| 31364 | + sqlite3_fprintf(p->out, "faultsim.iId: %d\n", |
| 31365 | + faultsim_state.iId); |
| 31366 | + sqlite3_fprintf(p->out, "faultsim.iErr: %d\n", |
| 31367 | + faultsim_state.iErr); |
| 31368 | + sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n", |
| 31369 | + faultsim_state.iCnt); |
| 31370 | + sqlite3_fprintf(p->out, "faultsim.nHit: %d\n", |
| 31371 | + faultsim_state.nHit); |
| 31372 | + sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n", |
| 31373 | + faultsim_state.iInterval); |
| 31374 | + sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n", |
| 31375 | + faultsim_state.eVerbose); |
| 31376 | + sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n", |
| 31377 | + faultsim_state.nRepeat); |
| 31378 | + sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n", |
| 31379 | + faultsim_state.nSkip); |
| 31835 | 31380 | }else if( cli_strcmp(z,"-v")==0 ){ |
| 31836 | 31381 | if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++; |
| 31837 | 31382 | }else if( cli_strcmp(z,"-q")==0 ){ |
| 31838 | 31383 | if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--; |
| 31839 | 31384 | }else if( cli_strcmp(z,"-id")==0 && kk+1<nArg ){ |
| | @@ -31847,19 +31392,20 @@ |
| 31847 | 31392 | }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){ |
| 31848 | 31393 | faultsim_state.nSkip = atoi(azArg[++kk]); |
| 31849 | 31394 | }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){ |
| 31850 | 31395 | bShowHelp = 1; |
| 31851 | 31396 | }else{ |
| 31852 | | - eputf("Unrecognized fault_install argument: \"%s\"\n", |
| 31397 | + sqlite3_fprintf(stderr, |
| 31398 | + "Unrecognized fault_install argument: \"%s\"\n", |
| 31853 | 31399 | azArg[kk]); |
| 31854 | 31400 | rc = 1; |
| 31855 | 31401 | bShowHelp = 1; |
| 31856 | 31402 | break; |
| 31857 | 31403 | } |
| 31858 | 31404 | } |
| 31859 | 31405 | if( bShowHelp ){ |
| 31860 | | - oputz( |
| 31406 | + sqlite3_fputs( |
| 31861 | 31407 | "Usage: .testctrl fault_install ARGS\n" |
| 31862 | 31408 | "Possible arguments:\n" |
| 31863 | 31409 | " off Disable faultsim\n" |
| 31864 | 31410 | " on Activate faultsim\n" |
| 31865 | 31411 | " reset Reset the trigger counter\n" |
| | @@ -31869,23 +31415,25 @@ |
| 31869 | 31415 | " --errcode N When triggered, return N as error code\n" |
| 31870 | 31416 | " --id ID Trigger only for the ID specified\n" |
| 31871 | 31417 | " --interval N Trigger only after every N-th call\n" |
| 31872 | 31418 | " --repeat N Turn off after N hits. 0 means never\n" |
| 31873 | 31419 | " --skip N Skip the first N encounters\n" |
| 31420 | + ,p->out |
| 31874 | 31421 | ); |
| 31875 | 31422 | } |
| 31876 | 31423 | break; |
| 31877 | 31424 | } |
| 31878 | 31425 | } |
| 31879 | 31426 | } |
| 31880 | 31427 | if( isOk==0 && iCtrl>=0 ){ |
| 31881 | | - oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); |
| 31428 | + sqlite3_fprintf(p->out, |
| 31429 | + "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); |
| 31882 | 31430 | rc = 1; |
| 31883 | 31431 | }else if( isOk==1 ){ |
| 31884 | | - oputf("%d\n", rc2); |
| 31432 | + sqlite3_fprintf(p->out, "%d\n", rc2); |
| 31885 | 31433 | }else if( isOk==2 ){ |
| 31886 | | - oputf("0x%08x\n", rc2); |
| 31434 | + sqlite3_fprintf(p->out, "0x%08x\n", rc2); |
| 31887 | 31435 | } |
| 31888 | 31436 | }else |
| 31889 | 31437 | #endif /* !defined(SQLITE_UNTESTABLE) */ |
| 31890 | 31438 | |
| 31891 | 31439 | if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){ |
| | @@ -31936,11 +31484,11 @@ |
| 31936 | 31484 | } |
| 31937 | 31485 | else if( optionMatch(z, "close") ){ |
| 31938 | 31486 | mType |= SQLITE_TRACE_CLOSE; |
| 31939 | 31487 | } |
| 31940 | 31488 | else { |
| 31941 | | - eputf("Unknown option \"%s\" on \".trace\"\n", z); |
| 31489 | + sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".trace\"\n", z); |
| 31942 | 31490 | rc = 1; |
| 31943 | 31491 | goto meta_command_exit; |
| 31944 | 31492 | } |
| 31945 | 31493 | }else{ |
| 31946 | 31494 | output_file_close(p->traceOut); |
| | @@ -31996,11 +31544,11 @@ |
| 31996 | 31544 | goto meta_command_exit; |
| 31997 | 31545 | } |
| 31998 | 31546 | rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], |
| 31999 | 31547 | strlen30(azArg[3])); |
| 32000 | 31548 | if( rc ){ |
| 32001 | | - eputf("Authentication failed for user %s\n", azArg[2]); |
| 31549 | + sqlite3_fprintf(stderr,"Authentication failed for user %s\n", azArg[2]); |
| 32002 | 31550 | rc = 1; |
| 32003 | 31551 | } |
| 32004 | 31552 | }else if( cli_strcmp(azArg[1],"add")==0 ){ |
| 32005 | 31553 | if( nArg!=5 ){ |
| 32006 | 31554 | eputz("Usage: .user add USER PASSWORD ISADMIN\n"); |
| | @@ -32008,11 +31556,11 @@ |
| 32008 | 31556 | goto meta_command_exit; |
| 32009 | 31557 | } |
| 32010 | 31558 | rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]), |
| 32011 | 31559 | booleanValue(azArg[4])); |
| 32012 | 31560 | if( rc ){ |
| 32013 | | - eputf("User-Add failed: %d\n", rc); |
| 31561 | + sqlite3_fprintf(stderr,"User-Add failed: %d\n", rc); |
| 32014 | 31562 | rc = 1; |
| 32015 | 31563 | } |
| 32016 | 31564 | }else if( cli_strcmp(azArg[1],"edit")==0 ){ |
| 32017 | 31565 | if( nArg!=5 ){ |
| 32018 | 31566 | eputz("Usage: .user edit USER PASSWORD ISADMIN\n"); |
| | @@ -32020,11 +31568,11 @@ |
| 32020 | 31568 | goto meta_command_exit; |
| 32021 | 31569 | } |
| 32022 | 31570 | rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]), |
| 32023 | 31571 | booleanValue(azArg[4])); |
| 32024 | 31572 | if( rc ){ |
| 32025 | | - eputf("User-Edit failed: %d\n", rc); |
| 31573 | + sqlite3_fprintf(stderr,"User-Edit failed: %d\n", rc); |
| 32026 | 31574 | rc = 1; |
| 32027 | 31575 | } |
| 32028 | 31576 | }else if( cli_strcmp(azArg[1],"delete")==0 ){ |
| 32029 | 31577 | if( nArg!=3 ){ |
| 32030 | 31578 | eputz("Usage: .user delete USER\n"); |
| | @@ -32031,11 +31579,11 @@ |
| 32031 | 31579 | rc = 1; |
| 32032 | 31580 | goto meta_command_exit; |
| 32033 | 31581 | } |
| 32034 | 31582 | rc = sqlite3_user_delete(p->db, azArg[2]); |
| 32035 | 31583 | if( rc ){ |
| 32036 | | - eputf("User-Delete failed: %d\n", rc); |
| 31584 | + sqlite3_fprintf(stderr,"User-Delete failed: %d\n", rc); |
| 32037 | 31585 | rc = 1; |
| 32038 | 31586 | } |
| 32039 | 31587 | }else{ |
| 32040 | 31588 | eputz("Usage: .user login|add|edit|delete ...\n"); |
| 32041 | 31589 | rc = 1; |
| | @@ -32044,38 +31592,38 @@ |
| 32044 | 31592 | }else |
| 32045 | 31593 | #endif /* SQLITE_USER_AUTHENTICATION */ |
| 32046 | 31594 | |
| 32047 | 31595 | if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ |
| 32048 | 31596 | char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; |
| 32049 | | - oputf("SQLite %s %s\n" /*extra-version-info*/, |
| 31597 | + sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, |
| 32050 | 31598 | sqlite3_libversion(), sqlite3_sourceid()); |
| 32051 | 31599 | #if SQLITE_HAVE_ZLIB |
| 32052 | | - oputf("zlib version %s\n", zlibVersion()); |
| 31600 | + sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion()); |
| 32053 | 31601 | #endif |
| 32054 | 31602 | #define CTIMEOPT_VAL_(opt) #opt |
| 32055 | 31603 | #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) |
| 32056 | 31604 | #if defined(__clang__) && defined(__clang_major__) |
| 32057 | | - oputf("clang-" CTIMEOPT_VAL(__clang_major__) "." |
| 31605 | + sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." |
| 32058 | 31606 | CTIMEOPT_VAL(__clang_minor__) "." |
| 32059 | 31607 | CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz); |
| 32060 | 31608 | #elif defined(_MSC_VER) |
| 32061 | | - oputf("msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); |
| 31609 | + sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); |
| 32062 | 31610 | #elif defined(__GNUC__) && defined(__VERSION__) |
| 32063 | | - oputf("gcc-" __VERSION__ " (%s)\n", zPtrSz); |
| 31611 | + sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz); |
| 32064 | 31612 | #endif |
| 32065 | 31613 | }else |
| 32066 | 31614 | |
| 32067 | 31615 | if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){ |
| 32068 | 31616 | const char *zDbName = nArg==2 ? azArg[1] : "main"; |
| 32069 | 31617 | sqlite3_vfs *pVfs = 0; |
| 32070 | 31618 | if( p->db ){ |
| 32071 | 31619 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); |
| 32072 | 31620 | if( pVfs ){ |
| 32073 | | - oputf("vfs.zName = \"%s\"\n", pVfs->zName); |
| 32074 | | - oputf("vfs.iVersion = %d\n", pVfs->iVersion); |
| 32075 | | - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); |
| 32076 | | - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); |
| 31621 | + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); |
| 31622 | + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); |
| 31623 | + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); |
| 31624 | + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); |
| 32077 | 31625 | } |
| 32078 | 31626 | } |
| 32079 | 31627 | }else |
| 32080 | 31628 | |
| 32081 | 31629 | if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){ |
| | @@ -32083,17 +31631,17 @@ |
| 32083 | 31631 | sqlite3_vfs *pCurrent = 0; |
| 32084 | 31632 | if( p->db ){ |
| 32085 | 31633 | sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); |
| 32086 | 31634 | } |
| 32087 | 31635 | for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ |
| 32088 | | - oputf("vfs.zName = \"%s\"%s\n", pVfs->zName, |
| 31636 | + sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, |
| 32089 | 31637 | pVfs==pCurrent ? " <--- CURRENT" : ""); |
| 32090 | | - oputf("vfs.iVersion = %d\n", pVfs->iVersion); |
| 32091 | | - oputf("vfs.szOsFile = %d\n", pVfs->szOsFile); |
| 32092 | | - oputf("vfs.mxPathname = %d\n", pVfs->mxPathname); |
| 31638 | + sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); |
| 31639 | + sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); |
| 31640 | + sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); |
| 32093 | 31641 | if( pVfs->pNext ){ |
| 32094 | | - oputz("-----------------------------------\n"); |
| 31642 | + sqlite3_fputs("-----------------------------------\n", p->out); |
| 32095 | 31643 | } |
| 32096 | 31644 | } |
| 32097 | 31645 | }else |
| 32098 | 31646 | |
| 32099 | 31647 | if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){ |
| | @@ -32100,11 +31648,11 @@ |
| 32100 | 31648 | const char *zDbName = nArg==2 ? azArg[1] : "main"; |
| 32101 | 31649 | char *zVfsName = 0; |
| 32102 | 31650 | if( p->db ){ |
| 32103 | 31651 | sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); |
| 32104 | 31652 | if( zVfsName ){ |
| 32105 | | - oputf("%s\n", zVfsName); |
| 31653 | + sqlite3_fprintf(p->out, "%s\n", zVfsName); |
| 32106 | 31654 | sqlite3_free(zVfsName); |
| 32107 | 31655 | } |
| 32108 | 31656 | } |
| 32109 | 31657 | }else |
| 32110 | 31658 | |
| | @@ -32124,11 +31672,11 @@ |
| 32124 | 31672 | p->colWidth[j-1] = (int)integerValue(azArg[j]); |
| 32125 | 31673 | } |
| 32126 | 31674 | }else |
| 32127 | 31675 | |
| 32128 | 31676 | { |
| 32129 | | - eputf("Error: unknown command or invalid arguments: " |
| 31677 | + sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " |
| 32130 | 31678 | " \"%s\". Enter \".help\" for help\n", azArg[0]); |
| 32131 | 31679 | rc = 1; |
| 32132 | 31680 | } |
| 32133 | 31681 | |
| 32134 | 31682 | meta_command_exit: |
| | @@ -32376,11 +31924,11 @@ |
| 32376 | 31924 | open_db(p, 0); |
| 32377 | 31925 | if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); |
| 32378 | 31926 | if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; |
| 32379 | 31927 | BEGIN_TIMER; |
| 32380 | 31928 | rc = shell_exec(p, zSql, &zErrMsg); |
| 32381 | | - END_TIMER; |
| 31929 | + END_TIMER(p->out); |
| 32382 | 31930 | if( rc || zErrMsg ){ |
| 32383 | 31931 | char zPrefix[100]; |
| 32384 | 31932 | const char *zErrorTail; |
| 32385 | 31933 | const char *zErrorType; |
| 32386 | 31934 | if( zErrMsg==0 ){ |
| | @@ -32400,28 +31948,28 @@ |
| 32400 | 31948 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, |
| 32401 | 31949 | "%s near line %d:", zErrorType, startline); |
| 32402 | 31950 | }else{ |
| 32403 | 31951 | sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType); |
| 32404 | 31952 | } |
| 32405 | | - eputf("%s %s\n", zPrefix, zErrorTail); |
| 31953 | + sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail); |
| 32406 | 31954 | sqlite3_free(zErrMsg); |
| 32407 | 31955 | zErrMsg = 0; |
| 32408 | 31956 | return 1; |
| 32409 | 31957 | }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ |
| 32410 | 31958 | char zLineBuf[2000]; |
| 32411 | 31959 | sqlite3_snprintf(sizeof(zLineBuf), zLineBuf, |
| 32412 | 31960 | "changes: %lld total_changes: %lld", |
| 32413 | 31961 | sqlite3_changes64(p->db), sqlite3_total_changes64(p->db)); |
| 32414 | | - oputf("%s\n", zLineBuf); |
| 31962 | + sqlite3_fprintf(p->out, "%s\n", zLineBuf); |
| 32415 | 31963 | } |
| 32416 | 31964 | |
| 32417 | 31965 | if( doAutoDetectRestore(p, zSql) ) return 1; |
| 32418 | 31966 | return 0; |
| 32419 | 31967 | } |
| 32420 | 31968 | |
| 32421 | 31969 | static void echo_group_input(ShellState *p, const char *zDo){ |
| 32422 | | - if( ShellHasFlag(p, SHFLG_Echo) ) oputf("%s\n", zDo); |
| 31970 | + if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo); |
| 32423 | 31971 | } |
| 32424 | 31972 | |
| 32425 | 31973 | #ifdef SQLITE_SHELL_FIDDLE |
| 32426 | 31974 | /* |
| 32427 | 31975 | ** Alternate one_input_line() impl for wasm mode. This is not in the primary |
| | @@ -32475,11 +32023,11 @@ |
| 32475 | 32023 | i64 startline = 0; /* Line number for start of current input */ |
| 32476 | 32024 | QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */ |
| 32477 | 32025 | |
| 32478 | 32026 | if( p->inputNesting==MAX_INPUT_NESTING ){ |
| 32479 | 32027 | /* This will be more informative in a later version. */ |
| 32480 | | - eputf("Input nesting limit (%d) reached at line %d." |
| 32028 | + sqlite3_fprintf(stderr,"Input nesting limit (%d) reached at line %d." |
| 32481 | 32029 | " Check recursion.\n", MAX_INPUT_NESTING, p->lineno); |
| 32482 | 32030 | return 1; |
| 32483 | 32031 | } |
| 32484 | 32032 | ++p->inputNesting; |
| 32485 | 32033 | p->lineno = 0; |
| | @@ -32487,11 +32035,11 @@ |
| 32487 | 32035 | while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){ |
| 32488 | 32036 | fflush(p->out); |
| 32489 | 32037 | zLine = one_input_line(p->in, zLine, nSql>0); |
| 32490 | 32038 | if( zLine==0 ){ |
| 32491 | 32039 | /* End of input */ |
| 32492 | | - if( p->in==0 && stdin_is_interactive ) oputz("\n"); |
| 32040 | + if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out); |
| 32493 | 32041 | break; |
| 32494 | 32042 | } |
| 32495 | 32043 | if( seenInterrupt ){ |
| 32496 | 32044 | if( p->in!=0 ) break; |
| 32497 | 32045 | seenInterrupt = 0; |
| | @@ -32707,19 +32255,19 @@ |
| 32707 | 32255 | } |
| 32708 | 32256 | zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); |
| 32709 | 32257 | shell_check_oom(zBuf); |
| 32710 | 32258 | sqliterc = zBuf; |
| 32711 | 32259 | } |
| 32712 | | - p->in = fopen(sqliterc,"rb"); |
| 32260 | + p->in = sqlite3_fopen(sqliterc,"rb"); |
| 32713 | 32261 | if( p->in ){ |
| 32714 | 32262 | if( stdin_is_interactive ){ |
| 32715 | | - eputf("-- Loading resources from %s\n", sqliterc); |
| 32263 | + sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); |
| 32716 | 32264 | } |
| 32717 | 32265 | if( process_input(p) && bail_on_error ) exit(1); |
| 32718 | 32266 | fclose(p->in); |
| 32719 | 32267 | }else if( sqliterc_override!=0 ){ |
| 32720 | | - eputf("cannot open: \"%s\"\n", sqliterc); |
| 32268 | + sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); |
| 32721 | 32269 | if( bail_on_error ) exit(1); |
| 32722 | 32270 | } |
| 32723 | 32271 | p->in = inSaved; |
| 32724 | 32272 | p->lineno = savedLineno; |
| 32725 | 32273 | sqlite3_free(zBuf); |
| | @@ -32790,15 +32338,15 @@ |
| 32790 | 32338 | #ifdef SQLITE_HAVE_ZLIB |
| 32791 | 32339 | " -zip open the file as a ZIP Archive\n" |
| 32792 | 32340 | #endif |
| 32793 | 32341 | ; |
| 32794 | 32342 | static void usage(int showDetail){ |
| 32795 | | - eputf("Usage: %s [OPTIONS] [FILENAME [SQL]]\n" |
| 32343 | + sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL]]\n" |
| 32796 | 32344 | "FILENAME is the name of an SQLite database. A new database is created\n" |
| 32797 | 32345 | "if the file does not previously exist. Defaults to :memory:.\n", Argv0); |
| 32798 | 32346 | if( showDetail ){ |
| 32799 | | - eputf("OPTIONS include:\n%s", zOptions); |
| 32347 | + sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions); |
| 32800 | 32348 | }else{ |
| 32801 | 32349 | eputz("Use the -help option for additional information\n"); |
| 32802 | 32350 | } |
| 32803 | 32351 | exit(0); |
| 32804 | 32352 | } |
| | @@ -32854,21 +32402,22 @@ |
| 32854 | 32402 | SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); |
| 32855 | 32403 | #endif |
| 32856 | 32404 | } |
| 32857 | 32405 | #else |
| 32858 | 32406 | static void printBold(const char *zText){ |
| 32859 | | - sputf(stdout, "\033[1m%s\033[0m", zText); |
| 32407 | + sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText); |
| 32860 | 32408 | } |
| 32861 | 32409 | #endif |
| 32862 | 32410 | |
| 32863 | 32411 | /* |
| 32864 | 32412 | ** Get the argument to an --option. Throw an error and die if no argument |
| 32865 | 32413 | ** is available. |
| 32866 | 32414 | */ |
| 32867 | 32415 | static char *cmdline_option_value(int argc, char **argv, int i){ |
| 32868 | 32416 | if( i==argc ){ |
| 32869 | | - eputf("%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); |
| 32417 | + sqlite3_fprintf(stderr, |
| 32418 | + "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); |
| 32870 | 32419 | exit(1); |
| 32871 | 32420 | } |
| 32872 | 32421 | return argv[i]; |
| 32873 | 32422 | } |
| 32874 | 32423 | |
| | @@ -32901,11 +32450,10 @@ |
| 32901 | 32450 | char *zErrMsg = 0; |
| 32902 | 32451 | #ifdef SQLITE_SHELL_FIDDLE |
| 32903 | 32452 | # define data shellState |
| 32904 | 32453 | #else |
| 32905 | 32454 | ShellState data; |
| 32906 | | - StreamsAreConsole consStreams = SAC_NoConsole; |
| 32907 | 32455 | #endif |
| 32908 | 32456 | const char *zInitFile = 0; |
| 32909 | 32457 | int i; |
| 32910 | 32458 | int rc = 0; |
| 32911 | 32459 | int warnInmemoryDb = 0; |
| | @@ -32924,25 +32472,25 @@ |
| 32924 | 32472 | #ifdef SQLITE_SHELL_FIDDLE |
| 32925 | 32473 | stdin_is_interactive = 0; |
| 32926 | 32474 | stdout_is_console = 1; |
| 32927 | 32475 | data.wasm.zDefaultDbName = "/fiddle.sqlite3"; |
| 32928 | 32476 | #else |
| 32929 | | - consStreams = consoleClassifySetup(stdin, stdout, stderr); |
| 32930 | | - stdin_is_interactive = (consStreams & SAC_InConsole)!=0; |
| 32931 | | - stdout_is_console = (consStreams & SAC_OutConsole)!=0; |
| 32932 | | - atexit(consoleRestore); |
| 32477 | + stdin_is_interactive = isatty(0); |
| 32478 | + stdout_is_console = isatty(1); |
| 32933 | 32479 | #endif |
| 32934 | 32480 | atexit(sayAbnormalExit); |
| 32935 | 32481 | #ifdef SQLITE_DEBUG |
| 32936 | 32482 | mem_main_enter = sqlite3_memory_used(); |
| 32937 | 32483 | #endif |
| 32938 | 32484 | #if !defined(_WIN32_WCE) |
| 32939 | 32485 | if( getenv("SQLITE_DEBUG_BREAK") ){ |
| 32940 | 32486 | if( isatty(0) && isatty(2) ){ |
| 32941 | | - eputf("attach debugger to process %d and press any key to continue.\n", |
| 32487 | + char zLine[100]; |
| 32488 | + sqlite3_fprintf(stderr, |
| 32489 | + "attach debugger to process %d and press ENTER to continue...", |
| 32942 | 32490 | GETPID()); |
| 32943 | | - fgetc(stdin); |
| 32491 | + sqlite3_fgets(zLine, sizeof(zLine), stdin); |
| 32944 | 32492 | }else{ |
| 32945 | 32493 | #if defined(_WIN32) || defined(WIN32) |
| 32946 | 32494 | #if SQLITE_OS_WINRT |
| 32947 | 32495 | __debugbreak(); |
| 32948 | 32496 | #else |
| | @@ -32963,11 +32511,12 @@ |
| 32963 | 32511 | } |
| 32964 | 32512 | #endif |
| 32965 | 32513 | |
| 32966 | 32514 | #if USE_SYSTEM_SQLITE+0!=1 |
| 32967 | 32515 | if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ |
| 32968 | | - eputf("SQLite header and source version mismatch\n%s\n%s\n", |
| 32516 | + sqlite3_fprintf(stderr, |
| 32517 | + "SQLite header and source version mismatch\n%s\n%s\n", |
| 32969 | 32518 | sqlite3_sourceid(), SQLITE_SOURCE_ID); |
| 32970 | 32519 | exit(1); |
| 32971 | 32520 | } |
| 32972 | 32521 | #endif |
| 32973 | 32522 | main_init(&data); |
| | @@ -33106,11 +32655,12 @@ |
| 33106 | 32655 | case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break; |
| 33107 | 32656 | case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break; |
| 33108 | 32657 | default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; |
| 33109 | 32658 | } |
| 33110 | 32659 | }else if( cli_strcmp(z,"-vfstrace")==0 ){ |
| 33111 | | - vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1); |
| 32660 | + vfstrace_register("trace",0,(int(*)(const char*,void*))sqlite3_fputs, |
| 32661 | + stderr,1); |
| 33112 | 32662 | bEnableVfstrace = 1; |
| 33113 | 32663 | #ifdef SQLITE_ENABLE_MULTIPLEX |
| 33114 | 32664 | }else if( cli_strcmp(z,"-multiplex")==0 ){ |
| 33115 | 32665 | extern int sqlite3_multiplex_initialize(const char*,int); |
| 33116 | 32666 | sqlite3_multiplex_initialize(0, 1); |
| | @@ -33187,21 +32737,22 @@ |
| 33187 | 32737 | if( zVfs ){ |
| 33188 | 32738 | sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs); |
| 33189 | 32739 | if( pVfs ){ |
| 33190 | 32740 | sqlite3_vfs_register(pVfs, 1); |
| 33191 | 32741 | }else{ |
| 33192 | | - eputf("no such VFS: \"%s\"\n", zVfs); |
| 32742 | + sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs); |
| 33193 | 32743 | exit(1); |
| 33194 | 32744 | } |
| 33195 | 32745 | } |
| 33196 | 32746 | |
| 33197 | 32747 | if( data.pAuxDb->zDbFilename==0 ){ |
| 33198 | 32748 | #ifndef SQLITE_OMIT_MEMORYDB |
| 33199 | 32749 | data.pAuxDb->zDbFilename = ":memory:"; |
| 33200 | 32750 | warnInmemoryDb = argc==1; |
| 33201 | 32751 | #else |
| 33202 | | - eputf("%s: Error: no database filename specified\n", Argv0); |
| 32752 | + sqlite3_fprintf(stderr, |
| 32753 | + "%s: Error: no database filename specified\n", Argv0); |
| 33203 | 32754 | return 1; |
| 33204 | 32755 | #endif |
| 33205 | 32756 | } |
| 33206 | 32757 | data.out = stdout; |
| 33207 | 32758 | #ifndef SQLITE_SHELL_FIDDLE |
| | @@ -33314,11 +32865,11 @@ |
| 33314 | 32865 | */ |
| 33315 | 32866 | ShellSetFlag(&data, SHFLG_Backslash); |
| 33316 | 32867 | }else if( cli_strcmp(z,"-bail")==0 ){ |
| 33317 | 32868 | /* No-op. The bail_on_error flag should already be set. */ |
| 33318 | 32869 | }else if( cli_strcmp(z,"-version")==0 ){ |
| 33319 | | - sputf(stdout, "%s %s (%d-bit)\n", |
| 32870 | + sqlite3_fprintf(stdout, "%s %s (%d-bit)\n", |
| 33320 | 32871 | sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*)); |
| 33321 | 32872 | return 0; |
| 33322 | 32873 | }else if( cli_strcmp(z,"-interactive")==0 ){ |
| 33323 | 32874 | /* Need to check for interactive override here to so that it can |
| 33324 | 32875 | ** affect console setup (for Windows only) and testing thereof. |
| | @@ -33377,18 +32928,18 @@ |
| 33377 | 32928 | rc = shell_exec(&data, z, &zErrMsg); |
| 33378 | 32929 | if( zErrMsg!=0 ){ |
| 33379 | 32930 | shellEmitError(zErrMsg); |
| 33380 | 32931 | if( bail_on_error ) return rc!=0 ? rc : 1; |
| 33381 | 32932 | }else if( rc!=0 ){ |
| 33382 | | - eputf("Error: unable to process SQL \"%s\"\n", z); |
| 32933 | + sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); |
| 33383 | 32934 | if( bail_on_error ) return rc; |
| 33384 | 32935 | } |
| 33385 | 32936 | } |
| 33386 | 32937 | #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) |
| 33387 | 32938 | }else if( cli_strncmp(z, "-A", 2)==0 ){ |
| 33388 | 32939 | if( nCmd>0 ){ |
| 33389 | | - eputf("Error: cannot mix regular SQL or dot-commands" |
| 32940 | + sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands" |
| 33390 | 32941 | " with \"%s\"\n", z); |
| 33391 | 32942 | return 1; |
| 33392 | 32943 | } |
| 33393 | 32944 | open_db(&data, OPEN_DB_ZIPFILE); |
| 33394 | 32945 | if( z[2] ){ |
| | @@ -33403,11 +32954,11 @@ |
| 33403 | 32954 | }else if( cli_strcmp(z,"-safe")==0 ){ |
| 33404 | 32955 | data.bSafeMode = data.bSafeModePersist = 1; |
| 33405 | 32956 | }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ |
| 33406 | 32957 | /* Acted upon in first pass. */ |
| 33407 | 32958 | }else{ |
| 33408 | | - eputf("%s: Error: unknown option: %s\n", Argv0, z); |
| 32959 | + sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); |
| 33409 | 32960 | eputz("Use -help for a list of options.\n"); |
| 33410 | 32961 | return 1; |
| 33411 | 32962 | } |
| 33412 | 32963 | data.cMode = data.mode; |
| 33413 | 32964 | } |
| | @@ -33430,11 +32981,12 @@ |
| 33430 | 32981 | rc = shell_exec(&data, azCmd[i], &zErrMsg); |
| 33431 | 32982 | if( zErrMsg || rc ){ |
| 33432 | 32983 | if( zErrMsg!=0 ){ |
| 33433 | 32984 | shellEmitError(zErrMsg); |
| 33434 | 32985 | }else{ |
| 33435 | | - eputf("Error: unable to process SQL: %s\n", azCmd[i]); |
| 32986 | + sqlite3_fprintf(stderr, |
| 32987 | + "Error: unable to process SQL: %s\n", azCmd[i]); |
| 33436 | 32988 | } |
| 33437 | 32989 | sqlite3_free(zErrMsg); |
| 33438 | 32990 | if( rc==0 ) rc = 1; |
| 33439 | 32991 | goto shell_main_exit; |
| 33440 | 32992 | } |
| | @@ -33450,11 +33002,12 @@ |
| 33450 | 33002 | #if CIO_WIN_WC_XLATE |
| 33451 | 33003 | # define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "") |
| 33452 | 33004 | #else |
| 33453 | 33005 | # define SHELL_CIO_CHAR_SET "" |
| 33454 | 33006 | #endif |
| 33455 | | - sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/ |
| 33007 | + sqlite3_fprintf(stdout, |
| 33008 | + "SQLite version %s %.19s%s\n" /*extra-version-info*/ |
| 33456 | 33009 | "Enter \".help\" for usage hints.\n", |
| 33457 | 33010 | sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET); |
| 33458 | 33011 | if( warnInmemoryDb ){ |
| 33459 | 33012 | sputz(stdout, "Connected to a "); |
| 33460 | 33013 | printBold("transient in-memory database"); |
| | @@ -33526,11 +33079,11 @@ |
| 33526 | 33079 | if( bEnableVfstrace ){ |
| 33527 | 33080 | vfstrace_unregister("trace"); |
| 33528 | 33081 | } |
| 33529 | 33082 | #ifdef SQLITE_DEBUG |
| 33530 | 33083 | if( sqlite3_memory_used()>mem_main_enter ){ |
| 33531 | | - eputf("Memory leaked: %u bytes\n", |
| 33084 | + sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n", |
| 33532 | 33085 | (unsigned int)(sqlite3_memory_used()-mem_main_enter)); |
| 33533 | 33086 | } |
| 33534 | 33087 | #endif |
| 33535 | 33088 | #else /* SQLITE_SHELL_FIDDLE... */ |
| 33536 | 33089 | shell_main_exit: |
| | @@ -33566,11 +33119,11 @@ |
| 33566 | 33119 | return pVfs; |
| 33567 | 33120 | } |
| 33568 | 33121 | |
| 33569 | 33122 | /* Only for emcc experimentation purposes. */ |
| 33570 | 33123 | sqlite3 * fiddle_db_arg(sqlite3 *arg){ |
| 33571 | | - oputf("fiddle_db_arg(%p)\n", (const void*)arg); |
| 33124 | + sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg); |
| 33572 | 33125 | return arg; |
| 33573 | 33126 | } |
| 33574 | 33127 | |
| 33575 | 33128 | /* |
| 33576 | 33129 | ** Intended to be called via a SharedWorker() while a separate |
| | @@ -33603,11 +33156,11 @@ |
| 33603 | 33156 | while( sqlite3_txn_state(globalDb,0)>0 ){ |
| 33604 | 33157 | /* |
| 33605 | 33158 | ** Resolve problem reported in |
| 33606 | 33159 | ** https://sqlite.org/forum/forumpost/0b41a25d65 |
| 33607 | 33160 | */ |
| 33608 | | - oputz("Rolling back in-progress transaction.\n"); |
| 33161 | + sqlite3_fputs("Rolling back in-progress transaction.\n", stdout); |
| 33609 | 33162 | sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0); |
| 33610 | 33163 | } |
| 33611 | 33164 | rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); |
| 33612 | 33165 | if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); |
| 33613 | 33166 | sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); |
| 33614 | 33167 | |