~noskcaj/ubuntu/trusty/libextractor/merge

« back to all changes in this revision

Viewing changes to src/intlemu/intlemu.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-17 20:27:32 UTC
  • mfrom: (1.10.4 upstream) (5.2.5 sid)
  • Revision ID: james.westby@ubuntu.com-20091117202732-ipm2h3gks5bdw2vx
Tags: 0.5.23+dfsg-3
* Building against libltdl7.
* Updating to standards version 3.8.3.
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Simplifying autotools handling in rules.
* Updating README.source.
* Moving maintainer homepage field from control to copyright.
* Dropping la files.
* Simplyfing debhelper install files.
* Bumping versioned build-depends on debhelper.
* Adding depends to dpkg install info.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  libintlemu - A Core Foundation libintl emulator
 
3
 *  Copyright (C) 2008  Heikki Lindholm <holin@iki.fi>
 
4
 *
 
5
 *  This program is free software; you can redistribute it and/or modify
 
6
 *  it under the terms of the GNU General Public License as published by
 
7
 *  the Free Software Foundation; either version 2 of the License, or
 
8
 *  (at your option) any later version.
 
9
 */
 
10
 
 
11
#include <CoreFoundation/CoreFoundation.h>
 
12
#include <stdlib.h>
 
13
#include <pthread.h>
 
14
 
 
15
static pthread_mutex_t intlemu_lock;
 
16
static CFMutableDictionaryRef intlemu_dict;
 
17
 
 
18
static void intlemu_cstring_release(CFAllocatorRef allocator, const void *value)
 
19
{
 
20
        free((void *)value);
 
21
}
 
22
 
 
23
void __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
 
 
44
void __attribute__ ((destructor)) intlemu_fini_() {
 
45
        if (intlemu_dict)
 
46
                CFRelease(intlemu_dict);
 
47
 
 
48
        pthread_mutex_destroy(&intlemu_lock);
 
49
}
 
50
 
 
51
char * intlemu_bgettext (CFBundleRef bundle, const char *msgid)
 
52
{
 
53
        CFStringRef key;
 
54
        const char *value;
 
55
        CFStringRef s;
 
56
        CFRange r;
 
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
}
 
146