From 4ec9b74a76a75383bbde704ad63e0e430bc9eeff Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Fri, 3 Dec 2010 01:00:21 -0800 Subject: [PATCH] Initial port to Windows using MinGW. Much of the credit goes to Michael Zenov. --- configure | 20 ++- src/framework/Makefile | 32 ++-- src/melt/Makefile | 6 + src/melt/io.c | 8 + src/mlt++/Makefile | 32 ++-- src/mlt++/MltFactory.cpp | 12 -- src/mlt++/MltFactory.h | 4 - src/mlt++/config.h | 2 +- src/mlt++/configure | 6 +- src/modules/avformat/Makefile | 5 + src/modules/core/Makefile | 6 + src/modules/core/producer_loader.c | 3 +- src/modules/kino/configure | 4 +- src/modules/motion_est/Makefile | 2 +- src/modules/sdl/Makefile | 7 +- src/modules/sdl/consumer_sdl.c | 4 + src/modules/sdl/consumer_sdl_audio.c | 2 + src/modules/sdl/consumer_sdl_preview.c | 2 + src/modules/sdl/consumer_sdl_still.c | 4 +- src/win32/fnmatch.c | 198 +++++++++++++++++++++++++ src/win32/fnmatch.h | 54 +++++++ src/win32/win32.c | 43 ++++++ 22 files changed, 406 insertions(+), 50 deletions(-) create mode 100644 src/win32/fnmatch.c create mode 100644 src/win32/fnmatch.h create mode 100644 src/win32/win32.c diff --git a/configure b/configure index 85f29b4f..13769b88 100755 --- a/configure +++ b/configure @@ -71,19 +71,19 @@ build_config() [ "$cpu" != "" ] && echo "TARGETCPU=-mcpu=$cpu" echo "OPTIMISATIONS=-O2 -pipe -fomit-frame-pointer" - echo "CFLAGS+=-Wall -fPIC -DPIC \$(TARGETARCH) \$(TARGETCPU) \$(OPTIMISATIONS) \$(MMX_FLAGS) \$(SSE_FLAGS) \$(SSE2_FLAGS) \$(DEBUG_FLAGS) \$(LARGE_FILE)" + echo "CFLAGS+=-Wall -DPIC \$(TARGETARCH) \$(TARGETCPU) \$(OPTIMISATIONS) \$(MMX_FLAGS) \$(SSE_FLAGS) \$(SSE2_FLAGS) \$(DEBUG_FLAGS) \$(LARGE_FILE)" case $targetos in Darwin) sysctl -a hw | grep "x86_64: 1" > /dev/null && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64" - echo "CFLAGS+=-D__DARWIN__ `sdl-config --cflags`" + echo "CFLAGS+=-fPIC -D__DARWIN__ `sdl-config --cflags`" echo "SHFLAGS=-dynamiclib" echo "LDFLAGS+=`sdl-config --libs`" ;; Linux) [ "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64" echo "OPTIMISATIONS+=-ffast-math" - echo "CFLAGS+=-pthread" + echo "CFLAGS+=-fPIC -pthread" echo "SHFLAGS=-shared" echo "LIBDL=-ldl" echo "RDYNAMIC=-rdynamic" @@ -92,7 +92,7 @@ build_config() FreeBSD) [ "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64" echo "OPTIMISATIONS+=-ffast-math" - echo "CFLAGS+=-pthread" + echo "CFLAGS+=-fPIC -pthread" echo "SHFLAGS=-shared" echo "RDYNAMIC=-rdynamic" echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed" @@ -105,6 +105,14 @@ build_config() echo "RDYNAMIC=-rdynamic" echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed" ;; + MinGW) + [ "$(uname -m)" = "x86_64" ] && echo "ARCH_X86_64=1" && echo "CFLAGS+=-DARCH_X86_64" + echo "OPTIMISATIONS+=-ffast-math" + echo "SHFLAGS=-shared" + echo "LIBDL=-ldl" + echo "RDYNAMIC=" + echo "LDFLAGS+=-Wl,--no-undefined -Wl,--as-needed" + ;; *) ;; esac @@ -182,6 +190,10 @@ case $targetos in Linux|FreeBSD|NetBSD) LIBSUF=".so" ;; + MINGW32_NT-*) + targetos="MinGW" + LIBSUF=".dll" + ;; *) LIBSUF=".so" ;; diff --git a/src/framework/Makefile b/src/framework/Makefile index 0c61cee0..dff36291 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -3,16 +3,20 @@ include ../../config.mak NAME = libmlt$(LIBSUF) TARGET = $(NAME).$(version) -ifneq ($(targetos), Darwin) -NAME = libmlt$(LIBSUF) -TARGET = $(NAME).$(version) -SONAME = $(NAME).$(soversion) -SHFLAGS += -Wl,-soname,$(SONAME) -else +ifeq ($(targetos), Darwin) NAME = libmlt$(LIBSUF) TARGET = libmlt.$(version)$(LIBSUF) SONAME = libmlt.$(soversion)$(LIBSUF) SHFLAGS += -install_name $(libdir)/$(SONAME) -current_version $(version) -compatibility_version $(soversion) +else ifeq ($(targetos), MinGW) +NAME = libmlt$(LIBSUF) +TARGET = libmlt-$(soversion)$(LIBSUF) +libdir = $(prefix) +else +NAME = libmlt$(LIBSUF) +TARGET = $(NAME).$(version) +SONAME = $(NAME).$(soversion) +SHFLAGS += -Wl,-soname,$(SONAME) endif OBJS = mlt_frame.o \ @@ -78,7 +82,9 @@ all: $(TARGET) $(TARGET): $(OBJS) $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) ln -sf $(TARGET) $(NAME) - ln -sf $(TARGET) $(SONAME) + if [ "$(targetos)" != "MinGW" ]; then \ + ln -sf $(TARGET) $(SONAME) ; \ + fi depend: $(SRCS) $(CC) -MM $(CFLAGS) $^ 1>.depend @@ -92,8 +98,10 @@ clean: install: install -d $(DESTDIR)$(libdir) install -m 755 $(TARGET) $(DESTDIR)$(libdir) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(SONAME) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) + if [ "$(targetos)" != "MinGW" ]; then \ + ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(SONAME) ; \ + ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) ; \ + fi install -d "$(DESTDIR)$(prefix)/include/mlt/framework" install -m 644 $(INCS) "$(DESTDIR)$(prefix)/include/mlt/framework" install -d "$(DESTDIR)$(datadir)/mlt" @@ -101,8 +109,10 @@ install: uninstall: rm -f "$(DESTDIR)$(libdir)/$(TARGET)" - rm -f "$(DESTDIR)$(libdir)/$(SONAME)" - rm -f "$(DESTDIR)$(libdir)/$(NAME)" + if [ "$(targetos)" != "MinGW" ]; then \ + rm -f "$(DESTDIR)$(libdir)/$(SONAME)" ; \ + rm -f "$(DESTDIR)$(libdir)/$(NAME)" ; \ + fi rm -rf "$(DESTDIR)$(prefix)/include/mlt/framework" rm -f "$(DESTDIR)$(datadir)/mlt/metaschema.yaml" diff --git a/src/melt/Makefile b/src/melt/Makefile index e89e98cf..41959939 100644 --- a/src/melt/Makefile +++ b/src/melt/Makefile @@ -10,6 +10,12 @@ LDFLAGS += -L../framework -lmlt -lpthread SRCS := $(OBJS:.o=.c) +ifeq ($(targetos), MinGW) +OBJS += ../win32/win32.o +SRCS += ../win32/win32.c +bindir = $(prefix) +endif + all: $(TARGET) $(TARGET): $(OBJS) diff --git a/src/melt/io.c b/src/melt/io.c index 520d74fc..8499a6cb 100644 --- a/src/melt/io.c +++ b/src/melt/io.c @@ -27,7 +27,9 @@ #include #include #include +#ifndef WIN32 #include +#endif #include #include @@ -102,11 +104,13 @@ static int mode = 0; void term_exit(void) { +#ifndef WIN32 if ( mode == 1 ) { tcsetattr( 0, TCSANOW, &oldtty ); mode = 0; } +#endif } /** Init terminal so that we can grab keys without blocking. @@ -114,6 +118,7 @@ void term_exit(void) void term_init( ) { +#ifndef WIN32 struct termios tty; tcgetattr( 0, &tty ); @@ -132,6 +137,7 @@ void term_init( ) mode = 1; atexit( term_exit ); +#endif } /** Check for a keypress without blocking infinitely. @@ -140,6 +146,7 @@ void term_init( ) int term_read( ) { +#ifndef WIN32 int n = 1; unsigned char ch; struct timeval tv; @@ -158,6 +165,7 @@ int term_read( ) return ch; return n; } +#endif return -1; } diff --git a/src/mlt++/Makefile b/src/mlt++/Makefile index 14c73b7e..efaa9a1b 100644 --- a/src/mlt++/Makefile +++ b/src/mlt++/Makefile @@ -2,16 +2,20 @@ include ../../config.mak include config.mak INSTALL = install -ifneq ($(targetos), Darwin) -NAME = libmlt++$(LIBSUF) -TARGET = $(NAME).$(version) -SONAME = $(NAME).$(soversion) -LIBFLAGS += -Wl,-soname,$(SONAME) -else +ifeq ($(targetos), Darwin) NAME = libmlt++$(LIBSUF) TARGET = libmlt++.$(version)$(LIBSUF) SONAME = libmlt++.$(soversion)$(LIBSUF) LIBFLAGS += -install_name $(libdir)/$(SONAME) -current_version $(version) -compatibility_version $(soversion) +else ifeq ($(targetos), MinGW) +NAME = libmlt++$(LIBSUF) +TARGET = libmlt++-$(soversion)$(LIBSUF) +libdir = $(prefix) +else +NAME = libmlt++$(LIBSUF) +TARGET = $(NAME).$(version) +SONAME = $(NAME).$(soversion) +LIBFLAGS += -Wl,-soname,$(SONAME) endif CXXFLAGS += -I.. $(RDYNAMIC) -DVERSION=\"$(version)\" @@ -49,7 +53,9 @@ all: $(TARGET) $(TARGET): $(OBJS) $(CXX) $(LIBFLAGS) -o $@ $(OBJS) $(LDFLAGS) ln -sf $(TARGET) $(NAME) - ln -sf $(TARGET) $(SONAME) + if [ "$(targetos)" != "MinGW" ]; then \ + ln -sf $(TARGET) $(SONAME) ; \ + fi depend: $(SRCS) $(CXX) -MM $(CXXFLAGS) $^ 1>.depend @@ -62,15 +68,19 @@ distclean: clean install: $(INSTALL) -d "$(DESTDIR)$(libdir)" $(INSTALL) -m 755 $(TARGET) $(DESTDIR)$(libdir) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) - ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(SONAME) + if [ "$(targetos)" != "MinGW" ]; then \ + ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) ; \ + ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(SONAME) ; \ + fi $(INSTALL) -d "$(DESTDIR)$(prefix)/include/mlt++" $(INSTALL) -m 644 $(HEADERS) "$(DESTDIR)$(prefix)/include/mlt++" uninstall: rm -f "$(DESTDIR)$(libdir)/$(TARGET)" - rm -f "$(DESTDIR)$(libdir)/$(NAME)" - rm -f "$(DESTDIR)$(libdir)/$(SONAME)" + if [ "$(targetos)" != "MinGW" ]; then \ + rm -f "$(DESTDIR)$(libdir)/$(NAME)" ; \ + rm -f "$(DESTDIR)$(libdir)/$(SONAME)" ; \ + fi rm -rf "$(DESTDIR)$(prefix)/include/mlt++" ifneq ($(wildcard .depend),) diff --git a/src/mlt++/MltFactory.cpp b/src/mlt++/MltFactory.cpp index 4c9d1f5a..17b7c318 100644 --- a/src/mlt++/MltFactory.cpp +++ b/src/mlt++/MltFactory.cpp @@ -57,18 +57,6 @@ Consumer *Factory::consumer( Profile& profile, char *id, char *arg ) return new Consumer( profile, id, arg ); } -#ifdef WIN32 -char *Factory::getenv( const char *name ) -{ - return mlt_getenv( name ); -} - -int Factory::setenv( const char *name, const char *value ) -{ - return mlt_setenv( name, value ); -} -#endif - void Factory::close( ) { mlt_factory_close( ); diff --git a/src/mlt++/MltFactory.h b/src/mlt++/MltFactory.h index 382bedee..0f1a693d 100644 --- a/src/mlt++/MltFactory.h +++ b/src/mlt++/MltFactory.h @@ -49,10 +49,6 @@ namespace Mlt static Filter *filter( Profile& profile, char *id, char *arg = NULL ); static Transition *transition( Profile& profile, char *id, char *arg = NULL ); static Consumer *consumer( Profile& profile, char *id, char *arg = NULL ); -#ifdef WIN32 - static char *getenv( const char * ); - static int setenv( const char *, const char * ); -#endif static void close( ); }; } diff --git a/src/mlt++/config.h b/src/mlt++/config.h index ccda822d..454771e2 100644 --- a/src/mlt++/config.h +++ b/src/mlt++/config.h @@ -21,7 +21,7 @@ #ifndef MLTPP_CONFIG_H_ #define MLTPP_CONFIG_H_ -#ifdef WIN32 +#if defined(WIN32) && defined(_MSC_VER) #ifdef MLTPP_EXPORTS #define MLTPP_DECLSPEC __declspec( dllexport ) #else diff --git a/src/mlt++/configure b/src/mlt++/configure index e7c0de62..8fe14f6b 100755 --- a/src/mlt++/configure +++ b/src/mlt++/configure @@ -4,7 +4,6 @@ echo "mlt++ -I$prefix/include -I$prefix/include/mlt++ -D_REENTRANT -L$libdir -lm WARNINGS="-W -Wwrite-strings -Wcast-qual -Wpointer-arith -Wcast-align -Wredundant-decls" -targetos=$(uname -s) case $targetos in Darwin) echo LIBSUF=.dylib @@ -16,4 +15,9 @@ case $targetos in echo "CXXFLAGS+=-Wall $WARNINGS -fPIC -DPIC" echo "LIBFLAGS=-shared" ;; + MinGW) + echo LIBSUF=.dll + echo "CXXFLAGS+=-Wall $WARNINGS -DPIC" + echo "LIBFLAGS=-enable-auto-import -shared" + ;; esac >> config.mak diff --git a/src/modules/avformat/Makefile b/src/modules/avformat/Makefile index 75d84668..30d8f401 100644 --- a/src/modules/avformat/Makefile +++ b/src/modules/avformat/Makefile @@ -56,6 +56,11 @@ endif SRCS := $(OBJS:.o=.c) +ifeq ($(targetos), MinGW) +OBJS += ../../win32/win32.o +SRCS += ../../win32/win32.c +endif + all: $(TARGET) $(LOCAL_FFMPEG_OBJS): diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index a6192868..788319c9 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -43,6 +43,12 @@ ASM_OBJS = SRCS := $(OBJS:.o=.c) +ifeq ($(targetos), MinGW) +CFLAGS += -I../../win32 +OBJS += ../../win32/fnmatch.o +SRCS += ../../win32/fnmatch.c +endif + all: $(TARGET) $(TARGET): $(OBJS) $(ASM_OBJS) diff --git a/src/modules/core/producer_loader.c b/src/modules/core/producer_loader.c index 35229d22..2600b62c 100644 --- a/src/modules/core/producer_loader.c +++ b/src/modules/core/producer_loader.c @@ -53,7 +53,8 @@ static mlt_producer create_producer( mlt_profile profile, char *file ) mlt_producer result = NULL; // 1st Line - check for service:resource handling - if ( strchr( file, ':' ) ) + // And ignore drive letters on Win32 - no single char services supported. + if ( strchr( file, ':' ) > file + 1 ) { char *temp = strdup( file ); char *service = temp; diff --git a/src/modules/kino/configure b/src/modules/kino/configure index f6524f38..88009a00 100755 --- a/src/modules/kino/configure +++ b/src/modules/kino/configure @@ -3,9 +3,9 @@ if [ "$help" != "1" ] then - if [ "$targetos" = "Darwin" ] + if [ "$targetos" = "Darwin" ] || [ "$targetos" = "MinGW" ] then - echo "- does not build on Darwin: disabling" + echo "- does not build on Darwin or Windows: disabling" touch ../disable-kino exit 0 fi diff --git a/src/modules/motion_est/Makefile b/src/modules/motion_est/Makefile index 78bcd22c..b0eefc76 100644 --- a/src/modules/motion_est/Makefile +++ b/src/modules/motion_est/Makefile @@ -4,7 +4,7 @@ LDFLAGS += -L../../framework -lmlt -lm include ../../../config.mak -TARGET = ../libmltmotion_est.so +TARGET = ../libmltmotion_est.$(LIBSUF) OBJS = factory.o \ filter_motion_est.o \ diff --git a/src/modules/sdl/Makefile b/src/modules/sdl/Makefile index 24a0faf2..1bb3b7a6 100644 --- a/src/modules/sdl/Makefile +++ b/src/modules/sdl/Makefile @@ -17,7 +17,7 @@ OBJS = factory.o \ ifeq ($(targetos),Darwin) CFLAGS += -ObjC LDFLAGS += -lobjc -framework Foundation -else +else ifeq ($(targetos), Linux|FreeBSD) LDFLAGS += -lX11 endif @@ -37,6 +37,11 @@ OBJS += consumer_sdl_osx.o SRCS += consumer_sdl_osx.m consumer_sdl_osx.h endif +ifeq ($(targetos), MinGW) +OBJS += ../../win32/win32.o +SRCS += ../../win32/win32.c +endif + all: $(TARGET) $(TARGET): $(OBJS) diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index f58e73de..92957cdf 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -264,7 +264,9 @@ int consumer_stop( mlt_consumer parent ) // Kill the thread and clean up this->joined = 1; this->running = 0; +#ifndef WIN32 if ( this->thread ) +#endif pthread_join( this->thread, NULL ); // internal cleanup @@ -855,6 +857,7 @@ static int consumer_get_dimensions( int *width, int *height ) // Get the wm structure if ( SDL_GetWMInfo( &wm ) == 1 ) { +#ifndef WIN32 // Check that we have the X11 wm if ( wm.subsystem == SDL_SYSWM_X11 ) { @@ -875,6 +878,7 @@ static int consumer_get_dimensions( int *width, int *height ) *width = attr.width; *height = attr.height; } +#endif } #endif diff --git a/src/modules/sdl/consumer_sdl_audio.c b/src/modules/sdl/consumer_sdl_audio.c index c6103fbb..f15bbf21 100644 --- a/src/modules/sdl/consumer_sdl_audio.c +++ b/src/modules/sdl/consumer_sdl_audio.c @@ -193,7 +193,9 @@ int consumer_stop( mlt_consumer parent ) pthread_mutex_unlock( &this->refresh_mutex ); // Cleanup the main thread +#ifndef WIN32 if ( this->thread ) +#endif pthread_join( this->thread, NULL ); // Unlatch the audio callback diff --git a/src/modules/sdl/consumer_sdl_preview.c b/src/modules/sdl/consumer_sdl_preview.c index 94a5598e..9d336dad 100644 --- a/src/modules/sdl/consumer_sdl_preview.c +++ b/src/modules/sdl/consumer_sdl_preview.c @@ -249,7 +249,9 @@ static int consumer_stop( mlt_consumer parent ) pthread_mutex_lock( &this->refresh_mutex ); pthread_cond_broadcast( &this->refresh_cond ); pthread_mutex_unlock( &this->refresh_mutex ); +#ifndef WIN32 if ( this->thread ) +#endif pthread_join( this->thread, NULL ); this->joined = 1; diff --git a/src/modules/sdl/consumer_sdl_still.c b/src/modules/sdl/consumer_sdl_still.c index 8a423db9..57dc4106 100644 --- a/src/modules/sdl/consumer_sdl_still.c +++ b/src/modules/sdl/consumer_sdl_still.c @@ -614,10 +614,11 @@ static int consumer_get_dimensions( int *width, int *height ) // Specify the SDL Version SDL_VERSION( &wm.version ); +#ifndef __DARWIN__ // Get the wm structure if ( SDL_GetWMInfo( &wm ) == 1 ) { -#ifndef __DARWIN__ +#ifndef WIN32 // Check that we have the X11 wm if ( wm.subsystem == SDL_SYSWM_X11 ) { @@ -640,6 +641,7 @@ static int consumer_get_dimensions( int *width, int *height ) } #endif } +#endif return changed; } diff --git a/src/win32/fnmatch.c b/src/win32/fnmatch.c new file mode 100644 index 00000000..1fbc5484 --- /dev/null +++ b/src/win32/fnmatch.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From FreeBSD fnmatch.c 1.11 + * $Id$ + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. + * Compares a filename or pathname to a pattern. + */ + +#include +#include +#include + +#include "fnmatch.h" + +#define EOS '\0' + +static const char *rangematch(const char *, char, int); + +int fnmatch(const char *pattern, const char *string, int flags) +{ + const char *stringstart; + char c, test; + + for (stringstart = string;;) + switch (c = *pattern++) { + case EOS: + if ((flags & FNM_LEADING_DIR) && *string == '/') + return (0); + return (*string == EOS ? 0 : FNM_NOMATCH); + case '?': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && (flags & FNM_PATHNAME)) + return (FNM_NOMATCH); + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + ++string; + break; + case '*': + c = *pattern; + /* Collapse multiple stars. */ + while (c == '*') + c = *++pattern; + + if (*string == '.' && (flags & FNM_PERIOD) && + (string == stringstart || + ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) + return (FNM_NOMATCH); + + /* Optimize for pattern with * at end or before /. */ + if (c == EOS) + if (flags & FNM_PATHNAME) + return ((flags & FNM_LEADING_DIR) || + strchr(string, '/') == NULL ? + 0 : FNM_NOMATCH); + else + return (0); + else if (c == '/' && flags & FNM_PATHNAME) { + if ((string = strchr(string, '/')) == NULL) + return (FNM_NOMATCH); + break; + } + + /* General case, use recursion. */ + while ((test = *string) != EOS) { + if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) + return (0); + if (test == '/' && flags & FNM_PATHNAME) + break; + ++string; + } + return (FNM_NOMATCH); + case '[': + if (*string == EOS) + return (FNM_NOMATCH); + if (*string == '/' && flags & FNM_PATHNAME) + return (FNM_NOMATCH); + if ((pattern = + rangematch(pattern, *string, flags)) == NULL) + return (FNM_NOMATCH); + ++string; + break; + case '\\': + if (!(flags & FNM_NOESCAPE)) { + if ((c = *pattern++) == EOS) { + c = '\\'; + --pattern; + } + } + /* FALLTHROUGH */ + default: + if (c == *string) + ; + else if ((flags & FNM_CASEFOLD) && + (tolower((unsigned char)c) == + tolower((unsigned char)*string))) + ; + else if ((flags & FNM_PREFIX_DIRS) && *string == EOS && + (c == '/' && string != stringstart || + string == stringstart+1 && *stringstart == '/') ) + return (0); + else + return (FNM_NOMATCH); + string++; + break; + } + /* NOTREACHED */ +} + +static const char * +rangematch(const char *pattern, char test, int flags) +{ + int negate, ok; + char c, c2; + + /* + * A bracket expression starting with an unquoted circumflex + * character produces unspecified results (IEEE 1003.2-1992, + * 3.13.2). This implementation treats it like '!', for + * consistency with the regular expression syntax. + * J.T. Conklin (conklin@ngai.kaleida.com) + */ + if ( (negate = (*pattern == '!' || *pattern == '^')) ) + ++pattern; + + if (flags & FNM_CASEFOLD) + test = tolower((unsigned char)test); + + for (ok = 0; (c = *pattern++) != ']';) { + if (c == '\\' && !(flags & FNM_NOESCAPE)) + c = *pattern++; + if (c == EOS) + return (NULL); + + if (flags & FNM_CASEFOLD) + c = tolower((unsigned char)c); + + if (*pattern == '-' + && (c2 = *(pattern+1)) != EOS && c2 != ']') { + pattern += 2; + if (c2 == '\\' && !(flags & FNM_NOESCAPE)) + c2 = *pattern++; + if (c2 == EOS) + return (NULL); + + if (flags & FNM_CASEFOLD) + c2 = tolower((unsigned char)c2); + + if ((unsigned char)c <= (unsigned char)test && + (unsigned char)test <= (unsigned char)c2) + ok = 1; + } else if (c == test) + ok = 1; + } + return (ok == negate ? NULL : pattern); +} diff --git a/src/win32/fnmatch.h b/src/win32/fnmatch.h new file mode 100644 index 00000000..e2af6997 --- /dev/null +++ b/src/win32/fnmatch.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 + * + * From FreeBSD fnmatch.h 1.7 + * $Id$ + */ + +#ifndef _FNMATCH_H_ +#define _FNMATCH_H_ + + +#define FNM_NOMATCH 1 /* Match failed. */ + +#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */ +#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */ +#define FNM_PERIOD 0x04 /* Period must be matched by period. */ +#define FNM_LEADING_DIR 0x08 /* Ignore / after Imatch. */ +#define FNM_CASEFOLD 0x10 /* Case insensitive search. */ +#define FNM_PREFIX_DIRS 0x20 /* Directory prefixes of pattern match too. */ + +int fnmatch(const char *pattern, const char *string, int flags); + +#endif /* !_FNMATCH_H_ */ diff --git a/src/win32/win32.c b/src/win32/win32.c new file mode 100644 index 00000000..5105efc1 --- /dev/null +++ b/src/win32/win32.c @@ -0,0 +1,43 @@ + +#include +#include +#include +#include + +int usleep(unsigned int useconds) +{ + HANDLE timer; + LARGE_INTEGER due; + + due.QuadPart = -(10 * (__int64)useconds); + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &due, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + return 0; +} + + +int nanosleep( const struct timespec * rqtp, struct timespec * rmtp ) +{ + if (rqtp->tv_nsec > 999999999) { + /* The time interval specified 1,000,000 or more microseconds. */ + errno = EINVAL; + return -1; + } + return usleep( rqtp->tv_sec * 1000000 + rqtp->tv_nsec / 1000 ); +} + +int setenv(const char *name, const char *value, int overwrite) +{ + int result = 1; + if (overwrite == 0 && getenv (name)) { + result = 0; + } else { + result = SetEnvironmentVariable (name,value); + } + + return result; +} + -- 2.39.2