source: src/router/php7/ext/gd/libgd/gdkanji.c @ 31879

Last change on this file since 31879 was 31879, checked in by brainslayer, 6 weeks ago

update php

File size: 12.2 KB
Line 
1
2/* gdkanji.c (Kanji code converter)                            */
3/*                 written by Masahito Yamaga (ma@yama-ga.com) */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include "gd.h"
9#include "gdhelpers.h"
10
11#include <stdarg.h>
12
13/* force usage of internal conversation routine */
14#undef HAVE_ICONV_H
15#undef HAVE_ICONV
16
17#if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)
18#include <iconv.h>
19#ifdef HAVE_ERRNO_H
20#include <errno.h>
21#endif
22#endif
23
24#if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV)
25#define HAVE_ICONV 1
26#endif
27
28#define LIBNAME "any2eucjp()"
29
30#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS)
31#ifndef SJISPRE
32#define SJISPRE 1
33#endif
34#endif
35
36#ifdef TRUE
37#undef TRUE
38#endif
39#ifdef FALSE
40#undef FALSE
41#endif
42
43#define TRUE  1
44#define FALSE 0
45
46#define NEW 1
47#define OLD 2
48#define ESCI 3
49#define NEC 4
50#define EUC 5
51#define SJIS 6
52#define EUCORSJIS 7
53#define ASCII 8
54
55#define NEWJISSTR "JIS7"
56#define OLDJISSTR "jis"
57#define EUCSTR    "eucJP"
58#define SJISSTR   "SJIS"
59
60#define ESC 27
61#define SS2 142
62
63static void
64debug (const char *format,...)
65{
66#ifdef DEBUG
67  va_list args;
68
69  va_start (args, format);
70  fprintf (stdout, "%s: ", LIBNAME);
71  vfprintf (stdout, format, args);
72  fprintf (stdout, "\n");
73  va_end (args);
74#endif
75}
76
77static void
78error (const char *format,...)
79{
80        va_list args;
81        char *tmp;
82
83        va_start(args, format);
84        vspprintf(&tmp, 0, format, args);
85        va_end(args);
86        php_error_docref(NULL, E_WARNING, "%s: %s", LIBNAME, tmp);
87        efree(tmp);
88}
89
90/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */
91
92static int
93DetectKanjiCode (unsigned char *str)
94{
95  static int whatcode = ASCII;
96  int oldcode = ASCII;
97  int c, i;
98  char *lang = NULL;
99
100  c = '\1';
101  i = 0;
102
103  if (whatcode != EUCORSJIS && whatcode != ASCII)
104    {
105      oldcode = whatcode;
106      whatcode = ASCII;
107    }
108
109  while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
110    {
111      if ((c = str[i++]) != '\0')
112        {
113          if (c == ESC)
114            {
115              c = str[i++];
116              if (c == '$')
117                {
118                  c = str[i++];
119                  if (c == 'B')
120                    whatcode = NEW;
121                  else if (c == '@')
122                    whatcode = OLD;
123                }
124              else if (c == '(')
125                {
126                  c = str[i++];
127                  if (c == 'I')
128                    whatcode = ESCI;
129                }
130              else if (c == 'K')
131                whatcode = NEC;
132            }
133          else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
134            whatcode = SJIS;
135          else if (c == SS2)
136            {
137              c = str[i++];
138              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
139                whatcode = SJIS;
140              else if (c >= 161 && c <= 223)
141                whatcode = EUCORSJIS;
142            }
143          else if (c >= 161 && c <= 223)
144            {
145              c = str[i++];
146              if (c >= 240 && c <= 254)
147                whatcode = EUC;
148              else if (c >= 161 && c <= 223)
149                whatcode = EUCORSJIS;
150              else if (c >= 224 && c <= 239)
151                {
152                  whatcode = EUCORSJIS;
153                  while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
154                    {
155                      if (c >= 129)
156                        {
157                          if (c <= 141 || (c >= 143 && c <= 159))
158                            whatcode = SJIS;
159                          else if (c >= 253 && c <= 254)
160                            whatcode = EUC;
161                        }
162                      c = str[i++];
163                    }
164                }
165              else if (c <= 159)
166                whatcode = SJIS;
167            }
168          else if (c >= 240 && c <= 254)
169            whatcode = EUC;
170          else if (c >= 224 && c <= 239)
171            {
172              c = str[i++];
173              if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
174                whatcode = SJIS;
175              else if (c >= 253 && c <= 254)
176                whatcode = EUC;
177              else if (c >= 161 && c <= 252)
178                whatcode = EUCORSJIS;
179            }
180        }
181    }
182
183#ifdef DEBUG
184  if (whatcode == ASCII)
185    debug ("Kanji code not included.");
186  else if (whatcode == EUCORSJIS)
187    debug ("Kanji code not detected.");
188  else
189    debug ("Kanji code detected at %d byte.", i);
190#endif
191
192  if (whatcode == EUCORSJIS && oldcode != ASCII)
193    whatcode = oldcode;
194
195  if (whatcode == EUCORSJIS)
196    {
197      if (getenv ("LC_ALL"))
198        lang = getenv ("LC_ALL");
199      else if (getenv ("LC_CTYPE"))
200        lang = getenv ("LC_CTYPE");
201      else if (getenv ("LANG"))
202        lang = getenv ("LANG");
203
204      if (lang)
205        {
206          if (strcmp (lang, "ja_JP.SJIS") == 0 ||
207#ifdef hpux
208              strcmp (lang, "japanese") == 0 ||
209#endif
210              strcmp (lang, "ja_JP.mscode") == 0 ||
211              strcmp (lang, "ja_JP.PCK") == 0)
212            whatcode = SJIS;
213          else if (strncmp (lang, "ja", 2) == 0)
214#ifdef SJISPRE
215            whatcode = SJIS;
216#else
217            whatcode = EUC;
218#endif
219        }
220    }
221
222  if (whatcode == EUCORSJIS)
223#ifdef SJISPRE
224    whatcode = SJIS;
225#else
226    whatcode = EUC;
227#endif
228
229  return whatcode;
230}
231
232/* SJIStoJIS() is sjis2jis() by Ken Lunde. */
233
234static void
235SJIStoJIS (int *p1, int *p2)
236{
237  register unsigned char c1 = *p1;
238  register unsigned char c2 = *p2;
239  register int adjust = c2 < 159;
240  register int rowOffset = c1 < 160 ? 112 : 176;
241  register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
242
243  *p1 = ((c1 - rowOffset) << 1) - adjust;
244  *p2 -= cellOffset;
245}
246
247/* han2zen() was derived from han2zen() written by Ken Lunde. */
248
249#define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
250#define IS_HANDAKU(c) (c >= 202 && c <= 206)
251
252static void
253han2zen (int *p1, int *p2)
254{
255  int c = *p1;
256  int daku = FALSE;
257  int handaku = FALSE;
258  int mtable[][2] =
259  {
260    {129, 66},
261    {129, 117},
262    {129, 118},
263    {129, 65},
264    {129, 69},
265    {131, 146},
266    {131, 64},
267    {131, 66},
268    {131, 68},
269    {131, 70},
270    {131, 72},
271    {131, 131},
272    {131, 133},
273    {131, 135},
274    {131, 98},
275    {129, 91},
276    {131, 65},
277    {131, 67},
278    {131, 69},
279    {131, 71},
280    {131, 73},
281    {131, 74},
282    {131, 76},
283    {131, 78},
284    {131, 80},
285    {131, 82},
286    {131, 84},
287    {131, 86},
288    {131, 88},
289    {131, 90},
290    {131, 92},
291    {131, 94},
292    {131, 96},
293    {131, 99},
294    {131, 101},
295    {131, 103},
296    {131, 105},
297    {131, 106},
298    {131, 107},
299    {131, 108},
300    {131, 109},
301    {131, 110},
302    {131, 113},
303    {131, 116},
304    {131, 119},
305    {131, 122},
306    {131, 125},
307    {131, 126},
308    {131, 128},
309    {131, 129},
310    {131, 130},
311    {131, 132},
312    {131, 134},
313    {131, 136},
314    {131, 137},
315    {131, 138},
316    {131, 139},
317    {131, 140},
318    {131, 141},
319    {131, 143},
320    {131, 147},
321    {129, 74},
322    {129, 75}
323  };
324
325  if (*p2 == 222 && IS_DAKU (*p1))
326    daku = TRUE;                /* Daku-ten */
327  else if (*p2 == 223 && IS_HANDAKU (*p1))
328    handaku = TRUE;             /* Han-daku-ten */
329
330  *p1 = mtable[c - 161][0];
331  *p2 = mtable[c - 161][1];
332
333  if (daku)
334    {
335      if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
336        (*p2)++;
337      else if (*p2 == 131 || *p2 == 69)
338        *p2 = 148;
339    }
340  else if (handaku && *p2 >= 110 && *p2 <= 122)
341    (*p2) += 2;
342}
343
344/* Recast strcpy to handle unsigned chars used below. */
345#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))
346
347static void
348do_convert (unsigned char *to, unsigned char *from, const char *code)
349{
350#ifdef HAVE_ICONV
351  iconv_t cd;
352  size_t from_len, to_len;
353
354  if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
355    {
356      error ("iconv_open() error");
357#ifdef HAVE_ERRNO_H
358      if (errno == EINVAL)
359        error ("invalid code specification: \"%s\" or \"%s\"",
360               EUCSTR, code);
361#endif
362      strcpy ((char *) to, (const char *) from);
363      return;
364    }
365
366  from_len = strlen ((const char *) from) + 1;
367  to_len = BUFSIZ;
368
369  if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1)
370    {
371#ifdef HAVE_ERRNO_H
372      if (errno == EINVAL)
373        error ("invalid end of input string");
374      else if (errno == EILSEQ)
375        error ("invalid code in input string");
376      else if (errno == E2BIG)
377        error ("output buffer overflow at do_convert()");
378      else
379#endif
380        error ("something happen");
381      strcpy ((char *) to, (const char *) from);
382      return;
383    }
384
385  if (iconv_close (cd) != 0)
386    {
387      error ("iconv_close() error");
388    }
389#else
390  int p1, p2, i, j;
391  int jisx0208 = FALSE;
392  int hankaku = FALSE;
393
394  j = 0;
395  if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
396    {
397      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
398        {
399          if (from[i] == ESC)
400            {
401              i++;
402              if (from[i] == '$')
403                {
404                  jisx0208 = TRUE;
405                  hankaku = FALSE;
406                  i++;
407                }
408              else if (from[i] == '(')
409                {
410                  jisx0208 = FALSE;
411                  i++;
412                  if (from[i] == 'I')   /* Hankaku Kana */
413                    hankaku = TRUE;
414                  else
415                    hankaku = FALSE;
416                }
417            }
418          else
419            {
420              if (jisx0208)
421                to[j++] = from[i] + 128;
422              else if (hankaku)
423                {
424                  to[j++] = SS2;
425                  to[j++] = from[i] + 128;
426                }
427              else
428                to[j++] = from[i];
429            }
430        }
431    }
432  else if (strcmp (code, SJISSTR) == 0)
433    {
434      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
435        {
436          p1 = from[i];
437          if (p1 < 127)
438            to[j++] = p1;
439          else if ((p1 >= 161) && (p1 <= 223))
440            {                   /* Hankaku Kana */
441              to[j++] = SS2;
442              to[j++] = p1;
443            }
444          else
445            {
446              p2 = from[++i];
447              SJIStoJIS (&p1, &p2);
448              to[j++] = p1 + 128;
449              to[j++] = p2 + 128;
450            }
451        }
452    }
453  else
454    {
455      error ("invalid code specification: \"%s\"", code);
456      return;
457    }
458
459  if (j >= BUFSIZ)
460    {
461      error ("output buffer overflow at do_convert()");
462      ustrcpy (to, from);
463    }
464  else
465    to[j] = '\0';
466#endif /* HAVE_ICONV */
467}
468
469static int
470do_check_and_conv (unsigned char *to, unsigned char *from)
471{
472  static unsigned char tmp[BUFSIZ];
473  int p1, p2, i, j;
474  int kanji = TRUE;
475
476  switch (DetectKanjiCode (from))
477    {
478    case NEW:
479      debug ("Kanji code is New JIS.");
480      do_convert (tmp, from, NEWJISSTR);
481      break;
482    case OLD:
483      debug ("Kanji code is Old JIS.");
484      do_convert (tmp, from, OLDJISSTR);
485      break;
486    case ESCI:
487      debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
488      do_convert (tmp, from, NEWJISSTR);
489      break;
490    case NEC:
491      debug ("Kanji code is NEC Kanji.");
492      error ("cannot convert NEC Kanji.");
493      ustrcpy (tmp, from);
494      kanji = FALSE;
495      break;
496    case EUC:
497      debug ("Kanji code is EUC.");
498      ustrcpy (tmp, from);
499      break;
500    case SJIS:
501      debug ("Kanji code is SJIS.");
502      do_convert (tmp, from, SJISSTR);
503      break;
504    case EUCORSJIS:
505      debug ("Kanji code is EUC or SJIS.");
506      ustrcpy (tmp, from);
507      kanji = FALSE;
508      break;
509    case ASCII:
510      debug ("This is ASCII string.");
511      ustrcpy (tmp, from);
512      kanji = FALSE;
513      break;
514    default:
515      debug ("This string includes unknown code.");
516      ustrcpy (tmp, from);
517      kanji = FALSE;
518      break;
519    }
520
521  /* Hankaku Kana ---> Zenkaku Kana */
522  if (kanji)
523    {
524      j = 0;
525      for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
526        {
527          if (tmp[i] == SS2)
528            {
529              p1 = tmp[++i];
530              if (tmp[i + 1] == SS2)
531                {
532                  p2 = tmp[i + 2];
533                  if (p2 == 222 || p2 == 223)
534                    i += 2;
535                  else
536                    p2 = 0;
537                }
538              else
539                p2 = 0;
540              han2zen (&p1, &p2);
541              SJIStoJIS (&p1, &p2);
542              to[j++] = p1 + 128;
543              to[j++] = p2 + 128;
544            }
545          else
546            to[j++] = tmp[i];
547        }
548
549      if (j >= BUFSIZ)
550        {
551          error ("output buffer overflow at Hankaku --> Zenkaku");
552          ustrcpy (to, tmp);
553        }
554      else
555        to[j] = '\0';
556    }
557  else
558    ustrcpy (to, tmp);
559
560  return kanji;
561}
562
563int
564any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)
565{
566  static unsigned char tmp_dest[BUFSIZ];
567  int ret;
568
569  if (strlen ((const char *) src) >= BUFSIZ)
570    {
571      error ("input string too large");
572      return -1;
573    }
574  if (dest_max > BUFSIZ)
575    {
576      error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
577      return -1;
578    }
579  ret = do_check_and_conv (tmp_dest, src);
580  if (strlen ((const char *) tmp_dest) >= dest_max)
581    {
582      error ("output buffer overflow");
583      ustrcpy (dest, src);
584      return -1;
585    }
586  ustrcpy (dest, tmp_dest);
587  return ret;
588}
589
590#if 0
591unsigned int
592strwidth (unsigned char *s)
593{
594  unsigned char *t;
595  unsigned int i;
596
597  t = (unsigned char *) gdMalloc (BUFSIZ);
598  any2eucjp (t, s, BUFSIZ);
599  i = strlen (t);
600  gdFree (t);
601  return i;
602}
603
604#ifdef DEBUG
605int
606main ()
607{
608  unsigned char input[BUFSIZ];
609  unsigned char *output;
610  unsigned char *str;
611  int c, i = 0;
612
613  while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
614    input[i++] = c;
615  input[i] = '\0';
616
617  printf ("input : %d bytes\n", strlen ((const char *) input));
618  printf ("output: %d bytes\n", strwidth (input));
619
620  output = (unsigned char *) gdMalloc (BUFSIZ);
621  any2eucjp (output, input, BUFSIZ);
622  str = output;
623  while (*str != '\0')
624    putchar (*(str++));
625  putchar ('\n');
626  gdFree (output);
627
628  return 0;
629}
630#endif
631#endif
Note: See TracBrowser for help on using the repository browser.