>From: Richard Hipp >Sent: 2015?12?30? 20:21 >To: SQLite mailing list >Subject: Re: [sqlite] A small patch for the SQLite shell in windows.
>Please send a unified diff, generated using the -u option to the >"diff" command.? Even better would be the "-U 8" option, to include >more context. diff -U 8 src/shell.c /home/nana/shell.c ----------------diff.txt------cut here---------------------- --- src/shell.c 2015-11-03 01:44:00.000000000 +0800 +++ /home/nana/shell.c 2015-12-28 01:36:42.643546200 +0800 @@ -809,21 +809,42 @@ /* ** This is the callback routine that the shell ** invokes for each row of a query result. */ static int shell_callback( void *pArg, int nArg, /* Number of result columns */ - char **azArg, /* Text of each result column */ + char **azArgZ, /* Text of each result column */ char **azCol, /* Column names */ int *aiType /* Column types */ ){ int i; +#if defined(_WIN32) || defined(WIN32) + char** azArg = malloc(sizeof(char*)*nArg); + for (i = 0;i < nArg;i++) { + if (azArgZ[i] == 0) + azArg[i] = 0; + else { + int nlen = MultiByteToWideChar(CP_UTF8, 0, azArgZ[i], -1, NULL, 0); + assert(nlen > 0); + WCHAR* buff = (WCHAR*)malloc(nlen * sizeof(WCHAR)); + (void)MultiByteToWideChar(CP_UTF8, 0, azArgZ[i], -1, buff, nlen); + int ilen = WideCharToMultiByte(CP_ACP, 0, buff, nlen, NULL, 0, NULL, NULL); + assert(ilen > 0); + char* buff1 = (char*)malloc(ilen); + (void)WideCharToMultiByte(CP_ACP, 0, buff, nlen, buff1, ilen, NULL, NULL); + azArg[i] = buff1; + free(buff); + } + } +#else + char** azArg = azArgZ; +#endif ShellState *p = (ShellState*)pArg; switch( p->mode ){ case MODE_Line: { int w = 5; if( azArg==0 ) break; for(i=0; i<nArg; i++){ int len = strlen30(azCol[i] ? azCol[i] : ""); @@ -1035,16 +1056,23 @@ for(i=0; i<nArg; i++){ if( i>0 ) fprintf(p->out, "%s", p->colSeparator); fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue); } fprintf(p->out, "%s", p->rowSeparator); break; } } +#if defined(_WIN32) || defined(WIN32) + for (i = 0;i < nArg;i++) { + if (azArg[i]) + free(azArg[i]); + } + free(azArg); +#endif return 0; } /* ** This is the callback routine that the SQLite library ** invokes for each row of a query result. */ static int callback(void *pArg, int nArg, char **azArg, char **azCol){ @@ -4247,19 +4275,35 @@ memcpy(zSql+nSql, zLine, nLine+1); nSql += nLine; } if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) && sqlite3_complete(zSql) ){ p->cnt = 0; open_db(p, 0); if( p->backslashOn ) resolve_backslashes(zSql); - BEGIN_TIMER; - rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); - END_TIMER; +#if defined(_WIN32) || defined(WIN32) + int nlen = MultiByteToWideChar(CP_ACP, 0, zSql, -1, 0, 0); + assert(nlen > 0); + WCHAR* buff = (WCHAR*)malloc(nlen * sizeof(WCHAR)); + (void)MultiByteToWideChar(CP_ACP, 0, zSql, -1, buff, nlen); + int ilen = WideCharToMultiByte(CP_UTF8, 0, buff, nlen, NULL, 0, NULL, NULL); + assert(ilen > 0); + char* buff1 = (char*)malloc(ilen); + (void)WideCharToMultiByte(CP_UTF8, 0, buff, nlen, buff1, ilen, NULL, NULL); + free(buff); + BEGIN_TIMER; + rc = shell_exec(p->db, buff1, shell_callback, p, &zErrMsg); + END_TIMER; + free(buff1); +#else + BEGIN_TIMER; + rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg); + END_TIMER; +#endif if( rc || zErrMsg ){ char zPrefix[100]; if( in!=0 || !stdin_is_interactive ){ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error: near line %d:", startline); }else{ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:"); } --------------------------------------cut here--------------------------------