Changeset: 7e16c8d15053 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7e16c8d15053
Modified Files:
        clients/Tests/exports.stable.out
        clients/mapiclient/mclient.c
        clients/mapilib/mapi.c
        common/stream/stream.c
        common/stream/stream.h
Branch: default
Log Message:

Updates to character encoding handling in mclient.
- Added new stream type: callback_stream where the user supplies a
  read function; mclient uses it for readline.
- When encapsulating an open FILE pointer in a stream, on Windows we
  use ReadConsoleW/WriteConsoleW if the FILE pointer point to the
  terminal.  This circumvents encoding problems (which encoding to use
  for the terminal since it may be (and usually is) different from the
  encoding used for everything else).
- Don't use iconv directly in mclient, but instead use the iconv
  stream.


diffs (truncated from 1545 to 300 lines):

diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -2622,6 +2622,7 @@ char *buffer_get_buf(buffer *b);
 void buffer_init(buffer *b, char *buf, size_t size);
 stream *buffer_rastream(buffer *b, const char *name);
 stream *buffer_wastream(buffer *b, const char *name);
+stream *callback_stream(void *private, ssize_t( *read)(void *private, void 
*buf, size_t elmsize, size_t cnt), void( *close)(void *private), void( 
*destroy)(void *private), const char *name);
 void close_stream(stream *s);
 stream *file_rastream(FILE *fp, const char *name);
 stream *file_rstream(FILE *fp, const char *name);
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -24,7 +24,6 @@
 #include "mapi.h"
 #include <unistd.h>
 #include <stdlib.h>
-#include <ctype.h>
 #include <sys/stat.h>
 #include <errno.h>
 #ifdef HAVE_STRING_H
@@ -74,10 +73,9 @@ enum modes {
 
 static enum modes mode = SQL;
 static stream *toConsole;
-static stream *toConsole_raw;  /* toConsole without iconv conversion */
 static stream *stdout_stream;
 static stream *stderr_stream;
-static FILE *fromConsole = NULL;
+static stream *fromConsole = NULL;
 static char *language = NULL;
 static char *logfile = NULL;
 static char promptbuf[16];
@@ -85,7 +83,6 @@ static int echoquery = 0;
 static int showtiming = 0;
 #ifdef HAVE_ICONV
 static char *encoding;
-static iconv_t cd_in;
 #endif
 static int errseen = 0;
 
@@ -191,6 +188,8 @@ static char *nullstring = default_nullst
 #define isatty _isatty
 #endif
 
+#define my_isspace(c)  ((c) == '\f' || (c) == '\n' || (c) == ' ')
+
 static timertype
 gettime(void)
 {
@@ -498,7 +497,7 @@ SQLrow(int *len, int *numeric, char **re
                        if ((t = rest[i]) != NULL &&
                            utf8strlen(t, NULL) > (size_t) len[i]) {
                                /* eat leading whitespace */
-                               while (*t != 0 && isascii((int) *t) && 
isspace((int) *t))
+                               while (*t != 0 && my_isspace(*t))
                                        t++;
                                rest[i] = t;
                        }
@@ -544,10 +543,10 @@ SQLrow(int *len, int *numeric, char **re
 
                                        t = utf8skip(rest[i], len[i]);
                                        if (trim == 1) {
-                                               while (t > rest[i] && 
!(isascii((int) *t) && isspace((int) *t)))
+                                               while (t > rest[i] && 
!my_isspace(*t))
                                                        while ((*--t & 0xC0) == 
0x80)
                                                                ;
-                                               if (t == rest[i] && 
!(isascii((int) *t) && isspace((int) *t)))
+                                               if (t == rest[i] && 
!my_isspace(*t))
                                                        t = utf8skip(rest[i], 
len[i]);
                                        }
                                        mnstr_printf(toConsole, "%c",
@@ -570,8 +569,7 @@ SQLrow(int *len, int *numeric, char **re
 
                                        s = t;
                                        if (trim == 1)
-                                               while (isascii((int) *s) &&
-                                                      isspace((int) *s))
+                                               while (my_isspace(*s))
                                                        s++;
                                        if (trim == 2 && *s == '\n')
                                                s++;
@@ -579,8 +577,7 @@ SQLrow(int *len, int *numeric, char **re
                                                t = utf8skip(rest[i], len[i] - 
2);
                                                s = t;
                                                if (trim == 1)
-                                                       while (isascii((int) 
*s) &&
-                                                              isspace((int) 
*s))
+                                                       while (my_isspace(*s))
                                                                s++;
                                                if (trim == 2 && *s == '\n')
                                                        s++;
@@ -664,17 +661,17 @@ XMLprdata(const char *val)
                return;
        while (*val) {
                if (*val == '&')
-                       mnstr_printf(toConsole_raw, "&amp;");
+                       mnstr_printf(toConsole, "&amp;");
                else if (*val == '<')
-                       mnstr_printf(toConsole_raw, "&lt;");
+                       mnstr_printf(toConsole, "&lt;");
                else if (*val == '>')
-                       mnstr_printf(toConsole_raw, "&gt;");
+                       mnstr_printf(toConsole, "&gt;");
                else if (*val == '"')
-                       mnstr_printf(toConsole_raw, "&quot;");
+                       mnstr_printf(toConsole, "&quot;");
                else if (*val == '\'')
-                       mnstr_printf(toConsole_raw, "&apos;");
+                       mnstr_printf(toConsole, "&apos;");
                else if ((*val & 0xFF) < 0x20)  /* control character */
-                       mnstr_printf(toConsole_raw, "&#%d;", *val & 0xFF);
+                       mnstr_printf(toConsole, "&#%d;", *val & 0xFF);
                else if ((*val & 0x80) != 0 /* && encoding != NULL */ ) {
                        int n;
                        unsigned int m;
@@ -684,9 +681,9 @@ XMLprdata(const char *val)
                                c &= ~m;
                        while (--n >= 0)
                                c = (c << 6) | (*++val & 0x3F);
-                       mnstr_printf(toConsole_raw, "&#x%x;", c);
+                       mnstr_printf(toConsole, "&#x%x;", c);
                } else
-                       mnstr_write(toConsole_raw, val, 1, 1);
+                       mnstr_write(toConsole, val, 1, 1);
                val++;
        }
 }
@@ -694,9 +691,9 @@ XMLprdata(const char *val)
 static void
 XMLprattr(const char *name, const char *val)
 {
-       mnstr_printf(toConsole_raw, " %s=\"", name);
+       mnstr_printf(toConsole, " %s=\"", name);
        XMLprdata(val);
-       mnstr_write(toConsole_raw, "\"", 1, 1);
+       mnstr_write(toConsole, "\"", 1, 1);
 }
 
 static void
@@ -705,10 +702,10 @@ XMLrenderer(MapiHdl hdl)
        int i, fields;
        char *name;
 
-       /* we must use toConsole_raw since the XML file is encoded in UTF-8 */
+       /* we must use toConsole since the XML file is encoded in UTF-8 */
        mnstr_flush(toConsole);
-       mnstr_printf(toConsole_raw, "<?xml version='1.0' encoding='UTF-8'?>\n");
-       mnstr_printf(toConsole_raw,
+       mnstr_printf(toConsole, "<?xml version='1.0' encoding='UTF-8'?>\n");
+       mnstr_printf(toConsole,
                     "<!DOCTYPE table [\n"
                     " <!ELEMENT table (row)*>\n" /* a table consists of zero 
or more rows */
                     " <!ELEMENT row (column)+>\n"      /* a row consists of 
one or more columns */
@@ -716,34 +713,34 @@ XMLrenderer(MapiHdl hdl)
                     " <!ATTLIST table name CDATA #IMPLIED>\n"  /* a table may 
have a name */
                     " <!ATTLIST column name CDATA #IMPLIED\n"  /* a column may 
have a name */
                     "                  isnull (true|false) 'false'>]>\n");
-       mnstr_printf(toConsole_raw, "<table");
+       mnstr_printf(toConsole, "<table");
        name = mapi_get_table(hdl, 0);
        if (name != NULL && *name != 0)
                XMLprattr("name", name);
-       mnstr_printf(toConsole_raw, ">\n");
+       mnstr_printf(toConsole, ">\n");
        while (!mnstr_errnr(toConsole) && (fields = fetch_row(hdl)) != 0) {
-               mnstr_printf(toConsole_raw, "<row>");
+               mnstr_printf(toConsole, "<row>");
                for (i = 0; i < fields; i++) {
                        char *data = mapi_fetch_field(hdl, i);
 
-                       mnstr_printf(toConsole_raw, "<column");
+                       mnstr_printf(toConsole, "<column");
                        name = mapi_get_name(hdl, i);
                        if (name != NULL && *name != 0)
                                XMLprattr("name", name);
                        if (data == NULL) {
                                XMLprattr("isnull", "true");
-                               mnstr_write(toConsole_raw, "/", 1, 1);
+                               mnstr_write(toConsole, "/", 1, 1);
                        }
-                       mnstr_write(toConsole_raw, ">", 1, 1);
+                       mnstr_write(toConsole, ">", 1, 1);
                        if (data) {
                                XMLprdata(data);
-                               mnstr_printf(toConsole_raw, "</column>");
+                               mnstr_printf(toConsole, "</column>");
                        }
                }
-               mnstr_printf(toConsole_raw, "</row>\n");
+               mnstr_printf(toConsole, "</row>\n");
        }
-       mnstr_printf(toConsole_raw, "</table>\n");
-       mnstr_flush(toConsole_raw);
+       mnstr_printf(toConsole, "</table>\n");
+       mnstr_flush(toConsole);
 }
 
 static void
@@ -917,7 +914,7 @@ classify(const char *s, size_t l)
        /* state is the current state of the state machine:
         * 0 - initial state, no input seen
         * 1 - initial sign
-        * 2 - valid integer (with optionally a sign)
+        * 2 - valid integer (optionally preceded by a sign)
         * 3 - valid integer, followed by a decimal point
         * 4 - fixed point number of the form [sign] digits period digits
         * 5 - exponent marker after integer or fixed point number
@@ -1082,8 +1079,8 @@ TESTrenderer(MapiHdl hdl)
                                 /* NULL byte in string? */
                                 strlen(s) < l ||
                                 /* start or end with white space? */
-                                (isascii(*s) && isspace((int) *s)) ||
-                                (isascii(s[l - 1]) && isspace((int) s[l - 1])) 
||
+                                my_isspace(*s) ||
+                                my_isspace(s[l - 1]) ||
                                 /* a bunch of geom types */
                                 strcmp(tp, "curve") == 0 ||
                                 strcmp(tp, "geometry") == 0 ||
@@ -1352,18 +1349,21 @@ SQLdebugRendering(MapiHdl hdl)
 static void
 SQLpagemove(int *len, int fields, int *ps, int *silent)
 {
-       int c;
+       char buf[512];
+       ssize_t sz;
 
        SQLseparator(len, fields, '-');
        mnstr_printf(toConsole, "next page? (continue,quit,next)");
        mnstr_flush(toConsole);
-       c = getc(fromConsole);
-       if (c == 'c')
-               *ps = 0;
-       if (c == 'q')
-               *silent = 1;
-       while (c != EOF && c != '\n')
-               c = getc(fromConsole);
+       sz = mnstr_readline(fromConsole, buf, sizeof(buf));
+       if (sz > 0) {
+               if (buf[0] == 'c')
+                       *ps = 0;
+               if (buf[0] == 'q')
+                       *silent = 1;
+               while (sz > 0 && buf[sz - 1] != '\n')
+                       sz = mnstr_readline(fromConsole, buf, sizeof(buf));
+       }
        if (*silent == 0)
                SQLseparator(len, fields, '-');
 }
@@ -1698,10 +1698,9 @@ setWidth(void)
 
 #ifdef HAVE_POPEN
 static void
-start_pager(stream **saveFD, stream **saveFD_raw)
+start_pager(stream **saveFD)
 {
        *saveFD = NULL;
-       *saveFD_raw = NULL;
 
        if (pager) {
                FILE *p;
@@ -1718,10 +1717,8 @@ start_pager(stream **saveFD, stream **sa
                        fprintf(stderr, "Starting '%s' failed\n", pager);
                else {
                        *saveFD = toConsole;
-                       *saveFD_raw = toConsole_raw;
                        /* put | in name to indicate that file should be closed 
with pclose */
                        toConsole = file_wastream(p, "|pager");
-                       toConsole_raw = toConsole;
 #ifdef HAVE_ICONV
                        if (encoding != NULL)
                                toConsole = iconv_wstream(toConsole, encoding, 
"pager");
@@ -1731,13 +1728,11 @@ start_pager(stream **saveFD, stream **sa
 }
 
 static void
-end_pager(stream *saveFD, stream *saveFD_raw)
+end_pager(stream *saveFD)
 {
        if (saveFD) {
-               mnstr_close(toConsole);
-               mnstr_destroy(toConsole);
+               close_stream(toConsole);
                toConsole = saveFD;
-               toConsole_raw = saveFD_raw;
        }
 }
 #endif
@@ -1749,9 +1744,9 @@ format_result(Mapi mid, MapiHdl hdl, cha
        mapi_int64 aff, lid;
        char *reply;
 #ifdef HAVE_POPEN
-       stream *saveFD, *saveFD_raw;
+       stream *saveFD;
 
-       start_pager(&saveFD, &saveFD_raw);
+       start_pager(&saveFD);
 #endif
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to