ObjFW  Check-in [3d5b88d42e]

Overview
Comment:Use LC_MESSAGES locale for messages
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3d5b88d42eb08747ed4c54bd615d6922ecbc8fa8beb792089679b48434fffbae
User & Date: js on 2017-04-09 20:50:59
Other Links: manifest | tags
Context
2017-04-13
12:57
OFSandbox: Don't waste memory on bools check-in: 0fc70a4510 user: js tags: trunk
2017-04-09
20:50
Use LC_MESSAGES locale for messages check-in: 3d5b88d42e user: js tags: trunk
18:26
platform.h: Add OF_FREEBSD and OF_OPENBSD check-in: cd47d59676 user: js tags: trunk
Changes

Modified src/OFApplication.m from [4ef7cfc06b] to [ec8cf68d84].

111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
	id <OFApplicationDelegate> delegate;
#ifdef OF_WINDOWS
	wchar_t **wargv, **wenvp;
	int wargc, si = 0;
#endif

	[[OFLocalization alloc] initWithLocale: setlocale(LC_ALL, "")];

	if ([cls isSubclassOfClass: [OFApplication class]]) {
		fprintf(stderr, "FATAL ERROR:\n  Class %s is a subclass of "
		    "class OFApplication, but class\n  %s was specified as "
		    "application delegate!\n  Most likely, you wanted to "
		    "subclass OFObject instead or specified\n  the wrong class "
		    "with OF_APPLICATION_DELEGATE().\n",







|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
{
	id <OFApplicationDelegate> delegate;
#ifdef OF_WINDOWS
	wchar_t **wargv, **wenvp;
	int wargc, si = 0;
#endif

	[[OFLocalization alloc] init];

	if ([cls isSubclassOfClass: [OFApplication class]]) {
		fprintf(stderr, "FATAL ERROR:\n  Class %s is a subclass of "
		    "class OFApplication, but class\n  %s was specified as "
		    "application delegate!\n  Most likely, you wanted to "
		    "subclass OFObject instead or specified\n  the wrong class "
		    "with OF_APPLICATION_DELEGATE().\n",

Modified src/OFLocalization.h from [9465b8ba1c] to [93f8b830ad].

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
	of_string_encoding_t _encoding;
	OFString *_decimalPoint;
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString*, id)*)
	    *_localizedStrings;
}

/**
 * The language of the locale.
 *
 * If the language is unknown, it is `nil`.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy) OFString *language;

/*!
 * The territory of the locale.
 *
 * If the territory is unknown, it is `nil`.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy) OFString *territory;

/*!
 * The native 8-bit string encoding for the locale.
 *
 * This is useful to encode strings correctly for passing them to operating
 * system calls.
 *
 * If the native 8-bit encoding is unknown, UTF-8 is assumed.
 */
@property (readonly) of_string_encoding_t encoding;

/*!
 * The decimal point of the system's locale.
 */
@property (readonly, copy) OFString *decimalPoint;

/*!
 * @brief Returns the shared OFLocalization instance.
 *
 * @warning If you don't use @ref OFApplication, this might be `nil`! In this
 *	    case, you need to manually allocate an instance and call
 *	    @ref initWithLocale: once, passing the locale used (as would be
 *	    returned by `setlocale()`).
 *
 * @return The shared OFLocalization instance
 */
+ (instancetype)sharedLocalization;

/**
 * @brief Returns the language of the locale.







|






|






|


















|
<







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
	of_string_encoding_t _encoding;
	OFString *_decimalPoint;
	OFMutableArray OF_GENERIC(OFDictionary OF_GENERIC(OFString*, id)*)
	    *_localizedStrings;
}

/**
 * The language of the locale for messages.
 *
 * If the language is unknown, it is `nil`.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy) OFString *language;

/*!
 * The territory of the locale for messages.
 *
 * If the territory is unknown, it is `nil`.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy) OFString *territory;

/*!
 * The native 8-bit string encoding of the locale for messages.
 *
 * This is useful to encode strings correctly for passing them to operating
 * system calls.
 *
 * If the native 8-bit encoding is unknown, UTF-8 is assumed.
 */
@property (readonly) of_string_encoding_t encoding;

/*!
 * The decimal point of the system's locale.
 */
@property (readonly, copy) OFString *decimalPoint;

/*!
 * @brief Returns the shared OFLocalization instance.
 *
 * @warning If you don't use @ref OFApplication, this might be `nil`! In this
 *	    case, you need to manually allocate an instance and call
 *	    @ref init once.

 *
 * @return The shared OFLocalization instance
 */
+ (instancetype)sharedLocalization;

/**
 * @brief Returns the language of the locale.
129
130
131
132
133
134
135


136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
 * @param path The path to the directory to scan for language files
 */
+ (void)addLanguageDirectory: (OFString*)path;
#endif

/*!
 * @brief Initializes the OFLocalization singleton with the specified locale.


 *
 * @warning You should never call this yourself, except if you do not use
 *	    @ref OFApplication. In this case, you need to allocate exactly one
 *	    instance of OFLocalization, which will be come the singleton, and
 *	    call this method.
 *
 * @param locale The locale used, as returned from `setlocale()`
 */
- initWithLocale: (char*)locale;

#ifdef OF_HAVE_FILES
/*!
 * @brief Adds a directory to scan for language files.
 *
 * @param path The path to the directory to scan for language files
 */







>
>





<
<

|







128
129
130
131
132
133
134
135
136
137
138
139
140
141


142
143
144
145
146
147
148
149
150
 * @param path The path to the directory to scan for language files
 */
+ (void)addLanguageDirectory: (OFString*)path;
#endif

/*!
 * @brief Initializes the OFLocalization singleton with the specified locale.
 *
 * @warning This sets the locale via `setlocale()`!
 *
 * @warning You should never call this yourself, except if you do not use
 *	    @ref OFApplication. In this case, you need to allocate exactly one
 *	    instance of OFLocalization, which will be come the singleton, and
 *	    call this method.


 */
- init;

#ifdef OF_HAVE_FILES
/*!
 * @brief Adds a directory to scan for language files.
 *
 * @param path The path to the directory to scan for language files
 */

Modified src/OFLocalization.m from [a996c854ff] to [306b376984].

23
24
25
26
27
28
29













































30
31
32
33
34
35
36
#import "OFArray.h"
#import "OFDictionary.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"

static OFLocalization *sharedLocalization = nil;














































@implementation OFLocalization
@synthesize language = _language, territory = _territory, encoding = _encoding;
@synthesize decimalPoint = _decimalPoint;

+ (instancetype)sharedLocalization
{







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#import "OFArray.h"
#import "OFDictionary.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"

static OFLocalization *sharedLocalization = nil;

static void
parseLocale(char *locale, of_string_encoding_t *encoding,
    OFString **language, OFString **territory)
{
	if ((locale = of_strdup(locale)) == NULL)
		return;

	@try {
		const of_string_encoding_t enc = OF_STRING_ENCODING_ASCII;
		char *tmp;

		/* We don't care for extras behind the @ */
		if ((tmp = strrchr(locale, '@')) != NULL)
			*tmp = '\0';

		/* Encoding */
		if ((tmp = strrchr(locale, '.')) != NULL) {
			*tmp++ = '\0';

			@try {
				if (encoding != NULL)
					*encoding = of_string_parse_encoding(
					    [OFString stringWithCString: tmp
							       encoding: enc]);
			} @catch (OFInvalidEncodingException *e) {
			}
		}

		/* Territory */
		if ((tmp = strrchr(locale, '_')) != NULL) {
			*tmp++ = '\0';

			if (territory != NULL)
				*territory = [OFString stringWithCString: tmp
								encoding: enc];
		}

		if (language != NULL)
			*language = [OFString stringWithCString: locale
						       encoding: enc];
	} @finally {
		free(locale);
	}
}

@implementation OFLocalization
@synthesize language = _language, territory = _territory, encoding = _encoding;
@synthesize decimalPoint = _decimalPoint;

+ (instancetype)sharedLocalization
{
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


103

104
105
106
107
108





109


110
111
112
113

114

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifdef OF_HAVE_FILES
+ (void)addLanguageDirectory: (OFString*)path
{
	[sharedLocalization addLanguageDirectory: path];
}
#endif

- initWithLocale: (char*)locale
{
	self = [super init];

	@try {
		_localizedStrings = [[OFMutableArray alloc] init];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	if (locale == NULL) {
		_encoding = OF_STRING_ENCODING_UTF_8;
		_decimalPoint = @".";

		sharedLocalization = self;

		return self;
	}

	locale = of_strdup(locale);

	@try {
		char *tmp;

		/* We don't care for extras behind the @ */
		if ((tmp = strrchr(locale, '@')) != NULL)
			*tmp = '\0';

		/* Encoding */
		if ((tmp = strrchr(locale, '.')) != NULL) {
			*tmp++ = '\0';

			@try {
				const of_string_encoding_t ascii =
				    OF_STRING_ENCODING_ASCII;




				_encoding = of_string_parse_encoding([OFString
				    stringWithCString: tmp
					     encoding: ascii]);
			} @catch (OFInvalidEncodingException *e) {
			}





		}



		/* Territory */
		if ((tmp = strrchr(locale, '_')) != NULL) {
			*tmp++ = '\0';



			_territory = [[OFString alloc]
			    initWithCString: tmp
				   encoding: OF_STRING_ENCODING_ASCII];
		}

		_language = [[OFString alloc]
		    initWithCString: locale
			   encoding: OF_STRING_ENCODING_ASCII];

		_decimalPoint = [[OFString alloc]
		    initWithCString: localeconv()->decimal_point
			   encoding: _encoding];
	} @catch (id e) {
		[self release];
		@throw e;
	} @finally {
		free(locale);
	}

	sharedLocalization = self;

	return self;
}








|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|

<
<
<
<
<
<
<
<
<
<
|
>
>

>
|
|
|
<
|
>
>
>
>
>
|
>
>

<
|
<
>

>
|
<
<
|
|
<
<
<
|
<
<
<



<
<







105
106
107
108
109
110
111
112
113
114
115
116


















117
118










119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136

137

138
139
140
141


142
143



144



145
146
147


148
149
150
151
152
153
154
#ifdef OF_HAVE_FILES
+ (void)addLanguageDirectory: (OFString*)path
{
	[sharedLocalization addLanguageDirectory: path];
}
#endif

- init
{
	self = [super init];

	@try {


















		char *locale, *messagesLocale = NULL;











		_encoding = OF_STRING_ENCODING_UTF_8;
		_decimalPoint = @".";
		_localizedStrings = [[OFMutableArray alloc] init];

		if ((locale = setlocale(LC_ALL, "")) != NULL)
			_decimalPoint = [[OFString alloc]
			    initWithCString: localeconv()->decimal_point
				   encoding: _encoding];


#ifdef LC_MESSAGES
		messagesLocale = setlocale(LC_MESSAGES, "");
#endif
		if (messagesLocale == NULL)
			messagesLocale = locale;

		if (messagesLocale != NULL) {
			void *pool = objc_autoreleasePoolPush();


			parseLocale(messagesLocale, &_encoding,

			    &_language, &_language);

			[_language retain];
			[_territory retain];



			objc_autoreleasePoolPop(pool);



		}



	} @catch (id e) {
		[self release];
		@throw e;


	}

	sharedLocalization = self;

	return self;
}