1 /***************************************************************************
2 
3 	"vnconvert" converts Vietnamese text files between different
4 	formats. It is intended to run on Unix platforms. The user
5 	shoul recompile on his/her specific platform. A very simple
6 	"Makefile" is provided.
7 
8 	This program is similar to the VPS "convert" for DOS, and in
9 	fact, is based on the coding table provided by Vietnamese
10 	Professional Society (VPS).
11 
12 	This program is also based on the TRICHLOR "vn7to8" package and
13 	takes advantage of its header files, converting functions between
14 	VISCII and VIQR formats.
15 
16 	This program considers only the standard VISCII and VIQR formats.
17 
18 	The package consists of the following files:
19 
20 		- vnconvert.c  (this file)
21 		- conv.c
22 		- vn78.c
23 
24 		- vnkeys.h
25 		- conv.h
26 		- ctype.h
27 		- vn78.h
28 		- charset.h
29 		- charsetv.h
30 		- charseta.h
31 		- portable.h
32 		- vncompos.h
33 
34 		- Makefile
35 
36 	Run "make: to install "vnconvert".
37 
38 	There may be a lot of things which can be improved and any comments
39 	or suggestions are welcome. Please forward them to
40 
41 		Binh Do <binhdo@cs.ubc.ca>
42 
43 *****************************************************************************/
44 
45 #include <sys/file.h>
46 #include <sys/stat.h>
47 #include <stdio.h>
48 #include "vnkeys.h"
49 #include "conv.h"
50 
51 
main()52 main()
53 
54 {
55 	u_char	buf[BUFSIZ];
56 	char	bufline[255];
57 	char	input_file[255], output_file[255];
58 	int fd_in, fd_out;
59 	int n, k, icontinue;
60 	int from, to;
61 
62         u_char   esc = VK_DEFAULT_ESC;
63         u_char   bs = VK_DEFAULT_BS;
64         Vk_State        state = VK_ST_VIETNAMESE;
65         u_char   obuf[4*BUFSIZ], newbuf[4*BUFSIZ];
66         int  i, count;
67         Vk_Fsm  id;
68         u_char FAR  *ic, *oc;
69 
70 	struct 	stat 	stbuf;
71 	short  mode;
72 
73 
74         /* Read in input_file, output_file and their formats */
75 
76         id = vk_init(state, esc, bs);
77         vk_set(id, 1, VK_SET_BATCH);
78 
79 
80 
81 	while (1)  {
82 
83 		/* Read in input_file, output_file and their formats */
84 		printf("\nVNCONVERT converts Vietnamese text files between the following formats :\n\n");
85 		printf("\t0 - VISCII \t\t\t 7 - VN Thin-Art (PC)\n");
86 		printf("\t1 - VNCII (VPSWin)\t\t 8 - Viet-Toan\n");
87 		printf("\t2 - VPSedit (DOS)\t\t 9 - Plain Vietnamese\n");
88 		printf("\t3 - VNI\t\t\t\t10 - Standard VIQR\n");
89 		printf("\t4 - VNLab/VNU\n");
90 		printf("\t5 - VNU (Windows)\n");
91 		printf("\t6 - VN Thin-Art (Mac)\n\n");
92 
93 		printf("Input-file name (or Enter to quit): ");
94 		gets_s(bufline, 255);
95 		if (strlen(bufline) == 0)
96 			break;
97 		sscanf(bufline, "%s", input_file);
98 
99 		printf("currently in the format number: ");
100 		*bufline = '\0';
101 		while (strlen(bufline)==0) {
102 			gets_s(bufline, 255);
103 			sscanf(bufline, "%d", &from);
104 		}
105 
106 		printf("\nOutput-file name: ");
107 		*bufline = '\0';
108                 while (strlen(bufline)==0) {
109                         gets_s(bufline, 255);
110                         sscanf(bufline, "%s", output_file);
111                 }
112 
113 		printf("to the format number: ");
114 		*bufline = '\0';
115                 while (strlen(bufline)==0) {
116                         gets_s(bufline, 255);
117                         sscanf(bufline, "%d", &to);
118                 }
119 
120 
121 		/* Check for possible errors */
122 		icontinue = 0;
123 
124         	if (stat(input_file, &stbuf) == -1) {
125 			fprintf(stderr, "cannot access \"%s\"\n", input_file);
126 			icontinue = 1;
127 		}
128 		else if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
129                      	 	fprintf(stderr, "\"%s\" is a directory\n",
130 						input_file);
131 				icontinue = 1;
132 		     }
133 
134 		mode = stbuf.st_mode;
135 
136 		if (from < 0  || from > FORMATS) {
137 			fprintf(stderr, "the format number (%d) of input file is out of range [0 - %d]\n", FORMATS, from);
138 			icontinue = 1;
139 		}
140 
141 		if (to < 0  || to > FORMATS) {
142                         fprintf(stderr, "the format number (%d) of output file is out of range [0 - %d]\n", FORMATS, to);
143                         icontinue = 1;
144                 }
145 
146 		if (stat(output_file, &stbuf) != -1)  {
147 			if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
148 				fprintf(stderr, "\"%s\" is a directory\n",
149 						output_file);
150 
151 				icontinue = 1;
152 			}
153 			else {
154 				fprintf(stderr, "\"%s\" already exists. Overwrite it (y/n)? ", output_file);
155 				gets_s(buf, BUFSIZ);
156 				if (toupper(buf[0]) != 'Y')
157 					icontinue = 1;
158 			}
159 		}
160 
161 		if (from == to)  {   /* no need to convert */
162 			fprintf(stderr, "Use \"cp\" to copy files of same formats\n");
163 			icontinue = 1;
164 		}
165 
166 
167 		/* And procesing the files as follows:
168 
169 			for formats 0 - 9, just find the corresponding
170 			chars in the table and done. (9 should be only
171 			destination, not source).
172 
173 			If one of the formats is 10 (VIQR), then we must go
174 			thru format 0 (VISCII).
175 			Should be improved here  */
176 
177 		if (icontinue)
178 			continue;
179 		else {
180 			if ((fd_in = open(input_file, 0)) == -1) {
181 				fprintf(stderr, "cannot open \"%s\"\n",
182 					input_file);
183 				continue;
184 			}
185 
186 			if ((fd_out = creat(output_file, mode))==-1) {
187 				fprintf(stderr, " cannot create \"%s\"\n",
188 					output_file);
189 				continue;
190 			}
191 		}
192 
193 		if (from == PLAIN_format)    /* nonsense */
194 			to = from;
195 
196 
197 		if (from != VIQR_format) {
198 			if (to != VIQR_format) {
199 				while ((n = read(fd_in, buf, BUFSIZ)) > 0)  {
200                 			for (k=0; k<n; ++k)  {
201                        		 		*(buf+k) =
202 						    convert_char(*(buf+k),
203 								 from, to);
204                 			}
205                 			write(fd_out, buf, n);
206         			}
207 			}
208 			else   { /* convert to VISCII and then to VIQR */
209 				while ((n = read(fd_in, buf, BUFSIZ-1)) > 0) {
210 					buf[n] = '\0';
211 					if (from != VISCII_format)
212 						for (k=0; k<n; ++k)
213                                                     *(buf+k) =
214                                                          convert_char(*(buf+k),
215                                                           from, VISCII_format);
216 
217 					k = vk_8toqr(buf, obuf, esc, state);
218 			                write(fd_out, obuf, k);
219 				}
220 			}
221 		}
222 		else  {    /* if from VIQR, */
223 		   while ((n = read(fd_in, buf, BUFSIZ)) > 0)  {
224                 	ic = buf;
225                 	oc = obuf;
226                 	for (i = 0; i < n; i++) {
227                         	vk_step(id, *ic++, oc, (int FAR *)&count);
228                         	if (count)
229                                	 	oc += count;
230                 	}
231 			if (to == VISCII_format)
232                 		write(fd_out, obuf, oc-obuf);
233 			else {
234 				k = oc - obuf;
235 				for (i=0; i<k; i++)
236 				   *(obuf+i) = convert_char(*(obuf+i),
237 						            VISCII_format, to);
238 				write(fd_out, obuf, k);
239 			}
240 
241 		    }
242 		}
243 
244         	close (fd_in);
245         	close (fd_out);
246 
247 	}
248 
249 
250 }
251 
252