RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [email protected] Module: rpm Date: 05-Apr-2010 19:19:41 Branch: HEAD Handle: 2010040517193901 Modified files: rpm CHANGES rpm/rpmio librpmio.vers rpmnix.h rpmsql.c rpmsql.h rpm/tools dbsql.c Log: - dbsql: send spewage to stdout or append to an iob, as needed. Summary: Revision Changes Path 1.3303 +1 -0 rpm/CHANGES 2.166 +1 -0 rpm/rpmio/librpmio.vers 1.19 +1 -1 rpm/rpmio/rpmnix.h 2.4 +149 -39 rpm/rpmio/rpmsql.c 2.5 +19 -0 rpm/rpmio/rpmsql.h 2.7 +206 -269 rpm/tools/dbsql.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3302 -r1.3303 CHANGES --- rpm/CHANGES 5 Apr 2010 12:26:27 -0000 1.3302 +++ rpm/CHANGES 5 Apr 2010 17:19:39 -0000 1.3303 @@ -1,5 +1,6 @@ 5.2b1 -> 5.3a1 + - jbj: dbsql: send spewage to stdout or append to an iob, as needed. - jbj: dbsql: move popt tables into -lrpmo for use by rpmsql ctor. - jbj: dbsql: refatoring to get an rpmsql object passed on callbacks. - jbj: dbsql: use popt for CLI processing. @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/librpmio.vers ============================================================================ $ cvs diff -u -r2.165 -r2.166 librpmio.vers --- rpm/rpmio/librpmio.vers 5 Apr 2010 12:26:28 -0000 2.165 +++ rpm/rpmio/librpmio.vers 5 Apr 2010 17:19:40 -0000 2.166 @@ -536,6 +536,7 @@ _sql; _rpmsql_debug; _rpmsqlOptions; + rpmsqlArgv; rpmsqlNew; rpmsqlRun; rpmsqlRunFile; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmnix.h ============================================================================ $ cvs diff -u -r1.18 -r1.19 rpmnix.h --- rpm/rpmio/rpmnix.h 4 Apr 2010 14:35:44 -0000 1.18 +++ rpm/rpmio/rpmnix.h 5 Apr 2010 17:19:40 -0000 1.19 @@ -289,7 +289,7 @@ * Return arguments from a nix interpreter. * @param nix nix interpreter * @retval *argcp no. of arguments - * @return new nix interpreter + * @return nix interpreter args */ /*...@null@*/ const char ** rpmnixArgv(/*...@null@*/ rpmnix nix, /*...@null@*/ int * argcp) @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmsql.c ============================================================================ $ cvs diff -u -r2.3 -r2.4 rpmsql.c --- rpm/rpmio/rpmsql.c 5 Apr 2010 12:26:28 -0000 2.3 +++ rpm/rpmio/rpmsql.c 5 Apr 2010 17:19:40 -0000 2.4 @@ -4,6 +4,7 @@ #define _RPMSQL_INTERNAL #include <rpmsql.h> +#include <rpmmacro.h> #if defined(WITH_SQLITE) #include <sqlite3.h> @@ -64,47 +65,50 @@ rpmsqlArgCallback, 0, NULL, NULL}, /*...@=type@*/ - { "init", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, &_sql.zInitFile, 0, - N_("read/process named FILE"), N_("FILE") }, - { "echo", '\0', POPT_BIT_SET|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_ECHO, - N_("print commands before execution"), NULL }, - - { "header", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_SHOWHDR, - N_("turn headers on or off"), NULL }, - - { "bail", '\0', POPT_BIT_SET|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_BAIL, - N_("stop after hitting an error"), NULL }, - - { "interactive", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_INTERACTIVE, - N_("force interactive I/O"), NULL }, - { "batch", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_INTERACTIVE, - N_("force batch I/O"), NULL }, - - { "column", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_COLUMN, - N_("set output mode to 'column'"), NULL }, - { "csv", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_CSV, - N_("set output mode to 'csv'"), NULL }, - { "html", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_HTML, - N_("set output mode to HTML"), NULL }, - { "line", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_LINE, - N_("set output mode to 'line'"), NULL }, - { "list", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_LIST, - N_("set output mode to 'list'"), NULL }, - { "separator", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, 0, 'S', - N_("set output field separator (|)"), N_("CHAR") }, - { "nullvalue", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, 0, 'N', - N_("set text string for NULL values"), N_("TEXT") }, + { "debug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsql_debug, -1, + N_("Debug embedded SQL interpreter"), NULL}, - { "version", '\0', POPT_ARG_NONE|POPT_ARGFLAG_ONEDASH, 0, 'V', - N_("show SQLite version"), NULL}, + { "init", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, &_sql.zInitFile, 0, + N_("read/process named FILE"), N_("FILE") }, + { "echo", '\0', POPT_BIT_SET|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_ECHO, + N_("print commands before execution"), NULL }, + + { "header", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_SHOWHDR, + N_("turn headers on or off"), NULL }, + + { "bail", '\0', POPT_BIT_SET|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_BAIL, + N_("stop after hitting an error"), NULL }, + + { "interactive", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_INTERACTIVE, + N_("force interactive I/O"), NULL }, + { "batch", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_ONEDASH, &_sql.flags, RPMSQL_FLAGS_INTERACTIVE, + N_("force batch I/O"), NULL }, + + { "column", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_COLUMN, + N_("set output mode to 'column'"), NULL }, + { "csv", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_CSV, + N_("set output mode to 'csv'"), NULL }, + { "html", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_HTML, + N_("set output mode to HTML"), NULL }, + { "line", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_LINE, + N_("set output mode to 'line'"), NULL }, + { "list", '\0', POPT_ARG_VAL|POPT_ARGFLAG_ONEDASH, &_sql.mode, RPMSQL_MODE_LIST, + N_("set output mode to 'list'"), NULL }, + { "separator", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, 0, 'S', + N_("set output field separator (|)"), N_("CHAR") }, + { "nullvalue", '\0', POPT_ARG_STRING|POPT_ARGFLAG_ONEDASH, 0, 'N', + N_("set text string for NULL values"), N_("TEXT") }, + + { "version", '\0', POPT_ARG_NONE|POPT_ARGFLAG_ONEDASH, 0, 'V', + N_("show SQLite version"), NULL}, #ifdef NOTYET - {NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0, - N_("Common options for all rpmio executables:"), NULL}, + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0, + N_("Common options for all rpmio executables:"), NULL}, #endif POPT_AUTOHELP {NULL, (char) -1, POPT_ARG_INCLUDE_TABLE, NULL, 0, - N_("\ + N_("\ Usage: dbsql [OPTIONS] FILENAME [SQL]\n\ FILENAME is the name of an SQLite database. A new database is created\n\ if the file does not previously exist.\n\ @@ -139,6 +143,14 @@ rpmsql sql = _sql; SQLDBG((stderr, "==> %s(%p)\n", __FUNCTION__, sql)); + + /* XXX INTERACTIVE cruft. */ + sql->zHome = _free(sql->zHome); + sql->zInitrc = _free(sql->zInitrc); + sql->zHistory = _free(sql->zHistory); + sql->zPrompt = _free(sql->zPrompt); + sql->zContinue = _free(sql->zContinue); + sql->zInitFile = _free(sql->zInitFile); sql->av = argvFree(sql->av); #if defined(WITH_SQLITE) @@ -155,6 +167,8 @@ } #endif sql->I = NULL; + (void) rpmiobFree(sql->iob); + sql->iob = NULL; } /*...@unchecked@*/ /*...@only@*/ /*...@null@*/ @@ -187,9 +201,54 @@ return _rpmsqlI; } -static void rpmsqlInitEnv(rpmsql sql) +const char ** rpmsqlArgv(rpmsql sql, int * argcp) +{ + const char ** av = sql->av; + + if (argcp) + *argcp = argvCount(av); + return av; +} + +static void rpmsqlInitPopt(rpmsql sql, int ac, char ** av, poptOption tbl) /*...@modifies sql @*/ { + void *use = sql->_item.use; + void *pool = sql->_item.pool; + poptContext con; + int rc; + +SQLDBG((stderr, "==> %s(%p, %p[%u], %p)\n", __FUNCTION__, sql, av, (unsigned)ac, tbl)); + if (av == NULL || av[0] == NULL || av[1] == NULL) + goto exit; + + con = poptGetContext(av[0], ac, (const char **)av, tbl, 0); + + /* Process all options into _sql, whine if unknown options. */ + while ((rc = poptGetNextOpt(con)) > 0) { + const char * arg = poptGetOptArg(con); + arg = _free(arg); + switch (rc) { + default: + fprintf(stderr, _("%s: option table misconfigured (%d)\n"), + __FUNCTION__, rc); + break; + } + } + /* XXX FIXME: arrange error return iff rc < -1. */ +if (rc != 0) +fprintf(stderr, "%s: poptGetNextOpt rc(%d): %s\n", __FUNCTION__, rc, poptStrerror(rc)); + + *sql = _sql; /* structure assignment */ + + sql->_item.use = use; + sql->_item.pool = pool; + rc = argvAppend(&sql->av, poptGetArgs(con)); + + con = poptFreeContext(con); + +exit: +SQLDBG((stderr, "<== %s(%p, %p[%u], %p)\n", __FUNCTION__, sql, av, (unsigned)ac, tbl)); } rpmsql rpmsqlNew(char ** av, uint32_t flags) @@ -203,12 +262,63 @@ if (av && av[1]) { sqlite3 * db = NULL; int xx; - xx = sqlite3_open(av[1], &db); - sql->I = (void *) db; + + /* Initialize defaults for popt parsing. */ + memset(&_sql, 0, sizeof(_sql)); + _sql.flags = flags; + _sql.mode = RPMSQL_MODE_LIST; + memcpy(_sql.separator, "|", 2); + rpmsqlInitPopt(sql, ac, av, (poptOption) _rpmsqlOptions); + + /* The 1st argument is the database to open (or :memory: default). */ + if (sql->av && sql->av[0]) { + sql->zDbFilename = xstrdup(sql->av[0]); /* XXX strdup? */ + /* If database alread exists, open immediately. */ + if (Access(sql->zDbFilename, R_OK)) { + xx = sqlite3_open(sql->zDbFilename, &db); + sql->I = (void *) db; + } + } else + sql->zDbFilename = xstrdup(":memory:"); + +#ifdef NOTYET + /* Read ~/.sqliterc (if specified), then reparse options. */ + if (sql->zInitFile) { + db = (sqlite3 *)sql->I; + xx = rpmsqlInitRC(sql, sql->zInitFIle); + sql->I = NULL; /* XXX avoid the db close */ + rpmsqlFini(sql); + rpmsqlInitPopt(sql, ac, av, (poptOption) _rpmsqlOptions); + sql->I = (void *)db; + } +#endif + + } + + { /* XXX INTERACTIVE cruft. */ + static const char _zInitrc[] = "/.sqliterc"; + static const char _zHistory[] = "/.sqlite_history"; + static const char _zPrompt[] = "dbsql> "; + static const char _zContinue[] = " ...> "; + /* XXX getpwuid? */ + sql->zHome = xstrdup(getenv("HOME")); + sql->zInitrc = rpmGetPath(sql->zHome, _zInitrc, NULL); + sql->zHistory = rpmGetPath(sql->zHome, _zHistory, NULL); + /* + ** Prompt strings. Initialized in main. Settable with + ** .prompt main continue + */ + sql->zPrompt = xstrdup(_zPrompt); + sql->zContinue = xstrdup(_zContinue); + + /* Determine whether stdio or rpmiob should be used for output */ + sql->out = (F_ISSET(sql, INTERACTIVE) ? stdout : NULL); } - rpmsqlInitEnv(sql); + #endif + sql->iob = rpmiobNew(0); + return rpmsqlLink(sql); } @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmsql.h ============================================================================ $ cvs diff -u -r2.4 -r2.5 rpmsql.h --- rpm/rpmio/rpmsql.h 5 Apr 2010 12:26:28 -0000 2.4 +++ rpm/rpmio/rpmsql.h 5 Apr 2010 17:19:40 -0000 2.5 @@ -75,6 +75,7 @@ int cnt; /* Number of records displayed so far */ + rpmiob iob; /* Output I/O buffer */ FILE * out; /* Write results here */ FILE * pLog; /* Write log output here */ @@ -86,6 +87,13 @@ char nullvalue[20]; /* Text to print for NULL from the database */ char outfile[FILENAME_MAX]; /* Filename for *out */ + /* XXX INTERACTIVE cruft. */ + const char * zHome; /* HOME */ + const char * zInitrc; /* ~/.sqliterc */ + const char * zHistory; /* ~/.sqlite_history */ + const char * zPrompt; /* "dbsql> " */ + const char * zContinue; /* " ...> " */ + #if defined(__LCLINT__) /*...@refs@*/ int nrefs; /*!< (unused) keep splint happy */ @@ -149,6 +157,17 @@ /*...@globals fileSystem, internalState @*/ /*...@modifies fileSystem, internalState @*/; +/** + * Return arguments from a sql interpreter. + * @param sql sql interpreter + * @retval *argcp no. of arguments + * @return sql interpreter args + */ +/*...@null@*/ +const char ** rpmsqlArgv(/*...@null@*/ rpmsql sql, /*...@null@*/ int * argcp) + /*...@globals fileSystem, internalState @*/ + /*...@modifies fileSystem, internalState @*/; + #ifdef NOTYET /** * Execute sql from a file. @@ . patch -p0 <<'@@ .' Index: rpm/tools/dbsql.c ============================================================================ $ cvs diff -u -r2.6 -r2.7 dbsql.c --- rpm/tools/dbsql.c 5 Apr 2010 12:26:28 -0000 2.6 +++ rpm/tools/dbsql.c 5 Apr 2010 17:19:40 -0000 2.7 @@ -149,13 +149,6 @@ static volatile int seenInterrupt = 0; /* -** Prompt strings. Initialized in main. Settable with -** .prompt main continue -*/ -static char mainPrompt[20]; /* First line prompt. default: "sqlite> " */ -static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */ - -/* ** Write I/O traces to the following stream. */ #ifdef SQLITE_ENABLE_IOTRACE @@ -163,6 +156,33 @@ #endif /*==============================================================*/ +static int rpmsqlFprintf(rpmsql sql, const char *fmt, ...) +{ + char b[BUFSIZ]; + size_t nb = sizeof(b); + int rc; + va_list ap; + + /* Format the output */ + va_start(ap, fmt); + rc = vsnprintf(b, nb, fmt, ap); + va_end(ap); + /* XXX just in case */ + if (!(rc >= 0 && rc < nb)) + rc = nb - 1; + b[rc] = '\0'; + + /* Dispose of the output. */ + if (sql->out) { + FILE * out = (FILE *) sql->out; + size_t nw = fwrite(b, 1, rc, out); +assert((int)nw == rc); + } + if (sql->iob) + (void) rpmiobAppend(sql->iob, b, 0); + + return rc; +} /* ** This routine works like printf in that its first argument is a @@ -262,6 +282,7 @@ int n; int eol; +SQLDBG((stderr, "--> %s(%s,%p)\n", __FUNCTION__, zPrompt, in)); if (zPrompt && *zPrompt) { printf("%s", zPrompt); fflush(stdout); @@ -309,19 +330,20 @@ ** zPrior is a string of prior text retrieved. If not the empty ** string, then issue a continuation prompt. */ -static char *one_input_line(const char *zPrior, FILE * in) +static char *one_input_line(rpmsql sql, const char *zPrior, FILE * in) { - char *zPrompt; + const char *zPrompt; char *zResult; +SQLDBG((stderr, "--> %s(%s,%p)\n", __FUNCTION__, zPrior, in)); if (in != 0) { return local_getline(0, in); } if (zPrior && zPrior[0]) { - zPrompt = continuePrompt; + zPrompt = sql->zContinue; } else { - zPrompt = mainPrompt; + zPrompt = sql->zPrompt; } - zResult = readline(zPrompt); + zResult = readline((char *)zPrompt); #if defined(HAVE_READLINE) && HAVE_READLINE==1 if (zResult && *zResult) add_history(zResult); @@ -374,86 +396,91 @@ /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ -static void output_hex_blob(FILE * out, const void *pBlob, int nBlob) +static void output_hex_blob(rpmsql sql, const void *pBlob, int nBlob) { - int i; char *zBlob = (char *) pBlob; - fprintf(out, "X'"); + int i; + +SQLDBG((stderr, "--> %s(%p,%p[%u])\n", __FUNCTION__, sql, pBlob, (unsigned)nBlob)); + rpmsqlFprintf(sql, "X'"); for (i = 0; i < nBlob; i++) { - fprintf(out, "%02x", zBlob[i]); + rpmsqlFprintf(sql, "%02x", zBlob[i]); } - fprintf(out, "'"); + rpmsqlFprintf(sql, "'"); } /* ** Output the given string as a quoted string using SQL quoting conventions. */ -static void output_quoted_string(FILE * out, const char *z) +static void output_quoted_string(rpmsql sql, const char *z) { int i; int nSingle = 0; +SQLDBG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, sql, z)); for (i = 0; z[i]; i++) { if (z[i] == '\'') nSingle++; } if (nSingle == 0) { - fprintf(out, "'%s'", z); + rpmsqlFprintf(sql, "'%s'", z); } else { - fprintf(out, "'"); + rpmsqlFprintf(sql, "'"); while (*z) { for (i = 0; z[i] && z[i] != '\''; i++) { } if (i == 0) { - fprintf(out, "''"); + rpmsqlFprintf(sql, "''"); z++; } else if (z[i] == '\'') { - fprintf(out, "%.*s''", i, z); + rpmsqlFprintf(sql, "%.*s''", i, z); z += i + 1; } else { - fprintf(out, "%s", z); + rpmsqlFprintf(sql, "%s", z); break; } } - fprintf(out, "'"); + rpmsqlFprintf(sql, "'"); } } /* ** Output the given string as a quoted according to C or TCL quoting rules. */ -static void output_c_string(FILE * out, const char *z) +static void output_c_string(rpmsql sql, const char *z) { unsigned int c; - fputc('"', out); +SQLDBG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, sql, z)); + rpmsqlFprintf(sql, "\""); while ((c = *(z++)) != 0) { if (c == '\\') { - fputc(c, out); - fputc(c, out); + rpmsqlFprintf(sql, "%c", c); + rpmsqlFprintf(sql, "%c", c); } else if (c == '\t') { - fputc('\\', out); - fputc('t', out); + rpmsqlFprintf(sql, "%c", '\\'); + rpmsqlFprintf(sql, "%c", 't'); } else if (c == '\n') { - fputc('\\', out); - fputc('n', out); + rpmsqlFprintf(sql, "%c", '\\'); + rpmsqlFprintf(sql, "%c", 'n'); } else if (c == '\r') { - fputc('\\', out); - fputc('r', out); + rpmsqlFprintf(sql, "%c", '\\'); + rpmsqlFprintf(sql, "%c", 'r'); } else if (!isprint(c)) { - fprintf(out, "\\%03o", c & 0xff); + rpmsqlFprintf(sql, "\\%03o", c & 0xff); } else { - fputc(c, out); + rpmsqlFprintf(sql, "%c", c); } } - fputc('"', out); + rpmsqlFprintf(sql, "\""); } /* ** Output the given string with characters that are special to ** HTML escaped. */ -static void output_html_string(FILE * out, const char *z) +static void output_html_string(rpmsql sql, const char *z) { int i; +SQLDBG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, sql, z)); while (*z) { for (i = 0; z[i] && z[i] != '<' @@ -461,18 +488,18 @@ && z[i] != '>' && z[i] != '\"' && z[i] != '\''; i++) { } if (i > 0) { - fprintf(out, "%.*s", i, z); + rpmsqlFprintf(sql, "%.*s", i, z); } if (z[i] == '<') { - fprintf(out, "<"); + rpmsqlFprintf(sql, "<"); } else if (z[i] == '&') { - fprintf(out, "&"); + rpmsqlFprintf(sql, "&"); } else if (z[i] == '>') { - fprintf(out, ">"); + rpmsqlFprintf(sql, ">"); } else if (z[i] == '\"') { - fprintf(out, """); + rpmsqlFprintf(sql, """); } else if (z[i] == '\'') { - fprintf(out, "'"); + rpmsqlFprintf(sql, "'"); } else { break; } @@ -511,9 +538,9 @@ */ static void output_csv(rpmsql sql, const char *z, int bSep) { - FILE *out = sql->out; +SQLDBG((stderr, "--> %s(%p,%s,0x%x)\n", __FUNCTION__, sql, z, bSep)); if (z == 0) { - fprintf(out, "%s", sql->nullvalue); + rpmsqlFprintf(sql, "%s", sql->nullvalue); } else { int i; int nSep = strlen30(sql->separator); @@ -526,19 +553,19 @@ } } if (i == 0) { - putc('"', out); + rpmsqlFprintf(sql, "\""); for (i = 0; z[i]; i++) { if (z[i] == '"') - putc('"', out); - putc(z[i], out); + rpmsqlFprintf(sql, "\""); + rpmsqlFprintf(sql, "%c", z[i]); } - putc('"', out); + rpmsqlFprintf(sql, "\""); } else { - fprintf(out, "%s", z); + rpmsqlFprintf(sql, "%s", z); } } if (bSep) { - fprintf(out, "%s", sql->separator); + rpmsqlFprintf(sql, "%s", sql->separator); } } @@ -550,9 +577,9 @@ int *aiType) { rpmsql sql = (rpmsql) pArg; - FILE *out = sql->out; int i; +SQLDBG((stderr, "--> %s(%p,%d,%p,%p,%p)\n", __FUNCTION__, pArg, nArg, azArg, azCol, aiType)); switch (sql->mode) { case RPMSQL_MODE_LINE:{ int w = 5; @@ -564,9 +591,9 @@ w = len; } if (sql->cnt++ > 0) - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); for (i = 0; i < nArg; i++) { - fprintf(out, "%*s = %s\n", w, azCol[i], + rpmsqlFprintf(sql, "%*s = %s\n", w, azCol[i], azArg[i] ? azArg[i] : sql->nullvalue); } break; @@ -594,7 +621,7 @@ sql->actualWidth[i] = w; } if (F_ISSET(sql, SHOWHDR)) { - fprintf(out, "%-*.*s%s", w, w, azCol[i], + rpmsqlFprintf(sql, "%-*.*s%s", w, w, azCol[i], i == nArg - 1 ? "\n" : " "); } } @@ -606,7 +633,7 @@ } else { w = 10; } - fprintf(out, "%-*.*s%s", w, w, + rpmsqlFprintf(sql, "%-*.*s%s", w, w, "-----------------------------------" "----------------------------------------------------------", i == nArg - 1 ? "\n" : " "); @@ -626,7 +653,7 @@ strlen30(azArg[i]) > w) { w = strlen30(azArg[i]); } - fprintf(out, "%-*.*s%s", w, w, + rpmsqlFprintf(sql, "%-*.*s%s", w, w, azArg[i] ? azArg[i] : sql->nullvalue, i == nArg - 1 ? "\n" : " "); } @@ -636,7 +663,7 @@ case RPMSQL_MODE_LIST:{ if (sql->cnt++ == 0 && F_ISSET(sql, SHOWHDR)) { for (i = 0; i < nArg; i++) { - fprintf(out, "%s%s", azCol[i], + rpmsqlFprintf(sql, "%s%s", azCol[i], i == nArg - 1 ? "\n" : sql->separator); } } @@ -646,55 +673,55 @@ char *z = azArg[i]; if (z == 0) z = sql->nullvalue; - fprintf(out, "%s", z); + rpmsqlFprintf(sql, "%s", z); if (i < nArg - 1) { - fprintf(out, "%s", sql->separator); + rpmsqlFprintf(sql, "%s", sql->separator); } else if (sql->mode == RPMSQL_MODE_SEMI) { - fprintf(out, ";\n"); + rpmsqlFprintf(sql, ";\n"); } else { - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); } } break; } case RPMSQL_MODE_HTML:{ if (sql->cnt++ == 0 && F_ISSET(sql, SHOWHDR)) { - fprintf(out, "<TR>"); + rpmsqlFprintf(sql, "<TR>"); for (i = 0; i < nArg; i++) { - fprintf(out, "<TH>"); - output_html_string(out, azCol[i]); - fprintf(out, "</TH>\n"); + rpmsqlFprintf(sql, "<TH>"); + output_html_string(sql, azCol[i]); + rpmsqlFprintf(sql, "</TH>\n"); } - fprintf(out, "</TR>\n"); + rpmsqlFprintf(sql, "</TR>\n"); } if (azArg == 0) break; - fprintf(out, "<TR>"); + rpmsqlFprintf(sql, "<TR>"); for (i = 0; i < nArg; i++) { - fprintf(out, "<TD>"); - output_html_string(out, + rpmsqlFprintf(sql, "<TD>"); + output_html_string(sql, azArg[i] ? azArg[i] : sql->nullvalue); - fprintf(out, "</TD>\n"); + rpmsqlFprintf(sql, "</TD>\n"); } - fprintf(out, "</TR>\n"); + rpmsqlFprintf(sql, "</TR>\n"); break; } case RPMSQL_MODE_TCL:{ if (sql->cnt++ == 0 && F_ISSET(sql, SHOWHDR)) { for (i = 0; i < nArg; i++) { - output_c_string(out, azCol[i] ? azCol[i] : ""); - fprintf(out, "%s", sql->separator); + output_c_string(sql, azCol[i] ? azCol[i] : ""); + rpmsqlFprintf(sql, "%s", sql->separator); } - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); } if (azArg == 0) break; for (i = 0; i < nArg; i++) { - output_c_string(out, + output_c_string(sql, azArg[i] ? azArg[i] : sql->nullvalue); - fprintf(out, "%s", sql->separator); + rpmsqlFprintf(sql, "%s", sql->separator); } - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); break; } case RPMSQL_MODE_CSV:{ @@ -702,50 +729,50 @@ for (i = 0; i < nArg; i++) { output_csv(sql, azCol[i] ? azCol[i] : "", i < nArg - 1); } - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); } if (azArg == 0) break; for (i = 0; i < nArg; i++) { output_csv(sql, azArg[i], i < nArg - 1); } - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); break; } case RPMSQL_MODE_INSERT:{ sql->cnt++; if (azArg == 0) break; - fprintf(out, "INSERT INTO %s VALUES(", sql->zDestTable); + rpmsqlFprintf(sql, "INSERT INTO %s VALUES(", sql->zDestTable); for (i = 0; i < nArg; i++) { char *zSep = i > 0 ? "," : ""; if ((azArg[i] == 0) || (aiType && aiType[i] == SQLITE_NULL)) { - fprintf(out, "%sNULL", zSep); + rpmsqlFprintf(sql, "%sNULL", zSep); } else if (aiType && aiType[i] == SQLITE_TEXT) { if (zSep[0]) - fprintf(out, "%s", zSep); - output_quoted_string(out, azArg[i]); + rpmsqlFprintf(sql, "%s", zSep); + output_quoted_string(sql, azArg[i]); } else if (aiType && (aiType[i] == SQLITE_INTEGER || aiType[i] == SQLITE_FLOAT)) { - fprintf(out, "%s%s", zSep, azArg[i]); + rpmsqlFprintf(sql, "%s%s", zSep, azArg[i]); } else if (aiType && aiType[i] == SQLITE_BLOB && sql->S) { sqlite3_stmt * pStmt = (sqlite3_stmt *)sql->S; const void *pBlob = sqlite3_column_blob(pStmt, i); int nBlob = sqlite3_column_bytes(pStmt, i); if (zSep[0]) - fprintf(out, "%s", zSep); - output_hex_blob(out, pBlob, nBlob); + rpmsqlFprintf(sql, "%s", zSep); + output_hex_blob(sql, pBlob, nBlob); } else if (isNumber(azArg[i], 0)) { - fprintf(out, "%s%s", zSep, azArg[i]); + rpmsqlFprintf(sql, "%s%s", zSep, azArg[i]); } else { if (zSep[0]) - fprintf(out, "%s", zSep); - output_quoted_string(out, azArg[i]); + rpmsqlFprintf(sql, "%s", zSep); + output_quoted_string(sql, azArg[i]); } } - fprintf(out, ");\n"); + rpmsqlFprintf(sql, ");\n"); break; } } @@ -773,6 +800,7 @@ int needQuote; char *z; +SQLDBG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, sql, zName)); if (sql->zDestTable) { free(sql->zDestTable); sql->zDestTable = NULL; @@ -822,6 +850,7 @@ int nAppend = strlen30(zAppend); int nIn = (zIn ? strlen30(zIn) : 0); +SQLDBG((stderr, "--> %s(%s,%s,0x%02x)\n", __FUNCTION__, zIn, zAppend, quote)); len = nAppend + nIn + 1; if (quote) { len += 2; @@ -863,11 +892,12 @@ ** This is used, for example, to show the schema of the database by ** querying the SQLITE_MASTER table. */ -static int run_table_dump_query(FILE * out, sqlite3 * db, +static int run_table_dump_query(rpmsql sql, sqlite3 * db, const char *zSelect, const char *zFirstRow) { sqlite3_stmt *pSelect; int rc; +SQLDBG((stderr, "--> %s(%p,%p,%s,%s)\n", __FUNCTION__, sql, db, zSelect, zFirstRow)); rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0); if (rc != SQLITE_OK || !pSelect) { return rc; @@ -875,10 +905,10 @@ rc = sqlite3_step(pSelect); while (rc == SQLITE_ROW) { if (zFirstRow) { - fprintf(out, "%s", zFirstRow); + rpmsqlFprintf(sql, "%s", zFirstRow); zFirstRow = 0; } - fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0)); + rpmsqlFprintf(sql, "%s;\n", sqlite3_column_text(pSelect, 0)); rc = sqlite3_step(pSelect); } return sqlite3_finalize(pSelect); @@ -911,12 +941,12 @@ char **pzErrMsg ) { - FILE *out = sql->out; sqlite3 * db = (sqlite3 *) sql->I; sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ int rc = SQLITE_OK; /* Return Code */ const char *zLeftover; /* Tail of unprocessed SQL */ +SQLDBG((stderr, "--> %s(%p,%s,%p,%p)\n", __FUNCTION__, sql, zSql, xCallback, pzErrMsg)); if (pzErrMsg) { *pzErrMsg = NULL; } @@ -939,7 +969,7 @@ /* echo the sql statement if echo on */ if (F_ISSET(sql, ECHO)) { const char *zStmtSql = sqlite3_sql(pStmt); - fprintf(out, "%s\n", zStmtSql ? zStmtSql : zSql); + rpmsqlFprintf(sql, "%s\n", zStmtSql ? zStmtSql : zSql); } /* perform the first step. this will tell us if we @@ -1033,7 +1063,6 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol) { rpmsql sql = (rpmsql) pArg; - FILE *out = sql->out; sqlite3 * db = (sqlite3 *) sql->I; int rc; const char *zTable; @@ -1041,6 +1070,7 @@ const char *zSql; const char *zPrepStmt = 0; +SQLDBG((stderr, "--> %s(%p,%d,%p,%p)\n", __FUNCTION__, pArg, nArg, azArg, azCol)); UNUSED_PARAMETER(azCol); if (nArg != 3) return 1; @@ -1051,24 +1081,24 @@ if (strcmp(zTable, "sqlite_sequence") == 0) { zPrepStmt = "DELETE FROM sqlite_sequence;\n"; } else if (strcmp(zTable, "sqlite_stat1") == 0) { - fprintf(out, "ANALYZE sqlite_master;\n"); + rpmsqlFprintf(sql, "ANALYZE sqlite_master;\n"); } else if (strncmp(zTable, "sqlite_", 7) == 0) { return 0; } else if (strncmp(zSql, "CREATE VIRTUAL TABLE", 20) == 0) { char *zIns; if (!F_ISSET(sql, WRITABLE)) { - fprintf(out, "PRAGMA writable_schema=ON;\n"); + rpmsqlFprintf(sql, "PRAGMA writable_schema=ON;\n"); sql->flags |= RPMSQL_FLAGS_WRITABLE; } zIns = sqlite3_mprintf ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" "VALUES('table','%q','%q',0,'%q');", zTable, zTable, zSql); - fprintf(out, "%s\n", zIns); + rpmsqlFprintf(sql, "%s\n", zIns); sqlite3_free(zIns); return 0; } else { - fprintf(out, "%s;\n", zSql); + rpmsqlFprintf(sql, "%s;\n", zSql); } if (strcmp(zType, "table") == 0) { @@ -1116,10 +1146,10 @@ zSelect = appendText(zSelect, "|| ')' FROM ", 0); zSelect = appendText(zSelect, zTable, '"'); - rc = run_table_dump_query(out, db, zSelect, zPrepStmt); + rc = run_table_dump_query(sql, db, zSelect, zPrepStmt); if (rc == SQLITE_CORRUPT) { zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0); - rc = run_table_dump_query(out, db, zSelect, 0); + rc = run_table_dump_query(sql, db, zSelect, 0); } if (zSelect) free(zSelect); @@ -1140,6 +1170,7 @@ sqlite3 * db = (sqlite3 *) sql->I; int rc; +SQLDBG((stderr, "--> %s(%p,%s,%p)\n", __FUNCTION__, sql, zQuery, pzErrMsg)); rc = sqlite3_exec(db, zQuery, dump_callback, sql, pzErrMsg); if (rc == SQLITE_CORRUPT) { char *zQ2; @@ -1223,6 +1254,7 @@ sqlite3 * db = (sqlite3 *)sql->I; if (db == NULL) { +SQLDBG((stderr, "--> %s(%p) %s\n", __FUNCTION__, sql, sql->zDbFilename)); sqlite3_open(sql->zDbFilename, &db); sql->I = db; if (db && sqlite3_errcode(db) == SQLITE_OK) { @@ -1295,6 +1327,7 @@ } else if (strcmp(zArg, "yes") == 0) { val = 1; } +SQLDBG((stderr, "<-- %s(%s) val %d\n", __FUNCTION__, zArg, val)); return val; } @@ -1309,7 +1342,6 @@ */ static int rpmsqlMetaCommand(rpmsql sql, char *zLine) { - FILE * out = sql->out; sqlite3 * db = (sqlite3 *)sql->I; int i = 1; int nArg = 0; @@ -1317,6 +1349,7 @@ int rc = 0; char *azArg[50]; +SQLDBG((stderr, "--> %s(%p,%s)\n", __FUNCTION__, sql, zLine)); /* Parse the input line into tokens. */ while (zLine[i] && nArg < ArraySize(azArg)) { @@ -1421,8 +1454,8 @@ /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ - fprintf(out, "PRAGMA foreign_keys=OFF;\n"); - fprintf(out, "BEGIN TRANSACTION;\n"); + rpmsqlFprintf(sql, "PRAGMA foreign_keys=OFF;\n"); + rpmsqlFprintf(sql, "BEGIN TRANSACTION;\n"); sql->flags &= ~RPMSQL_FLAGS_WRITABLE; sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0); if (nArg == 1) { @@ -1433,7 +1466,7 @@ run_schema_dump_query(sql, "SELECT name, type, sql FROM sqlite_master " "WHERE name=='sqlite_sequence'", 0); - run_table_dump_query(out, db, + run_table_dump_query(sql, db, "SELECT sql FROM sqlite_master " "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0); @@ -1445,7 +1478,7 @@ "SELECT name, type, sql FROM sqlite_master " "WHERE tbl_name LIKE shellstatic() AND type=='table'" " AND sql NOT NULL", 0); - run_table_dump_query(out, db, + run_table_dump_query(sql, db, "SELECT sql FROM sqlite_master " "WHERE sql NOT NULL" " AND type IN ('index','trigger','view')" @@ -1455,7 +1488,7 @@ } } if (F_ISSET(sql, WRITABLE)) { - fprintf(out, "PRAGMA writable_schema=OFF;\n"); + rpmsqlFprintf(sql, "PRAGMA writable_schema=OFF;\n"); sql->flags &= ~RPMSQL_FLAGS_WRITABLE; } sqlite3_exec(db, "PRAGMA writable_schema=OFF", 0, 0, 0); @@ -1463,7 +1496,7 @@ fprintf(stderr, "Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } else { - fprintf(out, "COMMIT;\n"); + rpmsqlFprintf(sql, "COMMIT;\n"); } } else if (c == 'e' && strncmp(azArg[0], "echo", n) == 0 && nArg > 1 @@ -1690,7 +1723,7 @@ #ifdef SQLITE_ENABLE_IOTRACE if (c == 'i' && strncmp(azArg[0], "iotrace", n) == 0) { extern void (*sqlite3IoTrace) (const char *, ...); - if (iotrace && iotrace != stdout) + if (iotrace && fileno(iotrace) > 2) fclose(iotrace); iotrace = 0; if (nArg < 2) { @@ -1729,16 +1762,15 @@ if (c == 'l' && strncmp(azArg[0], "log", n) == 0 && nArg >= 1) { const char *zFile = azArg[1]; - if (sql->pLog && sql->pLog != stdout && sql->pLog != stderr) { + if (sql->pLog && fileno(sql->pLog) > 2) fclose(sql->pLog); - sql->pLog = NULL; - } + sql->pLog = NULL; if (strcmp(zFile, "stdout") == 0) { sql->pLog = stdout; } else if (strcmp(zFile, "stderr") == 0) { sql->pLog = stderr; } else if (strcmp(zFile, "off") == 0) { - sql->pLog = 0; + sql->pLog = NULL; } else { sql->pLog = fopen(zFile, "w"); if (sql->pLog == NULL) { @@ -1792,19 +1824,18 @@ azArg[1]); } else if (c == 'o' && strncmp(azArg[0], "output", n) == 0 && nArg == 2) { - if (sql->out != stdout) { + if (fileno(sql->out) > 2) fclose(sql->out); - out = sql->out = NULL; - } + sql->out = NULL; if (strcmp(azArg[1], "stdout") == 0) { - out = sql->out = stdout; + sql->out = stdout; sqlite3_snprintf(sizeof(sql->outfile), sql->outfile, "stdout"); } else { - out = sql->out = fopen(azArg[1], "wb"); - if (out == NULL) { + sql->out = fopen(azArg[1], "wb"); + if (sql->out == NULL) { fprintf(stderr, "Error: cannot write to \"%s\"\n", azArg[1]); - out = sql->out = stdout; + sql->out = stdout; rc = 1; } else { sqlite3_snprintf(sizeof(sql->outfile), sql->outfile, "%s", @@ -1815,11 +1846,12 @@ if (c == 'p' && strncmp(azArg[0], "prompt", n) == 0 && (nArg == 2 || nArg == 3)) { if (nArg >= 2) { - strncpy(mainPrompt, azArg[1], (int) ArraySize(mainPrompt) - 1); + sql->zPrompt = _free(sql->zPrompt); + sql->zPrompt = xstrdup(azArg[1]); } if (nArg >= 3) { - strncpy(continuePrompt, azArg[2], - (int) ArraySize(continuePrompt) - 1); + sql->zContinue = _free(sql->zContinue); + sql->zContinue = xstrdup(azArg[2]); } } else if (c == 'q' && strncmp(azArg[0], "quit", n) == 0 && nArg == 1) { @@ -1957,27 +1989,27 @@ } else if (c == 's' && strncmp(azArg[0], "show", n) == 0 && nArg == 1) { int i; - fprintf(out, "%9.9s: %s\n", "echo", F_ISSET(sql, ECHO) ? "on" : "off"); - fprintf(out, "%9.9s: %s\n", "explain", + rpmsqlFprintf(sql, "%9.9s: %s\n", "echo", F_ISSET(sql, ECHO) ? "on" : "off"); + rpmsqlFprintf(sql, "%9.9s: %s\n", "explain", sql->explainPrev.valid ? "on" : "off"); - fprintf(out, "%9.9s: %s\n", "headers", + rpmsqlFprintf(sql, "%9.9s: %s\n", "headers", F_ISSET(sql, SHOWHDR) ? "on" : "off"); - fprintf(out, "%9.9s: %s\n", "mode", modeDescr[sql->mode]); - fprintf(out, "%9.9s: ", "nullvalue"); - output_c_string(out, sql->nullvalue); - fprintf(out, "\n"); - fprintf(out, "%9.9s: %s\n", "output", + rpmsqlFprintf(sql, "%9.9s: %s\n", "mode", modeDescr[sql->mode]); + rpmsqlFprintf(sql, "%9.9s: ", "nullvalue"); + output_c_string(sql, sql->nullvalue); + rpmsqlFprintf(sql, "\n"); + rpmsqlFprintf(sql, "%9.9s: %s\n", "output", strlen30(sql->outfile) ? sql->outfile : "stdout"); - fprintf(out, "%9.9s: ", "separator"); - output_c_string(out, sql->separator); - fprintf(out, "\n"); - fprintf(out, "%9.9s: ", "width"); + rpmsqlFprintf(sql, "%9.9s: ", "separator"); + output_c_string(sql, sql->separator); + rpmsqlFprintf(sql, "\n"); + rpmsqlFprintf(sql, "%9.9s: ", "width"); for (i = 0; i < (int) ArraySize(sql->colWidth) && sql->colWidth[i] != 0; i++) { - fprintf(out, "%d ", sql->colWidth[i]); + rpmsqlFprintf(sql, "%d ", sql->colWidth[i]); } - fprintf(out, "\n"); + rpmsqlFprintf(sql, "\n"); } else if (c == 't' && n > 1 && strncmp(azArg[0], "tables", n) == 0 && nArg < 3) { @@ -2072,6 +2104,7 @@ static int _contains_semicolon(const char *z, int N) { int i; +SQLDBG((stderr, "--> %s(%s,%d)\n", __FUNCTION__, z, N)); for (i = 0; i < N; i++) { if (z[i] == ';') return 1; @@ -2084,6 +2117,7 @@ */ static int _all_whitespace(const char *z) { +SQLDBG((stderr, "--> %s(%s)\n", __FUNCTION__, z)); for (; *z; z++) { if (isspace(*(unsigned char *) z)) continue; @@ -2118,6 +2152,7 @@ */ static int _is_command_terminator(const char *zLine) { +SQLDBG((stderr, "--> %s(%s)\n", __FUNCTION__, zLine)); while (isspace(*(unsigned char *) zLine)) { zLine++; }; @@ -2138,6 +2173,7 @@ static int _is_complete(char *zSql, int nSql) { int rc; +SQLDBG((stderr, "--> %s(%s,%d)\n", __FUNCTION__, zSql, nSql)); if (zSql == 0) return 1; zSql[nSql] = ';'; @@ -2170,11 +2206,12 @@ int lineno = 0; int startline = 0; +SQLDBG((stderr, "--> %s(%p,%p)\n", __FUNCTION__, sql, in)); while (errCnt == 0 || !F_ISSET(sql, BAIL) || (in == 0 && F_ISSET(sql, INTERACTIVE))) { fflush(out); free(zLine); - zLine = one_input_line(zSql, in); + zLine = one_input_line(sql, zSql, in); if (zLine == 0) { break; /* We have reached EOF */ } @@ -2268,78 +2305,27 @@ /*==============================================================*/ /* -** Return a pathname which is the user's home directory. A -** 0 return indicates an error of some kind. Space to hold the -** resulting string is obtained from malloc(). The calling -** function should free the result. -*/ -static char *rpmsqlHomeDir(void) -{ - char *home_dir = NULL; - - struct passwd *pwent; - uid_t uid = getuid(); - if ((pwent = getpwuid(uid)) != NULL) { - home_dir = pwent->pw_dir; - } - - if (!home_dir) { - home_dir = getenv("HOME"); - } - - if (home_dir) { - int n = strlen30(home_dir) + 1; - char *z = malloc(n); - if (z) - memcpy(z, home_dir, n); - home_dir = z; - } - - return home_dir; -} - -/* -** Read input from the file given by sqliterc_override. Or if that -** parameter is NULL, take input from ~/.sqliterc +** Read input from the sqliterc file parameter. +** If sqliterc is NULL, take input from ~/.sqliterc ** ** Returns the number of errors. */ -static int rpmsqlInitRC(rpmsql sql, const char *sqliterc_override) +static int rpmsqlInitRC(rpmsql sql, const char *sqliterc) { - char *home_dir = NULL; - const char *sqliterc = sqliterc_override; - char *zBuf = 0; FILE *in = NULL; - int nBuf; int rc = 0; - if (sqliterc == NULL) { - home_dir = rpmsqlHomeDir(); - if (home_dir == 0) { - fprintf(stderr, - "%s: Error: cannot locate your home directory\n", - __progname); - return 1; - } - nBuf = strlen30(home_dir) + 16; - zBuf = malloc(nBuf); - if (zBuf == 0) { - fprintf(stderr, "%s: Error: out of memory\n", __progname); - return 1; - } - sqlite3_snprintf(nBuf, zBuf, "%s/.sqliterc", home_dir); - free(home_dir); - sqliterc = (const char *) zBuf; - } + if (sqliterc == NULL) + sqliterc = sql->zInitrc; + if (sqliterc == NULL) + return rc; in = fopen(sqliterc, "rb"); if (in) { - if (F_ISSET(sql, INTERACTIVE)) { + if (F_ISSET(sql, INTERACTIVE)) fprintf(stderr, "-- Loading resources from %s\n", sqliterc); - } rc = rpmsqlInput(sql, in); fclose(in); } - free(zBuf); return rc; } @@ -2363,32 +2349,21 @@ */ static void rpmsqlInit(rpmsql sql) { - sql->mode = RPMSQL_MODE_LIST; - memcpy(sql->separator, "|", 2); - sql->flags &= ~RPMSQL_FLAGS_SHOWHDR; - sqlite3_config(SQLITE_CONFIG_LOG, shellLog, sql); - sqlite3_snprintf(sizeof(mainPrompt), mainPrompt, "dbsql> "); - sqlite3_snprintf(sizeof(continuePrompt), continuePrompt, " ...> "); sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); } int main(int argc, char **argv) { - rpmsql sql = &_sql; - poptContext con; + int _flags = (isatty(0) ? RPMSQL_FLAGS_INTERACTIVE : 0); + rpmsql sql = rpmsqlNew(argv, _flags); char *zErrMsg = NULL; char *zFirstCmd = NULL; const char ** av = NULL; int ac; int ec = 1; /* assume error */ - int xx; rpmsqlInit(sql); - if (isatty(0)) - sql->flags |= RPMSQL_FLAGS_INTERACTIVE; - else - sql->flags &= ~RPMSQL_FLAGS_INTERACTIVE; /* Make sure we have a valid signal handler early, before anything ** else is done. @@ -2401,34 +2376,20 @@ ** the name of the database file, the name of the initialization file, ** and the first command to execute. */ - con = rpmioInit(argc, argv, _rpmsqlOptions); - av = poptGetArgs(con); - ac = argvCount(av); - - if (ac > 0) { - sql->zDbFilename = xstrdup(av[0]); - av++; - ac--; - } else { -#ifndef SQLITE_OMIT_MEMORYDB - sql->zDbFilename = xstrdup(":memory:"); -#else - sql->zDbFilename = NULL; -#endif - } - if (ac > 0) { - zFirstCmd = xstrdup(av[0]); - av++; - ac--; - } - if (ac > 0) { - fprintf(stderr, "%s: Error: too many options: \"%s\"\n", __progname, - av[0]); - fprintf(stderr, "Use -help for a list of options.\n"); - return 1; + av = rpmsqlArgv(sql, &ac); + if (ac > 2) { + fprintf(stderr, "%s: Error: too many options: \"%s ...\"\n", __progname, + av[2]); + goto exit; } - sql->out = stdout; + if (ac > 1) + zFirstCmd = xstrdup(av[1]); /* XXX strdup? */ + + if (sql->out == NULL) /* XXX needed? */ + sql->out = stdout; + sql->iob = rpmiobFree(sql->iob); +#ifdef DYING #ifdef SQLITE_OMIT_MEMORYDB if (sql->zDbFilename == NULL) { fprintf(stderr, "%s: Error: no database filename specified\n", @@ -2467,6 +2428,7 @@ optArg = _free(optArg); /*...@=dependenttrans =modobserver =observertrans @*/ } +#endif /* DYING */ /* XXX refactored from popt callback */ if (sql->mode == RPMSQL_MODE_CSV) @@ -2495,34 +2457,21 @@ /* Run commands received from standard input */ if (F_ISSET(sql, INTERACTIVE)) { - char *zHome; - char *zHistory = 0; - int nHistory; extern char *db_full_version(int *, int *, int *, int *, int *); printf("%s\n" "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", db_full_version(NULL, NULL, NULL, NULL, NULL) ); - zHome = rpmsqlHomeDir(); - if (zHome) { - nHistory = strlen30(zHome) + 20; - if ((zHistory = malloc(nHistory)) != 0) { - sqlite3_snprintf(nHistory, zHistory, - "%s/.sqlite_history", zHome); - } - } #if defined(HAVE_READLINE) && HAVE_READLINE==1 - if (zHistory) - read_history(zHistory); + if (sql->zHistory) + read_history(sql->zHistory); #endif ec = rpmsqlInput(sql, 0); - if (zHistory) { + if (sql->zHistory) { stifle_history(100); - write_history(zHistory); - free(zHistory); + write_history(sql->zHistory); } - free(zHome); } else { ec = rpmsqlInput(sql, stdin); } @@ -2530,23 +2479,11 @@ exit: - sql->zDbFilename = _free(sql->zDbFilename); set_table_name(sql, NULL); - if (sql->I != NULL) { - sqlite3 * db = (sqlite3 *)sql->I; - if (sqlite3_close(db) != SQLITE_OK) { - fprintf(stderr, "Error: cannot close database \"%s\"\n", - sqlite3_errmsg(db)); - ec = 1; - } - } - zFirstCmd = _free(zFirstCmd); - sql->zInitFile = _free(sql->zInitFile); - - con = rpmioFini(con); + sql = rpmsqlFree(sql); return ec; } @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository [email protected]
