Add Russian translation provided by Валерий Крувялис <valkru@mail.ru>
[xiph-mirror.git] / vorbis-tools / oggenc / platform.c
blob6d9f4efc2ac773036162b5f58a9ac61c9bb1d5f9
1 /* OggEnc
2 **
3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
5 **
6 ** Copyright 2000, Michael Smith <msmith@xiph.org>
7 **
8 ** Portions from Vorbize, (c) Kenneth Arnold <kcarnold-xiph@arnoldnet.net>
9 ** and libvorbis examples, (c) Monty <monty@xiph.org>
10 **/
12 /* Platform support routines - win32, OS/2, unix */
14 #ifdef HAVE_CONFIG_H
15 #include <config.h>
16 #endif
18 #include "platform.h"
19 #include "encode.h"
20 #include "i18n.h"
21 #include <stdlib.h>
22 #include <ctype.h>
23 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
24 #include <getopt.h>
25 #include <fcntl.h>
26 #include <io.h>
27 #include <time.h>
28 #endif
30 #ifdef _WIN32
31 #include <windows.h>
32 #endif
34 #if defined(_WIN32) && defined(_MSC_VER)
36 void setbinmode(FILE *f)
38 _setmode( _fileno(f), _O_BINARY );
40 #endif /* win32 */
42 #ifdef __EMX__
43 void setbinmode(FILE *f)
45 _fsetmode( f, "b");
47 #endif
49 #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)
50 void setbinmode(FILE *f)
52 setmode(fileno(f), O_BINARY);
54 #endif
57 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
58 void *timer_start(void)
60 time_t *start = malloc(sizeof(time_t));
61 time(start);
62 return (void *)start;
65 double timer_time(void *timer)
67 time_t now = time(NULL);
68 time_t start = *((time_t *)timer);
70 if(now-start)
71 return (double)(now-start);
72 else
73 return 1; /* To avoid division by zero later, for very short inputs */
77 void timer_clear(void *timer)
79 free((time_t *)timer);
82 #else /* unix. Or at least win32 */
84 #include <sys/time.h>
85 #include <unistd.h>
87 void *timer_start(void)
89 struct timeval *start = malloc(sizeof(struct timeval));
90 gettimeofday(start, NULL);
91 return (void *)start;
94 double timer_time(void *timer)
96 struct timeval now;
97 struct timeval start = *((struct timeval *)timer);
99 gettimeofday(&now, NULL);
101 return (double)now.tv_sec - (double)start.tv_sec +
102 ((double)now.tv_usec - (double)start.tv_usec)/1000000.0;
105 void timer_clear(void *timer)
107 free((time_t *)timer);
110 #endif
112 #include <errno.h>
113 #include <string.h>
114 #include <sys/types.h>
115 #include <sys/stat.h>
117 #ifdef _WIN32
119 #include <direct.h>
121 #define PATH_SEPS "/\\"
122 #define mkdir(x,y) _mkdir((x))
124 /* MSVC does this, borland doesn't? */
125 #ifndef __BORLANDC__
126 #define stat _stat
127 #endif
129 #else
131 #define PATH_SEPS "/"
133 #endif
135 int create_directories(char *fn, int isutf8)
137 char *end, *start;
138 struct stat statbuf;
139 char *segment = malloc(strlen(fn)+1);
140 #ifdef _WIN32
141 wchar_t seg[MAX_PATH+1];
142 #endif
144 start = fn;
145 #ifdef _WIN32
146 if(strlen(fn) >= 3 && isalpha(fn[0]) && fn[1]==':')
147 start = start+2;
148 #endif
150 while((end = strpbrk(start+1, PATH_SEPS)) != NULL)
152 int rv;
153 memcpy(segment, fn, end-fn);
154 segment[end-fn] = 0;
156 #ifdef _WIN32
157 if (isutf8) {
158 MultiByteToWideChar(CP_UTF8, 0, segment, -1, seg, MAX_PATH+1);
159 rv = _wstat(seg,&statbuf);
160 } else
161 #endif
162 rv = stat(segment,&statbuf);
163 if(rv) {
164 if(errno == ENOENT) {
165 #ifdef _WIN32
166 if (isutf8)
167 rv = _wmkdir(seg);
168 else
169 #endif
170 rv = mkdir(segment, 0777);
171 if(rv) {
172 fprintf(stderr, _("Couldn't create directory \"%s\": %s\n"),
173 segment, strerror(errno));
174 free(segment);
175 return -1;
178 else {
179 fprintf(stderr, _("Error checking for existence of directory %s: %s\n"),
180 segment, strerror(errno));
181 free(segment);
182 return -1;
185 #if defined(_WIN32) && !defined(__BORLANDC__)
186 else if(!(_S_IFDIR & statbuf.st_mode)) {
187 #elif defined(__BORLANDC__)
188 else if(!(S_IFDIR & statbuf.st_mode)) {
189 #else
190 else if(!S_ISDIR(statbuf.st_mode)) {
191 #endif
192 fprintf(stderr, _("Error: path segment \"%s\" is not a directory\n"),
193 segment);
194 free(segment);
195 return -1;
198 start = end+1;
201 free(segment);
202 return 0;
206 #ifdef _WIN32
208 FILE *oggenc_fopen(char *fn, char *mode, int isutf8)
210 if (isutf8) {
211 wchar_t wfn[MAX_PATH+1];
212 wchar_t wmode[32];
213 MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, MAX_PATH+1);
214 MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, 32);
215 return _wfopen(wfn, wmode);
216 } else
217 return fopen(fn, mode);
220 static int
221 parse_for_utf8(int argc, char **argv)
223 extern struct option long_options[];
224 int ret;
225 int option_index = 1;
227 while((ret = getopt_long(argc, argv, "A:a:b:B:c:C:d:G:hkl:m:M:n:N:o:P:q:QrR:s:t:vX:",
228 long_options, &option_index)) != -1)
230 switch(ret)
232 case 0:
233 if(!strcmp(long_options[option_index].name, "utf8")) {
234 return 1;
236 break;
237 default:
238 break;
242 return 0;
245 typedef WINSHELLAPI LPWSTR * (APIENTRY *tCommandLineToArgvW)(LPCWSTR lpCmdLine, int*pNumArgs);
247 void get_args_from_ucs16(int *argc, char ***argv)
249 OSVERSIONINFO vi;
250 int utf8;
252 utf8 = parse_for_utf8(*argc, *argv);
253 optind = 1; /* Reset getopt_long */
255 /* If command line is already UTF-8, don't convert */
256 if (utf8)
257 return;
259 vi.dwOSVersionInfoSize = sizeof(vi);
260 GetVersionEx(&vi);
262 /* We only do NT4 and more recent.*/
263 /* It would be relatively easy to add NT3.5 support. Is anyone still using NT3? */
264 /* It would be relatively hard to add 9x support. Fortunately, 9x is
265 a lost cause for unicode support anyway. */
266 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion >= 4) {
267 const char utf8flag[] = "--utf8";
268 int newargc;
269 int sizeofargs = 0;
270 int a, count;
271 char *argptr;
272 char **newargv = NULL;
273 LPWSTR *ucs16argv = NULL;
274 tCommandLineToArgvW pCommandLineToArgvW = NULL;
275 HMODULE hLib = NULL;
277 hLib = LoadLibrary("shell32.dll");
278 if (!hLib)
279 goto bail;
280 pCommandLineToArgvW = (tCommandLineToArgvW)GetProcAddress(hLib, "CommandLineToArgvW");
281 if (!pCommandLineToArgvW)
282 goto bail;
284 ucs16argv = pCommandLineToArgvW(GetCommandLineW(), &newargc);
285 if (!ucs16argv)
286 goto bail;
288 for (a=0; a<newargc; a++) {
289 count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
290 NULL, 0, NULL, NULL);
291 if (count == 0)
292 goto bail;
293 sizeofargs += count;
296 sizeofargs += strlen(utf8flag) + 1;
298 newargv = malloc(((newargc + 2) * sizeof(char *)) + sizeofargs);
299 argptr = (char *)(&newargv[newargc+2]);
301 for (a=0; a<newargc; a++) {
302 count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
303 argptr, sizeofargs, NULL, NULL);
304 if (count == 0)
305 goto bail;
307 newargv[a] = argptr;
308 argptr += count;
309 sizeofargs -= count;
312 count = strlen(utf8flag) + 1;
313 strcpy(argptr, utf8flag);
314 newargv[a] = argptr;
315 argptr += count;
316 sizeofargs -= count;
318 newargv[a+1] = NULL;
320 *argc = newargc + 1;
321 *argv = newargv;
323 bail:
324 if (hLib != NULL)
325 FreeLibrary(hLib);
326 if (ucs16argv != NULL)
327 GlobalFree(ucs16argv);
331 #endif