34 #include "lt-memory.h"
37 #define ERR(m) LT_ERROR(NECHAR,m)
38 #define ERR1(m,x) LT_ERROR1(NECHAR,m,x)
39 #define ERR2(m,x,y) LT_ERROR2(NECHAR,m,x,y)
42 #define Realloc srealloc
50 #define ERR(m) fprintf(stderr,m)
51 #define ERR1(m,x) fprintf(stderr,m,x)
52 #define ERR2(m,x,y) fprintf(stderr,m,x,y)
68 #define BufferSize 4096
70 typedef int ReadProc(FILE16 *file,
unsigned char *buf,
int max_count);
71 typedef int WriteProc(FILE16 *file,
const unsigned char *buf,
int count);
72 typedef int SeekProc(FILE16 *file,
long offset,
int ptrname);
73 typedef int FlushProc(FILE16 *file);
74 typedef int CloseProc(FILE16 *file);
85 CharacterEncoding enc;
89 #define FILE16_read 0x01
90 #define FILE16_write 0x02
91 #define FILE16_close_underlying 0x04
93 static int FileRead(FILE16 *file,
unsigned char *buf,
int max_count);
94 static int FileWrite(FILE16 *file,
const unsigned char *buf,
int count);
95 static int FileSeek(FILE16 *file,
long offset,
int ptrname);
96 static int FileClose(FILE16 *file);
97 static int FileFlush(FILE16 *file);
99 static int StringRead(FILE16 *file,
unsigned char *buf,
int max_count);
100 static int StringWrite(FILE16 *file,
const unsigned char *buf,
int count);
101 static int StringSeek(FILE16 *file,
long offset,
int ptrname);
102 static int StringClose(FILE16 *file);
103 static int StringFlush(FILE16 *file);
106 #ifdef SOCKETS_IMPLEMENTED
107 static int WinsockRead(FILE16 *file,
unsigned char *buf,
int max_count);
108 static int WinsockWrite(FILE16 *file,
const unsigned char *buf,
int count);
109 static int WinsockSeek(FILE16 *file,
long offset,
int ptrname);
110 static int WinsockClose(FILE16 *file);
111 static int WinsockFlush(FILE16 *file);
116 static int GzipRead(FILE16 *file,
unsigned char *buf,
int max_count);
117 static int GzipWrite(FILE16 *file,
const unsigned char *buf,
int count);
118 static int GzipSeek(FILE16 *file,
long offset,
int ptrname);
119 static int GzipClose(FILE16 *file);
120 static int GzipFlush(FILE16 *file);
123 FILE16 *Stdin, *Stdout, *Stderr;
125 void init_stdio16(
void) {
126 Stdin = MakeFILE16FromFILE(stdin,
"r");
127 SetFileEncoding(Stdin, CE_ISO_8859_1);
128 Stdout = MakeFILE16FromFILE(stdout,
"w");
129 SetFileEncoding(Stdout, CE_ISO_8859_1);
130 Stderr = MakeFILE16FromFILE(stderr,
"w");
131 SetFileEncoding(Stderr, CE_ISO_8859_1);
134 static int ConvertASCII(
const char8 *buf,
int count, FILE16 *file);
135 static int ConvertUTF16(
const char16 *buf,
int count, FILE16 *file);
145 static int ConvertASCII(
const char8 *buf,
int count, FILE16 *file)
147 unsigned char outbuf[BufferSize*2];
161 case CE_unspecified_ascii_superset:
162 return file->write(file, (
unsigned char *)buf, count);
165 for(i=j=0; i<count; i++)
167 unsigned char c = buf[i];
172 outbuf[j++] = 0xc0 + (c >> 6);
173 outbuf[j++] = 0x80 + (c & 0x3f);
176 return file->write(file, outbuf, j);
179 case CE_ISO_10646_UCS_2B:
180 for(i=j=0; i<count; i++)
183 outbuf[j++] = buf[i];
185 return file->write(file, outbuf, count*2);
188 case CE_ISO_10646_UCS_2L:
189 for(i=j=0; i<count; i++)
191 outbuf[j++] = buf[i];
194 return file->write(file, outbuf, count*2);
197 ERR2(
"Bad output character encoding %d (%s)\n",
199 file->enc < CE_enum_count ? CharacterEncodingName[file->enc] :
208 static int ConvertUTF16(
const char16 *buf,
int count, FILE16 *file)
211 unsigned char outbuf[BufferSize*3 + 1];
212 int i, j, tablenum, max;
219 case CE_unspecified_ascii_superset:
220 for(i=0; i<count; i++)
223 outbuf[i] = (
unsigned char)buf[i];
227 return file->write(file, outbuf, count);
237 tablenum = (file->enc - CE_ISO_8859_2);
238 max = iso_max_val[tablenum];
239 from_unicode = unicode_to_iso[tablenum];
240 for(i=0; i<count; i++)
243 outbuf[i] = (
unsigned char)from_unicode[buf[i]];
247 return file->write(file, outbuf, count);
250 for(i=j=0; i<count; i++)
253 outbuf[j++] = (
unsigned char)buf[i];
254 else if(buf[i] < 0x800)
256 outbuf[j++] = 0xc0 + (buf[i] >> 6);
257 outbuf[j++] = 0x80 + (buf[i] & 0x3f);
259 else if(buf[i] >= 0xd800 && buf[i] <= 0xdbff)
261 else if(buf[i] >= 0xdc00 && buf[i] <= 0xdfff)
264 ((file->save - 0xd800) << 10) + (buf[i] - 0xdc00);
265 outbuf[j++] = 0xf0 + (big >> 18);
266 outbuf[j++] = 0x80 + ((big >> 12) & 0x3f);
267 outbuf[j++] = 0x80 + ((big >> 6) & 0x3f);
268 outbuf[j++] = 0x80 + (big & 0x3f);
272 outbuf[j++] = 0xe0 + (buf[i] >> 12);
273 outbuf[j++] = 0x80 + ((buf[i] >> 6) & 0x3f);
274 outbuf[j++] = 0x80 + (buf[i] & 0x3f);
277 return file->write(file, outbuf, j);
280 case CE_ISO_10646_UCS_2B:
281 for(i=j=0; i<count; i++)
283 outbuf[j++] = (buf[i] >> 8);
284 outbuf[j++] = (buf[i] & 0xff);
287 return file->write(file, outbuf, count*2);
290 case CE_ISO_10646_UCS_2L:
291 for(i=j=0; i<count; i++)
293 outbuf[j++] = (buf[i] & 0xff);
294 outbuf[j++] = (buf[i] >> 8);
297 return file->write(file, outbuf, count*2);
300 ERR2(
"Bad output character encoding %d (%s)\n",
302 file->enc < CE_enum_count ? CharacterEncodingName[file->enc] :
309 int Readu(FILE16 *file,
unsigned char *buf,
int max_count)
311 return file->read(file, buf, max_count);
314 int Writeu(FILE16 *file,
unsigned char *buf,
int count)
316 return file->write(file, buf, count);
319 int Fclose(FILE16 *file)
323 ret = file->close(file);
329 int Fseek(FILE16 *file,
long offset,
int ptrname)
331 return file->seek(file, offset, ptrname);
334 int Fflush(FILE16 *file)
336 return file->flush(file);
339 FILE *GetFILE(FILE16 *file)
341 if(file->read == FileRead)
342 return (FILE *)file->handle;
347 void SetCloseUnderlying(FILE16 *file,
int cu)
350 file->flags |= FILE16_close_underlying;
352 file->flags &= ~FILE16_close_underlying;
355 void SetFileEncoding(FILE16 *file, CharacterEncoding encoding)
357 file->enc = encoding;
360 CharacterEncoding GetFileEncoding(FILE16 *file)
365 int Fprintf(FILE16 *file,
const char *format, ...)
368 va_start(args, format);
369 return Vfprintf(file, format, args);
372 int Printf(
const char *format, ...)
375 va_start(args, format);
376 return Vfprintf(Stdout, format, args);
379 int Sprintf(
void *buf, CharacterEncoding enc,
const char *format, ...)
382 va_start(args, format);
383 return Vsprintf(buf, enc, format, args);
386 int Vprintf(
const char *format, va_list args)
388 return Vfprintf(Stdout, format, args);
391 int Vsprintf(
void *buf, CharacterEncoding enc,
const char *format,
395 FILE16 file = {0, 0, -1, StringRead, StringWrite, StringSeek, StringFlush, StringClose, FILE16_write};
400 nchars = Vfprintf(&file, format, args);
406 #define put(x) {nchars++; if(count == sizeof(buf)) {if(ConvertASCII(buf, count, file) == -1) return -1; count = 0;} buf[count++] = x;}
408 int Vfprintf(FILE16 *file,
const char *format, va_list args)
410 char8 buf[BufferSize];
412 int c, i, n, width, prec;
419 int mflag, pflag, sflag, hflag, zflag;
423 while((c = *format++))
434 mflag=0, pflag=0, sflag=0, hflag=0, zflag=0;
439 switch(c = *format++)
464 width = va_arg(args,
int);
467 else if(c >=
'0' && c <=
'9')
470 while((c = *format++) >=
'0' && c <=
'9')
471 width = width * 10 + c -
'0';
479 prec = va_arg(args,
int);
482 else if(c >=
'0' && c <=
'9')
485 while((c = *format++) >=
'0' && c <=
'9')
486 prec = prec * 10 + c -
'0';
502 #ifdef HAVE_LONG_DOUBLE
510 if(format - start + 1 >
sizeof(fmt))
512 ERR(
"Printf: format specifier too long");
517 strncpy(fmt, start, format - start);
518 fmt[format - start] =
'\0';
525 *va_arg(args,
int *) = nchars;
534 sprintf(val, fmt, va_arg(args,
int));
536 sprintf(val, fmt, va_arg(args,
long));
538 sprintf(val, fmt, va_arg(args,
int));
547 #ifdef HAVE_LONG_DOUBLE
549 sprintf(val, fmt, va_arg(args,
long double));
552 sprintf(val, fmt, va_arg(args,
double));
558 if(ConvertASCII(buf, count, file) == -1)
561 cbuf[0] = va_arg(args,
int);
562 if(ConvertUTF16(cbuf, 1, file) == -1)
566 put(va_arg(args,
int));
570 sprintf(val, fmt, va_arg(args,
void *));
580 static char16 sNULL[] = {
'(',
'N',
'U',
'L',
'L',
')',0};
584 q = va_arg(args, char16 *);
588 if(prec >= 0 && n > prec)
590 if(n < width && !mflag)
591 for(i=width-n; i>0; i--)
593 if(ConvertASCII(buf, count, file) == -1)
600 if(ConvertUTF16(q, n > BufferSize ? BufferSize : n, file) == -1)
611 p = va_arg(args, char8 *);
615 if(prec >= 0 && n > prec)
617 if(n < width && !mflag)
618 for(i=width-n; i>0; i--)
623 if(n < width && mflag)
624 for(i=width-n; i>0; i--)
630 ERR1(
"unknown format character %c\n", c);
637 if(ConvertASCII(buf, count, file) == -1)
643 static FILE16 *MakeFILE16(
const char *type)
647 if(!(file = Malloc(
sizeof(*file))))
652 file->flags |= FILE16_read;
654 file->flags |= FILE16_write;
656 file->enc = InternalCharacterEncoding;
661 FILE16 *MakeFILE16FromFILE(FILE *f,
const char *type)
665 if(!(file = MakeFILE16(type)))
668 file->read = FileRead;
669 file->write = FileWrite;
670 file->seek = FileSeek;
671 file->close = FileClose;
672 file->flush = FileFlush;
678 static int FileRead(FILE16 *file,
unsigned char *buf,
int max_count)
680 FILE *f = file->handle;
683 count = fread(buf, 1, max_count, f);
685 return ferror(f) ? -1 : count;
688 static int FileWrite(FILE16 *file,
const unsigned char *buf,
int count)
690 FILE *f = file->handle;
694 return fwrite(buf, 1, count, f) == 0 ? -1 : 0;
697 static int FileSeek(FILE16 *file,
long offset,
int ptrname)
699 FILE *f = file->handle;
701 return fseek(f, offset, ptrname);
704 static int FileClose(FILE16 *file)
706 FILE *f = file->handle;
708 return (file->flags & FILE16_close_underlying) ? fclose(f) : 0;
711 static int FileFlush(FILE16 *file)
713 FILE *f = file->handle;
718 FILE16 *MakeFILE16FromString(
void *buf,
long size,
const char *type)
722 if(!(file = MakeFILE16(type)))
725 file->read = StringRead;
726 file->write = StringWrite;
727 file->seek = StringSeek;
728 file->close = StringClose;
729 file->flush = StringFlush;
733 file->handle3 = size;
738 static int StringRead(FILE16 *file,
unsigned char *buf,
int max_count)
740 char *p = (
char *)file->handle + file->handle2;
742 if(file->handle3 >= 0 && file->handle2 + max_count > file->handle3)
743 max_count = file->handle3 - file->handle2;
748 memcpy(buf, p, max_count);
749 file->handle2 += max_count;
754 static int StringWrite(FILE16 *file,
const unsigned char *buf,
int count)
756 char *p = (
char *)file->handle + file->handle2;
758 if(file->handle3 >= 0 && file->handle2 + count > file->handle3)
761 memcpy(p, buf, count);
762 file->handle2 += count;
767 static int StringSeek(FILE16 *file,
long offset,
int ptrname)
772 offset = file->handle2 + offset;
775 if(file->handle3 < 0)
777 offset = file->handle3 + offset;
781 if(file->handle3 >= 0 && offset > file->handle3)
784 file->handle2 = offset;
789 static int StringClose(FILE16 *file)
791 static char8 null = 0;
793 if(file->flags & FILE16_write)
794 ConvertASCII(&null, 1, file);
796 if(file->flags & FILE16_close_underlying)
797 Free((
char *)file->handle);
802 static int StringFlush(FILE16 *file)
809 #ifdef SOCKETS_IMPLEMENTED
811 FILE16 *MakeFILE16FromWinsock(
int sock,
const char *type)
815 if(!(file = MakeFILE16(type)))
818 file->read = WinsockRead;
819 file->write = WinsockWrite;
820 file->seek = WinsockSeek;
821 file->close = WinsockClose;
822 file->flush = WinsockFlush;
823 file->handle2 = sock;
828 static int WinsockRead(FILE16 *file,
unsigned char *buf,
int max_count)
830 int f = (int)file->handle2;
834 count = recv(f, buf, max_count, 0);
839 static int WinsockWrite(FILE16 *file,
const unsigned char *buf,
int count)
846 static int WinsockSeek(FILE16 *file,
long offset,
int ptrname)
851 static int WinsockClose(FILE16 *file)
858 static int WinsockFlush(FILE16 *file)
868 FILE16 *MakeFILE16FromGzip(gzFile f,
const char *type)
872 if(!(file = MakeFILE16(type)))
875 file->read = GzipRead;
876 file->write = GzipWrite;
877 file->seek = GzipSeek;
878 file->close = GzipClose;
879 file->flush = GzipFlush;
880 file->handle = (
void *)f;
885 static int GzipRead(FILE16 *file,
unsigned char *buf,
int max_count)
887 gzFile f = (gzFile)file->handle;
890 const char *errorString;
892 count = gzread(f, buf, max_count);
894 errorString = gzerror(f, &gzerr);
895 if(gzerr != 0 && gzerr != Z_STREAM_END)
901 static int GzipWrite(FILE16 *file,
const unsigned char *buf,
int count)
903 gzFile f = (gzFile)file->handle;
905 const char *errorString;
907 count = gzwrite(f, (
char *)buf, count);
909 errorString = gzerror(f, &gzerr);
910 if(gzerr != 0 && gzerr != Z_STREAM_END)
916 static int GzipSeek(FILE16 *file,
long offset,
int ptrname)
921 static int GzipClose(FILE16 *file)
923 gzFile f = (gzFile)file->handle;
925 return (file->flags & FILE16_close_underlying) ? gzclose(f) : 0;
928 static int GzipFlush(FILE16 *file)
937 int main(
int argc,
char **argv)
941 char16 S[] = {
'w',
'o',
'r',
'l',
'd',
' ',
'£' & 0xff, 0xd841, 0xdc42, 0};
943 n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L,
"÷hello", S);
944 printf(
"\nreturned %d, c=%d\n", n, c);
945 n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L,
"÷hello", S);
946 printf(
"\nreturned %d, c=%d\n", n, c);
947 n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L,
"÷hello", S);
948 printf(
"\nreturned %d, c=%d\n", n, c);
949 n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L,
"÷hello", S);
950 printf(
"\nreturned %d, c=%d\n", n, c);