]> 4ch.mooo.com Git - 16.git/blob - src/lib/dl/ext/vorbtool/platform.c
refresh wwww
[16.git] / src / lib / dl / ext / vorbtool / platform.c
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  **/
11
12 /* Platform support routines  - win32, OS/2, unix */
13
14 #ifdef HAVE_CONFIG_H
15 #include "config.h"
16 #endif
17
18 #include "platform.h"
19 #include "encode.h"
20 #include "i18n.h"
21 #include <stdlib.h>
22 #include <direct.h>
23 #include <ctype.h>
24 #include <stdio.h>
25 #include <dos.h>
26 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
27 #include "getopt.h"
28 #include <fcntl.h>
29 #include <io.h>
30 #include <time.h>
31 #endif
32
33 #ifdef _WIN32
34 #include <windows.h>
35 #endif
36
37 #if defined(_WIN32) && defined(_MSC_VER)
38
39 void setbinmode(FILE *f)
40 {
41     _setmode( _fileno(f), _O_BINARY );
42 }
43 #endif /* win32 */
44
45 #ifdef __EMX__
46 void setbinmode(FILE *f) 
47 {
48             _fsetmode( f, "b");
49 }
50 #endif
51
52 #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)
53 #if 0 /* FIXME: Apparently, Watcom C defines this? */
54 void setbinmode(FILE *f)
55 {
56     setmode(fileno(f), O_BINARY);
57 }
58 #endif
59 #endif
60
61
62 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
63 void *timer_start(void)
64 {
65     time_t *start = malloc(sizeof(time_t));
66     time(start);
67     return (void *)start;
68 }
69
70 double timer_time(void *timer)
71 {
72     time_t now = time(NULL);
73     time_t start = *((time_t *)timer);
74
75     if(now-start)
76         return (double)(now-start);
77     else
78         return 1; /* To avoid division by zero later, for very short inputs */
79 }
80
81
82 void timer_clear(void *timer)
83 {
84     free((time_t *)timer);
85 }
86
87 #else /* unix. Or at least win32 */
88
89 #include <sys/time.h>
90 #include <unistd.h>
91
92 void *timer_start(void)
93 {
94     struct timeval *start = malloc(sizeof(struct timeval));
95     gettimeofday(start, NULL);
96     return (void *)start;
97 }
98
99 double timer_time(void *timer)
100 {
101     struct timeval now;
102     struct timeval start = *((struct timeval *)timer);
103
104     gettimeofday(&now, NULL);
105
106     return (double)now.tv_sec - (double)start.tv_sec + 
107         ((double)now.tv_usec - (double)start.tv_usec)/1000000.0;
108 }
109
110 void timer_clear(void *timer)
111 {
112     free((time_t *)timer);
113 }
114
115 #endif
116
117 #include <errno.h>
118 #include <string.h>
119 #include <sys/types.h>
120 #include <sys/stat.h>
121
122 #ifdef _WIN32
123
124 #include <direct.h>
125
126 #define PATH_SEPS "/\\"
127 #define mkdir(x,y) _mkdir((x))
128
129 /* MSVC does this, borland doesn't? */
130 #ifndef __BORLANDC__
131 #define stat _stat
132 #endif
133
134 #else
135
136 #define PATH_SEPS "/"
137
138 #endif
139
140 int create_directories(char *fn, int isutf8)
141 {
142     char *end, *start;
143     struct stat statbuf;
144     char *segment = malloc(strlen(fn)+1);
145 #ifdef _WIN32
146     wchar_t seg[MAX_PATH+1];
147 #endif
148
149     start = fn;
150 #ifdef _WIN32
151     if(strlen(fn) >= 3 && isalpha(fn[0]) && fn[1]==':')
152         start = start+2;
153 #endif
154
155     while((end = strpbrk(start+1, PATH_SEPS)) != NULL)
156     {
157         int rv;
158         memcpy(segment, fn, end-fn);
159         segment[end-fn] = 0;
160
161 #ifdef _WIN32
162         if (isutf8) {
163             MultiByteToWideChar(CP_UTF8, 0, segment, -1, seg, MAX_PATH+1);
164             rv = _wstat(seg,&statbuf);
165         } else
166 #endif
167             rv = stat(segment,&statbuf);
168         if(rv) {
169             if(errno == ENOENT) {
170 #ifdef _WIN32
171                 if (isutf8)
172                     rv = _wmkdir(seg);
173                 else
174 #endif
175                     rv = mkdir(segment/*, 0777*/); /* Watcom C: mkdir() has just one param */
176                 if(rv) {
177                     fprintf(stderr, _("Couldn't create directory \"%s\": %s\n"),
178                             segment, strerror(errno));
179                     free(segment);
180                     return -1;
181                 }
182             }
183             else {
184                 fprintf(stderr, _("Error checking for existence of directory %s: %s\n"), 
185                             segment, strerror(errno));
186                 free(segment);
187                 return -1;
188             }
189         }
190 #if defined(_WIN32) && !defined(__BORLANDC__)
191         else if(!(_S_IFDIR & statbuf.st_mode)) {
192 #elif defined(__BORLANDC__)
193         else if(!(S_IFDIR & statbuf.st_mode)) {
194 #else
195         else if(!S_ISDIR(statbuf.st_mode)) {
196 #endif
197             fprintf(stderr, _("Error: path segment \"%s\" is not a directory\n"),
198                     segment);
199             free(segment);
200             return -1;
201         }
202
203         start = end+1;
204     }
205
206     free(segment);
207     return 0;
208
209 }
210
211 #ifdef _WIN32
212
213 FILE *oggenc_fopen(char *fn, char *mode, int isutf8)
214 {
215     if (isutf8) {
216         wchar_t wfn[MAX_PATH+1];
217         wchar_t wmode[32];
218         MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, MAX_PATH+1);
219         MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, 32);
220         return _wfopen(wfn, wmode);
221     } else
222         return fopen(fn, mode);
223 }
224
225 static int
226 parse_for_utf8(int argc, char **argv)
227 {
228     extern struct option long_options[];
229     int ret;
230     int option_index = 1;
231
232     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:",
233                     long_options, &option_index)) != -1)
234     {
235         switch(ret)
236         {
237             case 0:
238                 if(!strcmp(long_options[option_index].name, "utf8")) {
239                     return 1;
240                 }
241                 break;
242             default:
243                 break;
244         }
245     }
246
247     return 0;
248 }
249
250 typedef WINSHELLAPI LPWSTR *  (APIENTRY *tCommandLineToArgvW)(LPCWSTR lpCmdLine, int*pNumArgs);
251
252 void get_args_from_ucs16(int *argc, char ***argv)
253 {
254     OSVERSIONINFO vi;
255     int utf8;
256
257     utf8 = parse_for_utf8(*argc, *argv);
258     optind = 1; /* Reset getopt_long */
259
260     /* If command line is already UTF-8, don't convert */
261     if (utf8)
262         return;
263
264     vi.dwOSVersionInfoSize = sizeof(vi);
265     GetVersionEx(&vi);
266
267     /* We only do NT4 and more recent.*/
268     /* It would be relatively easy to add NT3.5 support. Is anyone still using NT3? */
269     /* It would be relatively hard to add 9x support. Fortunately, 9x is
270        a lost cause for unicode support anyway. */
271     if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion >= 4) {
272         const char utf8flag[] = "--utf8";
273         int newargc;
274         int sizeofargs = 0;
275         int a, count;
276         char *argptr;
277         char **newargv = NULL;
278        LPWSTR *ucs16argv = NULL;
279         tCommandLineToArgvW pCommandLineToArgvW = NULL;
280         HMODULE hLib = NULL;
281
282         hLib = LoadLibrary("shell32.dll");
283         if (!hLib)
284             goto bail;
285         pCommandLineToArgvW = (tCommandLineToArgvW)GetProcAddress(hLib, "CommandLineToArgvW");
286         if (!pCommandLineToArgvW)
287             goto bail;
288
289         ucs16argv = pCommandLineToArgvW(GetCommandLineW(), &newargc);
290         if (!ucs16argv)
291             goto bail;
292
293         for (a=0; a<newargc; a++) {
294             count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
295                 NULL, 0, NULL, NULL);
296             if (count == 0)
297                 goto bail;
298             sizeofargs += count;
299         }
300
301         sizeofargs += strlen(utf8flag) + 1;
302
303         newargv = malloc(((newargc + 2) * sizeof(char *)) + sizeofargs);
304         argptr = (char *)(&newargv[newargc+2]);
305
306         for (a=0; a<newargc; a++) {
307             count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
308                 argptr, sizeofargs, NULL, NULL);
309             if (count == 0)
310                 goto bail;
311
312             newargv[a] = argptr;
313             argptr += count;
314             sizeofargs -= count;
315         }
316
317         count = strlen(utf8flag) + 1;
318         strcpy(argptr, utf8flag);
319         newargv[a] = argptr;
320         argptr += count;
321         sizeofargs -= count;
322
323         newargv[a+1] = NULL;
324
325         *argc = newargc + 1;
326         *argv = newargv;
327
328 bail:
329         if (hLib != NULL)
330             FreeLibrary(hLib);
331         if (ucs16argv != NULL)
332             GlobalFree(ucs16argv);
333     }
334 }
335
336 #endif