Initial Commit
[packages] / mule-packages / mule-base / lib-src / coco.c
1 #include <stdio.h>
2 #include "mulelib.h"
3
4 #define IN_BUF_SIZE 4096
5 #define OUT_BUF_SIZE (IN_BUF_SIZE * 5 + CONV_BUF_EXTRA)
6
7 static char *coco_version = "2.2";
8
9 static int
10 strpcmp(p0, p1)
11      char **p0, **p1;
12 {
13   return strcmp(*p0, *p1);
14 }
15
16 coco_list(stream)
17      FILE *stream;
18 {
19   int i, j, k, clm, len, maxlen;
20   char **names;
21
22   names = (char **)malloc((sizeof names[0]) * n_base_coding_system);
23   maxlen = 0;
24   for (i = 0; i < n_base_coding_system; i++) {
25     names[i] = coding_system_table[i].name;
26     len = strlen(names[i]);
27     if (len > maxlen) maxlen = len;
28   }
29   qsort (names, n_base_coding_system, sizeof names[0], strpcmp);
30
31   maxlen += 2;
32   clm = 79 / maxlen;
33   k = n_base_coding_system / clm;
34   if (n_base_coding_system % clm) k++;
35   fprintf (stream, "You can specify the following coding-systems:\n");
36   for (i = 0; i < k; i++) {
37     len = 0;
38     for (j = 0; j < clm; j++) {
39       if (i + j * k < n_base_coding_system) {
40         if (len < maxlen * j)
41           while (len < maxlen * j) {
42             putc(' ', stream);
43             len++;
44           }
45         fprintf (stream, "  %s", names[i + j * k]);
46         len += strlen(names[i + j * k]) + 2;
47       }
48     }
49     putc ('\n', stream);
50   }
51   fprintf (stream, "You can add \"unix*\", \"dos*\", or \"mac*\"");
52   fprintf (stream, " at the tail of these names\n");
53   fprintf (stream, " to specify type of end-of-line");
54   fprintf (stream, "(LF[default], CRLF, or CR).\n");
55
56   free(names);
57
58   return 0;
59 }
60
61 main(argc, argv)
62      int argc;
63      char **argv;
64 {
65   int help = 0, list = 0, verbose = 0, query = 0;
66   int in_total = 0, out_total = 0, n;
67   char inbuf[IN_BUF_SIZE], outbuf[OUT_BUF_SIZE];
68   char *inname = NULL, *outname = NULL;
69   coding_type incode, outcode;
70
71   if (mulelib_initialize(argc, argv, NULL, NULL) < 0) {
72     fprintf(stderr, "Initialization of Mule libarary failed.\n");
73     exit(1);
74   }
75
76   while (--argc > 0) {
77     argv++;
78     if (!strcmp(*argv, "-h")) { help = list = 1; break; }
79     if (!strcmp(*argv, "-l")) { list = 1; break; }
80     if (!strcmp(*argv, "-v")) { verbose = 1; continue; }
81     if (!strcmp(*argv, "-q")) { query = 1; continue; }
82     if (!query) {
83       if (outname != NULL) inname = outname;
84       outname = *argv;
85     }
86   }
87
88   if (help) {
89     printf("Version %s (mulelib version %s)\n",
90            coco_version, mule_library_version);
91     printf("Usage: coco [-h|-l|-v|-q] [[INCODE] OUTCODE] <INFILE >OUTFILE\n");
92     printf("  -h: print this message\n");
93     printf("  -l: list valid INCODE and OUTCODE\n");
94     printf("  -v: print information about conversion\n");
95     printf("  -q: just investigate how INFILE is encoded\n");
96     printf("  INCODE: coding-system of INFILE, defaults to `*autoconv*'\n");
97     printf("  OUTCODE: coding-system of OUTFILE, defaults to `*internal*'\n");
98   }
99
100   if (list) {
101     coco_list(stdout);
102     exit(0);
103   }
104
105   if (set_coding_system(inname, &incode, outname, &outcode) < 0) {
106     fprintf(stderr, "%s\n", mule_error_msg);
107     exit(1);
108   }
109
110   while ((n = read(0, inbuf, sizeof inbuf)) > 0) {
111     in_total += n;
112     if ((n = code_conversion(&incode, inbuf, n, &outcode, outbuf,
113                              OUT_BUF_SIZE)) < 0) {
114       if (!query) write(1, outbuf, OUT_BUF_SIZE);
115       exit(1);
116     }
117     if (!query && n > 0) write(1, outbuf, n);
118     out_total += n;
119   }
120
121   if (query) {
122     fprintf(stderr, "In (%s): %6d bytes\n", incode.name, in_total);
123     exit(0);
124   }
125
126   /* Flush out an unfinished state (e.g. terminating with "ESC ( B"). */
127   n = code_conversion(&incode, inbuf, 0, &outcode, outbuf, OUT_BUF_SIZE);
128   if (n > 0) write(1, outbuf, n);
129   out_total += n;
130
131   if (verbose)
132     fprintf(stderr, "In :%6d bytes of %s\nOut:%6d bytes of %s\n",
133             in_total, incode.name, out_total, outcode.name);
134   exit(0);
135 }