]> 4ch.mooo.com Git - 16.git/blobdiff - src/lib/dl/ext/vorbtool/platform.c
wwww
[16.git] / src / lib / dl / ext / vorbtool / platform.c
diff --git a/src/lib/dl/ext/vorbtool/platform.c b/src/lib/dl/ext/vorbtool/platform.c
new file mode 100755 (executable)
index 0000000..618f0ca
--- /dev/null
@@ -0,0 +1,336 @@
+/* OggEnc
+ **
+ ** This program is distributed under the GNU General Public License, version 2.
+ ** A copy of this license is included with this source.
+ **
+ ** Copyright 2000, Michael Smith <msmith@xiph.org>
+ **
+ ** Portions from Vorbize, (c) Kenneth Arnold <kcarnold-xiph@arnoldnet.net>
+ ** and libvorbis examples, (c) Monty <monty@xiph.org>
+ **/
+
+/* Platform support routines  - win32, OS/2, unix */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "platform.h"
+#include "encode.h"
+#include "i18n.h"
+#include <stdlib.h>
+#include <direct.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <dos.h>
+#if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
+#include "getopt.h"
+#include <fcntl.h>
+#include <io.h>
+#include <time.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#if defined(_WIN32) && defined(_MSC_VER)
+
+void setbinmode(FILE *f)
+{
+    _setmode( _fileno(f), _O_BINARY );
+}
+#endif /* win32 */
+
+#ifdef __EMX__
+void setbinmode(FILE *f) 
+{
+            _fsetmode( f, "b");
+}
+#endif
+
+#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__MINGW32__)
+#if 0 /* FIXME: Apparently, Watcom C defines this? */
+void setbinmode(FILE *f)
+{
+    setmode(fileno(f), O_BINARY);
+}
+#endif
+#endif
+
+
+#if defined(_WIN32) || defined(__EMX__) || defined(__WATCOMC__)
+void *timer_start(void)
+{
+    time_t *start = malloc(sizeof(time_t));
+    time(start);
+    return (void *)start;
+}
+
+double timer_time(void *timer)
+{
+    time_t now = time(NULL);
+    time_t start = *((time_t *)timer);
+
+    if(now-start)
+        return (double)(now-start);
+    else
+        return 1; /* To avoid division by zero later, for very short inputs */
+}
+
+
+void timer_clear(void *timer)
+{
+    free((time_t *)timer);
+}
+
+#else /* unix. Or at least win32 */
+
+#include <sys/time.h>
+#include <unistd.h>
+
+void *timer_start(void)
+{
+    struct timeval *start = malloc(sizeof(struct timeval));
+    gettimeofday(start, NULL);
+    return (void *)start;
+}
+
+double timer_time(void *timer)
+{
+    struct timeval now;
+    struct timeval start = *((struct timeval *)timer);
+
+    gettimeofday(&now, NULL);
+
+    return (double)now.tv_sec - (double)start.tv_sec + 
+        ((double)now.tv_usec - (double)start.tv_usec)/1000000.0;
+}
+
+void timer_clear(void *timer)
+{
+    free((time_t *)timer);
+}
+
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+
+#include <direct.h>
+
+#define PATH_SEPS "/\\"
+#define mkdir(x,y) _mkdir((x))
+
+/* MSVC does this, borland doesn't? */
+#ifndef __BORLANDC__
+#define stat _stat
+#endif
+
+#else
+
+#define PATH_SEPS "/"
+
+#endif
+
+int create_directories(char *fn, int isutf8)
+{
+    char *end, *start;
+    struct stat statbuf;
+    char *segment = malloc(strlen(fn)+1);
+#ifdef _WIN32
+    wchar_t seg[MAX_PATH+1];
+#endif
+
+    start = fn;
+#ifdef _WIN32
+    if(strlen(fn) >= 3 && isalpha(fn[0]) && fn[1]==':')
+        start = start+2;
+#endif
+
+    while((end = strpbrk(start+1, PATH_SEPS)) != NULL)
+    {
+        int rv;
+        memcpy(segment, fn, end-fn);
+        segment[end-fn] = 0;
+
+#ifdef _WIN32
+        if (isutf8) {
+            MultiByteToWideChar(CP_UTF8, 0, segment, -1, seg, MAX_PATH+1);
+            rv = _wstat(seg,&statbuf);
+        } else
+#endif
+            rv = stat(segment,&statbuf);
+        if(rv) {
+            if(errno == ENOENT) {
+#ifdef _WIN32
+                if (isutf8)
+                    rv = _wmkdir(seg);
+                else
+#endif
+                    rv = mkdir(segment/*, 0777*/); /* Watcom C: mkdir() has just one param */
+                if(rv) {
+                    fprintf(stderr, _("Couldn't create directory \"%s\": %s\n"),
+                            segment, strerror(errno));
+                    free(segment);
+                    return -1;
+                }
+            }
+            else {
+                fprintf(stderr, _("Error checking for existence of directory %s: %s\n"), 
+                            segment, strerror(errno));
+                free(segment);
+                return -1;
+            }
+        }
+#if defined(_WIN32) && !defined(__BORLANDC__)
+        else if(!(_S_IFDIR & statbuf.st_mode)) {
+#elif defined(__BORLANDC__)
+        else if(!(S_IFDIR & statbuf.st_mode)) {
+#else
+        else if(!S_ISDIR(statbuf.st_mode)) {
+#endif
+            fprintf(stderr, _("Error: path segment \"%s\" is not a directory\n"),
+                    segment);
+            free(segment);
+            return -1;
+        }
+
+        start = end+1;
+    }
+
+    free(segment);
+    return 0;
+
+}
+
+#ifdef _WIN32
+
+FILE *oggenc_fopen(char *fn, char *mode, int isutf8)
+{
+    if (isutf8) {
+        wchar_t wfn[MAX_PATH+1];
+        wchar_t wmode[32];
+        MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, MAX_PATH+1);
+        MultiByteToWideChar(CP_ACP, 0, mode, -1, wmode, 32);
+        return _wfopen(wfn, wmode);
+    } else
+        return fopen(fn, mode);
+}
+
+static int
+parse_for_utf8(int argc, char **argv)
+{
+    extern struct option long_options[];
+    int ret;
+    int option_index = 1;
+
+    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:",
+                    long_options, &option_index)) != -1)
+    {
+        switch(ret)
+        {
+            case 0:
+                if(!strcmp(long_options[option_index].name, "utf8")) {
+                    return 1;
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    return 0;
+}
+
+typedef WINSHELLAPI LPWSTR *  (APIENTRY *tCommandLineToArgvW)(LPCWSTR lpCmdLine, int*pNumArgs);
+
+void get_args_from_ucs16(int *argc, char ***argv)
+{
+    OSVERSIONINFO vi;
+    int utf8;
+
+    utf8 = parse_for_utf8(*argc, *argv);
+    optind = 1; /* Reset getopt_long */
+
+    /* If command line is already UTF-8, don't convert */
+    if (utf8)
+        return;
+
+    vi.dwOSVersionInfoSize = sizeof(vi);
+    GetVersionEx(&vi);
+
+    /* We only do NT4 and more recent.*/
+    /* It would be relatively easy to add NT3.5 support. Is anyone still using NT3? */
+    /* It would be relatively hard to add 9x support. Fortunately, 9x is
+       a lost cause for unicode support anyway. */
+    if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT && vi.dwMajorVersion >= 4) {
+        const char utf8flag[] = "--utf8";
+        int newargc;
+        int sizeofargs = 0;
+        int a, count;
+        char *argptr;
+        char **newargv = NULL;
+       LPWSTR *ucs16argv = NULL;
+        tCommandLineToArgvW pCommandLineToArgvW = NULL;
+        HMODULE hLib = NULL;
+
+        hLib = LoadLibrary("shell32.dll");
+        if (!hLib)
+            goto bail;
+        pCommandLineToArgvW = (tCommandLineToArgvW)GetProcAddress(hLib, "CommandLineToArgvW");
+        if (!pCommandLineToArgvW)
+            goto bail;
+
+        ucs16argv = pCommandLineToArgvW(GetCommandLineW(), &newargc);
+        if (!ucs16argv)
+            goto bail;
+
+        for (a=0; a<newargc; a++) {
+            count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
+                NULL, 0, NULL, NULL);
+            if (count == 0)
+                goto bail;
+            sizeofargs += count;
+        }
+
+        sizeofargs += strlen(utf8flag) + 1;
+
+        newargv = malloc(((newargc + 2) * sizeof(char *)) + sizeofargs);
+        argptr = (char *)(&newargv[newargc+2]);
+
+        for (a=0; a<newargc; a++) {
+            count = WideCharToMultiByte(CP_UTF8, 0, ucs16argv[a], -1,
+                argptr, sizeofargs, NULL, NULL);
+            if (count == 0)
+                goto bail;
+
+            newargv[a] = argptr;
+            argptr += count;
+            sizeofargs -= count;
+        }
+
+        count = strlen(utf8flag) + 1;
+        strcpy(argptr, utf8flag);
+        newargv[a] = argptr;
+        argptr += count;
+        sizeofargs -= count;
+
+        newargv[a+1] = NULL;
+
+        *argc = newargc + 1;
+        *argv = newargv;
+
+bail:
+        if (hLib != NULL)
+            FreeLibrary(hLib);
+        if (ucs16argv != NULL)
+            GlobalFree(ucs16argv);
+    }
+}
+
+#endif