}
#endif
-/*
-** Determines if a string is a number of not.
-*/
-static int isNumber(const char *z, int *realnum){
- if( *z=='-' || *z=='+' ) z++;
- if( !IsDigit(*z) ){
- return 0;
- }
- z++;
- if( realnum ) *realnum = 0;
- while( IsDigit(*z) ){ z++; }
- if( *z=='.' ){
- z++;
- if( !IsDigit(*z) ) return 0;
- while( IsDigit(*z) ){ z++; }
- if( realnum ) *realnum = 1;
- }
- if( *z=='e' || *z=='E' ){
- z++;
- if( *z=='+' || *z=='-' ) z++;
- if( !IsDigit(*z) ) return 0;
- while( IsDigit(*z) ){ z++; }
- if( realnum ) *realnum = 1;
- }
- return *z==0;
-}
-
/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
#endif
}
-/*
-** Output the given string as a hex-encoded blob (eg. X'1234' )
-*/
-static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
- int i;
- unsigned char *aBlob = (unsigned char*)pBlob;
-
- char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
- shell_check_oom(zStr);
-
- for(i=0; i<nBlob; i++){
- static const char aHex[] = {
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
- };
- zStr[i*2] = aHex[ (aBlob[i] >> 4) ];
- zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ];
- }
- zStr[i*2] = '\0';
-
- sqlite3_fprintf(out, "X'%s'", zStr);
- sqlite3_free(zStr);
-}
-
-/*
-** Output the given string as a quoted string using SQL quoting conventions:
-**
-** (1) Single quotes (') within the string are doubled
-** (2) The while string is enclosed in '...'
-** (3) Control characters other than \n, \t, and \r\n are escaped
-** using \u00XX notation and if such substitutions occur,
-** the whole string is enclosed in unistr('...') instead of '...'.
-**
-** Step (3) is omitted if the control-character escape mode is OFF.
-**
-** See also: output_quoted_escaped_string() which does the same except
-** that it does not make exceptions for \n, \t, and \r\n in step (3).
-*/
-static void output_quoted_string(ShellState *p, const char *zInX){
- int i;
- int needUnistr = 0;
- int needDblQuote = 0;
- const unsigned char *z = (const unsigned char*)zInX;
- unsigned char c;
- FILE *out = p->out;
- sqlite3_fsetmode(out, _O_BINARY);
- if( z==0 ) return;
- for(i=0; (c = z[i])!=0; i++){
- if( c=='\'' ){ needDblQuote = 1; }
- if( c>0x1f ) continue;
- if( c=='\t' || c=='\n' ) continue;
- if( c=='\r' && z[i+1]=='\n' ) continue;
- needUnistr = 1;
- break;
- }
- if( (needDblQuote==0 && needUnistr==0)
- || (needDblQuote==0 && p->eEscMode==SHELL_ESC_OFF)
- ){
- sqlite3_fprintf(out, "'%s'",z);
- }else if( p->eEscMode==SHELL_ESC_OFF ){
- char *zEncoded = sqlite3_mprintf("%Q", z);
- sqlite3_fputs(zEncoded, out);
- sqlite3_free(zEncoded);
- }else{
- if( needUnistr ){
- sqlite3_fputs("unistr('", out);
- }else{
- sqlite3_fputs("'", out);
- }
- while( *z ){
- for(i=0; (c = z[i])!=0; i++){
- if( c=='\'' ) break;
- if( c>0x1f ) continue;
- if( c=='\t' || c=='\n' ) continue;
- if( c=='\r' && z[i+1]=='\n' ) continue;
- break;
- }
- if( i ){
- sqlite3_fprintf(out, "%.*s", i, z);
- z += i;
- }
- if( c==0 ) break;
- if( c=='\'' ){
- sqlite3_fputs("''", out);
- }else{
- sqlite3_fprintf(out, "\\u%04x", c);
- }
- z++;
- }
- if( needUnistr ){
- sqlite3_fputs("')", out);
- }else{
- sqlite3_fputs("'", out);
- }
- }
- setCrlfMode(p);
-}
-
-/*
-** Output the given string as a quoted string using SQL quoting conventions.
-** Additionallly , escape the "\n" and "\r" characters so that they do not
-** get corrupted by end-of-line translation facilities in some operating
-** systems.
-**
-** This is like output_quoted_string() but with the addition of the \r\n
-** escape mechanism.
-*/
-static void output_quoted_escaped_string(ShellState *p, const char *z){
- char *zEscaped;
- sqlite3_fsetmode(p->out, _O_BINARY);
- if( p->eEscMode==SHELL_ESC_OFF ){
- zEscaped = sqlite3_mprintf("%Q", z);
- }else{
- zEscaped = sqlite3_mprintf("%#Q", z);
- }
- sqlite3_fputs(zEscaped, p->out);
- sqlite3_free(zEscaped);
- setCrlfMode(p);
-}
-
/*
** Find earliest of chars within s specified in zAny.
** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated.
sqlite3_fputs(zq, out);
}
-/*
-** Output the given string as quoted according to JSON quoting rules.
-*/
-static void output_json_string(FILE *out, const char *z, i64 n){
- unsigned char c;
- static const char *zq = "\"";
- static long ctrlMask = ~0L;
- static const char *zDQBS = "\"\\";
- const char *pcLimit;
- char ace[3] = "\\?";
- char cbsSay;
-
- if( z==0 ) z = "";
- pcLimit = z + ((n<0)? strlen(z) : (size_t)n);
- sqlite3_fputs(zq, out);
- while( z < pcLimit ){
- const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z);
- const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask);
- const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast;
- if( pcEnd > z ){
- sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z);
- z = pcEnd;
- }
- if( z >= pcLimit ) break;
- c = (unsigned char)*(z++);
- switch( c ){
- case '"': case '\\':
- cbsSay = (char)c;
- break;
- case '\b': cbsSay = 'b'; break;
- case '\f': cbsSay = 'f'; break;
- case '\n': cbsSay = 'n'; break;
- case '\r': cbsSay = 'r'; break;
- case '\t': cbsSay = 't'; break;
- default: cbsSay = 0; break;
- }
- if( cbsSay ){
- ace[1] = cbsSay;
- sqlite3_fputs(ace, out);
- }else if( c<=0x1f || c>=0x7f ){
- sqlite3_fprintf(out, "\\u%04x", c);
- }else{
- ace[1] = (char)c;
- sqlite3_fputs(ace+1, out);
- }
- }
- sqlite3_fputs(zq, out);
-}
-
-/*
-** Escape the input string if it is needed and in accordance with
-** eEscMode.
-**
-** Escaping is needed if the string contains any control characters
-** other than \t, \n, and \r\n
-**
-** If no escaping is needed (the common case) then set *ppFree to NULL
-** and return the original string. If escaping is needed, write the
-** escaped string into memory obtained from sqlite3_malloc64() or the
-** equivalent, and return the new string and set *ppFree to the new string
-** as well.
-**
-** The caller is responsible for freeing *ppFree if it is non-NULL in order
-** to reclaim memory.
-*/
-static const char *escapeOutput(
- ShellState *p,
- const char *zInX,
- char **ppFree
-){
- i64 i, j;
- i64 nCtrl = 0;
- unsigned char *zIn;
- unsigned char c;
- unsigned char *zOut;
-
-
- /* No escaping if disabled */
- if( p->eEscMode==SHELL_ESC_OFF ){
- *ppFree = 0;
- return zInX;
- }
-
- /* Count the number of control characters in the string. */
- zIn = (unsigned char*)zInX;
- for(i=0; (c = zIn[i])!=0; i++){
- if( c<=0x1f
- && c!='\t'
- && c!='\n'
- && (c!='\r' || zIn[i+1]!='\n')
- ){
- nCtrl++;
- }
- }
- if( nCtrl==0 ){
- *ppFree = 0;
- return zInX;
- }
- if( p->eEscMode==SHELL_ESC_SYMBOL ) nCtrl *= 2;
- zOut = sqlite3_malloc64( i + nCtrl + 1 );
- shell_check_oom(zOut);
- for(i=j=0; (c = zIn[i])!=0; i++){
- if( c>0x1f
- || c=='\t'
- || c=='\n'
- || (c=='\r' && zIn[i+1]=='\n')
- ){
- continue;
- }
- if( i>0 ){
- memcpy(&zOut[j], zIn, i);
- j += i;
- }
- zIn += i+1;
- i = -1;
- switch( p->eEscMode ){
- case SHELL_ESC_SYMBOL:
- zOut[j++] = 0xe2;
- zOut[j++] = 0x90;
- zOut[j++] = 0x80+c;
- break;
- case SHELL_ESC_ASCII:
- zOut[j++] = '^';
- zOut[j++] = 0x40+c;
- break;
- }
- }
- if( i>0 ){
- memcpy(&zOut[j], zIn, i);
- j += i;
- }
- zOut[j] = 0;
- *ppFree = (char*)zOut;
- return (char*)zOut;
-}
-
/*
** Output the given string with characters that are special to
** HTML escaped.
}
}
-/*
-** If a field contains any character identified by a 1 in the following
-** array, then the string must be quoted for CSV.
-*/
-static const char needCsvQuote[] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-};
-
-/*
-** Output a single term of CSV. Actually, p->colSeparator is used for
-** the separator, which may or may not be a comma. p->nullValue is
-** the null value. Strings are quoted if necessary. The separator
-** is only issued if bSep is true.
-*/
-static void output_csv(ShellState *p, const char *z, int bSep){
- if( z==0 ){
- sqlite3_fprintf(p->out, "%s",p->nullValue);
- }else{
- unsigned i;
- for(i=0; z[i]; i++){
- if( needCsvQuote[((unsigned char*)z)[i]] ){
- i = 0;
- break;
- }
- }
- if( i==0 || strstr(z, p->colSeparator)!=0 ){
- char *zQuoted = sqlite3_mprintf("\"%w\"", z);
- shell_check_oom(zQuoted);
- sqlite3_fputs(zQuoted, p->out);
- sqlite3_free(zQuoted);
- }else{
- sqlite3_fputs(z, p->out);
- }
- }
- if( bSep ){
- sqlite3_fputs(p->colSeparator, p->out);
- }
-}
-
/*
** This routine runs when the user presses Ctrl-C
*/