Upload Tizen:Base source
[external/bash.git] / lib / sh / fnxform.c
1 /* fnxform - use iconv(3) to transform strings to and from "filename" format */
2
3 /* Copyright (C) 2009 Free Software Foundation, Inc.
4
5    This file is part of GNU Bash, the Bourne Again SHell.
6
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <config.h>
22 #if defined (HAVE_UNISTD_H)
23 #  include <unistd.h>
24 #endif
25 #include "bashansi.h"
26 #include <stdio.h>
27 #include "bashtypes.h"
28
29 #include "stdc.h"
30 #include "bashintl.h"
31 #include <xmalloc.h>
32
33 #if defined (HAVE_ICONV)
34 #  include <iconv.h>
35 #endif
36
37 #if defined (HAVE_LOCALE_CHARSET)
38 extern const char *locale_charset __P((void));
39 #else
40 extern char *get_locale_var __P((char *));
41 #endif
42
43 #if defined (HAVE_ICONV)
44 static iconv_t conv_fromfs = (iconv_t)-1;
45 static iconv_t conv_tofs = (iconv_t)-1;
46
47 #define OUTLEN_MAX 4096
48
49 static char *outbuf = 0;
50 static size_t outlen = 0;
51
52 static char *curencoding __P((void));
53 static void init_tofs __P((void));
54 static void init_fromfs __P((void));
55
56 static char *
57 curencoding ()
58 {
59   char *loc;
60 #if defined (HAVE_LOCALE_CHARSET)
61   loc = (char *)locale_charset ();
62   return loc;
63 #else
64   char *dot, *mod;
65
66   loc = get_locale_var ("LC_CTYPE");
67   if (loc == 0 || *loc == 0)
68     return "";
69   dot = strchr (loc, '.');
70   if (dot == 0)
71     return loc;
72   mod = strchr (dot, '@');
73   if (mod)
74     *mod = '\0';
75   return dot;
76 #endif
77 }  
78
79 static void
80 init_tofs ()
81 {
82   char *cur;
83
84   cur = curencoding ();
85   conv_tofs = iconv_open ("UTF-8-MAC", cur);
86 }
87
88 static void
89 init_fromfs ()
90 {
91   char *cur;
92
93   cur = curencoding ();
94   conv_fromfs = iconv_open (cur, "UTF-8-MAC");
95 }
96
97 char *
98 fnx_tofs (string, len)
99      char *string;
100      size_t len;
101 {
102 #ifdef MACOSX
103   ICONV_CONST char *inbuf;
104   char *tempbuf;
105   size_t templen;
106   
107   if (conv_tofs == (iconv_t)-1)
108     init_tofs ();
109   if (conv_tofs == (iconv_t)-1)
110     return string;
111
112   /* Free and reallocate outbuf if it's *too* big */
113   if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
114     {
115       free (outbuf);
116       outbuf = 0;
117       outlen = 0;
118     }
119
120   inbuf = string;
121   if (outbuf == 0 || outlen < len + 8)
122     {
123       outlen = len + 8;
124       outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
125     }
126   tempbuf = outbuf;
127   templen = outlen;
128
129   iconv (conv_tofs, NULL, NULL, NULL, NULL);
130
131   if (iconv (conv_tofs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
132     return string;
133
134   *tempbuf = '\0';
135   return outbuf;
136 #else
137   return string;
138 #endif
139 }
140
141 char *
142 fnx_fromfs (string, len)
143      char *string;
144      size_t len;
145 {
146 #ifdef MACOSX
147   ICONV_CONST char *inbuf;
148   char *tempbuf;
149   size_t templen;
150
151   if (conv_fromfs == (iconv_t)-1)
152     init_fromfs ();
153   if (conv_fromfs == (iconv_t)-1)
154     return string;
155
156   /* Free and reallocate outbuf if it's *too* big */
157   if (outlen >= OUTLEN_MAX && len < OUTLEN_MAX - 8)
158     {
159       free (outbuf);
160       outbuf = 0;
161       outlen = 0;
162     }
163
164   inbuf = string;
165   if (outbuf == 0 || outlen < (len + 8))
166     {
167       outlen = len + 8;
168       outbuf = outbuf ? xrealloc (outbuf, outlen + 1) : xmalloc (outlen + 1);
169     }
170   tempbuf = outbuf;
171   templen = outlen;
172
173   iconv (conv_fromfs, NULL, NULL, NULL, NULL);
174
175   if (iconv (conv_fromfs, &inbuf, &len, &tempbuf, &templen) == (size_t)-1)
176     return string;
177
178   *tempbuf = '\0';
179   return outbuf;
180 #else
181   return string;
182 #endif
183 }
184
185 #else
186 char *
187 fnx_tofs (string)
188      char *string;
189 {
190   return string;
191 }
192
193 char *
194 fnx_fromfs (string)
195      char *string;
196 {
197   return string;
198 }
199 #endif