📄 tcs.c
字号:
#ifndef PLAN9#include <sys/types.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <errno.h>#include "plan9.h"#else /* PLAN9 */#include <u.h>#include <libc.h>#include <bio.h>#endif /* PLAN9 */#include "cyrillic.h"#include "misc.h"#include "ms.h"#include "8859.h"#include "big5.h"#include "gb.h"#include "hdr.h"#include "conv.h"void usage(void);void list(void);int squawk = 1;int clean = 0;int verbose = 0;long ninput, noutput, nrunes, nerrors;char *file = "stdin";char *argv0;Rune runes[N];char obuf[UTFmax*N]; /* maximum bloat from N runes */long tab[NRUNE];#ifndef PLAN9extern char version[];#endifvoid intable(int, long *, struct convert *);void unicode_in(int, long *, struct convert *);void unicode_out(Rune *, int, long *);intmain(int argc, char **argv){ char *from = "utf"; char *to = "utf"; int fd; int listem = 0; struct convert *t, *f; ARGBEGIN { case 'c': clean = 1; break; case 'f': from = EARGF(usage()); break; case 'l': listem = 1; break; case 's': squawk = 0; break; case 't': to = EARGF(usage()); break; case 'v': verbose = 1; break; default: usage(); break; } ARGEND USED(argc); if(verbose) squawk = 1; if(listem){ list(); EXIT(0, 0); } if(!from || !to) usage(); f = conv(from, 1); t = conv(to, 0);#define PROC {if(f->flags&Table)\ intable(fd, (long *)f->data, t);\ else\ ((Infn)(f->fn))(fd, (long *)0, t);} if(*argv){ while(*argv){ file = *argv;#ifndef PLAN9 if((fd = open(*argv, 0)) < 0){ EPR "%s: %s: %s\n", argv0, *argv, strerror(errno));#else /* PLAN9 */ if((fd = open(*argv, OREAD)) < 0){ EPR "%s: %s: %r\n", argv0, *argv);#endif /* PLAN9 */ EXIT(1, "open failure"); } PROC close(fd); argv++; } } else { fd = 0; PROC } if(verbose) EPR "%s: %ld input bytes, %ld runes, %ld output bytes (%ld errors)\n", argv0, ninput, nrunes, noutput, nerrors); EXIT(((nerrors && squawk)? 1:0), ((nerrors && squawk)? "conversion error":0)); return(0); /* shut up compiler */}voidusage(void){ EPR "Usage: %s [-slv] [-f cs] [-t cs] [file ...]\n", argv0); verbose = 1; list(); EXIT(1, "usage");}voidlist(void){ struct convert *c; char ch = verbose?'\t':' ';#ifndef PLAN9 EPR "%s version = '%s'\n", argv0, version);#endif if(verbose) EPR "character sets:\n"); else EPR "cs:"); for(c = convert; c->name; c++){ if((c->flags&From) && c[1].name && (strcmp(c[1].name, c->name) == 0)){ EPR "%c%s", ch, c->name); c++; } else if(c->flags&Table) EPR "%c%s", ch, c->name); else if(c->flags&From) EPR "%c%s(from)", ch, c->name); else EPR "%c%s(to)", ch, c->name); if(verbose) EPR "\t%s\n", c->chatter); } if(!verbose) EPR "\n");}struct convert *conv(char *name, int from){ struct convert *c; for(c = convert; c->name; c++){ if(cistrcmp(c->name, name) != 0) continue; if(c->flags&Table) return(c); if(((c->flags&From) == 0) == (from == 0)) return(c); } EPR "%s: charset `%s' unknown\n", argv0, name); EXIT(1, "unknown character set"); return(0); /* just shut the compiler up */}voidswab2(char *b, int n){ char *e, p; for(e = b+n; b < e; b++){ p = *b; *b = b[1]; *++b = p; }}voidunicode_in(int fd, long *notused, struct convert *out){ Rune buf[N]; int n; int swabme; USED(notused); if(read(fd, (char *)buf, 2) != 2) return; ninput += 2; switch(buf[0]) { default: OUT(out, buf, 1); case 0xFEFF: swabme = 0; break; case 0xFFFE: swabme = 1; break; } while((n = read(fd, (char *)buf, 2*N)) > 0){ ninput += n; if(swabme) swab2((char *)buf, n); if(n&1){ if(squawk) EPR "%s: odd byte count in %s\n", argv0, file); nerrors++; if(clean) n--; else buf[n++/2] = Runeerror; } OUT(out, buf, n/2); } OUT(out, buf, 0);}voidunicode_in_be(int fd, long *notused, struct convert *out){ int i, n; Rune buf[N], r; uchar *p; USED(notused); while((n = read(fd, (char *)buf, 2*N)) > 0){ ninput += n; p = (uchar*)buf; for(i=0; i<n/2; i++){ r = *p++<<8; r |= *p++; buf[i] = r; } if(n&1){ if(squawk) EPR "%s: odd byte count in %s\n", argv0, file); nerrors++; if(clean) n--; else buf[n++/2] = Runeerror; } OUT(out, buf, n/2); } OUT(out, buf, 0);}voidunicode_in_le(int fd, long *notused, struct convert *out){ int i, n; Rune buf[N], r; uchar *p; USED(notused); while((n = read(fd, (char *)buf, 2*N)) > 0){ ninput += n; p = (uchar*)buf; for(i=0; i<n/2; i++){ r = *p++; r |= *p++<<8; buf[i] = r; } if(n&1){ if(squawk) EPR "%s: odd byte count in %s\n", argv0, file); nerrors++; if(clean) n--; else buf[n++/2] = Runeerror; } OUT(out, buf, n/2); } OUT(out, buf, 0);}voidunicode_out(Rune *base, int n, long *notused){ static int first = 1; USED(notused); nrunes += n; if(first){ unsigned short x = 0xFEFF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -