3 ** This program is distributed under the GNU General Public License, version 2.
4 ** A copy of this license is included with this source.
6 ** Copyright 2000, Michael Smith <msmith@xiph.org>
8 ** Portions from Vorbize, (c) Kenneth Arnold <kcarnold-xiph@arnoldnet.net>
9 ** and libvorbis examples, (c) Monty <monty@xiph.org>
12 /* Platform support routines - win32, OS/2, unix */
26 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
37 #if defined(_WIN32) && defined(_MSC_VER)
39 void setbinmode(FILE *f)
41 _setmode( _fileno(f), _O_BINARY );
46 void setbinmode(FILE *f)
52 #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)
53 #if 0 /* FIXME: Apparently, Watcom C defines this? */
54 void setbinmode(FILE *f)
56 setmode(fileno(f), O_BINARY);
62 #if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
63 void *timer_start(void)
65 time_t *start = malloc(sizeof(time_t));
70 double timer_time(void *timer)
72 time_t now = time(NULL);
73 time_t start = *((time_t *)timer);
76 return (double)(now-start);
78 return 1; /* To avoid division by zero later, for very short inputs */
82 void timer_clear(void *timer)
84 free((time_t *)timer);
87 #else /* unix. Or at least win32 */
92 void *timer_start(void)
94 struct timeval *start = malloc(sizeof(struct timeval));
95 gettimeofday(start, NULL);
99 double timer_time(void *timer)
102 struct timeval start = *((struct timeval *)timer);
104 gettimeofday(&now, NULL);
106 return (double)now.tv_sec - (double)start.tv_sec +
107 ((double)now.tv_usec - (double)start.tv_usec)/1000000.0;
110 void timer_clear(void *timer)
112 free((time_t *)timer);
119 #include <sys/types.h>
120 #include <sys/stat.h>
126 #define PATH_SEPS "/\\"
127 #define mkdir(x,y) _mkdir((x))
129 /* MSVC does this, borland doesn't? */
136 #define PATH_SEPS "/"
140 int create_directories(char *fn, int isutf8)
144 char *segment = malloc(strlen(fn)+1);
146 wchar_t seg[MAX_PATH+1];
151 if(strlen(fn) >= 3 && isalpha(fn[0]) && fn[1]==':')
155 while((end = strpbrk(start+1, PATH_SEPS)) != NULL)
158 memcpy(segment, fn, end-fn);
163 MultiByteToWideChar(CP_UTF8, 0, segment, -1, seg, MAX_PATH+1);
164 rv = _wstat(seg,&statbuf);
167 rv = stat(segment,&statbuf);
169 if(errno == ENOENT) {
175 rv = mkdir(segment/*, 0777*/); /* Watcom C: mkdir() has just one param */
177 fprintf(stderr, _("Couldn't create directory \"%s\": %s\n"),
178 segment, strerror(errno));
184 fprintf(stderr, _("Error checking for existence of directory %s: %s\n"),
185 segment, strerror(errno));
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)) {
195 else if(!S_ISDIR(statbuf.st_mode)) {
197 fprintf(stderr, _("Error: path segment \"%s\" is not a directory\n"),
213 FILE *oggenc_fopen(char *fn, char *mode, int isutf8)
216 wchar_t wfn[MAX_PATH+1];
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);
222 return fopen(fn, mode);
226 parse_for_utf8(int argc, char **argv)
228 extern struct option long_options[];
230 int option_index = 1;
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)
238 if(!strcmp(long_options[option_index].name, "utf8")) {
250 typedef WINSHELLAPI LPWSTR * (APIENTRY *tCommandLineToArgvW)(LPCWSTR lpCmdLine, int*pNumArgs);
252 void get_args_from_ucs16(int *argc, char ***argv)
257 utf8 = parse_for_utf8(*argc, *argv);
258 optind = 1; /* Reset getopt_long */
260 /* If command line is already UTF-8, don't convert */
264 vi.dwOSVersionInfoSize = sizeof(vi);
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";
277 char **newargv = NULL;
278 LPWSTR *ucs16argv = NULL;
279 tCommandLineToArgvW pCommandLineToArgvW = NULL;
282 hLib = LoadLibrary("shell32.dll");
285 pCommandLineToArgvW = (tCommandLineToArgvW)GetProcAddress(hLib, "CommandLineToArgvW");
286 if (!pCommandLineToArgvW)
289 ucs16argv = pCommandLineToArgvW(GetCommandLineW(), &newargc);
293 for (a=0; a<newargc; a++) {
294 count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
295 NULL, 0, NULL, NULL);
301 sizeofargs += strlen(utf8flag) + 1;
303 newargv = malloc(((newargc + 2) * sizeof(char *)) + sizeofargs);
304 argptr = (char *)(&newargv[newargc+2]);
306 for (a=0; a<newargc; a++) {
307 count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
308 argptr, sizeofargs, NULL, NULL);
317 count = strlen(utf8flag) + 1;
318 strcpy(argptr, utf8flag);
331 if (ucs16argv != NULL)
332 GlobalFree(ucs16argv);