NAME

newlocale, freelocale - 로캘 객체 생성, 변경, 해제하기

SYNOPSIS

#include <locale.h>

locale_t newlocale(int category_mask, const char *locale,
                   locale_t base);
void freelocale(locale_t locobj);

glibc 기능 확인 매크로 요건 (feature_test_macros(7) 참고):

newlocale(), freelocale():
glibc 2.10부터:
_XOPEN_SOURCE >= 700
glibc 2.10 전:
_GNU_SOURCE

DESCRIPTION

newlocale() 함수는 새 로캘 객체를 만들거나 기존 객체를 변경한 다음 그 새 객체 내지 변경된 객체에 대한 참조를 함수 결과로 반환한다. 새 객체를 만들지 기존 객체를 변경할지는 base의 값에 따라 정해진다.

base가 특수 로캘 객체 LC_GLOBAL_LOCALE(duplocale(3) 참고)인 경우, 또는 (locale_t) 0이 아니면서 유효한 로캘 객체 핸들도 아닌 경우의 동작은 규정돼 있지 않다.

category_mask 인자는 새로 만드는 로캘 객체에 설정하거나 기존 객체에서 변경할 로캘 범주들을 나타내는 비트 마스크다. 상수 LC_ADDRESS_MASK, LC_CTYPE_MASK, LC_COLLATE_MASK, LC_IDENTIFICATION_MASK, LC_MEASUREMENT_MASK, LC_MESSAGES_MASK, LC_MONETARY_MASK, LC_NUMERIC_MASK, LC_NAME_MASK, LC_PAPER_MASK, LC_TELEPHONE_MASK, LC_TIME_MASK를 비트 OR 해서 마스크를 만든다. 또는 LC_ALL_MASK를 지정할 수도 있는데, 앞선 상수들 모두를 OR 한 것과 동등하다.

newlocale()이 반환하는 객체에서는 category_mask에 지정한 범주 각각에 locale에서 온 로캘 데이터가 쓰이게 된다. 로캘 객체가 새로 만들어지는 경우에 category_mask에 지정하지 않는 범주들은 기본("POSIX") 로캘에서 데이터를 가져온다.

category_mask에 지정할 수 있는 모든 범주들에 대해 다음 locale 값들이 기본적으로 정의돼 있다.

"POSIX"
C 언어 프로그램용 최소 로캘 환경.
"C"
"POSIX"와 동등.
""
LC_*LANG 환경 변수 값에 따라 정해지는 구현체별 기본 환경. (locale(7) 참고.)

freelocale()

freelocale() 함수는 앞선 newlocale() 내지 duplocale(3) 호출이 반환한 로캘 객체인 locobj에 연계된 자원들을 해제한다. locobjLC_GLOBAL_LOCALE이거나 유효한 로캘 객체가 아닌 경우의 결과는 규정돼 있지 않다.

로캘 객체가 해제된 후에는 프로그램에서 더 이상 그 객체를 사용하지 말아야 한다.

RETURN VALUE

성공 시 newlocale()은 핸들을 반환하며, 이를 duplocale(3)이나 freelocale(), locale_t 인자를 받는 기타 함수들에 사용할 수 있다. 오류 발생 시 newlocale()(locale_t) 0을 반환하며 오류를 나타내도록 errno를 설정한다.

ERRORS

EINVAL
category_mask의 비트 중 하나 이상이 유효한 로캘 범주에 대응하지 않는다.
EINVAL
locale이 NULL이다.
ENOENT
locale이 유효한 로캘을 가리키는 문자열 포인터가 아니다.
ENOMEM
로캘 객체를 만들 메모리가 충분치 않다.

VERSIONS

GNU C 라이브러리 버전 2.3에서 newlocale()freelocale() 함수가 처음 등장했다.

CONFORMING TO

POSIX.1-2008.

NOTES

newlocale()로 만든 로캘 객체 각각을 freelocale()로 해제해 줘야 한다.

EXAMPLES

아래 프로그램은 로캘을 나타내는 명령행 인자를 최대 2개 받는다. 첫 번째 인자는 필수이며, newlocale()로 만든 로캘 객체의 LC_NUMERIC 범주를 설정하는 데 쓰인다. 두 번째 명령행 인자는 선택적이며, 제공 시 로캘 객체의 LC_TIME 범주를 설정하는 데 쓰인다.

프로그램에서 로캘 객체를 만들어서 초기화한 다음 uselocale(3)로 적용하고, 다음 방식으로 로캘 변경 효과를 확인한다.

  1. 소수부 있는 부동소수점 수 찍기. LC_NUMERIC 설정이 출력에 영향을 주게 된다. 여러 유럽어 로캘들에선 점이 아니라 쉼표로 정수부와 소수부를 구분한다.

  2. 날짜 찍기. LC_DATE 설정이 출력 형식과 언어에 영향을 주게 된다.

다음 셸 세션들은 프로그램 실행 예를 보여 준다.

LC_NUMERIC 범주를 fr_FR(프랑스)로 설정하기:

$ ./a.out fr_FR
123456,789
Fri Mar  7 00:25:08 2014

LC_NUMERIC 범주를 fr_FR(프랑스)로 설정하고 LC_TIME 범주를 it_IT(이탈리아)로 설정하기:

$ ./a.out fr_FR it_IT
123456,789
ven 07 mar 2014 00:26:01 CET

LC_TIME 설정을 빈 문자열로 지정해서 환경 변수 설정 값(이 경우 뉴질랜드 마오리를 나타내는 mi_NZ)을 가져오게 하기:

$ LC_ALL=mi_NZ ./a.out fr_FR ""
123456,789
Te Paraire, te 07 o Poutū-te-rangi, 2014 00:38:44 CET

프로그램 소스

#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>

#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                        } while (0)

int
main(int argc, char *argv[])
{
    char buf[100];
    time_t t;
    size_t s;
    struct tm *tm;
    locale_t loc, nloc;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s locale1 [locale2]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* 새 로캘 객체 만들기. argv[1]에 지정된 로캘에서
       LC_NUMERIC 설정을 가져온다. */

    loc = newlocale(LC_NUMERIC_MASK, argv[1], (locale_t) 0);
    if (loc == (locale_t) 0)
        errExit("newlocale");

    /* 두 번째 명령행 인자가 있으면 argv[2]에 지정된 로캘에서
       LC_TIME 설정을 가져오도록 로캘 객체를 변경한다. 이 호출이
       실패한 경우 'loc'을 유지하고 싶을 수도 있을 테니까
       newlocale() 호출 결과를 'loc'이 아닌 'nloc'에 할당한다. */

    if (argc > 2) {
        nloc = newlocale(LC_TIME_MASK, argv[2], loc);
        if (nloc == (locale_t) 0)
            errExit("newlocale");
        loc = nloc;
    }

    /* 새로 만든 로캘을 현재 스레드에 적용하기. */

    uselocale(loc);

    /* LC_NUMERIC의 효과 확인하기. */

    printf("%8.3f\n", 123456.789);

    /* LC_TIME의 효과 확인하기. */

    t = time(NULL);
    tm = localtime(&t);
    if (tm == NULL)
        errExit("time");

    s = strftime(buf, sizeof(buf), "%c", tm);
    if (s == 0)
        errExit("strftime");

    printf("%s\n", buf);

    /* 로캘 객체 해제하기. */

    uselocale(LC_GLOBAL_HANDLE);    /* 이제 'loc' 쓰는 곳 없음 */
    freelocale(loc);

    exit(EXIT_SUCCESS);
}

SEE ALSO

locale(1), duplocale(3), setlocale(3), uselocale(3), locale(5), locale(7)


2021-03-22