1 /*
2 Purpose: call LATEX after preprocessing of the .tex file by
3 the cjk conversion tool. The old f_name.bat script
4 is not working anymore.
5 Author : F. Popineau <Fabrice.Popineau@supelec.fr>
6 Date : <29/06/2001>
7 */
8
9 #ifndef LATEX
10 #define LATEX "latex"
11 #endif
12
13 /*
14 Copyright (C) 2001-2015 F. Popineau <Fabrice.Popineau@supelec.fr>
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program in doc/COPYING; if not, write to the Free
28 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
29 MA 02110-1301 USA
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34
35 #include <kpathsea/config.h>
36 #include <kpathsea/lib.h>
37 #include <kpathsea/getopt.h>
38
39 static const char *cjklatex_version_string = "1.0";
40
41 static const char *usage_str[] = {
42 "Usage: %s OPTIONS FILE\n",
43 "Calls `" LATEX "' on FILE after conversion by the filter\n",
44 "specified by OPTIONS.\n",
45 "--conv=bg5\tfor traditional Chinese, encoding Big 5,\n",
46 "--conv=cef\tfor Chinese Encoding Framework, encoding CEF,\n",
47 "--conv=cef5\tidem CEF, also converts Big5 characters,\n",
48 "--conv=cefs\tidem CEF, also converts SJIS characters,\n",
49 "--conv=gbk\tfor Chinese, encoding GBK,\n",
50 "--conv=sjis\tfor Japanese, SJIS encoding.",
51 "\nAlternatively, for compatibility with the previous DOS batch files,\n",
52 "you can also copy this program to any of the following names:\n",
53 "bg5" LATEX ".exe, cef5" LATEX ".exe, cef" LATEX ".exe, cefs" LATEX ".exe,\n",
54 "gbk" LATEX ".exe and sjis" LATEX ".exe .\n",
55 "Then running one of these programs will be identical to specify\n",
56 "the corresponding option.\n",
57 "\nAdditional options:\n",
58 "--verbose\tbe a bit more verbose about what is happening,\n",
59 "--nocleanup\tdo not remove intermediate files,\n",
60 "--latex=engine\tuse `engine' instead of `" LATEX "' to process the file.\n",
61 NULL
62 };
63
64 static char *progname = NULL;
65
66 static struct _conv_table {
67 const char *progname;
68 const char *processor;
69 } CJKtable[] = {
70 { "cjk" LATEX, "" },
71 { "bg5" LATEX, "bg5conv" },
72 { "cef" LATEX, "cefconv" },
73 { "cef5" LATEX, "cef5conv" },
74 { "cefs" LATEX, "cefsconv" },
75 { "gbk" LATEX, "extconv" },
76 { "sjis" LATEX, "sjisconv" }
77 };
78
79 #define PROGRAM_IS(p) FILESTRCASEEQ (p, progname)
80 #define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
81
82 static int program_number = -1;
83 static int opt_verbose = 0;
84 static int opt_nocleanup = 0;
85 static char *texname, *cjkname, *texengine;
86
87 static struct option long_options [] = {
88 { "debug", 1, 0, 0},
89 { "help", 0, 0, 0},
90 { "version", 0, 0, 0},
91 { "verbose", 0, 0, 0},
92 { "nocleanup", 0, 0, 0},
93 { "latex", 1, 0, 0},
94 { "conv", 1, 0, 0},
95 {0, 0, 0, 0}
96 };
97
sigint_handler(DWORD dwCtrlType)98 static BOOL sigint_handler(DWORD dwCtrlType)
99 {
100 /* Fix me : there is a problem if a system() command is running.
101 We should wait for the son process to be interrupted.
102 Only way I can think of to do that : rewrite system() based on
103 spawn() with parsing of the command line and set a global pid
104 Next cwait(pid) in the HandlerRoutine.
105 */
106
107 /* This is not that good, but else we would need to wait for
108 the child processes to finish ! */
109 Sleep(250);
110
111 fprintf(stderr, "Sending Ctrl+Break!\n");
112 GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
113
114 if (! opt_nocleanup)
115 unlink(cjkname);
116
117 exit(1);
118
119 return FALSE; /* return value obligatory */
120 }
121
usage(void)122 static void usage(void)
123 {
124 int i;
125 fprintf(stderr, "CJK" LATEX " version %s\n", cjklatex_version_string);
126 fprintf(stderr,usage_str[0], progname );
127 fputs("\n", stderr);
128 for(i = 1; usage_str[i]; ++i)
129 fputs(usage_str[i], stderr);
130 }
131
do_process(const char * processor,const char * filename)132 static int do_process(const char *processor, const char *filename)
133 {
134 char *ext, *p;
135 char cmd[_MAX_PATH*3];
136 DWORD dwFA;
137 int ret;
138
139 if (strlen(filename) > 4 && _strnicmp(filename + strlen(filename) - 4, ".tex", 4) == 0) {
140 texname = xstrdup(filename);
141 }
142 else {
143 texname = concat(filename, ".tex");
144 }
145 for (p = texname; p && *p; p++)
146 *p = (*p == '\\' ? '/' : *p);
147
148 dwFA = GetFileAttributes(texname);
149 if (dwFA == 0xFFFFFFFF || (dwFA & FILE_ATTRIBUTE_DIRECTORY)) {
150 fprintf(stderr, "%s: %s is an invalid input file.\n",
151 progname, texname);
152 ret = 1;
153 }
154 else {
155 cjkname = xstrdup(texname);
156 ext = strrchr(cjkname, '.');
157 assert(ext != NULL);
158 strcpy(cjkname + (ext - cjkname), ".cjk");
159
160 sprintf(cmd, "%s < %s > %s", processor, texname, cjkname);
161 if (opt_verbose)
162 fprintf(stderr, "%s: running command `%s'.\n", progname, cmd);
163 ret = system(cmd);
164 if (ret == 0) {
165 sprintf(cmd, "%s %s", texengine, cjkname);
166 if (opt_verbose)
167 fprintf(stderr, "%s: running command `%s'.\n", progname, cmd);
168 ret = system(cmd);
169 if (! opt_nocleanup)
170 unlink(cjkname);
171 }
172 }
173
174 free(texname);
175 free(cjkname);
176
177 return ret;
178 }
179
main(int argc,char * argv[])180 int main(int argc, char *argv[])
181 {
182 int g; /* getopt return code */
183 int i;
184 int option_index;
185 char *filename;
186
187 if (!progname)
188 progname = argv[0];
189
190 kpse_set_program_name (progname, NULL);
191 progname = kpse_program_name;
192
193 for (i = 0; i < sizeof(CJKtable)/sizeof(CJKtable[0]) && program_number < 0; i++) {
194 if (STREQ(progname, CJKtable[i].progname)
195 #if 0
196 || (STREQ(progname, CJKtable[i].progname)
197 && STREQ(progname+strlen(CJKtable[i].progname), ".exe"))
198 #endif
199 ) {
200 program_number = i;
201 }
202 }
203
204 if (program_number == -1) {
205 fprintf(stderr, "%s: this program has been incorrecty copied to the name %s.\n", progname, progname);
206 usage();
207 exit(1);
208 }
209
210 for(;;) {
211 g = getopt_long_only (argc, argv, "", long_options, &option_index);
212
213 if (g == EOF)
214 break;
215
216 if (g == '?') {
217 usage(); /* Unknown option. */
218 exit(1);
219 }
220
221 /* assert (g == 0); */ /* We have no short option names. */
222 /*
223 FIXME : try 'mktexpk --mfmode --bdpi 600 ...'
224 */
225 if (ARGUMENT_IS ("debug")) {
226 kpathsea_debug |= atoi (optarg);
227 }
228 else if (ARGUMENT_IS ("help")) {
229 usage();
230 exit(0);
231 }
232 else if (ARGUMENT_IS ("verbose")) {
233 opt_verbose = 1;
234 }
235 else if (ARGUMENT_IS ("nocleanup")) {
236 opt_nocleanup = 1;
237 }
238 else if (ARGUMENT_IS ("latex")) {
239 texengine = xstrdup(optarg);
240 }
241 else if (ARGUMENT_IS ("version")) {
242 fprintf(stderr, "%s of %s.\n", progname, cjklatex_version_string);
243 exit(0);
244 }
245 else if (PROGRAM_IS("cjk" LATEX)) {
246 if (ARGUMENT_IS("conv")) {
247 for (i = 1; i < sizeof(CJKtable)/sizeof(CJKtable[0]) && program_number <= 0; i++) {
248 if (STRNEQ(optarg, CJKtable[i].progname, strlen(optarg))) {
249 program_number = i;
250 }
251 }
252 }
253 }
254 }
255
256 /* shifting options from argv[] list */
257 for (i = 1; optind < argc; i++, optind++)
258 argv[i] = argv[optind];
259 argv[i] = NULL;
260
261 argc = i;
262
263 if (argc < 2) {
264 fprintf (stderr, "%s: Missing argument(s).\nTry `%s --help' for more information.\n", progname, kpse_program_name);
265 exit(1);
266 }
267
268 if (argc > 2) {
269 fprintf(stderr, "%s: Extra arguments", progname);
270 for (i = 2; i < argc; i++)
271 fprintf (stderr, " \"%s\"", argv[i]);
272 fprintf (stderr, "\nTry `%s --help' for more information.\n",
273 kpse_program_name);
274 exit(1);
275 }
276
277 SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigint_handler, TRUE);
278
279 filename = xstrdup(argv[1]);
280
281 assert(program_number > 0);
282
283 if (! texengine) {
284 texengine = xstrdup(LATEX);
285 }
286
287 do_process(CJKtable[program_number].processor, filename);
288
289 free(filename);
290 free(texengine);
291
292 return 0;
293 }
294