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

📄 gconv_conf.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Handle configuration data.   Copyright (C) 1997,98,99,2000,2001 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 2.1 of the License, or (at your option) any later version.   The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with the GNU C Library; if not, write to the Free   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307 USA.  */#include <assert.h>#include <ctype.h>#include <errno.h>#include <limits.h>#include <locale.h>#include <search.h>#include <stddef.h>#include <stdio.h>#include <stdio_ext.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/param.h>#include <dirent.h>#include <gconv_int.h>/* This is the default path where we look for module lists.  */static const char default_gconv_path[] = GCONV_PATH;/* The path elements, as determined by the __gconv_get_path function.   All path elements end in a slash.  */struct path_elem *__gconv_path_elem;/* Maximum length of a single path element in __gconv_path_elem.  */size_t __gconv_max_path_elem_len;/* We use the following struct if we couldn't allocate memory.  */static const struct path_elem empty_path_elem;/* Name of the file containing the module information in the directories   along the path.  */static const char gconv_conf_filename[] = "gconv-modules";/* Filename extension for the modules.  */#ifndef MODULE_EXT# define MODULE_EXT ".so"#endifstatic const char gconv_module_ext[] = MODULE_EXT;/* We have a few builtin transformations.  */static struct gconv_module builtin_modules[] ={#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \			       MinT, MaxT) \  {									      \    from_string: From,							      \    to_string: To,							      \    cost_hi: Cost,							      \    cost_lo: INT_MAX,							      \    module_name: Name							      \  },#define BUILTIN_ALIAS(From, To)#include "gconv_builtin.h"};#undef BUILTIN_TRANSFORMATION#undef BUILTIN_ALIASstatic const char *builtin_aliases[] ={#define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \			       MinT, MaxT)#define BUILTIN_ALIAS(From, To) From " " To,#include "gconv_builtin.h"};#ifdef USE_IN_LIBIO# include <libio/libioP.h># define __getdelim(line, len, c, fp) _IO_getdelim (line, len, c, fp)#endif/* Value of the GCONV_PATH environment variable.  */const char *__gconv_path_envvar;/* Test whether there is already a matching module known.  */static intinternal_functiondetect_conflict (const char *alias){  struct gconv_module *node = __gconv_modules_db;  while (node != NULL)    {      int cmpres = strcmp (alias, node->from_string);      if (cmpres == 0)	/* We have a conflict.  */	return 1;      else if (cmpres < 0)	node = node->left;      else	node = node->right;    }  return node != NULL;}/* Add new alias.  */static inline voidadd_alias (char *rp, void *modules){  /* We now expect two more string.  The strings are normalized     (converted to UPPER case) and strored in the alias database.  */  struct gconv_alias *new_alias;  char *from, *to, *wp;  char old_locale[20], *old_locale_p;  /* Set locale to default C locale. */  old_locale_p = setlocale(LC_ALL, "C");  strncpy(old_locale, old_locale_p, 20);  while (isspace (*rp))    ++rp;  from = wp = rp;  while (*rp != '\0' && !isspace (*rp))    *wp++ = toupper (*rp++);  if (*rp == '\0')    {      setlocale(LC_ALL, old_locale);      /* There is no `to' string on the line.  Ignore it.  */      return;    }  *wp++ = '\0';  to = ++rp;  while (isspace (*rp))    ++rp;  while (*rp != '\0' && !isspace (*rp))    *wp++ = toupper (*rp++);  if (to == wp)    {      setlocale(LC_ALL, old_locale);      /* No `to' string, ignore the line.  */      return;    }  *wp++ = '\0';  /* Test whether this alias conflicts with any available module.  */  if (detect_conflict (from))    {      setlocale(LC_ALL, old_locale);      /* It does conflict, don't add the alias.  */      return;    }  new_alias = (struct gconv_alias *) malloc (sizeof (struct gconv_alias) + (wp - from));  if (new_alias != NULL)    {      void **inserted;      new_alias->fromname = memcpy ((char *) new_alias				    + sizeof (struct gconv_alias),				    from, wp - from);      new_alias->toname = new_alias->fromname + (to - from);      inserted = (void **) tsearch (new_alias, &__gconv_alias_db,				      __gconv_alias_compare);      if (inserted == NULL || *inserted != new_alias)	/* Something went wrong, free this entry.  */	free (new_alias);    }  setlocale(LC_ALL, old_locale);}/* Insert a data structure for a new module in the search tree.  */static inline voidinternal_functioninsert_module (struct gconv_module *newp, int tobefreed){  struct gconv_module **rootp = &__gconv_modules_db;  while (*rootp != NULL)    {      struct gconv_module *root = *rootp;      int cmpres;      cmpres = strcmp (newp->from_string, root->from_string);      if (cmpres == 0)	{	  /* Both strings are identical.  Insert the string at the	     end of the `same' list if it is not already there.  */	  while (strcmp (newp->from_string, root->from_string) != 0		 || strcmp (newp->to_string, root->to_string) != 0)	    {	      rootp = &root->same;	      root = *rootp;	      if (root == NULL)		break;	    }	  if (root != NULL)	    {	      /* This is a no new conversion.  But maybe the cost is		 better.  */	      if (newp->cost_hi < root->cost_hi		  || (newp->cost_hi == root->cost_hi		      && newp->cost_lo < root->cost_lo))		{		  newp->left = root->left;		  newp->right = root->right;		  newp->same = root->same;		  *rootp = newp;		  free (root);		}	      else if (tobefreed)		free (newp);	      return;	    }	  break;	}      else if (cmpres < 0)	rootp = &root->left;      else	rootp = &root->right;    }  /* Plug in the new node here.  */  *rootp = newp;}/* Add new module.  */static voidinternal_functionadd_module (char *rp, const char *directory, size_t dir_len, void **modules,	    size_t *nmodules, int modcounter){  /* We expect now     1. `from' name     2. `to' name     3. filename of the module     4. an optional cost value  */  struct gconv_alias fake_alias;  struct gconv_module *new_module;  char *from, *to, *module, *wp;  int need_ext;  int cost_hi;  char old_locale[20], *old_locale_p;  char *old;  size_t len;  char *new;  /* Set locale to default C locale. */  old_locale_p = setlocale(LC_ALL, "C");  strncpy(old_locale, old_locale_p, 20);  while (isspace (*rp))    ++rp;  from = rp;  while (*rp != '\0' && !isspace (*rp))    {      *rp = toupper (*rp);      ++rp;    }  if (*rp == '\0')    {      setlocale(LC_ALL, old_locale);      return;    }  *rp++ = '\0';  to = wp = rp;  while (isspace (*rp))    {      setlocale(LC_ALL, old_locale);      ++rp;    }  while (*rp != '\0' && !isspace (*rp))    *wp++ = toupper (*rp++);  if (*rp == '\0')    {      setlocale(LC_ALL, old_locale);      return;    }  *wp++ = '\0';  do    ++rp;  while (isspace (*rp));  module = wp;  while (*rp != '\0' && !isspace (*rp))    *wp++ = *rp++;  if (*rp == '\0')    {      /* There is no cost, use one by default.  */      *wp++ = '\0';      cost_hi = 1;    }  else    {      /* There might be a cost value.  */      char *endp;      *wp++ = '\0';      cost_hi = strtol (rp, &endp, 10);      if (rp == endp || cost_hi < 1)	/* No useful information.  */	cost_hi = 1;    }  if (module[0] == '\0')    {      setlocale(LC_ALL, old_locale);      /* No module name given.  */      return;    }  if (module[0] == '/')    dir_len = 0;  /* See whether we must add the ending.  */  need_ext = 0;  if (wp - module < (ptrdiff_t) sizeof (gconv_module_ext)      || memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext,		 sizeof (gconv_module_ext)) != 0)    /* We must add the module extension.  */

⌨️ 快捷键说明

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