8 src/sox.c | 33 ++++++++---
9 src/unicode_support.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++
10 src/unicode_support.h | 16 +++++
12 11 files changed, 211 insertions(+), 19 deletions(-)
14 diff --git a/src/8svx.c b/src/8svx.c
15 index 63c30e6..fd712f4 100644
19 /* Amiga 8SVX format handler: W V Neisius, February 1992 */
22 +#include "unicode_support.h"
26 @@ -161,7 +162,7 @@ static int startread(sox_format_t * ft)
27 chan1_pos = lsx_tell(ft);
29 for (i = 1; i < channels; i++) {
30 - if ((p->ch[i] = fopen(ft->filename, "rb")) == NULL)
31 + if ((p->ch[i] = fopen_utf8(ft->filename, "rb")) == NULL)
33 lsx_fail_errno(ft,errno,"Can't open channel file '%s'",
35 diff --git a/src/adpcm.c b/src/adpcm.c
36 index 2e13867..15c27c2 100644
43 +#include "unicode_support.h"
45 #include <sys/types.h>
47 diff --git a/src/effects_i.c b/src/effects_i.c
48 index 7d72166..65d6a0b 100644
55 +#include "unicode_support.h"
59 @@ -355,7 +356,7 @@ FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
60 effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
63 - else if (!(file = fopen(filename, "r"))) {
64 + else if (!(file = fopen_utf8(filename, "r"))) {
65 lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
68 diff --git a/src/formats.c b/src/formats.c
69 index cac686c..1baa213 100644
76 +#include "unicode_support.h"
80 @@ -396,7 +397,7 @@ static FILE * xfopen(char const * identifier, char const * mode, lsx_io_type * i
84 - return fopen(identifier, mode);
85 + return fopen_utf8(identifier, mode);
88 /* Hack to rewind pipes (a small amount).
89 @@ -847,8 +848,8 @@ static sox_format_t * open_write(
94 - if (!stat(path, &st) && (st.st_mode & S_IFMT) == S_IFREG &&
96 + if (!stat_utf8(path, &st) && (st.st_mode & S_IFMT) == S_IFREG &&
97 (overwrite_permitted && !overwrite_permitted(path))) {
98 lsx_fail("permission to overwrite `%s' denied", path);
100 @@ -858,7 +859,7 @@ static sox_format_t * open_write(
101 buffer? fmemopen(buffer, buffer_size, "w+b") :
102 buffer_ptr? open_memstream(buffer_ptr, buffer_size_ptr) :
104 - fopen(path, "w+b");
105 + fopen_utf8(path, "w+b");
106 if (ft->fp == NULL) {
107 lsx_fail("can't open output file `%s': %s", path, strerror(errno));
109 diff --git a/src/libsox.c b/src/libsox.c
110 index 75354e4..a766aa9 100644
117 +#include "unicode_support.h"
121 const char *sox_version(void)
122 diff --git a/src/libsox_i.c b/src/libsox_i.c
123 index 8a7074a..b498cc0 100644
130 +#include "unicode_support.h"
136 static int check_dir(char * buf, size_t buflen, char const * name)
139 - if (!name || stat(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR)
141 + if (!name || stat_utf8(name, &st) || (st.st_mode & S_IFMT) != S_IFDIR)
145 @@ -102,7 +103,7 @@ FILE * lsx_tmpfile(void)
146 fildes = mkstemp(name);
148 lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (unlinked)", name);
152 lsx_debug(FAKE_MKSTEMP "mkstemp, name=%s (O_TEMPORARY)", name);
154 diff --git a/src/noiseprof.c b/src/noiseprof.c
155 index 603402f..d46c280 100644
156 --- a/src/noiseprof.c
157 +++ b/src/noiseprof.c
161 #include "noisered.h"
162 +#include "unicode_support.h"
166 @@ -75,7 +76,7 @@ static int sox_noiseprof_start(sox_effect_t * effp)
167 effp->global_info->global_info->stdout_in_use_by = effp->handler.name;
168 data->output_file = stdout;
170 - else if ((data->output_file = fopen(data->output_filename, "w")) == NULL) {
171 + else if ((data->output_file = fopen_utf8(data->output_filename, "w")) == NULL) {
172 lsx_fail("Couldn't open profile file %s: %s", data->output_filename, strerror(errno));
175 diff --git a/src/sox.c b/src/sox.c
176 index 665149b..da43424 100644
180 #include "soxconfig.h"
183 +#include "unicode_support.h"
187 @@ -236,12 +237,12 @@ static void cleanup(void)
190 if (!success && ofile->ft->fp) { /* If we failed part way through */
191 - struct stat st; /* writing a normal file, remove it. */
192 - if (!stat(ofile->ft->filename, &st) &&
193 + struct _stat st; /* writing a normal file, remove it. */
194 + if (!stat_utf8(ofile->ft->filename, &st) &&
195 (st.st_mode & S_IFMT) == S_IFREG)
196 - unlink(ofile->ft->filename);
197 + unlink_utf8(ofile->ft->filename);
199 - sox_close(ofile->ft); /* Assume we can unlink a file before closing it. */
200 + sox_close(ofile->ft); /* Assume we can unlink_utf8 a file before closing it. */
202 free(ofile->filename);
204 @@ -293,8 +294,8 @@ static char const * str_time(double seconds)
206 static char const * size_and_bitrate(sox_format_t * ft, char const * * text)
208 - struct stat st; /* ft->fp may validly be NULL, so stat not fstat */
209 - if (stat(ft->filename, &st) || (st.st_mode & S_IFMT) != S_IFREG)
210 + struct _stat st; /* ft->fp may validly be NULL, so stat not fstat */
211 + if (stat_utf8(ft->filename, &st) || (st.st_mode & S_IFMT) != S_IFREG)
213 if (ft->signal.length && ft->signal.channels && ft->signal.rate && text) {
214 double secs = ft->signal.length / ft->signal.channels / ft->signal.rate;
215 @@ -906,7 +907,7 @@ static char * * strtoargv(char * s, int * argc)
217 static void read_user_effects(char const *filename)
219 - FILE *file = fopen(filename, "rt");
220 + FILE *file = fopen_utf8(filename, "rt");
221 const size_t buffer_size_step = 1024;
222 size_t buffer_size = buffer_size_step;
223 char *s = lsx_malloc(buffer_size); /* buffer for one input line */
224 @@ -1269,6 +1270,7 @@ static void display_status(sox_bool all_done)
225 lsx_sigfigs3((double)output_samples),
226 vu(0), vu(1), headroom(), lsx_sigfigs3((double)total_clips()));
232 @@ -2123,7 +2125,7 @@ static void read_comment_file(sox_comments_t * comments, char const * const file
234 size_t text_length = 100;
235 char * text = lsx_malloc(text_length + 1);
236 - FILE * file = fopen(filename, "rt");
237 + FILE * file = fopen_utf8(filename, "rt");
240 lsx_fail("Cannot open comment file `%s'", filename);
241 @@ -2830,7 +2832,7 @@ static sox_bool cmp_comment_text(char const * c1, char const * c2)
242 return c1 && c2 && !strcasecmp(c1, c2);
245 -int main(int argc, char **argv)
246 +static int sox_main(int argc, char **argv)
250 @@ -3032,3 +3034,16 @@ int main(int argc, char **argv)
255 +int main( int argc, char **argv )
261 + init_commandline_arguments_utf8(&sox_argc, &sox_argv);
262 + exit_code = sox_main(sox_argc, sox_argv);
263 + free_commandline_arguments_utf8(&sox_argc, &sox_argv);
267 diff --git a/src/unicode_support.c b/src/unicode_support.c
269 index 0000000..e0cbbc9
271 +++ b/src/unicode_support.c
273 +#include "unicode_support.h"
275 +#include <windows.h>
278 +char *utf16_to_utf8(const wchar_t *input)
281 + int BuffSize = 0, Result = 0;
283 + BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
284 + Buffer = (char*) malloc(sizeof(char) * BuffSize);
287 + Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL);
290 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
293 +char *utf16_to_ansi(const wchar_t *input)
296 + int BuffSize = 0, Result = 0;
298 + BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL);
299 + Buffer = (char*) malloc(sizeof(char) * BuffSize);
302 + Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL);
305 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
308 +wchar_t *utf8_to_utf16(const char *input)
311 + int BuffSize = 0, Result = 0;
313 + BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
314 + Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize);
317 + Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize);
320 + return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
323 +void init_commandline_arguments_utf8(int *argc, char ***argv)
328 + szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
330 + if(NULL == szArglist)
332 + fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n");
336 + *argv = (char**) malloc(sizeof(char*) * nArgs);
341 + fprintf(stderr, "\nFATAL: Malloc failed\n\n");
345 + for(i = 0; i < nArgs; i++)
347 + (*argv)[i] = utf16_to_utf8(szArglist[i]);
348 + if(NULL == (*argv)[i])
350 + fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n");
355 + LocalFree(szArglist);
358 +void free_commandline_arguments_utf8(int *argc, char ***argv)
364 + for(i = 0; i < *argc; i++)
366 + if((*argv)[i] != NULL)
377 +FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8)
380 + wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8);
381 + wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8);
383 + if(filename_utf16 && mode_utf16)
385 + ret = _wfopen(filename_utf16, mode_utf16);
388 + if(filename_utf16) free(filename_utf16);
389 + if(mode_utf16) free(mode_utf16);
394 +int stat_utf8(const char *path_utf8, struct _stat *buf)
398 + wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
401 + ret = _wstat(path_utf16, buf);
408 +int unlink_utf8(const char *path_utf8)
412 + wchar_t *path_utf16 = utf8_to_utf16(path_utf8);
415 + ret = _wunlink(path_utf16);
421 diff --git a/src/unicode_support.h b/src/unicode_support.h
423 index 0000000..6775e00
425 +++ b/src/unicode_support.h
427 +#ifndef UNICODE_SUPPORT_H_INCLUDED
428 +#define UNICODE_SUPPORT_H_INCLUDED
431 +#include <sys/stat.h>
433 +char *utf16_to_utf8(const wchar_t *input);
434 +char *utf16_to_ansi(const wchar_t *input);
435 +wchar_t *utf8_to_utf16(const char *input);
436 +void init_commandline_arguments_utf8(int *argc, char ***argv);
437 +void free_commandline_arguments_utf8(int *argc, char ***argv);
438 +FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8);
439 +int stat_utf8(const char *path_utf8, struct _stat *buf);
440 +int unlink_utf8(const char *path_utf8);
443 \ No newline at end of file
444 diff --git a/src/util.h b/src/util.h
445 index f10b676..4a835f0 100644
452 +#define inline __inline
453 +#define snprintf _snprintf
457 #define O_BINARY _O_BINARY
458 #define O_CREAT _O_CREAT
460 #define off_t __int64
461 #define HAVE_FSEEKO 1
465 #elif defined(__MINGW32__)