aboutsummaryrefslogtreecommitdiff
path: root/src/intlemu/intlemu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/intlemu/intlemu.c')
-rw-r--r--src/intlemu/intlemu.c251
1 files changed, 132 insertions, 119 deletions
diff --git a/src/intlemu/intlemu.c b/src/intlemu/intlemu.c
index a8461b7..eaa9252 100644
--- a/src/intlemu/intlemu.c
+++ b/src/intlemu/intlemu.c
@@ -15,132 +15,145 @@
15static pthread_mutex_t intlemu_lock; 15static pthread_mutex_t intlemu_lock;
16static CFMutableDictionaryRef intlemu_dict; 16static CFMutableDictionaryRef intlemu_dict;
17 17
18static void intlemu_cstring_release(CFAllocatorRef allocator, const void *value) 18static void
19intlemu_cstring_release (CFAllocatorRef allocator, const void *value)
19{ 20{
20 free((void *)value); 21 free ((void *) value);
21} 22}
22 23
23void __attribute__ ((constructor)) intlemu_init_() {
24 CFDictionaryValueCallBacks cstring_value_callbacks =
25 {
26 0, /* version */
27 NULL, /* retain callback */
28 &intlemu_cstring_release, /* release callback */
29 NULL, /* copy description */
30 NULL /* equal */
31 };
32 if (pthread_mutex_init(&intlemu_lock, NULL) != 0)
33 abort();
34
35 intlemu_dict = CFDictionaryCreateMutable(
36 kCFAllocatorDefault,
37 0,
38 &kCFCopyStringDictionaryKeyCallBacks,
39 &cstring_value_callbacks);
40 if (intlemu_dict == NULL)
41 abort();
42}
43 24
44void __attribute__ ((destructor)) intlemu_fini_() { 25void __attribute__ ((constructor))
45 if (intlemu_dict) 26intlemu_init_ ()
46 CFRelease(intlemu_dict); 27{
28 CFDictionaryValueCallBacks cstring_value_callbacks = {
29 0, /* version */
30 NULL, /* retain callback */
31 &intlemu_cstring_release, /* release callback */
32 NULL, /* copy description */
33 NULL /* equal */
34 };
35 if (pthread_mutex_init (&intlemu_lock, NULL) != 0)
36 abort ();
47 37
48 pthread_mutex_destroy(&intlemu_lock); 38 intlemu_dict = CFDictionaryCreateMutable (
39 kCFAllocatorDefault,
40 0,
41 &kCFCopyStringDictionaryKeyCallBacks,
42 &cstring_value_callbacks);
43 if (intlemu_dict == NULL)
44 abort ();
49} 45}
50 46
51char * intlemu_bgettext (CFBundleRef bundle, const char *msgid) 47
48void __attribute__ ((destructor))
49intlemu_fini_ ()
52{ 50{
53 CFStringRef key; 51 if (intlemu_dict)
54 const char *value; 52 CFRelease (intlemu_dict);
55 CFStringRef s; 53
56 CFRange r; 54 pthread_mutex_destroy (&intlemu_lock);
57 CFIndex len;
58 CFIndex clen;
59 char *buf;
60
61 if (msgid == NULL)
62 return NULL;
63 if (bundle == NULL)
64 return msgid;
65
66 key = CFStringCreateWithBytes(
67 kCFAllocatorDefault,
68 (const UInt8 *)msgid,
69 (CFIndex)strlen(msgid),
70 kCFStringEncodingUTF8,
71 false);
72
73 if (pthread_mutex_lock(&intlemu_lock) != 0)
74 abort();
75 value = (char *)CFDictionaryGetValue(intlemu_dict, key);
76 if (pthread_mutex_unlock(&intlemu_lock) != 0)
77 abort();
78 if (value != NULL) {
79 CFRelease(key);
80 return (char *)value;
81 }
82
83 /* no cached translaation, so, find one from the bundle */
84 s = CFBundleCopyLocalizedString(
85 bundle,
86 key,
87 NULL,
88 NULL);
89 if (s == key) {
90 CFRelease(key);
91 return (char *)msgid;
92 }
93 /* get the length in bytes */
94 r.location = 0;
95 r.length = CFStringGetLength(s);
96 len = 0;
97 clen = CFStringGetBytes(
98 s,
99 r,
100 kCFStringEncodingUTF8,
101 0,
102 false,
103 NULL,
104 0,
105 &len);
106 buf = NULL;
107 if (clen == r.length) {
108 buf = malloc(len + 1);
109 }
110
111 if (buf == NULL) {
112 CFRelease(s);
113 CFRelease(key);
114 return (char *)msgid;
115 }
116
117 clen = CFStringGetBytes(
118 s,
119 r,
120 kCFStringEncodingUTF8,
121 0,
122 false,
123 (UInt8 *)buf,
124 len,
125 &len);
126 buf[len] = '\0';
127 if (clen == r.length) {
128 if (pthread_mutex_lock(&intlemu_lock) != 0)
129 abort();
130 CFDictionaryAddValue(intlemu_dict, key, buf);
131 if (pthread_mutex_unlock(&intlemu_lock) != 0)
132 abort();
133 value = buf;
134 }
135 else {
136 free(buf);
137 value = msgid;
138 }
139
140 CFRelease(s);
141
142 CFRelease(key);
143
144 return (char *)value;
145} 55}
146 56
57
58char *
59intlemu_bgettext (CFBundleRef bundle, const char *msgid)
60{
61 CFStringRef key;
62 const char *value;
63 CFStringRef s;
64 CFRange r;
65 CFIndex len;
66 CFIndex clen;
67 char *buf;
68
69 if (msgid == NULL)
70 return NULL;
71 if (bundle == NULL)
72 return msgid;
73
74 key = CFStringCreateWithBytes (
75 kCFAllocatorDefault,
76 (const UInt8 *) msgid,
77 (CFIndex) strlen (msgid),
78 kCFStringEncodingUTF8,
79 false);
80
81 if (pthread_mutex_lock (&intlemu_lock) != 0)
82 abort ();
83 value = (char *) CFDictionaryGetValue (intlemu_dict, key);
84 if (pthread_mutex_unlock (&intlemu_lock) != 0)
85 abort ();
86 if (value != NULL)
87 {
88 CFRelease (key);
89 return (char *) value;
90 }
91
92 /* no cached translaation, so, find one from the bundle */
93 s = CFBundleCopyLocalizedString (
94 bundle,
95 key,
96 NULL,
97 NULL);
98 if (s == key)
99 {
100 CFRelease (key);
101 return (char *) msgid;
102 }
103 /* get the length in bytes */
104 r.location = 0;
105 r.length = CFStringGetLength (s);
106 len = 0;
107 clen = CFStringGetBytes (
108 s,
109 r,
110 kCFStringEncodingUTF8,
111 0,
112 false,
113 NULL,
114 0,
115 &len);
116 buf = NULL;
117 if (clen == r.length)
118 {
119 buf = malloc (len + 1);
120 }
121
122 if (buf == NULL)
123 {
124 CFRelease (s);
125 CFRelease (key);
126 return (char *) msgid;
127 }
128
129 clen = CFStringGetBytes (
130 s,
131 r,
132 kCFStringEncodingUTF8,
133 0,
134 false,
135 (UInt8 *) buf,
136 len,
137 &len);
138 buf[len] = '\0';
139 if (clen == r.length)
140 {
141 if (pthread_mutex_lock (&intlemu_lock) != 0)
142 abort ();
143 CFDictionaryAddValue (intlemu_dict, key, buf);
144 if (pthread_mutex_unlock (&intlemu_lock) != 0)
145 abort ();
146 value = buf;
147 }
148 else
149 {
150 free (buf);
151 value = msgid;
152 }
153
154 CFRelease (s);
155
156 CFRelease (key);
157
158 return (char *) value;
159}