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

📄 gconv_trans.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
字号:
/* Transliteration using the locale's data.   Copyright (C) 2000 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000.   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 <dlfcn.h>#include <search.h>#include <stdint.h>#include <string.h>#include <stdlib.h>#include <dirent.h>#include <ltdl.h>#include "gconv_int.h"#include "localeinfo.h"int__gconv_transliterate (struct __gconv_step *step,		       struct __gconv_step_data *step_data,		       void *trans_data __attribute__ ((unused)),		       const unsigned char *inbufstart,		       const unsigned char **inbufp,		       const unsigned char *inbufend,		       unsigned char **outbufstart, size_t *irreversible){  return 0;}/* Structure to represent results of found (or not) transliteration   modules.  */struct known_trans{  /* This structure must remain the first member.  */  struct trans_struct info;  char *fname;  void *handle;  int open_count;};/* Tree with results of previous calls to __gconv_translit_find.  */static void *search_tree;/* We modify global data.   */__LOCK_INIT(static, lock);/* Compare two transliteration entries.  */static inttrans_compare (const void *p1, const void *p2){  const struct known_trans *s1 = (const struct known_trans *) p1;  const struct known_trans *s2 = (const struct known_trans *) p2;  return strcmp (s1->info.name, s2->info.name);}/* Open (maybe reopen) the module named in the struct.  Get the function   and data structure pointers we need.  */static intopen_translit (struct known_trans *trans){  __gconv_trans_query_fct queryfct;  trans->handle = __libc_dlopen (trans->fname);  if (trans->handle == NULL)    /* Not available.  */    return 1;  /* Find the required symbol.  */  queryfct = __libc_dlsym (trans->handle, "gconv_trans_context");  if (queryfct == NULL)    {      /* We cannot live with that.  */    close_and_out:      __libc_dlclose (trans->handle);      trans->handle = NULL;      return 1;    }  /* Get the context.  */  if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames)      != 0)    goto close_and_out;  /* Of course we also have to have the actual function.  */  trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans");  if (trans->info.trans_fct == NULL)    goto close_and_out;  /* Now the optional functions.  */  trans->info.trans_init_fct =    __libc_dlsym (trans->handle, "gconv_trans_init");  trans->info.trans_context_fct =    __libc_dlsym (trans->handle, "gconv_trans_context");  trans->info.trans_end_fct =    __libc_dlsym (trans->handle, "gconv_trans_end");  trans->open_count = 1;  return 0;}intinternal_function__gconv_translit_find (struct trans_struct *trans){  struct known_trans **found;  const struct path_elem *runp;  int res = 1;  /* We have to have a name.  */  assert (trans->name != NULL);  /* Acquire the lock.  */#ifdef HAVE_DD_LOCK  __lock_acquire(lock);#endif  /* See whether we know this module already.  */  found = tfind (trans, &search_tree, trans_compare);  if (found != NULL)    {      /* Is this module available?  */      if ((*found)->handle != NULL)	{	  /* Maybe we have to reopen the file.  */	  if ((*found)->handle != (void *) -1)	    /* The object is not unloaded.  */	    res = 0;	  else if (open_translit (*found) == 0)	    {	      /* Copy the data.  */	      *trans = (*found)->info;	      (*found)->open_count++;	      res = 0;	    }	}    }  else    {      size_t name_len = strlen (trans->name) + 1;      int need_so = 0;      struct known_trans *newp;      /* We have to continue looking for the module.  */      if (__gconv_path_elem == NULL)	__gconv_get_path ();      /* See whether we have to append .so.  */      if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0)	need_so = 1;      /* Create a new entry.  */      newp = (struct known_trans *) malloc (sizeof (struct known_trans)					    + (__gconv_max_path_elem_len					       + name_len + 3)					    + name_len);      if (newp != NULL)	{	  char *cp;	  /* Clear the struct.  */	  memset (newp, '\0', sizeof (struct known_trans));	  /* Store a copy of the module name.  */	  newp->info.name = cp = (char *) (newp + 1);	  cp = memcpy (cp, trans->name, name_len);          cp += name_len;	  newp->fname = cp;	  /* Search in all the directories.  */	  for (runp = __gconv_path_elem; runp->name != NULL; ++runp)	    {              strcpy ((char *) newp->fname, runp->name);              while(newp->fname != '\0') newp->fname++;	      cp = memcpy (newp->fname,                            trans->name, name_len);              cp += name_len;	      if (need_so)		memcpy (cp, ".so", sizeof (".so"));	      if (open_translit (newp) == 0)		{		  /* We found a module.  */		  res = 0;		  break;		}	    }	  if (res)	    newp->fname = NULL;	  /* In any case we'll add the entry to our search tree.  */	  if (tsearch (newp, &search_tree, trans_compare) == NULL)	    {	      /* Yickes, this should not happen.  Unload the object.  */	      res = 1;	      /* XXX unload here.  */	    }	}    }#ifdef HAVE_DD_LOCK  __lock_release(lock);#endif  return res;}

⌨️ 快捷键说明

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