summaryrefslogtreecommitdiff
path: root/dev/build/windows/patches_coq/ln.c
diff options
context:
space:
mode:
Diffstat (limited to 'dev/build/windows/patches_coq/ln.c')
-rw-r--r--dev/build/windows/patches_coq/ln.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/dev/build/windows/patches_coq/ln.c b/dev/build/windows/patches_coq/ln.c
new file mode 100644
index 00000000..5e02c72b
--- /dev/null
+++ b/dev/build/windows/patches_coq/ln.c
@@ -0,0 +1,137 @@
+// (C) 2016 Intel Deutschland GmbH
+// Author: Michael Soegtrop
+// Released to the public under CC0
+// See https://creativecommons.org/publicdomain/zero/1.0/
+
+// Windows drop in repacement for Linux ln
+// Supports command form "ln TARGET LINK_NAME"
+// Supports -s and -f options
+// Does not support hard links to folders (but symlinks are ok)
+
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+
+// Cygwin MinGW doesn't have this Vista++ function in windows.h
+#ifdef UNICODE
+ WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkW ( LPCWSTR, LPCWSTR, DWORD );
+ #define CreateSymbolicLink CreateSymbolicLinkW
+ #define CommandLineToArgv CommandLineToArgvW
+#else
+ WINBASEAPI BOOLEAN APIENTRY CreateSymbolicLinkA ( LPCSTR, LPCSTR, DWORD );
+ #define CreateSymbolicLink CreateSymbolicLinkA
+ #define CommandLineToArgv CommandLineToArgvA
+#endif
+#define SYMBOLIC_LINK_FLAG_DIRECTORY 1
+
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLineA, int nShowCmd )
+{
+ int iarg;
+ BOOL symbolic = FALSE;
+ BOOL force = FALSE;
+ BOOL folder;
+ const _TCHAR *target;
+ const _TCHAR *link;
+ LPTSTR lpCmdLine;
+ int argc;
+ LPTSTR *argv;
+
+ // Parse command line
+ // This is done explicitly here for two reasons
+ // 1.) MinGW doesn't seem to support _tmain, wWinMain and the like
+ // 2.) We want to make sure that CommandLineToArgv is used
+ lpCmdLine = GetCommandLine();
+ argv = CommandLineToArgv( lpCmdLine, &argc );
+
+ // Get target and link name
+ if( argc<3 )
+ {
+ _ftprintf( stderr, _T("Expecting at least 2 arguments, got %d\n"), argc-1 );
+ return 1;
+ }
+ target = argv[argc-2];
+ link = argv[argc-1];
+
+ // Parse options
+ // The last two arguments are interpreted as file names
+ // All other arguments must be -s or -f os multi letter options like -sf
+ for(iarg=1; iarg<argc-2; iarg++ )
+ {
+ const _TCHAR *pos = argv[iarg];
+ if( *pos != _T('-') )
+ {
+ _ftprintf( stderr, _T("Command line option expected in argument %d\n"), iarg );
+ return 1;
+ }
+ pos ++;
+
+ while( *pos )
+ {
+ switch( *pos )
+ {
+ case _T('s') : symbolic = TRUE; break;
+ case _T('f') : force = TRUE; break;
+ default :
+ _ftprintf( stderr, _T("Unknown option '%c'\n"), *pos );
+ return 1;
+ }
+ pos ++;
+ }
+ }
+
+ #ifdef IGNORE_SYMBOLIC
+ symbolic = FALSE;
+ #endif
+
+ // Check if link already exists - delete it if force is given or abort
+ {
+ if( GetFileAttributes(link) != INVALID_FILE_ATTRIBUTES )
+ {
+ if( force )
+ {
+ if( !DeleteFile( link ) )
+ {
+ _ftprintf( stderr, _T("Error deleting file '%s'\n"), link );
+ return 1;
+ }
+ }
+ else
+ {
+ _ftprintf( stderr, _T("File '%s' exists!\n"), link );
+ return 1;
+ }
+ }
+ }
+
+ // Check if target is a folder
+ folder = ( (GetFileAttributes(target) & FILE_ATTRIBUTE_DIRECTORY) ) != 0;
+
+ // Create link
+ if(symbolic)
+ {
+ if( !CreateSymbolicLink( link, target, folder ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0 ) )
+ {
+ _ftprintf( stderr, _T("Error creating symbolic link '%s' -> '%s'!\n"), link, target );
+ return 1;
+ }
+ }
+ else
+ {
+ if( folder )
+ {
+ _ftprintf( stderr, _T("Cannot create hard link to folder") );
+ return 1;
+ }
+ else
+ {
+ if( !CreateHardLink( link, target, NULL ) )
+ {
+ _ftprintf( stderr, _T("Error creating hard link '%s' -> '%s'!\n"), link, target );
+ return 1;
+ }
+ }
+ }
+
+ // Everything is fine
+ return 0;
+} \ No newline at end of file