⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdkanji.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
字号:
/* gdkanji.c (Kanji code converter)                            *//*                 written by Masahito Yamaga (ma@yama-ga.com) */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "gd.h"#include "gdhelpers.h"#include <stdarg.h>#if defined(HAVE_ICONV_H) || defined(HAVE_ICONV)#include <iconv.h>#ifdef HAVE_ERRNO_H#include <errno.h>#endif#endif#if defined(HAVE_ICONV_H) && !defined(HAVE_ICONV)#define HAVE_ICONV 1#endif#define LIBNAME "any2eucjp()"#if defined(__MSC__) || defined(__BORLANDC__) || defined(__TURBOC__) || defined(_Windows) || defined(MSDOS)#ifndef SJISPRE#define SJISPRE 1#endif#endif#ifdef TRUE#undef TRUE#endif#ifdef FALSE#undef FALSE#endif#define TRUE  1#define FALSE 0#define NEW 1#define OLD 2#define ESCI 3#define NEC 4#define EUC 5#define SJIS 6#define EUCORSJIS 7#define ASCII 8#define NEWJISSTR "JIS7"#define OLDJISSTR "jis"#define EUCSTR    "eucJP"#define SJISSTR   "SJIS"#define ESC 27#define SS2 142static voiddebug (const char *format,...){#ifdef DEBUG  va_list args;  va_start (args, format);  fprintf (stdout, "%s: ", LIBNAME);  vfprintf (stdout, format, args);  fprintf (stdout, "\n");  va_end (args);#endif}static voiderror (const char *format,...){	va_list args;	char *tmp;	TSRMLS_FETCH();	va_start(args, format);	vspprintf(&tmp, 0, format, args);	va_end(args);	php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", LIBNAME, tmp);	efree(tmp);}/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */static intDetectKanjiCode (unsigned char *str){  static int whatcode = ASCII;  int oldcode = ASCII;  int c, i;  char *lang = NULL;  c = '\1';  i = 0;  if (whatcode != EUCORSJIS && whatcode != ASCII)    {      oldcode = whatcode;      whatcode = ASCII;    }  while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')    {      if ((c = str[i++]) != '\0')	{	  if (c == ESC)	    {	      c = str[i++];	      if (c == '$')		{		  c = str[i++];		  if (c == 'B')		    whatcode = NEW;		  else if (c == '@')		    whatcode = OLD;		}	      else if (c == '(')		{		  c = str[i++];		  if (c == 'I')		    whatcode = ESCI;		}	      else if (c == 'K')		whatcode = NEC;	    }	  else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))	    whatcode = SJIS;	  else if (c == SS2)	    {	      c = str[i++];	      if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))		whatcode = SJIS;	      else if (c >= 161 && c <= 223)		whatcode = EUCORSJIS;	    }	  else if (c >= 161 && c <= 223)	    {	      c = str[i++];	      if (c >= 240 && c <= 254)		whatcode = EUC;	      else if (c >= 161 && c <= 223)		whatcode = EUCORSJIS;	      else if (c >= 224 && c <= 239)		{		  whatcode = EUCORSJIS;		  while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)		    {		      if (c >= 129)			{			  if (c <= 141 || (c >= 143 && c <= 159))			    whatcode = SJIS;			  else if (c >= 253 && c <= 254)			    whatcode = EUC;			}		      c = str[i++];		    }		}	      else if (c <= 159)		whatcode = SJIS;	    }	  else if (c >= 240 && c <= 254)	    whatcode = EUC;	  else if (c >= 224 && c <= 239)	    {	      c = str[i++];	      if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))		whatcode = SJIS;	      else if (c >= 253 && c <= 254)		whatcode = EUC;	      else if (c >= 161 && c <= 252)		whatcode = EUCORSJIS;	    }	}    }#ifdef DEBUG  if (whatcode == ASCII)    debug ("Kanji code not included.");  else if (whatcode == EUCORSJIS)    debug ("Kanji code not detected.");  else    debug ("Kanji code detected at %d byte.", i);#endif  if (whatcode == EUCORSJIS && oldcode != ASCII)    whatcode = oldcode;  if (whatcode == EUCORSJIS)    {      if (getenv ("LC_ALL"))	lang = getenv ("LC_ALL");      else if (getenv ("LC_CTYPE"))	lang = getenv ("LC_CTYPE");      else if (getenv ("LANG"))	lang = getenv ("LANG");      if (lang)	{	  if (strcmp (lang, "ja_JP.SJIS") == 0 ||#ifdef hpux	      strcmp (lang, "japanese") == 0 ||#endif	      strcmp (lang, "ja_JP.mscode") == 0 ||	      strcmp (lang, "ja_JP.PCK") == 0)	    whatcode = SJIS;	  else if (strncmp (lang, "ja", 2) == 0)#ifdef SJISPRE	    whatcode = SJIS;#else	    whatcode = EUC;#endif	}    }  if (whatcode == EUCORSJIS)#ifdef SJISPRE    whatcode = SJIS;#else    whatcode = EUC;#endif  return whatcode;}/* SJIStoJIS() is sjis2jis() by Ken Lunde. */static voidSJIStoJIS (int *p1, int *p2){  register unsigned char c1 = *p1;  register unsigned char c2 = *p2;  register int adjust = c2 < 159;  register int rowOffset = c1 < 160 ? 112 : 176;  register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;  *p1 = ((c1 - rowOffset) << 1) - adjust;  *p2 -= cellOffset;}/* han2zen() was derived from han2zen() written by Ken Lunde. */#define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))#define IS_HANDAKU(c) (c >= 202 && c <= 206)static voidhan2zen (int *p1, int *p2){  int c = *p1;  int daku = FALSE;  int handaku = FALSE;  int mtable[][2] =  {    {129, 66},    {129, 117},    {129, 118},    {129, 65},    {129, 69},    {131, 146},    {131, 64},    {131, 66},    {131, 68},    {131, 70},    {131, 72},    {131, 131},    {131, 133},    {131, 135},    {131, 98},    {129, 91},    {131, 65},    {131, 67},    {131, 69},    {131, 71},    {131, 73},    {131, 74},    {131, 76},    {131, 78},    {131, 80},    {131, 82},    {131, 84},    {131, 86},    {131, 88},    {131, 90},    {131, 92},    {131, 94},    {131, 96},    {131, 99},    {131, 101},    {131, 103},    {131, 105},    {131, 106},    {131, 107},    {131, 108},    {131, 109},    {131, 110},    {131, 113},    {131, 116},    {131, 119},    {131, 122},    {131, 125},    {131, 126},    {131, 128},    {131, 129},    {131, 130},    {131, 132},    {131, 134},    {131, 136},    {131, 137},    {131, 138},    {131, 139},    {131, 140},    {131, 141},    {131, 143},    {131, 147},    {129, 74},    {129, 75}  };  if (*p2 == 222 && IS_DAKU (*p1))    daku = TRUE;		/* Daku-ten */  else if (*p2 == 223 && IS_HANDAKU (*p1))    handaku = TRUE;		/* Han-daku-ten */  *p1 = mtable[c - 161][0];  *p2 = mtable[c - 161][1];  if (daku)    {      if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))	(*p2)++;      else if (*p2 == 131 && *p2 == 69)	*p2 = 148;    }  else if (handaku && *p2 >= 110 && *p2 <= 122)    (*p2) += 2;}/* Recast strcpy to handle unsigned chars used below. */#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))static voiddo_convert (unsigned char *to, unsigned char *from, const char *code){#ifdef HAVE_ICONV  iconv_t cd;  size_t from_len, to_len;  if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)    {      error ("iconv_open() error");#ifdef HAVE_ERRNO_H      if (errno == EINVAL)	error ("invalid code specification: \"%s\" or \"%s\"",	       EUCSTR, code);#endif      strcpy ((char *) to, (const char *) from);      return;    }  from_len = strlen ((const char *) from) + 1;  to_len = BUFSIZ;  if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1)    {#ifdef HAVE_ERRNO_H      if (errno == EINVAL)	error ("invalid end of input string");      else if (errno == EILSEQ)	error ("invalid code in input string");      else if (errno == E2BIG)	error ("output buffer overflow at do_convert()");      else#endif	error ("something happen");      strcpy ((char *) to, (const char *) from);      return;    }  if (iconv_close (cd) != 0)    {      error ("iconv_close() error");    }#else  int p1, p2, i, j;  int jisx0208 = FALSE;  int hankaku = FALSE;  j = 0;  if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)    {      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)	{	  if (from[i] == ESC)	    {	      i++;	      if (from[i] == '$')		{		  jisx0208 = TRUE;		  hankaku = FALSE;		  i++;		}	      else if (from[i] == '(')		{		  jisx0208 = FALSE;		  i++;		  if (from[i] == 'I')	/* Hankaku Kana */		    hankaku = TRUE;		  else		    hankaku = FALSE;		}	    }	  else	    {	      if (jisx0208)		to[j++] = from[i] + 128;	      else if (hankaku)		{		  to[j++] = SS2;		  to[j++] = from[i] + 128;		}	      else		to[j++] = from[i];	    }	}    }  else if (strcmp (code, SJISSTR) == 0)    {      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)	{	  p1 = from[i];	  if (p1 < 127)	    to[j++] = p1;	  else if ((p1 >= 161) && (p1 <= 223))	    {			/* Hankaku Kana */	      to[j++] = SS2;	      to[j++] = p1;	    }	  else	    {	      p2 = from[++i];	      SJIStoJIS (&p1, &p2);	      to[j++] = p1 + 128;	      to[j++] = p2 + 128;	    }	}    }  else    {      error ("invalid code specification: \"%s\"", code);      return;    }  if (j >= BUFSIZ)    {      error ("output buffer overflow at do_convert()");      ustrcpy (to, from);    }  else    to[j] = '\0';#endif /* HAVE_ICONV */}static intdo_check_and_conv (unsigned char *to, unsigned char *from){  static unsigned char tmp[BUFSIZ];  int p1, p2, i, j;  int kanji = TRUE;  switch (DetectKanjiCode (from))    {    case NEW:      debug ("Kanji code is New JIS.");      do_convert (tmp, from, NEWJISSTR);      break;    case OLD:      debug ("Kanji code is Old JIS.");      do_convert (tmp, from, OLDJISSTR);      break;    case ESCI:      debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");      do_convert (tmp, from, NEWJISSTR);      break;    case NEC:      debug ("Kanji code is NEC Kanji.");      error ("cannot convert NEC Kanji.");      ustrcpy (tmp, from);      kanji = FALSE;      break;    case EUC:      debug ("Kanji code is EUC.");      ustrcpy (tmp, from);      break;    case SJIS:      debug ("Kanji code is SJIS.");      do_convert (tmp, from, SJISSTR);      break;    case EUCORSJIS:      debug ("Kanji code is EUC or SJIS.");      ustrcpy (tmp, from);      kanji = FALSE;      break;    case ASCII:      debug ("This is ASCII string.");      ustrcpy (tmp, from);      kanji = FALSE;      break;    default:      debug ("This string includes unknown code.");      ustrcpy (tmp, from);      kanji = FALSE;      break;    }  /* Hankaku Kana ---> Zenkaku Kana */  if (kanji)    {      j = 0;      for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)	{	  if (tmp[i] == SS2)	    {	      p1 = tmp[++i];	      if (tmp[i + 1] == SS2)		{		  p2 = tmp[i + 2];		  if (p2 == 222 || p2 == 223)		    i += 2;		  else		    p2 = 0;		}	      else		p2 = 0;	      han2zen (&p1, &p2);	      SJIStoJIS (&p1, &p2);	      to[j++] = p1 + 128;	      to[j++] = p2 + 128;	    }	  else	    to[j++] = tmp[i];	}      if (j >= BUFSIZ)	{	  error ("output buffer overflow at Hankaku --> Zenkaku");	  ustrcpy (to, tmp);	}      else	to[j] = '\0';    }  else    ustrcpy (to, tmp);  return kanji;}intany2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max){  static unsigned char tmp_dest[BUFSIZ];  int ret;  if (strlen ((const char *) src) >= BUFSIZ)    {      error ("input string too large");      return -1;    }  if (dest_max > BUFSIZ)    {      error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);      return -1;    }  ret = do_check_and_conv (tmp_dest, src);  if (strlen ((const char *) tmp_dest) >= dest_max)    {      error ("output buffer overflow");      ustrcpy (dest, src);      return -1;    }  ustrcpy (dest, tmp_dest);  return ret;}#if 0unsigned intstrwidth (unsigned char *s){  unsigned char *t;  unsigned int i;  t = (unsigned char *) gdMalloc (BUFSIZ);  any2eucjp (t, s, BUFSIZ);  i = strlen (t);  gdFree (t);  return i;}#ifdef DEBUGintmain (){  unsigned char input[BUFSIZ];  unsigned char *output;  unsigned char *str;  int c, i = 0;  while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)    input[i++] = c;  input[i] = '\0';  printf ("input : %d bytes\n", strlen ((const char *) input));  printf ("output: %d bytes\n", strwidth (input));  output = (unsigned char *) gdMalloc (BUFSIZ);  any2eucjp (output, input, BUFSIZ);  str = output;  while (*str != '\0')    putchar (*(str++));  putchar ('\n');  gdFree (output);  return 0;}#endif#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -