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

📄 dcigettext.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, elinks也是gentoo安装过程中默认使用的浏览器, 这是elinks源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
							known_translation_t,							msgid)						       + msgid_len +						       domainname_len + 1);					if (newp != NULL) {						newp->domainname =							mempcpy(newp->msgid,								msgid1,								msgid_len);						memcpy(newp->domainname,						       domainname,						       domainname_len + 1);						newp->category = category;						newp->counter =							_nl_msg_cat_cntr;						newp->domain = domain;						newp->translation = retval;						newp->translation_length =							retlen;						/* Insert the entry in the search tree.  */						foundp = (struct							  known_translation_t							  **)							tsearch(newp, &root,								transcmp);						if (foundp == NULL						    || *foundp != newp)							/* The insert failed.  */							free(newp);					}				} else {					/* We can update the existing entry.  */					(*foundp)->counter = _nl_msg_cat_cntr;					(*foundp)->domain = domain;					(*foundp)->translation = retval;					(*foundp)->translation_length = retlen;				}#endif				/* Now deal with plural.  */				if (plural)					retval = plural_lookup(domain, n,							       retval, retlen);				return retval;			}		}	}	/* NOTREACHED */}unsigned char *_nl_find_msg(struct loaded_l10nfile *domain_file,			       struct binding *domainbinding,			       const unsigned char *msgid, size_t *lengthp){	struct loaded_domain *domain;	size_t act;	unsigned char *result;	size_t resultlen;	if (domain_file->decided == 0)		_nl_load_domain(domain_file, domainbinding);	if (domain_file->data == NULL)		return NULL;	domain = (struct loaded_domain *) domain_file->data;	/* Locate the MSGID and its translation.  */	if (domain->hash_size > 2 && domain->hash_tab != NULL) {		/* Use the hashing table.  */		nls_uint32 len = strlen(msgid);		nls_uint32 hash_val = hash_string(msgid);		nls_uint32 idx = hash_val % domain->hash_size;		nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2));		while (1) {			nls_uint32 nstr =				W(domain->must_swap, domain->hash_tab[idx]);			if (nstr == 0)				/* Hash table entry is empty.  */				return NULL;			/* Compare msgid with the original string at index nstr-1.			   We compare the lengths with >=, not ==, because plural entries			   are represented by strings with an embedded NUL.  */			if (W			    (domain->must_swap,			     domain->orig_tab[nstr - 1].length) >= len			    &&			    (strcmp			     (msgid,			      domain->data + W(domain->must_swap,					       domain->orig_tab[nstr -								1].offset))			     == 0)) {				act = nstr - 1;				goto found;			}			if (idx >= domain->hash_size - incr)				idx -= domain->hash_size - incr;			else				idx += incr;		}		/* NOTREACHED */	} else {		/* Try the default method:  binary search in the sorted array of		   messages.  */		size_t top, bottom;		bottom = 0;		top = domain->nstrings;		while (bottom < top) {			int cmp_val;			act = (bottom + top) / 2;			cmp_val = strcmp(msgid, (domain->data						 + W(domain->must_swap,						     domain->orig_tab[act].						     offset)));			if (cmp_val < 0)				top = act;			else if (cmp_val > 0)				bottom = act + 1;			else				goto found;		}		/* No translation was found.  */		return NULL;	}found:	/* The translation was found at index ACT.  If we have to convert the	   string to use a different character set, this is the time.  */	result = ((unsigned char *) domain->data		  + W(domain->must_swap, domain->trans_tab[act].offset));	resultlen = W(domain->must_swap, domain->trans_tab[act].length) + 1;#if HAVE_ICONV	if (domain->codeset_cntr	    != (domainbinding != NULL ? domainbinding->codeset_cntr : 0)) {		/* The domain's codeset has changed through bind_textdomain_codeset()		   since the message catalog was initialized or last accessed.  We		   have to reinitialize the converter.  */		_nl_free_domain_conv(domain);		_nl_init_domain_conv(domain_file, domain, domainbinding);	}	if (domain->conv != (iconv_t) - 1) {		/* We are supposed to do a conversion.  First allocate an		   appropriate table with the same structure as the table		   of translations in the file, where we can put the pointers		   to the converted strings in.		   There is a slight complication with plural entries.  They		   are represented by consecutive NUL terminated strings.  We		   handle this case by converting RESULTLEN bytes, including		   NULs.  */		if (domain->conv_tab == NULL		    && ((domain->conv_tab = (unsigned char **) calloc(domain->nstrings,							     sizeof(unsigned char *)))			== NULL))			/* Mark that we didn't succeed allocating a table.  */			domain->conv_tab = (unsigned char **) -1;		if (domain->conv_tab == (unsigned char **) -1)			/* Nothing we can do, no more memory.  */			goto converted;		if (domain->conv_tab[act] == NULL) {			/* We haven't used this string so far, so it is not			   translated yet.  Do this now.  */			/* We use a bit more efficient memory handling.			   We allocate always larger blocks which get used over			   time.  This is faster than many small allocations.   */#define INITIAL_BLOCK_SIZE	4080			static unsigned char *freemem;			static size_t freemem_size;			const unsigned char *inbuf;			unsigned char *outbuf;			int malloc_count;			transmem_block_t *transmem_list = NULL;			inbuf = (const unsigned char *) result;			outbuf = freemem + sizeof(size_t);			malloc_count = 0;			while (1) {				transmem_block_t *newmem;				ICONV_CONST char *inptr = (ICONV_CONST char *) inbuf;				size_t inleft = resultlen;				char *outptr = (unsigned char *) outbuf;				size_t outleft;				if (freemem_size < sizeof(size_t))					goto resize_freemem;				outleft = freemem_size - sizeof(size_t);				if (iconv(domain->conv, &inptr, &inleft,					  &outptr, &outleft)				    != (size_t) (-1)) {					outbuf = (unsigned char *) outptr;					break;				}				if (errno != E2BIG) {					goto converted;				}resize_freemem:				/* We must allocate a new buffer or resize the old one.  */				if (malloc_count > 0) {					++malloc_count;					freemem_size =						malloc_count *						INITIAL_BLOCK_SIZE;					newmem = (transmem_block_t *)						realloc(transmem_list,							freemem_size);				} else {					malloc_count = 1;					freemem_size = INITIAL_BLOCK_SIZE;					newmem = (transmem_block_t *)						malloc(freemem_size);				}				if (newmem == NULL) {					freemem = NULL;					freemem_size = 0;					goto converted;				}				transmem_list = newmem;				freemem = newmem;				outbuf = freemem + sizeof(size_t);			}			/* We have now in our buffer a converted string.  Put this			   into the table of conversions.  */			*(size_t *) freemem = outbuf - freemem - sizeof(size_t);			domain->conv_tab[act] = (unsigned char *) freemem;			/* Shrink freemem, but keep it aligned.  */			freemem_size -= outbuf - freemem;			freemem = outbuf;			freemem += freemem_size & (alignof(size_t) - 1);			freemem_size = freemem_size & ~(alignof(size_t) - 1);		}		/* Now domain->conv_tab[act] contains the translation of all		   the plural variants.  */		result = domain->conv_tab[act] + sizeof(size_t);		resultlen = *(size_t *) domain->conv_tab[act];	}converted:	/* The result string is converted.  */#endif /* HAVE_ICONV */	*lengthp = resultlen;	return result;}/* Look up a plural variant.  */static unsigned char *plural_lookup(struct loaded_l10nfile *domain, unsigned long int n,	      const unsigned char *translation, size_t translation_len){	struct loaded_domain *domaindata =		(struct loaded_domain *) domain->data;	unsigned long int indexx;	const unsigned char *p;	indexx = plural_eval(domaindata->plural, n);	if (indexx >= domaindata->nplurals)		/* This should never happen.  It means the plural expression and the		   given maximum value do not match.  */		indexx = 0;	/* Skip INDEX strings at TRANSLATION.  */	p = translation;	while (indexx-- > 0) {		p = strchr(p, '\0');		/* And skip over the NUL byte.  */		p++;		if (p >= translation + translation_len)			/* This should never happen.  It means the plural expression			   evaluated to a value larger than the number of variants			   available for MSGID1.  */			return (unsigned char *) translation;	}	return (unsigned char *) p;}/* Function to evaluate the plural expression and return an index value.  */static unsigned long intplural_eval(struct expression *pexp, unsigned long int n){	switch (pexp->nargs) {		case 0:			switch (pexp->operation) {				case var:					return n;				case num:					return pexp->val.num;default:					break;			}			/* NOTREACHED */			break;		case 1:			{				/* pexp->operation must be lnot.  */				unsigned long int arg =					plural_eval(pexp->val.args[0], n);				return !arg;			}		case 2:			{				unsigned long int leftarg =					plural_eval(pexp->val.args[0], n);				if (pexp->operation == lor)					return leftarg						|| plural_eval(pexp->val.							       args[1], n);				else if (pexp->operation == land)					return leftarg						&& plural_eval(pexp->val.							       args[1], n);				else {					unsigned long int rightarg =						plural_eval(pexp->val.args[1],							    n);					switch (pexp->operation) {						case mult:							return leftarg *								rightarg;						case divide:							return leftarg /								rightarg;						case module:							return leftarg %								rightarg;						case plus:							return leftarg +								rightarg;						case minus:							return leftarg -								rightarg;						case less_than:							return leftarg <								rightarg;						case greater_than:							return leftarg >								rightarg;						case less_or_equal:							return leftarg <=								rightarg;						case greater_or_equal:							return leftarg >=								rightarg;						case equal:							return leftarg ==								rightarg;						case not_equal:							return leftarg !=								rightarg;default:							break;					}				}				/* NOTREACHED */				break;			}		case 3:			{				/* pexp->operation must be qmop.  */				unsigned long int boolarg =					plural_eval(pexp->val.args[0], n);				return plural_eval(pexp->val.						   args[boolarg ? 1 : 2], n);			}	}	/* NOTREACHED */	return 0;}/* Return string representation of locale CATEGORY.  */static const unsigned char *category_to_name(int category){	const unsigned char *retval;	switch (category) {#ifdef LC_COLLATE		case LC_COLLATE:			retval = "LC_COLLATE";			break;#endif#ifdef LC_CTYPE		case LC_CTYPE:			retval = "LC_CTYPE";			break;#endif#ifdef LC_MONETARY		case LC_MONETARY:			retval = "LC_MONETARY";			break;#endif#ifdef LC_NUMERIC		case LC_NUMERIC:			retval = "LC_NUMERIC";			break;#endif#ifdef LC_TIME		case LC_TIME:			retval = "LC_TIME";			break;#endif#ifdef LC_MESSAGES		case LC_MESSAGES:			retval = "LC_MESSAGES";			break;#endif#ifdef LC_RESPONSE		case LC_RESPONSE:			retval = "LC_RESPONSE";			break;#endif#ifdef LC_ALL		case LC_ALL:			/* This might not make sense but is perhaps better than any other			   value.  */			retval = "LC_ALL";			break;#endifdefault:			/* If you have a better idea for a default value let me know.  */			retval = "LC_XXX";	}	return retval;}/* Guess value of current locale from value of the environment variables.  */static const unsigned char *guess_category_value(int category, const unsigned char *categoryname){	const unsigned char *language;	const unsigned char *retval;	/* Takes precedence to anything else, damn it's what the application wants!	 * ;-) --pasky  */	if (LANGUAGE && *LANGUAGE)		return LANGUAGE;	/* The highest priority value is the `LANGUAGE' environment	   variable.  But we don't use the value if the currently selected	   locale is the C locale.  This is a GNU extension.  */	/* XXX: This GNU extension breaks things for me and I can't see what is it	 * good for - I think it only makes things more difficult and arcane, since	 * it requires you to set up more variables than LANGUAGE, it's poorly	 * documented and so on. If this breaks anything, let me know at	 * pasky@ucw.cz, I'm really curious. If LANGUAGE exists, we just use it and	 * do no more tests. This is an ELinks extension. --pasky  */	language = getenv("LANGUAGE");	if (language && language[0])		return language;	/* We have to proceed with the POSIX methods of looking to `LC_ALL',	   `LC_xxx', and `LANG'.  On some systems this can be done by the	   `setlocale' function itself.  */#if (defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL)	retval = setlocale(category, NULL);#else	/* Setting of LC_ALL overwrites all other.  */	retval = getenv("LC_ALL");	if (retval == NULL || retval[0] == '\0') {		/* Next comes the name of the desired category.  */		retval = getenv(categoryname);		if (retval == NULL || retval[0] == '\0') {			/* Last possibility is the LANG environment variable.  */			retval = getenv("LANG");			if (retval == NULL || retval[0] == '\0')				/* We use C as the default domain.  POSIX says this is				   implementation defined.  */				retval = "C";		}	}#endif	return retval;}

⌨️ 快捷键说明

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