comparison lib-src/mule/mulelib.c @ 70:131b0175ea99 r20-0b30

Import from CVS: tag r20-0b30
author cvs
date Mon, 13 Aug 2007 09:02:59 +0200
parents
children
comparison
equal deleted inserted replaced
69:804d1389bcd6 70:131b0175ea99
1 #include <stdio.h>
2 #include <sys/param.h>
3 #include "mulelib.h"
4
5 #ifdef STDC_HEADERS
6 #include <stdlib.h>
7 #endif
8
9 #ifdef USG
10 #include <string.h>
11 #else
12 #include <strings.h>
13 #endif
14
15 #include <ctype.h>
16
17 char *mule_library_version = "2.2";
18
19 int mule_error;
20 char mule_error_msg[256];
21
22 static int mulelib_initialized = 0;
23
24 #ifdef MSDOS
25 #define READ_TEXT "rt"
26 #else /* not MSDOS */
27 #define READ_TEXT "r"
28 #endif /* not MSDOS */
29
30 /********************
31 * General routines *
32 ********************/
33
34 #define LINE_SIZE 4096
35
36 FILE *
37 open_file(dirs, file)
38 char *dirs, *file;
39 {
40 char path[MAXPATHLEN], *tail;
41 int len;
42 FILE *fp;
43
44 if (file[0] == '/'
45 #ifdef MSDOS
46 || file[0] && file[1] == ':'
47 #endif
48 )
49 return fopen(file, READ_TEXT);
50
51 while (*dirs) {
52 (tail = index(dirs, ','))
53 #ifdef MSDOS
54 || (tail = index(dirs, ';'))
55 #else
56 || (tail = index(dirs, ':'))
57 #endif
58 || (tail = index(dirs, '\0'));
59
60 len = tail - dirs;
61 strncpy(path, dirs, len);
62 while (path[--len] == '/'); /* back to non-slash */
63 path[++len] = '/';
64 strcpy(&path[++len], file);
65
66 fp = fopen (path, READ_TEXT);
67 if (fp || *tail == '\0') return fp;
68
69 dirs = tail + 1;
70 }
71 }
72
73 get_line(buf, size, fp)
74 char *buf;
75 int size;
76 FILE *fp;
77 {
78 int len;
79
80 if (fgets(buf, size, fp) != NULL) {
81 len = strlen(buf);
82 if (buf[len - 1] == '\n')
83 buf[--len] = '\0';
84 return len;
85 } else
86 return -1;
87 }
88
89 #define PROCEED_CHAR(c) \
90 if (!(p1 = (char *)index(p0, c))) goto invalid_entry
91
92 warning1(format, arg1)
93 char *format;
94 int arg1;
95 {
96 fprintf(stderr, format, arg1);
97 }
98
99 warning2(format, arg1, arg2)
100 char *format;
101 int arg1, arg2;
102 {
103 fprintf(stderr, format, arg1, arg2);
104 }
105
106 warning3(format, arg1, arg2, arg3)
107 char *format;
108 int arg1, arg2, arg3;
109 {
110 fprintf(stderr, format, arg1, arg2, arg3);
111 }
112
113 fatal1(arg)
114 char *arg;
115 {
116 fprintf(stderr, "%s", arg);
117 exit(1);
118 }
119
120 /*****************************
121 * Reading CHARSETS database *
122 *****************************/
123
124 /* extra information table */
125 char *font_name[128];
126 int font_encoding[128];
127
128 set_charsets_param(line)
129 char *line;
130 {
131 char *p0 = line, *p1;
132 int len;
133 unsigned char lc, bytes, clm, type, graphic, final, direction;
134 char *doc;
135
136 lc = atoi(p0);
137
138 PROCEED_CHAR(':');
139 p0 = p1 + 1;
140 bytes = atoi(p0);
141
142 PROCEED_CHAR(':');
143 p0 = p1 + 1;
144 clm = atoi(p0);
145
146 PROCEED_CHAR(':');
147 p0 = p1 + 1;
148 type = atoi(p0);
149
150 PROCEED_CHAR(':');
151 p0 = p1 + 1;
152 graphic = atoi(p0);
153
154 PROCEED_CHAR(':');
155 p0 = p1 + 1;
156 final = atoi(p0);
157
158 PROCEED_CHAR(':');
159 p0 = p1 + 1;
160 direction = atoi(p0);
161
162 PROCEED_CHAR(':');
163 p0 = p1 + 1;
164 (p1 = index(p0, ':')) || (p1 = index(p0, '\0'));
165 len = p1 - p0;
166 doc = (char *)malloc(len + 1);
167 bcopy(p0, doc, len);
168 doc[len] = '\0';
169
170 update_mc_table(lc, bytes, clm, type, graphic, final, direction, doc);
171
172 if (*p1) {
173 p0 = p1 + 1;
174 (p1 = index(p0, ':')) || (p1 = index(p0, '\0'));
175 len = p1 - p0;
176 font_name[lc & 0x7F] = (char *)malloc(len + 1);
177 bcopy(p0, font_name[lc & 0x7F], len);
178 font_name[lc & 0x7F][len] = '\0';
179
180 font_encoding[lc & 0x7F] = *p1 ? atoi(p1) : 0;
181 }
182
183 return 0;
184
185 invalid_entry:
186 mule_error = MULE_ERROR_INVALID_CHARSETS;
187 sprintf(mule_error_msg, "Invalid line in CHARSETS file: %s", line);
188 return -1;
189 }
190
191 set_ccl_program_param(line)
192 char *line;
193 {
194 int lc, len, i, j;
195 char *p, *p1;
196 Lisp_Object ccl;
197
198 lc = atoi(line) & 0x7F;
199 p = p1 = index(line, ':') + 1;
200 if (!p) return -1;
201 len = 0;
202 while (*p1) if (*p1++ == ' ') len++;
203 ccl = make_vector(len);
204 for (i = 0; i < len; i++) {
205 sscanf(p, "%x", XVECTOR (ccl)->contents + i);
206 p = index(p + 1, ' ');
207 }
208 x_ccl_programs[lc] = (CCL_PROGRAM *)malloc(sizeof (CCL_PROGRAM));
209 set_ccl_program(x_ccl_programs[lc], ccl);
210 return 0;
211 }
212
213 charsets_initialize(charsets)
214 char *charsets;
215 {
216 FILE *fp;
217 char line[LINE_SIZE];
218 int i, status;
219
220 if (!charsets) charsets = CHARSETS;
221 fp = open_file(PATH_DATA, charsets);
222 if (!fp) {
223 mule_error = MULE_ERROR_NO_CHARSETS;
224 sprintf(mule_error_msg, "File %s not in the path %s", charsets, PATH_DATA);
225 return -1;
226 }
227 init_charset_once();
228 for (i = 0; i < 128; i++)
229 x_ccl_programs[i] = NULL;
230
231 status = 0;
232 while (get_line(line, sizeof line, fp) >= 0) {
233 if (line[0] == '#') {
234 if (status > 0) status++;
235 continue;
236 }
237 if (status <= 1) {
238 status = 1;
239 if (set_charsets_param(line) < 0) return -1;
240 } else {
241 if (set_ccl_program_param(line) < 0) return -1;
242 }
243 }
244 return 0;
245 }
246
247 /*****************************
248 * Reading CODINGS database *
249 *****************************/
250
251 coding_type coding_system_table[CODING_SYSTEM_COUNT];
252 int n_base_coding_system = 0;
253 int n_coding_system;
254
255 set_coding_system_param(line, cs)
256 char *line;
257 coding_type *cs;
258 {
259 char *p0 = line, *p1;
260 int len, i;
261
262 PROCEED_CHAR(':');
263 len = p1 - p0;
264 cs->name = (char *)malloc(len + 1);
265 bcopy(p0, cs->name, len);
266 cs->name[len] = '\0';
267
268 p0 = p1 + 1;
269 i = atoi(p0);
270 CODE_TYPE_SET(cs, i);
271
272 PROCEED_CHAR(':');
273 p0 = p1 + 1;
274 cs->mnemonic = *p0;
275
276 PROCEED_CHAR(':');
277 p0 = p1 + 1;
278 i = atoi(p0);
279 CODE_FORM (cs)
280 = (i==0) ? CODE_EOL_AUTO : (i==1) ? CODE_EOL_LF
281 : (i==2) ? CODE_EOL_CRLF : CODE_EOL_CR;
282 CODE_LF (cs) = CODE_CRLF (cs) = CODE_CR (cs) = Qnil;
283
284 PROCEED_CHAR(':');
285 p0 = p1 + 1;
286 if (CODE_TYPE (cs) == ISO2022) {
287 int flags[12];
288 for (i = 0; i < 11; i++) {
289 if (!(flags[i] = atoi(p0))) flags[i] = Qnil;
290 PROCEED_CHAR(',');
291 p0 = p1 + 1;
292 }
293 flags[i] = atoi(p0);
294 CODE_LC_SET(cs, flags[0], flags[1], flags[2], flags[3]);
295 CODE_FORM_SET(cs, (Lisp_Object)flags[4], (Lisp_Object)flags[5],
296 (Lisp_Object)flags[6], (Lisp_Object)flags[7],
297 (Lisp_Object)flags[8], (Lisp_Object)flags[9],
298 (Lisp_Object)flags[10], (Lisp_Object)flags[11]);
299 } else if (CODE_TYPE (cs) == BIG5) {
300 CODE_FORM_SET(cs, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil);
301 } else if (CODE_TYPE (cs) == CCL) {
302 int len;
303 char *start = p0, c;
304 Lisp_Object ccl;
305
306 len = 0;
307 while ((c = *p0++) != ',') if (c == ' ') len++;
308 ccl = make_vector (len);
309 for (i = 0; i < len; i++) {
310 sscanf(start, "%x", XVECTOR (ccl)->contents + i);
311 start = index (start + 1, ' ');
312 }
313 set_ccl_program (&CODE_CCL_ENCODE (cs), ccl);
314
315 start = p0;
316 len = 0;
317 while ((c = *p0++) != ':') if (c == ' ') len++;
318 ccl = make_vector (len);
319 for (i = 0; i < len; i++) {
320 sscanf(start, "%x", XVECTOR (ccl)->contents + i);
321 start = index (start + 1, ' ');
322 }
323 set_ccl_program (&CODE_CCL_DECODE (cs), ccl);
324 p0 -= 2;
325 }
326
327 PROCEED_CHAR(':');
328 p0 = p1 + 1;
329 len = strlen(p0);
330 cs->doc = (char *)malloc(len + 1);
331 bcopy(p0, cs->doc, len + 1);
332 return 0;
333
334 invalid_entry:
335 mule_error = MULE_ERROR_INVALID_CODING;
336 sprintf(mule_error_msg, "Invalid line in CODINGS file: %s", line);
337 return -1;
338 }
339
340 char *coding_category_names[IDX_BIN + 1] = {
341 "*coding-category-internal*",
342 "*coding-category-sjis*",
343 "*coding-category-iso-7*",
344 "*coding-category-iso-8-1*",
345 "*coding-category-iso-8-2*",
346 "*coding-category-iso-else*",
347 "*coding-category-big5*",
348 "*coding-category-bin*"};
349
350 set_coding_category(line, priority)
351 char *line;
352 int priority;
353 {
354 char *p0 = line, *p1;
355 int i, len;
356
357 PROCEED_CHAR(':');
358 len = p1 - p0;
359 for (i = 0; i <= IDX_BIN; i++) {
360 if (!strncmp(p0, XSYMBOL (code_category[i])->name, len))
361 break;
362 }
363 if (i <= IDX_BIN) {
364 code_priority_category[priority] = i;
365 p0 = p1 + 1;
366 XSYMBOL (code_category[i])->value = make_symbol(p0);
367 return 0;
368 }
369
370 invalid_entry:
371 mule_error = MULE_ERROR_INVALID_CODING;
372 sprintf(mule_error_msg, "Invalid line in CODINGS file: %s", line);
373 return -1;
374 }
375
376 codings_initialize(codings)
377 char *codings;
378 {
379 FILE *fp;
380 char line[LINE_SIZE];
381 char *coding_category_header = "## LIST OF CODING CATEGORIES";
382 coding_type *cs;
383 int i;
384
385 if (!codings) codings = CODINGS;
386 fp = open_file(PATH_DATA, codings);
387 if (!fp) {
388 mule_error = MULE_ERROR_NO_CODING;
389 sprintf(mule_error_msg, "File %s not in the path %s!", codings, PATH_DATA);
390 return -1;
391 }
392 n_coding_system = 0;
393 while (get_line(line, sizeof line, fp) >= 0
394 && strncmp(line, coding_category_header,
395 strlen(coding_category_header))) {
396 if (line[0] != '#') {
397 if (set_coding_system_param(line, coding_system_table + n_coding_system)
398 < 0)
399 return -1;
400 n_coding_system++;
401 }
402 }
403
404 n_base_coding_system = n_coding_system;
405
406 for (i = 0; i < n_base_coding_system; i++) {
407 if (CODE_TYPE (&coding_system_table[i]) != CCL) {
408 sprintf(line, "%sunix", coding_system_table[i].name);
409 coding_system_table[i].eol_lf = make_symbol(line);
410 cs = &coding_system_table[n_coding_system++];
411 *cs = coding_system_table[i];
412 cs->name = XSYMBOL (coding_system_table[i].eol_lf)->name;
413 CODE_FORM (cs) |= CODE_EOL_LF;
414 CODE_LF (cs) = CODE_CRLF (cs) = CODE_CR (cs) = Qnil;
415
416 sprintf(line, "%sdos", coding_system_table[i].name);
417 coding_system_table[i].eol_crlf = make_symbol(line);
418 cs = &coding_system_table[n_coding_system++];
419 *cs = coding_system_table[i];
420 cs->name = XSYMBOL (coding_system_table[i].eol_crlf)->name;
421 CODE_FORM (cs) |= CODE_EOL_CRLF;
422 CODE_LF (cs) = CODE_CRLF (cs) = CODE_CR (cs) = Qnil;
423
424 sprintf(line, "%smac", coding_system_table[i].name);
425 coding_system_table[i].eol_cr = make_symbol(line);
426 cs = &coding_system_table[n_coding_system++];
427 *cs = coding_system_table[i];
428 cs->name = XSYMBOL (coding_system_table[i].eol_cr)->name;
429 CODE_FORM (cs) |= CODE_EOL_CR;
430 CODE_LF (cs) = CODE_CRLF (cs) = CODE_CR (cs) = Qnil;
431 }
432 }
433
434 for (i = 0; i <= IDX_BIN; i++)
435 code_category[i] = make_symbol(coding_category_names[i]);
436 i = 0;
437 while (get_line(line, sizeof line, fp) >= 0) {
438 if (line[0] && line[0] != '#') {
439 if (set_coding_category(line, i) < 0)
440 return -1;
441 i++;
442 }
443 }
444 return 0;
445 }
446
447 static
448 find_coding(str)
449 char *str;
450 {
451 int i;
452
453 if (*str == '*') {
454 for (i = 0; i < n_coding_system; i++)
455 if (!strcmp(str, coding_system_table[i].name)) return i;
456 } else {
457 unsigned int eol_type;
458 switch (str[1]) {
459 case '\0': eol_type = CODE_EOL_AUTO; break;
460 case '.': eol_type = CODE_EOL_LF; break;
461 case ':': eol_type = CODE_EOL_CRLF; break;
462 case '\'': eol_type = CODE_EOL_CR; break;
463 default: return -1;
464 }
465 for (i = 0; i < n_coding_system; i++)
466 if (coding_system_table[i].mnemonic == *str
467 && (CODE_FORM (&coding_system_table[i]) & CODE_EOL_MASK) == eol_type)
468 return i;
469 }
470 return -1;
471 }
472
473 encode_code(code, mccode)
474 Lisp_Object code;
475 coding_type *mccode;
476 {
477 int i;
478
479 if ((i = find_coding(XSYMBOL (code)->name)) >= 0)
480 *mccode = coding_system_table[i];
481 else
482 CODE_TYPE_SET (mccode, NOCONV);
483 }
484
485 set_coding_system(inname, incode, outname, outcode)
486 char *inname, *outname;
487 coding_type *incode, *outcode;
488 {
489 int i;
490
491 if (inname == NULL) inname = "*autoconv*";
492 if ((i = find_coding(inname)) < 0) {
493 mule_error = MULE_ERROR_UNKNOWN_CODE;
494 sprintf(mule_error_msg, "Unknown code: %s", inname);
495 return -1;
496 }
497 *incode = coding_system_table[i];
498
499 if (outname == NULL) outname = "*internal*";
500 if ((i = find_coding(outname)) < 0) {
501 mule_error = MULE_ERROR_UNKNOWN_CODE;
502 sprintf(mule_error_msg, "Unknown code: %s", outname);
503 return -1;
504 }
505 *outcode = coding_system_table[i];
506
507 return 0;
508 }
509
510 code_conversion(incode, inbuf, insize, outcode, outbuf, outsize)
511 coding_type *incode, *outcode;
512 char *inbuf, *outbuf;
513 int insize, outsize;
514 {
515 Lisp_Object found = Qnil;
516 char *buf1, *buf2;
517 int buf1_used = 0, buf2_used = 0, n;
518
519 if (insize > 0) {
520 if (CODE_TYPE (incode) == ITNCODE) {
521 buf1 = inbuf;
522 n = insize;
523 } else {
524 buf1 = (char *)malloc(ENCODE_BUF_SIZE(insize, incode));
525 buf1_used = 1;
526 n = encode(incode, inbuf, buf1, insize, &found);
527 if (found != Qnil)
528 incode->name = (char *)XSYMBOL (found)->name;
529 }
530 } else {
531 buf1 = inbuf;
532 n = 0;
533 CODE_CNTL(outcode) |= CC_END;
534 }
535
536 if (CODE_TYPE (outcode) == ITNCODE) {
537 buf2 = buf1;
538 } else {
539 if ((CODE_FORM (outcode) & CODE_EOL_MASK) == CODE_EOL_AUTO
540 && (CODE_FORM (incode) & CODE_EOL_MASK) != CODE_EOL_AUTO) {
541 unsigned int eol = CODE_FORM (incode) & CODE_EOL_MASK;
542
543 CODE_FORM (outcode) |= eol;
544 switch (eol) {
545 case CODE_EOL_LF:
546 outcode->name = (char *)XSYMBOL (outcode->eol_lf)->name; break;
547 case CODE_EOL_CRLF:
548 outcode->name = (char *)XSYMBOL (outcode->eol_crlf)->name; break;
549 case CODE_EOL_CR:
550 outcode->name = (char *)XSYMBOL (outcode->eol_cr)->name; break;
551 }
552 }
553 buf2 = (char *)malloc(DECODE_BUF_SIZE(n, outcode));
554 buf2_used = 1;
555 n = decode(outcode, buf1, buf2, n);
556 }
557
558 if (n <= outsize) {
559 bcopy(buf2, outbuf, n);
560 } else {
561 bcopy(buf2, outbuf, outsize);
562 mule_error = MULE_ERROR_OVERFLOW;
563 sprintf(mule_error_msg, "Output buffer overflow");
564 }
565
566 if (buf2_used) free(buf2);
567 if (buf1_used) free(buf1);
568 return (n <= outsize ? n : -1);
569 }
570
571 /****************
572 * MSDOS staffs *
573 ****************/
574
575 #ifdef MSDOS
576
577 static char emacsroot[MAXPATHLEN];
578
579 void
580 init_environment (argc, argv, skip_args)
581 int argc;
582 char **argv;
583 int skip_args;
584 {
585 char *s, *t, *root;
586 int len;
587
588 /* Find our root from argv[0]. Assuming argv[0] is, say,
589 "c:/emacs/bin/emacs.exe" our root will be "c:/emacs". */
590 len = strlen (argv[0]);
591 root = alloca (len + 10); /* A little extra space for the stuff below. */
592 strcpy (root, argv[0]);
593 while (len > 0 && root[len] != '/' && root[len] != ':')
594 len--;
595 root[len] = '\0';
596 if (len > 4 && strcmp (root + len - 4, "/bin") == 0)
597 root[len - 4] = '\0';
598 else
599 strcpy (root, "c:/emacs"); /* Only under debuggers, I think. */
600 len = strlen (root);
601 strcpy (emacsroot, root);
602 }
603
604 char *
605 rootrelativepath (rel)
606 char *rel;
607 {
608 static char result[MAXPATHLEN + 10];
609
610 strcpy (result, emacsroot);
611 strcat (result, "/");
612 strcat (result, rel);
613 return result;
614 }
615
616 #endif /* MSDOS */
617
618 /***************
619 * INITIALIZER *
620 ***************/
621
622 mulelib_initialize(argc, argv, charsets, codings)
623 int argc;
624 char **argv, *charsets, *codings;
625 {
626 if (!mulelib_initialized) {
627 int i;
628
629 #ifdef MSDOS
630 init_environment(argc, argv, 0);
631 #endif
632
633 for (i = 0; i < 128; i++) {
634 font_name[i] = NULL;
635 font_encoding[i] = 0;
636 }
637
638 if (charsets_initialize(charsets) < 0) return -1;
639 if (codings_initialize(codings) < 0) return -1;
640 mulelib_initialized = 1;
641 }
642 return 0;
643 }