fixed unicode writing to stderr/stdout directly on windows
#ifdef HL_WIN
#ifdef HL_WIN_DESKTOP
# include <windows.h>
+# include <io.h>
+# include <fcntl.h>
#else
# include<xdk.h>
#endif
# define HL_UFOPEN
#endif
+#ifdef HL_WIN_DESKTOP
+# define SET_IS_STD(f,b) (f)->is_std = b
+#else
+# define SET_IS_STD(f,b)
+#endif
+
typedef struct _hl_fdesc hl_fdesc;
struct _hl_fdesc {
void (*finalize)( hl_fdesc * );
FILE *f;
+# ifdef HL_WIN_DESKTOP
+ bool is_std;
+# endif
};
static void fdesc_finalize( hl_fdesc *f ) {
@@ -57,6 +68,7 @@ HL_PRIM hl_fdesc *hl_file_open( vbyte *name, int mode, bool binary ) {
fd = (hl_fdesc*)hl_gc_alloc_finalizer(sizeof(hl_fdesc));
fd->finalize = fdesc_finalize;
fd->f = f;
+ SET_IS_STD(fd, false);
return fd;
}
@@ -71,6 +83,21 @@ HL_PRIM int hl_file_write( hl_fdesc *f, vbyte *buf, int pos, int len ) {
int ret;
if( !f ) return -1;
hl_blocking(true);
+# ifdef HL_WIN_DESKTOP
+ if( f->is_std ) {
+ // except utf8, handle the case where it's not \0 terminated
+ uchar *out = (uchar*)malloc((len+1)*2);
+ vbyte prev = buf[pos+len-1];
+ if( buf[pos+len] ) buf[pos+len-1] = 0;
+ int olen = hl_from_utf8(out,len,(const char*)(buf+pos));
+ buf[pos+len-1] = prev;
+ _setmode(fileno(f->f),_O_U8TEXT);
+ ret = _write(fileno(f->f),out,olen<<1);
+ _setmode(fileno(f->f),_O_TEXT);
+ if( ret > 0 ) ret = len;
+ free(out);
+ } else
+# endif
ret = (int)fwrite(buf+pos,1,len,f->f);
hl_blocking(false);
return ret;
@@ -90,6 +117,15 @@ HL_PRIM bool hl_file_write_char( hl_fdesc *f, int c ) {
unsigned char cc = (unsigned char)c;
if( !f ) return false;
hl_blocking(true);
+# ifdef HL_WIN_DESKTOP
+ if( f->is_std ) {
+ uchar wcc = cc;
+ _setmode(fileno(f->f),_O_U8TEXT);
+ ret = _write(fileno(f->f),&wcc,2);
+ _setmode(fileno(f->f),_O_TEXT);
+ if( ret > 0 ) ret = 1;
+ } else
+# endif
ret = fwrite(&cc,1,1,f->f);
hl_blocking(false);
return ret == 1;
@@ -136,6 +172,7 @@ HL_PRIM bool hl_file_flush( hl_fdesc *f ) {
f = (hl_fdesc*)hl_gc_alloc_noptr(sizeof(hl_fdesc)); \
f->f = k; \
f->finalize = NULL; \
+ SET_IS_STD(f, true); \
return f; \
}
