~ubuntu-branches/ubuntu/lucid/mc/lucid

« back to all changes in this revision

Viewing changes to src/ecs.c

  • Committer: Bazaar Package Importer
  • Author(s): Patrick Winnertz
  • Date: 2008-09-16 10:38:59 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080916103859-2uwn8w61xk5mbxxq
Tags: 2:4.6.2~git20080311-4
Corrected fix for odt2txt issue (Closes: #492019) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Basic support for extended character sets.
 
3
 
 
4
   Written by:
 
5
   Roland Illig <roland.illig@gmx.de>, 2005.
 
6
 
 
7
   This file is part of the Midnight Commander.
 
8
 
 
9
   The Midnight Commander is free software; you can redistribute it
 
10
   and/or modify it under the terms of the GNU General Public License as
 
11
   published by the Free Software Foundation; either version 2 of the
 
12
   License, or (at your option) any later version.
 
13
 
 
14
   The Midnight Commander is distributed in the hope that it will be
 
15
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 
16
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
   General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program; if not, write to the Free Software
 
21
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
22
   MA 02110-1301, USA.
 
23
 */
 
24
 
 
25
#include <config.h>
 
26
 
 
27
#include <assert.h>
 
28
#include <ctype.h>
 
29
 
 
30
#include "global.h"
 
31
#include "ecs.h"
 
32
 
 
33
/*
 
34
 * String type conversion
 
35
 */
 
36
 
 
37
extern gboolean ecs_mbstr_to_str(ecs_char **ret_str, const char *s)
 
38
{
 
39
#ifdef EXTCHARSET_ENABLED
 
40
        size_t maxlen, len;
 
41
        ecs_char *str;
 
42
 
 
43
        maxlen = strlen(s);
 
44
 
 
45
        str = g_new(ecs_char, maxlen + 1);
 
46
        len = mbstowcs(str, s, maxlen + 1);
 
47
        if (len == (size_t) -1) {
 
48
                g_free(str);
 
49
                return FALSE;
 
50
        }
 
51
 
 
52
        assert(len <= maxlen);
 
53
        *ret_str = g_renew(ecs_char, str, len + 1);
 
54
        return TRUE;
 
55
#else
 
56
        *ret_str = g_strdup(s);
 
57
        return TRUE;
 
58
#endif
 
59
}
 
60
 
 
61
extern gboolean ecs_str_to_mbstr(char **ret_str, const ecs_char *s)
 
62
{
 
63
#ifdef EXTCHARSET_ENABLED
 
64
        size_t maxlen, len;
 
65
        char *str;
 
66
 
 
67
        maxlen = ecs_strlen(s) * MB_CUR_MAX;
 
68
 
 
69
        str = g_new(char, maxlen + 1);
 
70
        len = wcstombs(str, s, maxlen + 1);
 
71
        if (len == (size_t) -1) {
 
72
                g_free(str);
 
73
                return FALSE;
 
74
        }
 
75
 
 
76
        assert(len <= maxlen);
 
77
        *ret_str = g_renew(char, str, len + 1);
 
78
        return TRUE;
 
79
#else
 
80
        *ret_str = g_strdup(s);
 
81
        return TRUE;
 
82
#endif
 
83
}
 
84
 
 
85
/*
 
86
 * Character classification
 
87
 */
 
88
 
 
89
#ifdef EXTCHARSET_ENABLED
 
90
# ifdef HAVE_WCTYPE_H
 
91
#  include <wctype.h>
 
92
#  define ECS_CTYPE(wf, cf, c) \
 
93
        (wf(c))
 
94
# else
 
95
#  define ECS_CTYPE(wf, cf, c) \
 
96
        (((unsigned char) c != c) ? FALSE : (cf(c)))
 
97
# endif
 
98
#else
 
99
# define ECS_CTYPE(wf, cf, c) \
 
100
        (cf(c))
 
101
#endif
 
102
 
 
103
extern gboolean ecs_isalnum(ecs_char c)
 
104
{
 
105
        return ECS_CTYPE(iswalnum, isalnum, c);
 
106
}
 
107
 
 
108
extern gboolean ecs_isalpha(ecs_char c)
 
109
{
 
110
        return ECS_CTYPE(iswalpha, isalpha, c);
 
111
}
 
112
 
 
113
extern gboolean ecs_iscntrl(ecs_char c)
 
114
{
 
115
        return ECS_CTYPE(iswcntrl, iscntrl, c);
 
116
}
 
117
 
 
118
extern gboolean ecs_isdigit(ecs_char c)
 
119
{
 
120
        return ECS_CTYPE(iswdigit, isdigit, c);
 
121
}
 
122
 
 
123
extern gboolean ecs_isgraph(ecs_char c)
 
124
{
 
125
        return ECS_CTYPE(iswgraph, isgraph, c);
 
126
}
 
127
 
 
128
extern gboolean ecs_islower(ecs_char c)
 
129
{
 
130
        return ECS_CTYPE(iswlower, islower, c);
 
131
}
 
132
 
 
133
extern gboolean ecs_isprint(ecs_char c)
 
134
{
 
135
        return ECS_CTYPE(iswprint, isprint, c);
 
136
}
 
137
 
 
138
extern gboolean ecs_ispunct(ecs_char c)
 
139
{
 
140
        return ECS_CTYPE(iswpunct, ispunct, c);
 
141
}
 
142
 
 
143
extern gboolean ecs_isspace(ecs_char c)
 
144
{
 
145
        return ECS_CTYPE(iswspace, isspace, c);
 
146
}
 
147
 
 
148
extern gboolean ecs_isupper(ecs_char c)
 
149
{
 
150
        return ECS_CTYPE(iswupper, isupper, c);
 
151
}
 
152
 
 
153
extern gboolean ecs_isxdigit(ecs_char c)
 
154
{
 
155
        return ECS_CTYPE(iswxdigit, isxdigit, c);
 
156
}
 
157
 
 
158
#undef ECS_CTYPE
 
159
 
 
160
/*
 
161
 * ISO C90 <string.h> functions
 
162
 */
 
163
 
 
164
/* left out: ecs_strcpy */
 
165
/* left out: ecs_strncpy */
 
166
/* left out: ecs_strcat */
 
167
/* left out: ecs_strncat */
 
168
 
 
169
int
 
170
ecs_strcmp(const ecs_char *a, const ecs_char *b)
 
171
{
 
172
        size_t i;
 
173
        unsigned long ca, cb;
 
174
 
 
175
        for (i = 0; a[i] == b[i]; i++) {
 
176
                if (a[i] == ECS_CHAR('\0'))
 
177
                        return 0;
 
178
        }
 
179
        ca = (unsigned long) a[i];
 
180
        cb = (unsigned long) b[i];
 
181
        return (ca < cb) ? -1 : (ca > cb) ? 1 : 0;
 
182
}
 
183
 
 
184
/* left out: ecs_strcoll */
 
185
/* left out: ecs_strncmp */
 
186
/* left out: ecs_strxfrm */
 
187
 
 
188
ecs_char *
 
189
ecs_strchr(const ecs_char *s, ecs_char c)
 
190
{
 
191
        size_t i;
 
192
 
 
193
        for (i = 0; s[i] != c; i++) {
 
194
                if (s[i] == ECS_CHAR('\0'))
 
195
                        return NULL;
 
196
        }
 
197
        return (ecs_char *) s + i;
 
198
}
 
199
 
 
200
size_t
 
201
ecs_strcspn(const ecs_char *haystack, const ecs_char *needles)
 
202
{
 
203
        size_t i, j;
 
204
 
 
205
        for (i = 0; haystack[i] != ECS_CHAR('\0'); i++) {
 
206
                for (j = 0; needles[j] != ECS_CHAR('\0'); j++) {
 
207
                        if (haystack[i] == needles[j])
 
208
                                return i;
 
209
                }
 
210
        }
 
211
        return i;
 
212
}
 
213
 
 
214
/* left out: ecs_strpbrk */
 
215
 
 
216
ecs_char *
 
217
ecs_strrchr(const ecs_char *s, ecs_char c)
 
218
{
 
219
        ecs_char *pos;
 
220
        size_t i;
 
221
 
 
222
        for (i = 0, pos = NULL;; i++) {
 
223
                if (s[i] == c)
 
224
                        pos = (ecs_char *) s + i;
 
225
                if (s[i] == ECS_CHAR('\0'))
 
226
                        return pos;
 
227
        }
 
228
}
 
229
 
 
230
size_t
 
231
ecs_strspn(const ecs_char *s, const ecs_char *chars)
 
232
{
 
233
        size_t i;
 
234
 
 
235
        for (i = 0; s[i] != ECS_CHAR('\0'); i++) {
 
236
                if (ecs_strchr(chars, s[i]) == NULL)
 
237
                        break;
 
238
        }
 
239
        return i;
 
240
}
 
241
 
 
242
ecs_char *
 
243
ecs_strstr(const ecs_char *s, const ecs_char *sub)
 
244
{
 
245
        size_t i, j;
 
246
 
 
247
        for (i = 0; s[i] != ECS_CHAR('\0'); i++) {
 
248
                for (j = 0; sub[j] != ECS_CHAR('\0'); j++) {
 
249
                        if (s[i + j] != sub[j])
 
250
                                goto next_i;
 
251
                }
 
252
                return (ecs_char *) s + i;
 
253
        next_i:
 
254
                continue;
 
255
        }
 
256
        return NULL;
 
257
}
 
258
 
 
259
/* left out: ecs_strtok */
 
260
 
 
261
size_t
 
262
ecs_strlen(const ecs_char *s)
 
263
{
 
264
        size_t i;
 
265
 
 
266
        for (i = 0; s[i] != ECS_CHAR('\0'); i++)
 
267
                continue;
 
268
        return i;
 
269
}
 
270
 
 
271
/*
 
272
 * Other functions
 
273
 */
 
274
 
 
275
ecs_char *ecs_xstrdup(const ecs_char *s)
 
276
{
 
277
        ecs_char *retval;
 
278
        size_t len;
 
279
 
 
280
        len = ecs_strlen(s);
 
281
        retval = g_new(ecs_char, len + 1);
 
282
        memcpy(retval, s, (len + 1) * sizeof(ecs_char));
 
283
        return retval;
 
284
}
 
285
 
 
286
size_t
 
287
ecs_strlcpy(ecs_char *dst, const ecs_char *src, size_t dstsize)
 
288
{
 
289
        size_t n = 0;           /* number of copied characters */
 
290
 
 
291
        if (dstsize >= 1) {
 
292
                while (n < dstsize - 1 && *src != ECS_CHAR('\0')) {
 
293
                        *dst++ = *src++;
 
294
                        n++;
 
295
                }
 
296
                *dst = ECS_CHAR('\0');
 
297
        }
 
298
 
 
299
        while (*src != ECS_CHAR('\0')) {
 
300
                n++;
 
301
                src++;
 
302
        }
 
303
 
 
304
        return n;
 
305
}
 
306
 
 
307
size_t
 
308
ecs_strlcat(ecs_char *dst, const ecs_char *src, size_t dstsize)
 
309
{
 
310
        size_t di = 0;
 
311
 
 
312
        while (di < dstsize && dst[di] != ECS_CHAR('\0'))
 
313
                di++;
 
314
        return di + ecs_strlcpy(dst + di, src, dstsize - di);
 
315
}
 
316
 
 
317
gboolean
 
318
ecs_strbox(const ecs_char *s, size_t *ret_width, size_t *ret_height)
 
319
{
 
320
        size_t nlines = 0, ncolumns = 0, colindex = 0, i;
 
321
 
 
322
        for (i = 0; s[i] != ECS_CHAR('\0'); i++) {
 
323
                if (s[i] == ECS_CHAR('\n')) {
 
324
                        nlines++;
 
325
                        colindex = 0;
 
326
                } else {
 
327
                        if (!ecs_isprint(s[i]))
 
328
                                return FALSE;
 
329
 
 
330
                        /* FIXME: This code assumes that each printable
 
331
                         * character occupies one cell on the screen. */
 
332
                        colindex++;
 
333
                        if (colindex > ncolumns)
 
334
                                ncolumns = colindex;
 
335
                }
 
336
        }
 
337
        *ret_width  = ncolumns;
 
338
        *ret_height = nlines;
 
339
        return TRUE;
 
340
}