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

📄 setlocale.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*/#if	!defined(lint) && defined(SCCSIDS)static  char *sccsid = "@(#)setlocale.c 1.1 92/07/30 SMI";#endif#include <fcntl.h>extern int	open();#include <locale.h>#include <stdlib.h>#include "codeset.h"#include <ctype.h>#include <string.h>#include <memory.h>#include <malloc.h>#include <sys/param.h>		/* for MAXPATHLEN */#include <sys/stat.h>#include <errno.h>#include <limits.h>#define	TRAILER ".ci"extern int	stat();extern char	*getenv();struct	_code_set_info _code_set_info = {	NULL,	CODESET_NONE, 	/* no codeset */	NULL, 		/* not defined */	0,};/* tolower()  and toupper() conversion table  * is hidden here to avoid being placed in the  * extern  .sa file in the dynamic version of libc */	char _ctype_ul[] = { 0,/*	 0	 1	 2	 3	 4	 5	 6	 7  */	'\000',	'\001',	'\002',	'\003',	'\004',	'\005',	'\006',	'\007',	'\010',	'\011',	'\012',	'\013',	'\014',	'\015',	'\016',	'\017',	'\020',	'\021',	'\022',	'\023',	'\024',	'\025',	'\026',	'\027',	'\030',	'\031',	'\032',	'\033',	'\034',	'\035',	'\036',	'\037',	' ',	'!',	'"',	'#',	'$',	'%',	'&',	'\'',	'(',	')',	'*',	'+',	',',	'-',	'.',	'/',	'0',	'1',	'2',	'3',	'4',	'5',	'6',	'7',	'8',	'9',	':',	';',	'<',	'=',	'>',	'?',	'@',	'a',	'b',	'c',	'd',	'e',	'f',	'g',	'h',	'i',	'j',	'k',	'l',	'm',	'n',	'o',	'p',	'q',	'r',	's',	't',	'u',	'v',	'w',	'x',	'y',	'z',	'[',	'\\',	']',	'^',	'_',	'`',	'A',	'B',	'C',	'D',	'E',	'F',	'G',	'H',	'I',	'J',	'K',	'L',	'M',	'N',	'O',	'P',	'Q',	'R',	'S',	'T',	'U',	'V',	'W',	'X',	'Y',	'Z',	'{',	'|',	'}',	'~',	'\177',	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,	0,};/* following layout is: * LC_NUMERIC LC_TIME LC_MONETARY LANGINFO LC_COLLATE LC_MESSAGES */char _locales[MAXLOCALE - 1][MAXLOCALENAME + 1] ;char _my_time[MAXLOCALENAME + 1];/* The array Default holds the systems notion of default locale. It is normally * found in {LOCALE}/.default and moved to here. Note there is only one * default locale spanning all categories */static char Default[MAXLOCALENAME+1];struct	langinfo _langinfo;struct	dtconv *_dtconv = NULL;static	char *realmonths = NULL;static	char *realdays = NULL;static	char *realfmts = NULL;static  short lang_succ = ON;	/* setlocale success *//* Set the values here to guarantee stdio use of the    decimal point */static struct lconv lconv_arr = {	".", "", "", "", "", 	"", "", "", "", "",	CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, 	CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX};/* lconv is externally defined by ANSI C */struct	lconv *lconv = &lconv_arr;static	char *lconv_numeric_str = NULL;static 	char *lconv_monetary_str = NULL;int	getlocale_ctype(/*char *locale, char *ctypep, char *newlocale*/);char	*getlocale_numeric(/*char *locale, struct lconv *lconvp*/);static 	char	*getlocale_monetary();void	init_statics();static	char	*getstr(/*char *p, char **strp*/);static	char	*getgrouping(/*char *p, char **groupingp*/);static	char	*getnum(/*char *p, int *nump*/);static	char	*getbool(/*char *p, int *boolp*/);int		openlocale(/*char *category, int cat_id, char *locale, char *newlocale */);static int	set_codeinfo(/*char */);static int	set_default();char *setlocale(category, locale)	int category;	char *locale;{	static char buf[MAXLOCALE*(MAXLOCALENAME + 1) + 1];		/* buffer for current LC_ALL value */	int nonuniform;	short ret;	char my_ctype[CTYPE_SIZE];	/* local copy */	struct lconv my_lconv;		/* local copy */	char *my_lconv_numeric_str;	char *my_lconv_monetary_str;	register int i;	register char *p;	/*	 *  Following code is to avoid static initialisation of	 *  strings which would otherwise blow up "xstr".	 */	if (_locales[0][0] == '\0')		init_statics();	if (locale == NULL) {		if (category == LC_ALL) {			/*			 * Assume all locales are set to the same value.  Then			 * scan through the locales to see if any are			 * different.  If they are the same, return the common			 * value; otherwise, construct a "composite" value.			 */			nonuniform = 0;	/* assume all locales set the same */			for (i = 0; i < MAXLOCALE - 2; i++) {				if (strcmp(_locales[i], _locales[i + 1]) != 0) {					nonuniform = 1;					break;				}			}			if (nonuniform) {				/*				 * They're not all the same.  Construct a list				 * of all the locale values, in order,				 * separated by slashes.  Return that value.				 */				(void) strcpy(buf, _locales[0]);				for (i = 1; i < MAXLOCALE - 1; i++) {					(void) strcat(buf, "/");					(void) strcat(buf, _locales[i]);				}				return (buf);			} else {				/*				 * They're all the same; any one you return is				 * OK.				 */				return (_locales[0]);			}		} else			return (_locales[category - 1]);	}	switch (category) {	case LC_ALL:		if (strchr(locale, '/') != NULL) {			/*			 * Composite value; extract each category.			 */			if (strlen(locale) > sizeof buf - 1)				return (NULL);	/* too long */			(void) strcpy(buf, locale);			p = buf;			/*			 * LC_CTYPE and LC_NUMERIC are set here.			 * Others locales won't be set here,			 * they will be just marked.			 */			for (i = 0; i < MAXLOCALE - 1; i++) {				p = strtok(p, "/");				if (p == NULL)					return (NULL);	/* missing item */				switch (i) {				case LC_CTYPE - 1:					if (setlocale(LC_CTYPE,p) == NULL)						return NULL;					break;				case LC_NUMERIC - 1:					if (setlocale(LC_NUMERIC,p) == NULL)						return NULL;					break;				case LC_TIME - 1:					if (setlocale(LC_TIME,p) == NULL)						return NULL;					break;				case LC_MONETARY - 1:					if (setlocale(LC_MONETARY,p) == NULL)						return NULL;					break;				case LANGINFO - 1:					if (setlocale(LANGINFO,p) == NULL)						return NULL;					break;				case LC_COLLATE - 1:					if (setlocale(LC_COLLATE,p) == NULL)						return NULL;					break;				case LC_MESSAGES - 1:					if (setlocale(LC_MESSAGES,p) == NULL)						return NULL;					break;				}				p = NULL;			}			if (strtok((char *)NULL, "/") != NULL)				return (NULL);	/* extra stuff at end */		}	/* If category = LC_ALL, Drop through to test each individual  	 * category, one at a time. Note default rules where env vars	 * are not set	 */	case LC_CTYPE:		if ((ret = getlocale_ctype(locale , my_ctype,		    _locales[LC_CTYPE - 1])) < 0)			return (NULL);		if (ret) {		      (void) memcpy(_ctype_, my_ctype, CTYPE_SIZE/2);		      (void) memcpy(_ctype_ul, my_ctype+(CTYPE_SIZE/2), CTYPE_SIZE/2); 		}		if (category != LC_ALL)			break;	case LC_NUMERIC:		if ((my_lconv_numeric_str =		    getlocale_numeric(locale, &my_lconv,		      _locales[LC_NUMERIC - 1])) == NULL)			return (NULL);		if (*my_lconv_numeric_str) {			if (lconv_numeric_str != NULL)				free((malloc_t)lconv_numeric_str);			lconv_numeric_str = my_lconv_numeric_str;			memcpy(lconv, my_lconv, sizeof(my_lconv));		}		if (category != LC_ALL)			break;	case LC_TIME:		if ((ret = openlocale("LC_TIME", LC_TIME, locale,		      _locales[LC_TIME -1])) < 0)			return (NULL);		if (ret)			(void) close(ret);		if (category != LC_ALL)			break;	case LC_MONETARY:		if ((my_lconv_monetary_str =		    getlocale_monetary(locale, &my_lconv,		      _locales[LC_MONETARY - 1])) == NULL)			return (NULL);		if (*my_lconv_monetary_str) {			if (lconv_monetary_str != NULL)				free((malloc_t)lconv_monetary_str);			lconv_monetary_str = my_lconv_monetary_str;			memcpy(lconv, &my_lconv, sizeof(my_lconv));		}		if (category != LC_ALL)			break;	case LANGINFO:		if ((ret = openlocale("LANGINFO", LANGINFO, locale,		      _locales[LANGINFO - 1])) < 0) {			lang_succ = OFF;			return (NULL);		}		if (ret) {			lang_succ = OFF;			(void) close(ret);		}		if (category != LC_ALL)			break;	case LC_COLLATE:		if ((ret = openlocale("LC_COLLATE", LC_COLLATE, locale,		      _locales[LC_COLLATE - 1])) < 0)			return (NULL);		if (ret) {			(void) close(ret);		}		if (category != LC_ALL)			break;	case LC_MESSAGES:		if ((ret = openlocale("LC_MESSAGES", LC_MESSAGES, locale,		      _locales[LC_MESSAGES - 1])) < 0)			return (NULL);		if (ret) {			(void) close(ret);		}	}	return (setlocale(category, (char *)NULL));}intgetlocale_ctype(locale, ctypep, newlocale)	char *locale;	char *ctypep;	char *newlocale;{	register int fd;	if ((fd = openlocale("LC_CTYPE", LC_CTYPE, locale, newlocale)) > 0) {		if (read(fd, (char *)ctypep, CTYPE_SIZE) != CTYPE_SIZE) {			(void) close(fd);			fd = -1;		}		(void) close(fd);	}	return (fd);}/* open and load the numeric information */char *getlocale_numeric(locale, lconvp, newlocale)	char *locale;	register struct lconv *lconvp;	char *newlocale;{	register int fd;	struct stat buf;	char *str;	register char *p;	if ((fd = openlocale("LC_NUMERIC", LC_NUMERIC, locale, newlocale)) < 0)		return (NULL);	if (fd == 0)		return "";	if ((fstat(fd, &buf)) != 0)		return (NULL);	if ((str = (char*)malloc((unsigned)buf.st_size + 2)) == NULL)		return (NULL);	if ((read(fd, str, (int)buf.st_size)) != buf.st_size) {		free((malloc_t)str);		return (NULL);	}	/* Set last character of str to '\0' */	p = &str[buf.st_size];	*p++ = '\n';	*p = '\0';	/* p will "walk thru" str */	p = str;	p = getstr(p, &lconvp->decimal_point);	if (p == NULL)		goto fail;	p = getstr(p, &lconvp->thousands_sep);	if (p == NULL)		goto fail;	p = getgrouping(p, &lconvp->grouping);	if (p == NULL)		goto fail;	(void) close(fd);	return (str);fail:	(void) close(fd);	free((malloc_t)str);	return (NULL);}

⌨️ 快捷键说明

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