📄 setlocale.c
字号:
static char *getlocale_monetary(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_MONETARY", LC_MONETARY, 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->int_curr_symbol); if (p == NULL) goto fail; p = getstr(p, &lconvp->currency_symbol); if (p == NULL) goto fail; p = getstr(p, &lconvp->mon_decimal_point); if (p == NULL) goto fail; p = getstr(p, &lconvp->mon_thousands_sep); if (p == NULL) goto fail; p = getgrouping(p, &lconvp->mon_grouping); if (p == NULL) goto fail; p = getstr(p, &lconvp->positive_sign); if (p == NULL) goto fail; p = getstr(p, &lconvp->negative_sign); if (p == NULL) goto fail; p = getnum(p, &lconvp->frac_digits); if (p == NULL) goto fail; p = getbool(p, &lconvp->p_cs_precedes); if (p == NULL) goto fail; p = getbool(p, &lconvp->p_sep_by_space); if (p == NULL) goto fail; p = getbool(p, &lconvp->n_cs_precedes); if (p == NULL) goto fail; p = getbool(p, &lconvp->n_sep_by_space); if (p == NULL) goto fail; p = getnum(p, &lconvp->p_sign_posn); if (p == NULL) goto fail; p = getnum(p, &lconvp->n_sign_posn); if (p == NULL) goto fail; (void) close(fd); return _locales[LC_MONETARY-1];fail: (void) close(fd); free((malloc_t)str); return NULL;}static char *getstr(p, strp) register char *p; char **strp;{ *strp = p; p = strchr(p, '\n'); if (p == NULL) return (NULL); /* no end-of-line */ *p++ = '\0'; return (p);}static char *getgrouping(p, groupingp) register char *p; char **groupingp;{ register int c; if (*p == '\0') return (NULL); /* no grouping */ *groupingp = p; while ((c = *p) != '\n') { if (c == '\0') return (NULL); /* no end-of-line */ if (c >= '0' && c <= '9') *p++ = c - '0'; else *p++ = '\177'; } *p++ = '\0'; return (p);}static char *getnum(p, nump) register char *p; char *nump;{ register int num; register int c; if (*p == '\0') return (NULL); /* no number */ if (*p == '\n') *nump = '\177'; /* blank line - no value */ else { num = 0; while ((c = *p) != '\n') { if (c < '0' || c > '9') return (NULL); /* bad number */ num = num*10 + c - '0'; p++; } *nump = num; } *p++ = '\0'; return (p);}static char *getbool(p, boolp) register char *p; char *boolp;{ if (*p == '\0') return (NULL); /* no number */ if (*p == '\n') *boolp = '\177'; /* blank line - no value */ else { switch (*p++) { case 'y': case 'Y': case 't': case 'T': *boolp = 1; /* true */ break; case 'n': case 'N': case 'f': case 'F': *boolp = 0; /* false */ break; default: return (NULL); /* bad boolean */ } if (*p != '\n') return (NULL); /* noise at end of line */ } *p++ = '\0'; return (p);}/* * Open a locale file. First, check the value of "locale"; if it's a null * string, first check the environment variable with the same name as the * category, and then check the environment variable "LANG". If neither of * them are set to non-null strings, use the LC_default env.var and if this * has no meaning then assume we are running in the C locale. It is expected * That LC_default is set across the whole system. If the resulting locale is * longer than MAXLOCALENAME characters, reject it. Then, try looking in the * per-machine locale directory for the file in question; if it's not found * there, try looking in the shared locale directory. * If there is no work to do, that is, the last setting of locales is equal * to the current request, then we don't do anything, and exit with value 0. * Copy the name of the locale used into "newlocale". * Exit with positive value if we opened a file * Exit with -1 if an error occured (invalid locale). * Exit with 0 if there is no need to look at the disk file. * (Assumption - there is always at least one fd open before setlocale * is called) */intopenlocale(category, cat_id, locale, newlocale) char *category; register int cat_id; register char *locale; char *newlocale;{ char pathname[MAXPATHLEN], *defp; int fd, fd2; struct _code_header code_header; char *my_info; if (*locale == '\0') { locale = getenv(category); if (locale == NULL || *locale == '\0') { locale = getenv("LANG"); if (locale == NULL || *locale == '\0') { if (*Default == '\0') { defp = getenv("LC_default"); if (defp == NULL || *defp == '\0') strcpy(Default,"C"); else strcpy(Default, defp); } locale = Default; } } } if (strcmp(locale,_locales[cat_id-1]) == 0) { (void) strcpy(newlocale, locale); return 0; } if (strlen(locale) > MAXLOCALENAME) return -1; (void) strcpy(pathname, PRIVATE_LOCALE_DIR); (void) strcat(pathname, category); (void) strcat(pathname, "/"); (void) strcat(pathname, locale); if ((fd = open(pathname, O_RDONLY)) < 0 && errno == ENOENT) { (void) strcpy(pathname, LOCALE_DIR); (void) strcat(pathname, category); (void) strcat(pathname, "/"); (void) strcat(pathname, locale); fd = open(pathname, O_RDONLY); } if (fd == 0) { fd = dup(fd); close(0); } if (fd >= 0) (void) strcpy(newlocale, locale); if (cat_id == LC_CTYPE) { /* Go and get the trailer file */ (void) strcat(pathname, TRAILER); fd2 = open(pathname, O_RDONLY); if (fd2 == 0) { fd2 = dup(fd2); close(0); } if (fd2 == -1) { set_default(); return fd; } /* * ctype trailer file exists - read it */ if (read (fd2, (char *)&code_header, sizeof (code_header)) != sizeof (code_header)) { /* * File format not correct */ set_default(); close(fd2); return -1; } /* * set up trailer file */ strcpy(_code_set_info.code_name, code_header.code_name); _code_set_info.code_id = code_header.code_id; if (_code_set_info.code_info != NULL) free (_code_set_info.code_info); if (code_header.code_info_size > 0) { my_info = malloc(code_header.code_info_size); if (read (fd2, (char *)my_info, code_header.code_info_size) != code_header.code_info_size) { close(fd2); set_default(); return -1; } _code_set_info.code_info = my_info; } else { /* * We have a corrupted file too */ _code_set_info.code_info = NULL; close(fd2); set_default(); return -1; } close (fd2); } return fd;}struct lconv *localeconv(){ return (lconv);}struct dtconv *localdtconv(){ register char *p; register short i; char *rawmonths = "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec\nJanuary\nFebruary\nMarch\nApril\nMay\nJune\nJuly\nAugust\nSeptember\nOctober\nNovember\nDecember"; char *rawdays = "Sun\nMon\nTue\nWed\nThu\nFri\nSat\nSunday\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday";char *rawfmts = "%H:%M:%S\n%m/%d/%y\n%a %b %e %T %Z %Y\nAM\nPM\n%A, %B %e, %Y\n"; if (_dtconv == NULL) { /* We malloc both the space for the dtconv struct and the * copy of the strings above because this program is later run * through xstr and the resultant strings are put in read-only * text segment. Therefore we cannot write to the original * raw strings but we can to their copies. */ _dtconv = (struct dtconv*)malloc(sizeof (struct dtconv)); if (_dtconv == NULL) return (NULL); if ((realmonths = malloc(strlen(rawmonths)+1)) == NULL) return (NULL); strcpy(realmonths, rawmonths); if ((realdays = malloc(strlen(rawdays)+1)) == NULL) return (NULL); strcpy(realdays, rawdays); if ((realfmts = malloc(strlen(rawfmts)+1)) == NULL) return (NULL); strcpy(realfmts, rawfmts); /* p will "walk thru" str */ p = realmonths; for (i = 0; i < 12; i++) p = getstr(p, &(_dtconv->abbrev_month_names[i])); for (i = 0; i < 12; i++) p = getstr(p, &(_dtconv->month_names[i])); p = realdays; for (i= 0; i < 7; i++) p = getstr(p, &(_dtconv->abbrev_weekday_names[i])); for (i = 0; i < 7; i++) p = getstr(p, &(_dtconv->weekday_names[i])); p = realfmts; p = getstr(p, &_dtconv->time_format); p = getstr(p, &_dtconv->sdate_format); p = getstr(p, &_dtconv->dtime_format); p = getstr(p, &_dtconv->am_string); p = getstr(p, &_dtconv->pm_string); p = getstr(p, &_dtconv->ldate_format); } return (_dtconv);}static intset_default(){ strcpy(_code_set_info.code_name, Default); _code_set_info.code_id = CODESET_NONE; if (_code_set_info.code_info != NULL) free (_code_set_info.code_info); _code_set_info.code_info = NULL; _code_set_info.open_flag = 0;}void init_statics() { short i; for (i=0; i<MAXLOCALE-1;i++) strcpy(_locales[i],"C"); strcpy(_code_set_info.code_name, "default"); strcpy(_my_time,"C"); _langinfo.yesstr = "yes"; _langinfo.nostr = "no";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -