diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index f5291c6125ede8d1566a7b4c8add6f43b2a4f05b..64930b29d2880ba70348e1fd50c4bd953ba2d980 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -8,7 +8,7 @@ ADD_SUBDIRECTORY(iconv) ADD_SUBDIRECTORY(lz4) ADD_SUBDIRECTORY(cJson) ADD_SUBDIRECTORY(wepoll) -#ADD_SUBDIRECTORY(MsvcLibX) +ADD_SUBDIRECTORY(MsvcLibX) IF (TD_LINUX) ADD_SUBDIRECTORY(MQTT-C) diff --git a/deps/MsvcLibX/CMakeLists.txt b/deps/MsvcLibX/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a94625f29dfb5a06a663d38a822e45f88d45958a --- /dev/null +++ b/deps/MsvcLibX/CMakeLists.txt @@ -0,0 +1,23 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(TDengine) + +IF (TD_WINDOWS_64) + SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + + include(FindWindowsSDK) + get_mywindowssdk_include_dirs(${WINDOWSSDK_PREFERRED_DIR} WINSDK_INCLUDE_DIR) + get_ucrt_include_dirs(${WINDOWSSDK_PREFERRED_DIR} UCRT_INCLUDE_DIR) + + Message(STATUS "WINSDK_INCLUDE_DIR ============> ${WINSDK_INCLUDE_DIR}") + Message(STATUS "UCRT_INCLUDE_DIR ============> ${UCRT_INCLUDE_DIR}") + + Add_Definitions("-DUCRTINCLUDE=${UCRT_INCLUDE_DIR}") + Add_Definitions("-DWSDKINCLUDE=${WINSDK_INCLUDE_DIR}") + + include(FindMSVC) + Add_Definitions("-DMSVCINCLUDE=${VC_INCLUDE_DIR}") + + INCLUDE_DIRECTORIES(include) + AUX_SOURCE_DIRECTORY(src SRC) + ADD_LIBRARY(MsvcLibXw64 ${SRC}) +ENDIF () diff --git a/deps/MsvcLibX/README.md b/deps/MsvcLibX/README.md new file mode 100644 index 0000000000000000000000000000000000000000..8f689412cbd1e1d4c4b5b89e69865998964c159f --- /dev/null +++ b/deps/MsvcLibX/README.md @@ -0,0 +1,820 @@ +MsvcLibX - A set of MSVC Library eXtensions +=========================================== + + +Introduction +------------ + +The MsvcLibX library is built upon 30 years of work. +It exists because the Microsoft Visual C/C++ library is only a subset of the +standard C library, and I wanted to port to DOS and Windows programs using some +of the missing parts. +Initially Microsoft C compilers for MS-DOS tried to be as compliant as possible +with the standard C library. Then Microsoft rewrote their library for Windows. +But when the WIN32 API became prevalent, Microsoft apparently lost interest, +and stopped porting to MS-DOS and Windows the new C include files and library +routines that got standardized over the years. +To the point that's it's now impossible to rebuild any recent Posix/Unix/Linux +program using the MSVC library. + +MsvcLibX adds a number of standard include files and library routines that I've +needed over the years. For example the directory access routines defined in +dirent.h, or the symbolic link support in unistd.h. +It also includes a number of useful routines and macros, either needed +internally to implement and debug the above, or made necessary by irresolvable +incompatibilities between Unix and Windows. + +Other major features of the MsvcLibX library are: + +* A powerful make system, based on Microsoft nmake files, that allow building + multiple versions of the same program (Ex: DOS/WIN32/WIN64) with one simple + command. And in most cases without having to write any dedicated make file. +* Support for UTF-8 sources, allowing to build programs working in any code page. +* Support for NTFS symlinks and junctions. +* Support for DOS, and Windows 95 targets, for targeting old computers. +* Support for bound DOS+Windows programs, for truly universal executables that + work in *all* versions of DOS and Windows. + +An obvious alternative exists for building Windows programs: MinGW. +But I started all this before MinGW even existed. And, surprisingly, even MinGW +still has holes in 2014, where MsvcLibX in significantly more advanced. +Another alternative is CygWin. This one is more complete, but also much more +heavyweight. Using programs built with CygWin requires installing CygWin DLLs. +Copying the program .exe from one system to the next is not sufficient. In that +sense, MinGW or MsvcLibX are much better. + +Contrary to MinGW and CygWin, MsvcLibX does not attempt to be complete, and is +unlikely to ever be. But any contribution of improvements is welcome. +Likewise, any help at contributing unique MsvcLibX features to MinGW is welcome. + +Jean-François Larvoire +2016-09-29 + + +Building the MsvcLibX library +----------------------------- + +On a recent Windows PC, with Microsoft Visual C++ compilers installed: + +- Select a base work directory. I'll call it %BASEDIR% in the examples below: + + set "HOME=%HOMEDRIVE%%HOMEPATH%" + set "BASEDIR=%HOME%\Documents\SRC" + md "%BASEDIR%" + cd "%BASEDIR%" + +- Extract the MsvcLibX archive into a work subdirectory. Ex: %BASEDIR%\MsvcLibX\ + This will put files in several subdirectories: include, src + +- Open a cmd window, and run: + + cd "%BASEDIR%\MsvcLibX\src" + configure + make + +The configure.bat script will locate your MSVC tools, and generate a config +file. It needs to be run once initially, then again if new MSVC tool versions +are installed. +The make.bat script should take care of everything, and rebuild normal and debug +versions of the MsvcLibX.lib library for all operating systems your tools support. +In the end, it defines system environment variable MSVCLIBX, necessary for +building programs using the MsvcLibX.lib library. + +Requirements: + +- Microsoft Visual C++ compiler and linker for Windows 32 and 64 bits targets. +- Microsoft Windows SDK. (May be installed along with Visual C++) + +As of 2015-12-10, I've tested the make.bat script and make files with Visual C++ +2005, 2008, 2012, and 2015, and Windows SDK 5.2, 8.1, and 10. +Support for older versions is still built-in, but I've not tested it for long. +Support for newer versions will require minor tweaks in configure.bat. +Note that configure.bat does not depend on MSVC's vcvars.bat. It will attempt +to locate and use the latest usable version of MSVC it finds in Program Files. + +Optional: + +- Microsoft Visual C++ 1.52 compiler and linker for MS-DOS targets. + If present in C:\MSVC, make.bat will also generate libraries for DOS. + Note that generating DOS versions is still more useful than it looks: + Experience has shown that the severe memory constraints under DOS are a very + good revelator of memory leaks, and other bad pointer issues. Build your + programs for DOS too if you can, and test them in a VM with Windows XP. + This takes a very small extra build time. And it'll be very much worth the time + if the Windows version appears to work, but the DOS version does not. + Visual C++ 1.52 is available on the Visual Studio 2005 CD. +- The Visual C++ 8 compiler and tools from Microsoft Visual Studio 2005. + This is the last version that allowed building programs for Windows 95/NT4. + +The MsvcLibX.lib libraries are generated in subdirectories of src, then copied +into the %BASEDIR%\MsvcLibX\lib directory, and renamed as shown in this table: + +Subdirectory | Description | Renamed as +---------------- | -------------------------------------- | ---------------- +DOS\BIN\T\ | DOS normal version, tiny memory model | MsvcLibXdt.lib +DOS\DEBUG\BIN\T\ | DOS debug version, tiny memory model | MsvcLibXdtd.lib +DOS\BIN\S\ | DOS normal version, small memory model | MsvcLibXds.lib +DOS\DEBUG\BIN\S\ | DOS debug version, small memory model | MsvcLibXdsd.lib +DOS\BIN\L\ | DOS normal version, large memory model | MsvcLibXdl.lib +DOS\DEBUG\BIN\L\ | DOS debug version, large memory model | MsvcLibXdld.lib +WIN95\ | WIN32 normal version for Windows 95 | MsvcLibXw32.lib +WIN95\DEBUG\ | WIN32 debug version for Windows 95 | MsvcLibXw32d.lib +WIN32\ | WIN32 (X86) normal version | MsvcLibXw32.lib +WIN32\DEBUG\ | WIN32 (X86) debug version | MsvcLibXw32d.lib +WIN64\ | WIN64 (AMD64) normal version | MsvcLibXw64.lib +WIN64\DEBUG\ | WIN64 (AMD64) debug version | MsvcLibXw64d.lib + + +Building programs using the MsvcLibX library +-------------------------------------------- + +Create a work directory, distinct from the MsvcLibX directories. Ex: + + set "HOME=%HOMEDRIVE%%HOMEPATH%" + set "BASEDIR=%HOME%\Documents\SRC" + md "%BASEDIR%\MyTools" + cd "%BASEDIR%\MyTools" + :# Define a variable giving the location of the MsvcLibX base directory + :# (Automatically defined if you built the library already on that same system.) + set "MSVCLIBX=%BASEDIR%\MsvcLibX" + :# Get batch files and make files from MsvcLibX sources + copy "%MSVCLIBX%\src\*.bat" + copy "%MSVCLIBX%\src\*.mak" + :# Create the configuration file (To be done just once) + configure + :# Compile and link your C or C++ program. + :# Ex, for the dirc.c sample, to create all dirc.exe versions, type: + make dirc.exe + :# If there is any error, the dirc.log file will pop up. + :# If there's no error, it's possible to check for warnings by reading dirc.log: + notepad dirc.log + :# All generated object files, listings, executables, etc, are in + :# target-OS-specific subdirectories, like for the MsvcLibX builds above. + :# They're automatically linked with the corresponding (renamed) MsvcLibX*.lib. + +make.bat will generate WIN32 (X86) and WIN64 (AMD64) versions by default, +and put them respectively in the WIN32\ and WIN64\ subdirectories. +It will also generate a DOS version in DOS\ if MSVC 1.52 is installed. +It will also generate a WIN95 version in WIN95\ if MSVC 8 (aka. 2005) is installed. +Run `make -?` get a help screen for make.bat. + +Note that the configure.bat and make.bat scripts are actually independent of the +rest of the MsvcLibX library. They can be used to easily build any console +programs for DOS and Windows, without loading the Visual Studio GUI. + +An exe.bat script is a front-end to make.bat, saving a few characters to type: +`exe dirc` <==> `make dirc.exe` + + +Building Linux versions of the same programs +-------------------------------------------- + +Install virtual machines with Linux, and give them access to the host's file +system, for example in the /c directory. +Then execute the following commands, adapting the paths as needed: + + # Go to the work directory + BASEDIR=/c/Users/YOURNAME/Documents/SRC + mkdir $BASEDIR/MyTools + cd $BASEDIR/MyTools + # Get a bash script to build Linux versions using similar directory outputs + cp $BASEDIR/MsvcLibX/src/exe . + # Make sure the Linux C compiler finds MsvcLibX debug macros, but not other MsvcLibX include files. + # Important: Do not point C_INCLUDE_PATH at MsvcLibX/include, as this directory + # contains duplicates for standard include files (Ex: stdio.h), that will fail + # to compile in Linux. + mkdir ~/include + cp $BASEDIR/MsvcLibX/include/debugm.h ~/include + export C_INCLUDE_PATH=~/include + # Make sure that variable is defined in all future sessions + echo "export C_INCLUDE_PATH=~/include" >>~/.bashrc + # Compile your sample dirc.c program (which uses MsvcLibX debug macros) + ./exe dirc + # The output will be in subdirectories such as Linux.i686/ or Linux.x86_64/. + # (The exact name depends on `echo "$(uname -s).$(uname -m)"` output) + + +Adding new files to the library +------------------------------- + +All new files should have headers and comments similar to the existing ones. + +To add a new source file (let's call it newfile.c) into the library: + +- Put newfile.c in the %MSVCLIBX%\src directory. +- Add a +newfile.obj entry to the OBJECTS list in %MSVCLIBX%\src\Files.mak +- Also add a rule with newfile.c include files dependencies in src\Files.mak. +- Rebuild the library, and make sure there are no errors nor warnings. + +To add a new include file into the library: + +- All new include file names should be standard C library include files names! +- Put it in the include or include\sys subdirectory. + +To add an include file overriding an homonym one in the MSVC library: + +- The trick is to make it include MSVC's one, then define its own extensions. + As MSVC compilers do not support the #include_next directive, I've implemented + a mechanism for including MSVC include files using their full pathname. + As an example, see include/direct.h or include/sys/stat.h. + + +The make file system +-------------------- + +Microsoft Visual Studio tools contain a build tool called nmake, very similar +to, but slightly incompatible with, Unix make. +MsvcLibX's make.bat is designed to give a similar feel to Unix make. +It uses internally a number of make files: + +Make file | Description +----------- | ---------------------------------------------------------------- +NMakefile | Default make file to use, if none is specified. +DOS.mak | Generic rules for building MS-DOS programs into the DOS subdir. +WIN32.mak | Generic rules for building 32-bits Windows programs into WIN32. +WIN64.mak | Generic rules for building 64-bits Windows programs into WIN64. +WIN95.mak | Generic rules for building Windows 95 programs into WIN95. +All.mak | Generic rules for building one or more of the above. +Files.mak | Application-specific source file dependancy rules. Intended to be includable from both Windows' nmakefile and Linux' makefile. + +DOS.mak, WIN32.mak, WIN64.mak, and All.mak are pretty stable, and should not +be changed. The only likely case where a change is needed would be to add extra +libraries to link with _all_ programs. +To add a library for one particular program, it'd be better to add a specific +rule in its own make file, as described below. +In all cases, see the detailed notes in each make file header. + +Specific make files: + +To build a target called program.exe, the 5 make files with generic rules +(DOS.mak, WIN32.mak, WIN64.mak, WIN95.mak, and All.mak) first look for a +specific make file called program.mak. They include it if present. This allows +defining application-specific rules. +These rules should use macros defined in the 4 make files to specify the +build environment and parameters. Here's a list of the most useful ones: + +Macro | Description +--------- | ---------------------------------------------------------------- +T | Target OS. One of DOS, WIN32, WIN64, WIN95. +S | Path of the source files +O | Path where to put the object files +B | Path where to put the binary executable files +L | Path where to put the listings +CFLAGS | Flags for Microsoft C compiler +INCLUDE | List of C include file paths, serarated by ';' +LFLAGS | Flags for Microsoft linker +PROGRAM | The program base name, infered from the target name. +SOURCES | The list of sources for the program. Default: PROGRAM.c or .cpp +OBJECTS | The list of objects to link. Default: PROGRAM.obj + +Scripts: + +Script | Description +--------------------- | -------------------------------------------------------- +make.bat | The main build tool. Invokes nmake. +config.%HOSTNAME%.bat | Defines paths to all tools used by make. Do not edit. +configure.bat | Analyses your system, and generates a config.%HOSTNAME%.bat file. +configure.*.bat | Define user or task-specific extensions to configure.bat. +exe.bat | Front end to make.bat, generating multiple goals. +exe | Linux shell script, invoking cc with multiple goals. +src2objs.bat | Internal script used by make files to convert SOURCES to OBJECTS + +configure.bat with search for configure.*.bat scripts in %windir%, then in %HOME%, +then in the current directory. +Put configuration scripts with your global preferences in %windir% for example. +Within each directory, the files are called in the alphabetic order, allowing +to manage predictable dependancies. + +Example 1: The 2clip program has no MS-DOS version. To prevent the make system +from attempting to build a DOS version (Only necessary if you DO have MSVC 1.52 +installed), create a 2clip.mak file with this content: + + !IF "$(T)"=="DOS" + complain: + @echo>con There's no DOS version of this program. + + dirs $(O)\2clip.obj $(B)\2clip.exe: complain + @rem Do nothing + !ENDIF + +Example 2: Porting to Windows a resize.c program manipulating jpeg images, +and using the libjpeg library. Create a resize.mak file with lines like these: + + INCLUDE=$(INCLUDE);C:\JFL\SRC\Libs\libjpeg;C:\JFL\SRC\Libs\libjpeg\jpeg-8d + LFLAGS=$(LFLAGS) C:\JFL\SRC\Libs\libjpeg\$(B)\libjpeg.lib + +Example 3: Some Windows programs need to include additional resources, defined +in a .rc file. Ex: The update program uses a manifest to control its rights. +Create an update.mak file with directives like this: + + !IF "$(T)"=="WIN32" || "$(T)"=="WIN64" + SOURCES=update.c update.rc + LFLAGS=$(LFLAGS) /MANIFEST + !ENDIF + + +The debug system +---------------- + +The MsvcLibX library makes it easy to build two versions of each program: + +- A release version, small lean and fast. +- A debug version, with additional code to help developers debug the program. + +It follows Microsoft's convention of defining the macro _DEBUG when compiling +a C/C++ source for a debug build. +But it goes much further, by providing in debugm.h a set of macros to assist +debugging. + +The general principle is that by default, the debug version operates exactly +like the release version. (Except possibly for performance) +Then, if the "debug mode" is enabled, it outputs debug messages on stdout. +A major property of the MsvcLibX debugging output is that is is intended by +function call depth. This makes it considerably easier to read the debug output. + +The MsvcLibX library itself is built in debug and release versions. +The make.bat system will link the release version of your program with the +release version of the MsvcLibX library, and likewise for the debug versions. +To use it, include debugm.h in your main module, and add to your main() routine +a command-line option (-d or --debug maybe?) that calls DEBUG_ON(). +There's also an "extra debug mode", displaying even more details than the +debug mode. It is enabled by calling DEBUG_ON() twice. ==> Invoke with -d -d. + +Debug macros: + +Macro | Description +--------------------------- | ------------------------------------------------ +DEBUG_ON() | Enable the debug mode. +DEBUG_CODE(...) | The code within parentheses is only compiled in the debug version +DEBUG_PRINTF((format, ...)) | Generates a printf instruction in the debug version only, that prints only if debug mode is enabled, with the output indented by call depth. +DEBUG_ENTER((format, ...)) | Like DEBUG_PRINTF, but for use at the beginning of a function. Increases the indent level. +DEBUG_LEAVE((format, ...)) | Like DEBUG_PRINTF, but for use before returning from a function. Decreases the indent level. + +Note that every use of DEBUG_ENTER must be matched by one DEBUG_LEAVE. So if a +function has several return instructions, every return must be preceded by a +DEBUG_LEAVE. + +DEBUG_LEAVE alternatives: +To further simplify the source, a pair DEBUG_LEAVE()/return can be replaced by +one of the following macros: + +Macro | Simplified description +----------------------------- | ------------------------------------------------ +RETURN_INT(i) | DEBUG_LEAVE(("return %d\n", i)); return i; +RETURN_INT_COMMENT(i, (args)) | Idem, plus prints a comment behind the return +RETURN_BOOL(b) | DEBUG_LEAVE(("return %s\n", b?"TRUE":"FALSE")); return b; +RETURN_BOOL_COMMENT(b, (...)) | Idem, plus prints a comment behind the return +RETURN_CHAR(c) | DEBUG_LEAVE(("return %c\n", c)); return c; +RETURN_STRING(s) | DEBUG_LEAVE(("return %s\n", s)); return s; + +For all the above, the release version just does return retValue; + +Example for a recursive function factorial: + + int fact(int n) { + DEBUG_ENTER((__FUNCTION__ "(%d);\n", n)); + if (n) n *= fact(n-1); else n = 1; + RETURN_INT(n); + } + +The debug version, in debug mode, invoked with argument 4, prints: + + fact(4); + fact(3); + fact(2); + fact(1); + fact(0); + return 1; + return 1; + return 2; + return 6; + return 24; + + +Support for UTF-8 sources +------------------------- + +The MsvcLibX library supports writing C programs using 8-bit characters, +with strings encoded as UTF-8, and that will work for any cmd.exe code page. +This makes the sources much more simple and readable that using full-fledged +Unicode, with 16-bits wchar_t or WCHAR and L"strings" or _T("strings"). + +Note: The cmd.exe code page can be read and changed with the CHCP command. +The most common code pages are: + +CP | Description +----- | ---------------------------------------------------------------------------- +437 | MS-DOS OEM code page, still used by cmd.exe in US and west-European systems. +1252 | Windows "ANSI" code page, used by most GUI programs, like notepad.exe. +65001 | UTF-8 code page. Allows display any Unicode character. + +Important: Changing the code page will only work correctly if cmd.exe is using +a TrueType font. The default "Raster" font supports code page 437 only. + +To enable that UTF-8 support: + +1. Set the C or C++ source encoding to UTF-8 with BOM. (BOM = Byte-Order Mark) +Having a BOM is important, as without it some Windows editors will incorrectly +detect the encoding, and then sometimes corrupt the source. +2. Define one of the following constants in the .c source, _before_ including +any .h include files: + + #define _BSD_SOURCE 1 /* Defined by many standard BSD-Unix programs */ + #define _GNU_SOURCE 1 /* Defined by many standard GNU-Unix/Linux programs */ + #define _UTF8_SOURCE 1 /* MsvcLibX-specific */ + +Note that most modern Linux compilers do expect C sources encoded as UTF-8, +and will silently ignore the UTF-8 BOM if present. + +Internally, MsvcLibX extends Microsoft's convention of having two ANSI and Wide +versions of each routine, respectively with an 'A' and a 'W' suffix. Ex: +FindFirstFile() being an alias to either FindFirstFileA() or FindFirstFileW(). +MsvcLibX uses two additional suffixes: 'U' for the UTF-8 version, and 'M' for +the common MultiByte subroutine used by both the 'A' and 'U' versions. Ex: + +Function | Description +---------- | --------------------------------------------------------------- +readlinkW | Posix routine readlink - Wide char version +readlinkM | MultiByte char sub-routine, used by the next two routines. +readlinkA | Posix routine readlink - ANSI version +readlinkU | Posix routine readlink - UTF-8 version +readlink | Posix routine readlink - Alias to either readlinkA or readlinkU + +Note that the M version has one additional argument: The code page to use for +converting strings to and from Unicode. In that sense, it's not Posix-compliant. + +Gotcha: As of 2014-03-25, most file I/O and enumeration routines have been +restructured this way, but a few have not yet been: +scandir() and lstat() only support UTF-8 file names, not ANSI names. + +Gotcha: As of 2014-03-25, there's a potential issue with the C main() routine: +Supporting UTF-8 file names is not just supporting UTF-8 strings in library +functions. It's also necessary to process the command line, so that command line +arguments are passed in to the main() routine as UTF-8 strings. +Currently this is implemented as a macro that redefines the main token, so +that it generates a main() routine just calling a _mainU0() routine from +MsvcLibX.lib, followed by another local _mainU() routine with the body intended +for your main routine. Ex: + + int main(int argc, char *argv[]) { /* your main body */ } + +Becomes: + + int main(int argc, char *argv[]) {return _mainU0()} + int _mainU(int argc, char *argv[]) { /* your main body */ } + +The _mainU0() routine from MsvcLibX.lib reprocesses the Win32 command line as +UTF-8 argv[] arguments, then calls _mainU(argc, argv[]). +This works well and transparently, except in one case: +If one of your sources or include files contain a prototype for the main() +routine, then MsvcLibX' main macro will break that prototype, and cause +compilation and/or link errors. +If this happens, simply remove the main() prototype, which is useless anyway. + + +Support for NTFS symlinks and junctions +--------------------------------------- + +Posix defines only a single kind of symbolic links, usable for any kind of +targets, whether they're files, directories, or further symbolic links. +The standard C library defines functions for managing symbolic links: + +Function | Description +---------- | ---------------------------------------------------------------- +readlink() | Read a link target +symlink() | Create a link, or change its target +lstat() | Read the metadata (timestamp, access rights) for the link itself +lchmod() | Change the link access rights +lchown() | Change the link owner +realpath() | Generate an absolute path, with all links resolved + +Windows defines three types of links: + +Type | Description +--------- | --------------------------------------------------------------- +SYMLINK | Symbolic link to a file +SYMLINKD | Symbolic link to a directory +JUNCTION | Mount point, often used as a symbolic link to another directory + +All three types can be created in Vista and later by the mklink command. +JUNCTIONS can also be created in 2000 and later by Microsoft's SysInternal's +junction command. +One important difference is that JUNCTIONs can be created with normal user +rights, whereas SYMLINKs and SYMLINKDs require administrator rights in an +elevated command window. +A second important difference is that on networks, SYMLINKs and SYMLINKDs are +interpreted on the client side, whereas JUNCTIONs are interpreted on the server +side (despite having their target readable from the client side). + +The MsvcLibcX library tries to hide that complexity, and implements the standard +functions as if there were only one kind of link. +It also provides non-standard functions symlinkd() and junction() to +specifically create SYMLINKDs and JUNCTIONs respectively. + +Notes about readlink(): +For SYMLINKs and SYMLINKDs, the case is straightforward. +For JUNCTIONs, there are two problems: + +- The target is stored as an absolute path, even when the JUNCTION was created + with a relative path. readlink() tries to convert the absolute path to a + relative path, so that file copying utilities can clone trees with internal + JUNCTIONs. +- When the JUNCTION is on a network drive, the target refers to the absolute + path on the server. This may not be accessible from the client through the + existing mounted shares. Even when this is accessible, it's not always easy + to map the server path to a valid client path. + readlink() uses heuristics which always work for drives shared at the drive + level. Ex: a C: drive shared as C$, a D: drive shared as D$, etc. + The heuristic also very likely works for drives shared at the root or first + directory level. Ex: C:\ shared as CROOT, or C:\Public shared as PUBLIC. + As of 2014-03-25, it'll fail in any other case. Ex: + C:\Users\YOURNAME shared as YOURHOME, + or a C:\Public share mounted through its subdirectory C:\Public\Temp + +Notes about symlink(): +symlink() will attempt to create a SYMLINK or a SYMLINKD, depending on the type +of the target. This works well when the target exists. But when it does not +(which is legal), it will create a SYMLINK by default, or a SYMLINKD if the +target ends with a '/' or a '\'. Posix allows, but does not require, providing +a trailing '/', so the link type may possibly be incorrect. +junction() will have the same issues as readlink() above. + +Notes about junction(): +The problem for junction() is to convert a client-side target pathname provided +by the program running on the client, to a server-side pathname, necessary for +junctions to work. +For full-drive shares (i.e. any share named like D$), this is easy. +For non-full-drive shares (i.e. anything else), it will assume this is a +first level shared directory on the C: drive. Ex: A link on share PUBLIC +will be targeted at C:\PUBLIC. +Problem: The junction will not work if the share actually resides anywhere else +on the server. But, surprisingly, there's an easy workaround: +Simply create manually on the server itself, a junction called C:\PUBLIC, +pointing at the actual directory shared as PUBLIC. +This way the junctions created from the client side will work correctly, both +on the client and on the server side, after being resolved on the server side +through that second junction. + + +Support for Windows 95/98 +------------------------- + +The configure.bat script searches for old versions of the Visual C++ compiler, +which can build WIN32 programs that can run in Windows 95/98/ME/NT4. +The most recent of these is Visual C++ 8, from Visual Studio 2005. +The make.bat script can then use rules in win95.mak to builds WIN32 programs +that will run in any version of Windows from Windown 95 to Windows 10. + +Note however that Windows 95/98/ME only have a very limited support for Unicode +built in. The rest of this section mentions 95, but applies to 98 & ME as well. +The MsvcLibX library uses a number of Unicode functions not available in default +installations of Windows 95. This includes all file management functions. +Thus most of our WIN95 executables will not work by default in Windows 95. +To allow them to work, it is necessary to download from Microsoft a "Microsoft +Layer for Unicode on Windows 95/98/ME Systems" (MSLU for short), and install it +on the Windows 95 system. See the following links for details: +https://en.wikipedia.org/wiki/Microsoft_Layer_for_Unicode +https://msdn.microsoft.com/en-us/goglobal/bb688166.aspx +MSLU installation procedure: + +- Download the MSLU redistributable setup (unicows.exe) from: + http://go.microsoft.com/fwlink/?LinkId=14851 +- Extract unicows.dll from the unicows.exe archive. +- Copy that unicows.dll to the Windows 95 system, into %windir%\System. + +Testing WIN95 executables in a Windows 95 VM +VMWare Player does not have Windows 95 drivers for the HGFS file system. +This prevents accessing the host's files directly as network files, as is +usually done for Windows XP and later versions of Windows. +It is not possible to use network shares either, as Windows 95 only supports +the SMB 1 protocol, which is actively blocked by Windows Vista and later hosts. +It is possible, but inconvenient, to transit through a web server, and download +the files in the Windows 95 VM using Internet Explorer 4. +The best solution probably is to transit through a floppy or CD image, and +mount that image in the VM Player. Many tools, including our own HpMkIso.exe +can create CD images. A very convenient shareware called WinImage allows to +create floppy images. +Another solution is to install a Web server on the host PC, and use Internet +Explorer 4 in Windows 95 to download the executable files into the VM. + + +Support for DOS, and bound DOS+Windows programs +----------------------------------------------- + +- If Visual C++ 1.52 is installed, configure.bat will setup the make system +for building the MS-DOS version of your programs. (Output in the DOS directory) +- If Visual C++ 8 is installed, configure.bat will setup the make system +for building 32-bits versions of your programs compatible with Windows 95 +and all later versions, including 64-bits ones. (Output in the WIN95 directory) + +Both are available as part of the Visual Studio 2005 CD, still available for +download for MSDN subscribers from the MSDN web site. + +Win32 programs have an "MS-DOS stub", that runs when the Windows program is +executed under MS-DOS. +The default stub used by the Win32 linker if a tiny DOS program that displays +an error message such as: "This program can only run in Windows" + +When it builds the WIN95 or WIN32 version of a program, and when it has built +the DOS version already, the MsvcLibX make system uses that DOS version as the +stub for the Windows version. +This allows building executables that work in *all* versions of DOS and Windows! + +- When run in MS-DOS, it's the DOS stub of the exe that runs. +- When run in Windows (even 64-bits versions), it's the Win32 part that runs. + +Note that the make system will build such bound executables for any WIN32 +build made with more recent compilers. But these recent compilers generate +executables that cannot run in old versions of Windows. For example, the +Visual C++ 14 compiler can only target Windows Vista and later systems. +Having an executable that can run in DOS and Windows 7, but not in Windows XP, +is not very useful. Make sure to install the Visual C++ 8 compiler in parallel +with Visual C++ 1.52, and the latest compiler (Visual C++ 14 at the time of +this writing), to generate truly universal WIN95 builds, that run in +DOS/95/98/ME/2000/XP/Vista/7/8/10. + + +History +------- + +**1986** + +I (Jean-François Larvoire) started writing command-line tools for MS-DOS. +Some were enumerating files, using inline assembly language to make MS-DOS +interrupt 21h system calls: update, dirsize, redo, backnum, which, dirc... +To make it simple I factored these out in subroutines srch1st and srchnext, +that I manually copied from one program to the next. +Things got a bit tricky to support recursion, which was not straightforward +in MS-DOS. + + +**1992** + +We got an OS/2 server, and I started porting the above programs to OS/2. +MS-DOS was still important, so I used conditional compilation to support +both operating systems with the same source. +I wrote a second version of srch1st and srchnext for OS/2, and had to +include a new routine srchdone due to OS/2 API constraints. +dirc was the first program I ported, then I slowly duplicated the code into +the other programs. Synchronizing bug fixes became more difficult. +A nice trick was the OS/2 supported dual-mode EXEs, with both the DOS and +OS/2 version bound in the same .exe file. + + +**1995** + +We ditched the OS/2 server, and got a new one running Windows NT. +Again, I created a third conditionally compiled version of srch1st/srchnext/ +srchdone for WIN32, for use in dirc. +Manually back porting the updates and bug fixes to all programs became +really painful, and took several years. +Like OS/2, Windows supported dual-mode EXEs, and I updated my make files +to include both the DOS and Windows version in the same file. + + +**2005** + +I started working on Linux projects. Despite the bonanza of command-line +tools available, I couldn't find one equivalent to dirc. +So, yet another time, I created a fourth conditionally compiled version of +srch1st/srchnext/srchdone for Linux, and obtained a Linux version of dirc. +I also ported it and a couple of other programs to Tru64, which was the +first 64-bits OS I worked with. This exposed a few unsuspected bugs. +The thing became so complex than porting the changes and updates to the +other programs was a nightmare. I did it for a few of them, but never +got the time to port them all. + + +**2010** + +Building WIN64 versions was relatively easier due to the Tru64 precedent, +but added yet another set of conditional compilations. +The porting nightmare worsened. + + +**2012** + +I tried porting some unrelated Linux programs to Windows, and hit a wall: +Many include files and standard C library routines were missing in MSVC. +I then tried using MinGW, but it too was missing many required features! +I considered contributing updates to MinGW, but that project was too +complex and ill-documented at that time, and I eventually gave up. +Instead, I started writing my own "libc-ext" library of include files and +routines to supplement MSVC. +Ex: stdint.h, inttypes.h, fnmatch.h/fnmatch.c, ... +Also it became obvious that multiplying conditional compilations and +duplicating directory access code everywhere was wrong. Instead I had to +write standard dirent.h/dirent.c routines for DOS/OS2/Windows, and +rewrite all my programs around these standard routines. +I did it for DOS and Windows versions, and left stubs of the OS/2 versions, +for the unlikely case where somebody wants to revive them. + +**2013** + +The restructuration was over for dirc, dirsize, which, backnum, update. +The library got its final name, "MsvcLibX", to better match it purpose: +An extension of the Microsoft Visual C library, not of the standard libc. +As the library grew, debugging it became more difficult, and I decided to +use my debugm.h within the library: This file contains a set of debugging +macros I had developed for other programs. +I started thinking about sorely needed improvements: + +- There was no support for Windows symlinks and junctions. +- The Windows versions of the programs output ANSI file names into a + cmd.exe window using the OEM character set. This caused all files with + French names to be shown as garbage. +- Worse still, I had a few files and directories with non-ANSI names + (In Russian and Chinese), that caused the programs to fail! + +The Linux version of the program did not have these issues, as all recent +versions of Linux use the UTF-8 encoding, and this works transparently +even for old programs using 8-bits characters like mine. + + +**2014** + +I got a bit more time, and started working on a redesign of MsvcLibX's +dirent.c/dirent.h, and added lstat.c, symlink.c, readlink.c, etc, to +support symlinks, junctions, and UTF-8 file names. +This proved to be much more work than I initially thought, but the result +was worth the effort: dirc, update got easily adapted, with remarkably +few changes to their source. Adding recursion to update was easy. +I'm now able to use update to backup all files on my system, including +symbolic links, and junctions used as poor man's links. And the programs +now display names correctly in any code page with the right font. +A seventh program, truename, joined the collection using dirent.h routines. +Later in the year, I made significant other changes: + +- Split make.bat into a generic make.bat/configure.bat pair of scripts. + configure.bat needs to be run once, plus everytime the environment + changes. (Such as if a new MSVC version is installed.) + Project-specific definitions are moved to new files, such as our + configure.MsvcLibX.bat. +- Added a general mechanism for defining extensions to existing MSVC + include files. This allowed defining our own homonym include files, + containing just the missing definitions. Which in turn allowed to move + many such definitions, that were initially stored in unistd.h for lack + of an alternative, to their standard location. +- Updated all file functions to support WIN32 pathnames > 260 characters. + (The basic WIN32 functions that I used until then had that limitation; + I'm now using extended functions supporting path lengths up to 64K.) + +All tools like dirc, dirsize, which, backnum, update, truename, redo +benefit from that last change. + +**2015** + +A major improvement was the addition of support for new operating systems +and processor targets. This required redesigning several things: +The OS-specific definition macros have been renamed to more generic names. +The DosWin.mak file has been replaced by a more generic All.mak, +supporting the old dos.mak, win32.mak, and win64.mak, plus the new... + +- bios.mak Allows building 16-bits programs that can run in BIOS option + ROMs. These programs are based on the BiosLib library, + documented separately. +- win95.mak Allows building win32 programs that run in Windows 95. +- ia64.mak Allows building 64-bits programs that run in IA64 versions + of Windows. Not tested. +- arm.mak Allows building win32 programs for Windows RT. + Tests failed so far, due to a missing "ARM Desktop SDK". + +All.mak also skips building versions for which no tools are available; +This prevents problems in the normal case when people only have the latest +version of MSVC. In this case, it just builds the WIN32 and WIN64 versions. +The support for Windows 95 required fixing numerous issues with old +Microsoft tools and Windows SDKs. +Conversely, the support for Visual Studio 15 also required fixing lots of +issues, as the MSVC library has been completely redesigned, and split into +two parts: + +- A compiler-specific part, part of the compiler tree as before. +- A generic part, called Universal C runtime (UCRT) that's now part of + the windows SDK. + +And of course there were also issues with MsvcLibX recent improvements, +like Unicode support and symlink support, which had never been tested, +and of course did not work, in Windows 95 and XP. + + +**2016** + +Many significant changes and improvements this year: + +- Changed the UTF-8 C source support to require a UTF-8 BOM. + This is to prevent problems with Windows tools that tend to corrupt files + without a UTF-8 BOM, but with other UTF-8 characters. + This required changing all C/C++ compilation rules to first remove the + UTF-8 BOM, as MS compilers do not react correctly when they find one. +- Added a windows.h extension. + Just like Standard C library APIs, windows 8-bit APIs can be overriden to + refer to custom routines that support UTF-8 strings. + The MsvcLibX library was beginning to use a significant number of these + custom routines internally. They're now accessible directly to outside + UTF-8 programs targeting only Windows. +- Finished implementing support for the OUTDIR variable. (Started in 2015.) + All make files now optionally create output files in an %OUTDIR% directory. + This is intended for testing builds in VMs, with shared sources on the + host, but the output locally in the VM, avoiding to overwrite the main + version on the host. IF %OUTDIR% is not defined, the default output + still goes below the source directory as before. diff --git a/deps/MsvcLibX/config.DESKTOP-U79TD6T.bat b/deps/MsvcLibX/config.DESKTOP-U79TD6T.bat new file mode 100644 index 0000000000000000000000000000000000000000..b1b68e1540ff11bfd8fd1eee985bb28d0f439044 --- /dev/null +++ b/deps/MsvcLibX/config.DESKTOP-U79TD6T.bat @@ -0,0 +1,146 @@ +:# config.DESKTOP-U79TD6T.bat generated by configure.bat on 2020/05/19 Öܶþ 7:49:05.47 +:# +:# If changes are needeed, do not edit this file, but instead create a new script +:# called configure.YOURCHOICE.bat. This new script will be invoked automatically +:# by configure.bat while creating this file. Then your script can write extra +:# definitions, or change some of the variables before configure.bat writes them. +:# +:# Invoke configure.bat manually if anything changes in the tools config, such as +:# installing a Visual Studio update, or updating a configure.XXX.bat script. + +set "HAS_STINCLUDE=1" &:# Found the System Tools global C includes +set "STINCLUDE=C:\Users\admin\Desktop\temp\MyGitHub\C\include" &:# System Tools global C includes +set "HAS_SDK_FLAGS=/DHAS_STINCLUDE=1" &:# SDK detection flags for the C compiler + +SET "PF32=C:\Program Files (x86)" &:# 32-bits Program Files +SET "PF64=C:\Program Files" &:# 64-bits Program Files +SET "ARCH=AMD64" &:# PROCESSOR_ARCHITECTURE + +SET "MASM=" &:# Microsoft 16-bits Assembler base path +SET "MSVC=" &:# Microsoft 16-bits Visual C++ base path +SET "MAPSYM=" &:# 16-bits debugging symbols generator + +SET "VSTUDIOLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0" &:# Microsoft Visual Studio (Long path) +SET "VSTUDIO=C:\PROGRA~2\MICROS~2.0" &:# Microsoft Visual Studio (Short path) +SET "VSCOMMONLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7" &:# Microsoft Visual Studio Common Files (Long path) +SET "VSCOMMON=C:\PROGRA~2\MICROS~2.0\Common7" &:# Microsoft Visual Studio Common Files (Short path) +SET "VSIDELONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE" &:# Microsoft Visual Studio IDE Files (Long path) +SET "VSIDE=C:\PROGRA~2\MICROS~2.0\Common7\IDE" &:# Microsoft Visual Studio IDE Files (Short path) +SET "VSTOOLSLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools" &:# Microsoft Visual Studio Tools (Long paths) +SET "VSTOOLS=C:\PROGRA~2\MICROS~2.0\Common7\Tools" &:# Microsoft Visual Studio Tools (Short paths) +SET "MSVC32LONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC" &:# Microsoft Visual C++ 32/64 bits (Long path) +SET "MSVC32=C:\PROGRA~2\MICROS~2.0\VC" &:# Microsoft Visual C++ 32/64 bits (Short path) + +SET "WIN_CP=936" &:# Windows Code Page +SET "WIN_CS=gb2312" &:# Windows Character Set +SET "DOS_CP=936" &:# DOS Code Page +SET "DOS_CS=gb2312" &:# DOS Character Set + +SET "AS=" &:# Assembler +SET "CC=" &:# C compiler +SET "INCLUDE=C:\Users\admin\Desktop\temp\MyGitHub\C\include" &:# Include paths. Define USER_INCLUDE if needed. +SET "LK=" &:# Linker +SET "LIB=" &:# Libraries paths. Define USER_LIBS if needed. +SET "LB=" &:# Library manager +SET "RC=" &:# Resource compiler +SET "MT=" &:# Manifest tool + +SET "DOS_CC=" &:# Microsoft Visual C++ 16-bits compiler +SET "DOS_AS=" &:# Microsoft 16-bits assembler +SET "DOS_LK=" &:# Microsoft 16-bits linker +SET "DOS_LB=" &:# Microsoft 16-bits librarian +SET "DOS_RC=" &:# Microsoft 16-bits resource compiler +SET "DOS_MT=" &:# Microsoft 16-bits manifest tool +SET "DOS_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for 16-bits compilation +SET "DOS_VCINC=" &:# Visual C++ 16-bits compiler include dir for MsvcLibX include_next +SET "DOS_CRTINC=" &:# Visual C++ 16-bits CRT library include dir for MsvcLibX include_next +SET "DOS_INCPATH=" &:# Include paths for 16-bits compilation +SET "DOS_LIBPATH=" &:# Libraries paths for 16-bits linking +SET "DOS_WINSDK=" &:# Microsoft Windows 16-bits SDK +SET "DOS_WINSDKINC=" &:# Microsoft Windows 16-bits SDK Include directory + +SET "WIN95_CC=" &:# Microsoft Visual C++ 32-bits compiler +SET "WIN95_AS=" &:# Microsoft 32-bits assembler +SET "WIN95_LK=" &:# Microsoft 32-bits linker +SET "WIN95_LB=" &:# Microsoft 32-bits librarian +SET "WIN95_RC=" &:# Microsoft 32-bits resource compiler +SET "WIN95_MT=" &:# Microsoft 32-bits manifest tool +SET "WIN95_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for 32-bits compilation +SET "WIN95_VCINC=" &:# Visual C++ 32-bits compiler include dir for MsvcLibX include_next +SET "WIN95_CRTINC=" &:# Visual C++ 32-bits CRT library include dir for MsvcLibX include_next +SET "WIN95_INCPATH=" &:# Include paths for 32-bits compilation +SET "WIN95_LIBPATH=" &:# Libraries paths for 32-bits linking +SET "WIN95_WINSDK=" &:# Microsoft Windows 32-bits SDK +SET "WIN95_WINSDKINC=" &:# Microsoft Windows 32-bits SDK Include directory + +SET "WIN32_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.EXE"" &:# Microsoft Visual C++ 32-bits compiler +SET "WIN32_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\ML.EXE"" &:# Microsoft 32-bits assembler +SET "WIN32_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\LINK.EXE"" &:# Microsoft 32-bits linker +SET "WIN32_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\LIB.EXE"" &:# Microsoft 32-bits librarian +SET "WIN32_RC=" &:# Microsoft 32-bits resource compiler +SET "WIN32_MT=" &:# Microsoft 32-bits manifest tool +SET "WIN32_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for 32-bits compilation +SET "WIN32_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ 32-bits compiler include dir for MsvcLibX include_next +SET "WIN32_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ 32-bits CRT library include dir for MsvcLibX include_next +SET "WIN32_INCPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for 32-bits compilation +SET "WIN32_LIBPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86" &:# Libraries paths for 32-bits linking +SET "WIN32_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows 32-bits SDK +SET "WIN32_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows 32-bits SDK Include directory + +SET "IA64_CC=" &:# Microsoft Visual C++ IA64 compiler +SET "IA64_AS=" &:# Microsoft IA64 assembler +SET "IA64_LK=" &:# Microsoft IA64 linker +SET "IA64_LB=" &:# Microsoft IA64 librarian +SET "IA64_RC=" &:# Microsoft IA64 resource compiler +SET "IA64_MT=" &:# Microsoft IA64 manifest tool +SET "IA64_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for IA64 compilation +SET "IA64_VCINC=" &:# Visual C++ IA64 compiler include dir for MsvcLibX include_next +SET "IA64_CRTINC=" &:# Visual C++ IA64 CRT library include dir for MsvcLibX include_next +SET "IA64_INCPATH=" &:# Include paths for IA64 compilation +SET "IA64_LIBPATH=" &:# Libraries paths for IA64 linking +SET "IA64_WINSDK=" &:# Microsoft Windows IA64 SDK +SET "IA64_WINSDKINC=" &:# Microsoft Windows IA64 SDK Include directory + +SET "WIN64_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\CL.EXE"" &:# Microsoft Visual C++ 64-bits compiler +SET "WIN64_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ML64.EXE"" &:# Microsoft 64-bits assembler +SET "WIN64_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\LINK.EXE"" &:# Microsoft 64-bits linker +SET "WIN64_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\LIB.EXE"" &:# Microsoft 64-bits librarian +SET "WIN64_RC=" &:# Microsoft 64-bits resource compiler +SET "WIN64_MT=" &:# Microsoft 64-bits manifest tool +SET "WIN64_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for 64-bits compilation +SET "WIN64_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ 64-bits compiler include dir for MsvcLibX include_next +SET "WIN64_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ 64-bits CRT library include dir for MsvcLibX include_next +SET "WIN64_INCPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for 64-bits compilation +SET "WIN64_LIBPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64" &:# Libraries paths for 64-bits linking +SET "WIN64_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows 64-bits SDK +SET "WIN64_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows 64-bits SDK Include directory + +SET "ARM_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\CL.EXE"" &:# Microsoft Visual C++ ARM compiler +SET "ARM_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\ARMASM.EXE"" &:# Microsoft ARM assembler +SET "ARM_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\LINK.EXE"" &:# Microsoft ARM linker +SET "ARM_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\LIB.EXE"" &:# Microsoft ARM librarian +SET "ARM_RC=" &:# Microsoft ARM resource compiler +SET "ARM_MT=" &:# Microsoft ARM manifest tool +SET "ARM_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for ARM compilation +SET "ARM_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ ARM compiler include dir for MsvcLibX include_next +SET "ARM_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ ARM CRT library include dir for MsvcLibX include_next +SET "ARM_INCPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for ARM compilation +SET "ARM_LIBPATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm" &:# Libraries paths for ARM linking +SET "ARM_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows ARM SDK +SET "ARM_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows ARM SDK Include directory + +SET "ARM64_CC=" &:# Microsoft Visual C++ ARM64 compiler +SET "ARM64_AS=" &:# Microsoft ARM64 assembler +SET "ARM64_LK=" &:# Microsoft ARM64 linker +SET "ARM64_LB=" &:# Microsoft ARM64 librarian +SET "ARM64_RC=" &:# Microsoft ARM64 resource compiler +SET "ARM64_MT=" &:# Microsoft ARM64 manifest tool +SET "ARM64_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for ARM64 compilation +SET "ARM64_VCINC=" &:# Visual C++ ARM64 compiler include dir for MsvcLibX include_next +SET "ARM64_CRTINC=" &:# Visual C++ ARM64 CRT library include dir for MsvcLibX include_next +SET "ARM64_INCPATH=" &:# Include paths for ARM64 compilation +SET "ARM64_LIBPATH=" &:# Libraries paths for ARM64 linking +SET "ARM64_WINSDK=" &:# Microsoft Windows ARM64 SDK +SET "ARM64_WINSDKINC=" &:# Microsoft Windows ARM64 SDK Include directory + +exit /b 0 &:# Configuration done successfully diff --git a/deps/MsvcLibX/configure.bat b/deps/MsvcLibX/configure.bat new file mode 100644 index 0000000000000000000000000000000000000000..7037eb92afccbfe2e0d6872a108799d56538c490 --- /dev/null +++ b/deps/MsvcLibX/configure.bat @@ -0,0 +1,35 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: configure.bat * +:# * +:# Description: Detect system-specific settings and create config.*.bat * +:# * +:# Notes: Proxy script for %STINCLUDE%\configure.bat. * +:# * +:# Make any change needed in %STINCLUDE%\configure.bat. * +:# * +:# History: * +:# 2016-10-10 JFL jf.larvoire@hpe.com created this file. * +:# 2016-12-15 JFL Search for the real make.bat in [.|..|../..]\include. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +:# Get the full pathname of the STINCLUDE library directory +if defined STINCLUDE if not exist "%STINCLUDE%\make.bat" set "STINCLUDE=" &:# Allow overriding with another alias name, but ignore invalid overrides +for %%p in (. .. ..\..) do if not defined STINCLUDE if exist %%p\include\make.bat ( :# Default: Search it the current directory, and 2 levels above. + for /f "delims=" %%d in ('"pushd %%p\include & cd & popd"') do SET "STINCLUDE=%%d" +) +if not defined STINCLUDE ( :# Try getting the copy in the master environment + for /f "tokens=3" %%v in ('reg query "HKCU\Environment" /v STINCLUDE 2^>NUL') do set "STINCLUDE=%%v" +) + +if not exist %STINCLUDE%\make.bat ( + >&2 echo %0 Error: Cannot find SysToolsLib's global C include directory. Please define variable STINCLUDE. + exit /b 1 +) + +if [%1]==[-d] echo "%STINCLUDE%\configure.bat" %* +"%STINCLUDE%\configure.bat" %* diff --git a/deps/MsvcLibX/include/debugm.h b/deps/MsvcLibX/include/debugm.h new file mode 100644 index 0000000000000000000000000000000000000000..b20a7035c696864324e9a496cfaf5e777f5d0cd1 --- /dev/null +++ b/deps/MsvcLibX/include/debugm.h @@ -0,0 +1,206 @@ +/*****************************************************************************\ +* * +* Filename: debugm.h * +* * +* Description: Debug macros * +* * +* Notes: Macros inspired by my Tcl/Bash/Batch debugging libraries. * +* The idea is to output the function call stack, indenting * +* subroutines proportionally to the call depth. * +* To ease reading the output, it must look like real C code.* +* * +* DEBUG_GLOBALS Define global variables used by macros below: * +* int iDebug = FALSE; Global variable enabling debug output if TRUE.* +* int iIndent = 0; Global variable controlling debug indentation.* +* * +* DEBUG_PRINTF((format, ...)) Print a debug string if debug is on. * +* The double parenthesis are necessary * +* because C90 does not support macros * +* with variable list of arguments. * +* DEBUG_ENTER((format, ...)) Print a function name and arguments. * +* Increase indentation of further calls.* +* It's the caller's responsibility to * +* format the routine name and arguments.* +* DEBUG_LEAVE((format, ...)) Print a function return value. * +* Decrease indentation of further calls.* +* It's the caller's responsibility to * +* format the return instruction & value.* +* * +* Any call to DEBUG_ENTER MUST be matched by one call to * +* DEBUG_LEAVE or RETURN_... when the function returns. * * +* * +* History: * +* 2012-01-16 JFL jf.larvoire@hp.com created this file. * +* 2012-02-03 JFL Renamed DEBUG_IF_IS_ON DEBUG_CODE_IF_ON. * +* Renamed file from debug.h to debugm.h because of a file * +* name collision with another library on my PC. * +* 2014-02-10 JFL Added macros for an extra debug mode. * +* 2014-07-02 JFL renamed macro RETURN() as RETURN_CONST(), and defined * +* new macro RETURN() to return nothing. * +* Idem for RETURN_COMMENT() as RETURN_CONST_COMMENT(). * +* 2016-09-09 JFL Flush every DEBUG_PRINTF output, to make sure to see * +* every debug string printed before a program crash. * +* 2016-09-13 JFL Added macros DEBUG_WSTR2NEWUTF8() and DEBUG_FREEUTF8(). * +* 2016-10-04 JFL Added macros DEBUG_OFF(), DEBUG_MORE(), DEBUG_LESS(). * +* Allow using DEBUG_ON()/MORE()/LESS()/OFF() in release mode. +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _DEBUGM_H +#define _DEBUGM_H 1 + +#include /* Macros use printf */ + +#ifdef _MSC_VER +#pragma warning(disable:4127) /* Avoid warnings on while(0) below */ +#endif + +#define DEBUG_DO(code) do {code} while (0) +#define DEBUG_DO_NOTHING() do {} while (0) + +/* Conditional compilation based on Microsoft's standard _DEBUG definition */ +#if defined(_DEBUG) + +#define DEBUG_VERSION " Debug" + +#define DEBUG_GLOBALS \ +int iDebug = 0; /* Global variable enabling debug output if TRUE. */ \ +int iIndent = 0; /* Global variable controlling debug indentation. */ + +extern int iDebug; /* Global variable enabling of disabling debug messages */ +#define DEBUG_ON() iDebug = 1 /* Turn debug mode on */ +#define DEBUG_MORE() iDebug += 1 /* Increase the debug level */ +#define DEBUG_LESS() iDebug -= 1 /* Decrease the debug level */ +#define DEBUG_OFF() iDebug = 0 /* Turn debug mode off */ +#define DEBUG_IS_ON() (iDebug > 0) /* Check if the debug mode is enabled */ +#define XDEBUG_ON() iDebug = 2 /* Turn extra debug mode on. Same as calling DEBUG_MORE() twice. */ +#define XDEBUG_IS_ON() (iDebug > 1) /* Check if the extra debug mode is enabled */ + +#define DEBUG_CODE(code) code /* Code included in the _DEBUG version only */ +#define DEBUG_CODE_IF_ON(code) DEBUG_CODE(if (DEBUG_IS_ON()) {code}) /* + Debug code executed if debug mode is on */ +#define XDEBUG_CODE_IF_ON(code) DEBUG_CODE(if (XDEBUG_IS_ON()) {code}) /* + Debug code executed if extra debug mode is on */ + +extern int iIndent; /* Debug messages indentation */ +#define DEBUG_INDENT_STEP 2 /* How many spaces to add for each indentation level */ +#define DEBUG_PRINT_INDENT() printf("%*s", iIndent, "") + +/* Debug code, conditionally printing a string based on global variable 'debug' */ +/* The enter and leave variants print, then respectively increase or decrease indentation, + to make recursive calls easier to review. */ +#define DEBUG_FPRINTF(args) DEBUG_DO(if (DEBUG_IS_ON()) {DEBUG_PRINT_INDENT(); fprintf args;}) +#define DEBUG_PRINTF(args) DEBUG_DO(if (DEBUG_IS_ON()) {DEBUG_PRINT_INDENT(); printf args; fflush(stdout);}) +#define XDEBUG_PRINTF(args) DEBUG_DO(if (XDEBUG_IS_ON()) {DEBUG_PRINT_INDENT(); printf args; fflush(stdout);}) +#define DEBUG_ENTER(args) DEBUG_DO(DEBUG_PRINTF(args); iIndent += DEBUG_INDENT_STEP;) +#define DEBUG_LEAVE(args) DEBUG_DO(DEBUG_PRINTF(args); iIndent -= DEBUG_INDENT_STEP;) + +#define DEBUG_RETURN_INT(i, comment) DEBUG_DO(int DEBUG_i = (i); \ + DEBUG_LEAVE(("return %d; // " comment "\n", DEBUG_i)); return DEBUG_i;) + +/* print return instruction and decrease indent */ +#define RETURN() DEBUG_DO(DEBUG_LEAVE(("return;\n")); return;) +#define RETURN_CONST(value) DEBUG_DO(DEBUG_LEAVE(("return %s;\n", #value)); return value;) +#define RETURN_INT(i) DEBUG_DO(int DEBUG_i = (i); \ + DEBUG_LEAVE(("return %d;\n", DEBUG_i)); return DEBUG_i;) +#define RETURN_STRING(s) DEBUG_DO(char *DEBUG_s = (s); \ + DEBUG_LEAVE(("return \"%s\";\n", DEBUG_s)); return DEBUG_s;) +#define RETURN_CHAR(c) DEBUG_DO(char DEBUG_c = (c); \ + DEBUG_LEAVE(("return '%c';\n", DEBUG_c)); return DEBUG_c;) +#define RETURN_BOOL(b) DEBUG_DO(int DEBUG_b = (b); \ + DEBUG_LEAVE(("return %s;\n", DEBUG_b ? "TRUE" : "FALSE")); return DEBUG_b;) + +#define RETURN_COMMENT(args) DEBUG_DO(DEBUG_LEAVE(("return; // ")); \ + if (DEBUG_IS_ON()) printf args; return;) +#define RETURN_CONST_COMMENT(value, args) DEBUG_DO(DEBUG_LEAVE(("return %s; // ", #value)); \ + if (DEBUG_IS_ON()) printf args; return value;) +#define RETURN_INT_COMMENT(i, args) DEBUG_DO(int DEBUG_i = (i); \ + DEBUG_LEAVE(("return %d; // ", DEBUG_i)); if (DEBUG_IS_ON()) printf args; return DEBUG_i;) +#define RETURN_BOOL_COMMENT(b, args) DEBUG_DO(int DEBUG_b = (b); \ + DEBUG_LEAVE(("return %s; // ", DEBUG_b ? "TRUE" : "FALSE")); if (DEBUG_IS_ON()) printf args; return DEBUG_b;) + +#else /* !defined(_DEBUG) */ + +#define DEBUG_VERSION "" /* Non debug version: Simply don't say it */ + +#define DEBUG_GLOBALS + +#define DEBUG_ON() (void)0 +#define DEBUG_MORE() (void)0 +#define DEBUG_LESS() (void)0 +#define DEBUG_OFF() (void)0 +#define DEBUG_IS_ON() 0 +#define XDEBUG_IS_ON() 0 +#define DEBUG_CODE(code) /* Code included in _DEBUG version only */ +#define DEBUG_CODE_IF_ON(code) /* Code included in _DEBUG version only */ +#define XDEBUG_CODE_IF_ON(code) /* Code included in _DEBUG version only */ + +#define DEBUG_PRINT_INDENT() DEBUG_DO_NOTHING() /* Print call-depth spaces */ + +#define DEBUG_FPRINTF(args) DEBUG_DO_NOTHING() /* Print a debug string to a stream */ +#define DEBUG_PRINTF(args) DEBUG_DO_NOTHING() /* Print a debug string to stdout */ +#define XDEBUG_PRINTF(args) DEBUG_DO_NOTHING() /* Print an extra debug string to stdout */ +#define DEBUG_ENTER(args) DEBUG_DO_NOTHING() /* Print and increase indent */ +#define DEBUG_LEAVE(args) DEBUG_DO_NOTHING() /* Print and decrease indent */ + +#define DEBUG_RETURN_INT(i, comment) return(i) + +/* print return instruction and decrease indent */ +#define RETURN() return +#define RETURN_CONST(value) return(value) +#define RETURN_INT(i) return(i) +#define RETURN_STRING(s) return(s) +#define RETURN_CHAR(c) return(c) +#define RETURN_BOOL(b) return(b) + +#define RETURN_COMMENT(args) return +#define RETURN_CONST_COMMENT(value, args) return(value) +#define RETURN_INT_COMMENT(i, args) return(i) +#define RETURN_BOOL_COMMENT(b, args) return(b) + +#endif /* defined(_DEBUG) */ + +#define STRINGIZE(s) #s /* Convert a macro name to a string */ +#define VALUEIZE(s) STRINGIZE(s) /* Convert a macro value to a string */ +#define MACRODEF(s) "#define " #s " " STRINGIZE(s) + +/* Display a macro name and value. */ +#define DEBUG_PRINT_MACRO(name) DEBUG_DO( \ + const char *pszName = #name; /* Don't use STRINGIZE because we're already inside a macro */ \ + const char *pszValue = STRINGIZE(name); /* Don't use VALUEIZE because we're already inside a macro */ \ + DEBUG_PRINT_INDENT(); \ + if (strcmp(pszName, pszValue)) { \ + printf("#define %s %s\n", pszName, pszValue); \ + } else { /* Not 100% certain, but most likely. */ \ + printf("#undef %s\n", pszName); \ + } \ +) + +#ifdef _WIN32 + +/* Helper macros for displaying Unicode strings */ +#define DEBUG_WSTR2UTF8(from, to, toSize) DEBUG_CODE( \ + WideCharToMultiByte(CP_UTF8, 0, from, lstrlenW(from)+1, to, toSize, NULL, NULL); \ +) + +/* Dynamically allocate a new buffer, then convert a Unicode string to UTF-8 */ +/* The dynamic allocation is useful in modules using lots of UTF-16 pathnames. + This avoids having many local buffers of length UTF8_PATH_MAX, which may + make the stack grow too large and overflow. */ +#define DEBUG_WSTR2NEWUTF8(pwStr, pUtf8) \ + DEBUG_CODE( \ + do { \ + int nUtf8 = (int)lstrlenW(pwStr) * 2 + 1; \ + pUtf8 = malloc(nUtf8); \ + DEBUG_WSTR2UTF8(pwStr, pUtf8, nUtf8); \ + } while (0); \ + ) /* DEBUG_FREE(pUtf8) MUST be used to free the UTF-8 string after use, else there will be a memory leak */ + +#define DEBUG_FREEUTF8(pUtf8) DEBUG_CODE(free(pUtf8)) + +#endif /* defined(_WIN32) */ + +#endif /* !defined(_DEBUGM_H) */ + diff --git a/deps/MsvcLibX/include/direct.h b/deps/MsvcLibX/include/direct.h new file mode 100644 index 0000000000000000000000000000000000000000..7cedc1cf7dbc5db620efb1d8e41d2ab8afca3ab7 --- /dev/null +++ b/deps/MsvcLibX/include/direct.h @@ -0,0 +1,27 @@ +/*****************************************************************************\ +* * +* Filename: direct.h * +* * +* Description: MsvcLibX extensions to direct.h. * +* * +* Notes: * +* * +* History: * +* 2014-03-24 JFL Created this file, with content moved from unistd.h. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_DIRECT_H +#define _MSVCLIBX_DIRECT_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(direct.h) /* Include MSVC's own file */ + +#undef mkdir /* This MSVC macro is incompatible with mkdir() function in unistd.h */ + +#endif /* defined(_MSVCLIBX_DIRECT_H) */ + diff --git a/deps/MsvcLibX/include/dirent.h b/deps/MsvcLibX/include/dirent.h new file mode 100644 index 0000000000000000000000000000000000000000..ac702e01dd62d897405bb94e455bd950e832c640 --- /dev/null +++ b/deps/MsvcLibX/include/dirent.h @@ -0,0 +1,282 @@ +/*****************************************************************************\ +* * +* Filename: dirent.h * +* * +* Description: DOS/WIN32 port of standard C library's dirent.h. * +* * +* Notes: There are also remains of an OS/2 implementation here. * +* This code did work c. 1990, in an OS/2 1.3 port of dirc.c.* +* It's not maintained anymore, and unlikely to still work. * +* Left in as a historic reference, in the very unlikely * +* case somebody wants to revive it. * +* * +* History: * +* 2012-01-09 JFL Created this file, based on dirc and other programs. * +* 2013-03-09 JFL Rewrote the stat/fstat/lstat and fseeko/ftello definitions* +* based on _FILE_OFFSET_BITS, _LARGEFILE_SOURCE, and * +* _LARGEFILE_SOURCE64 definitions. * +* 2014-02-06 JFL Moved stat extensions to statx.h. * +* 2014-02-27 JFL Use a WIN32_FIND_DATAW in Windows, to support UTF-8 names.* +* 2014-03-20 JFL Restructured Windows opendir and readdir functions into * +* Wide and MultiByte versions, and changed the Unicode and * +* Ansi versions to macros. * +* 2014-06-06 JFL Fixed macro _D_EXACT_NAMLEN(). * +* 2015-12-07 JFL Added the conditional definition of symlink constants, so * +* that our code builds even in XP and older Windows SDKs. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _DIRENT_H +#define _DIRENT_H 1 + +#include "msvclibx.h" + +#define _DIRENT_FOR_DOS_WINDOWS /* Uniquely identify this module */ + +#include +#include +#include +#include +#include + +#ifndef ENAMETOOLONG /* Not defined in DOS' errno.h */ +#define ENAMETOOLONG 38 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros to extract size information from a struct dirent */ +#define _D_EXACT_NAMLEN(d) (strlen((d)->d_name)) /* Name length, not including NUL */ + +#define _DIRENT_HAVE_D_TYPE /* We commit to providing this field */ + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + +#include + +#define NAME_MAX 12 + +#pragma pack(1) +struct _fileinfo { /* MS-DOS structure returning file search results */ + uint8_t fiReserved[21]; + uint8_t fiAttribute; /* Attributes of file found */ + uint16_t fiFileTime; /* Time of last write */ + uint16_t fiFileDate; /* Time of last write */ + uint32_t fiSize; /* File Size */ + char fiFileName[13]; /* File name and extension */ +}; +#pragma pack() +typedef struct _fileinfo fileinfo; + +#pragma pack(1) +struct dirent { /* Standard C library structure returning directory entries. */ + /* Standard fields */ + _ino_t d_ino; /* We don't need it, but it's required by the spec */ + unsigned char d_type; /* File type. Values defined in macros DT_xxxx */ + /* unsigned char d_namlen; /* File name length, not including NUL */ + /* OS-specific extensions (allowed by the Posix specification) */ + /* Matches exactly the struc _fileinfo above, to avoid doing any copying */ + uint8_t d_reserved[21]; + uint8_t d_attribs; /* Attribute of file found */ + uint16_t d_time; /* Time of last write */ + uint16_t d_date; /* Time of last write */ + uint32_t d_filesize; /* File Size */ + /* Standard field: The file name, which must be last in the dirent structure */ + char d_name[NAME_MAX+1]; /* Null-terminated file name. Must be last */ +}; +#pragma pack() + +#pragma pack(1) +struct _dirhandle { /* Private structure, not for use by users */ + struct dirent sDirent; + /* char dta_buf[128]; /* Protection area, in case MS-DOS uses the whole DTA, and not just the struct _fileinfo ahead of it. */ + char wildcards[4]; /* Leave room for the "\*.*" that we append initially. This field MUST follow sDirent. */ + char first; /* Tracks if this is the first search call */ +}; +#pragma pack() + +/* Macros to extract size information from a struct dirent */ +#define _D_ALLOC_NAMLEN(d) 13 /* Upper bound of the block size to alloc for a name */ + +/* MS-DOS compatible functions for searching with a specific attribute */ +int srch1st(char *pszFile, uint16_t wAttr, fileinfo *pFI); /* Search first matching file */ +int srchnext(fileinfo *pFI); /* Search next matching file */ +#define DOS_SEARCH_FUNCTIONS_DEFINED 1 + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#ifndef WINVER +#define WINVER 0x0400 +#endif + +#include +#include + +/* Add symlink definitions, that may be missing in XP and older Windows SDKs */ +#ifndef IO_REPARSE_TAG_SYMLINK +#define IO_REPARSE_TAG_SYMLINK 0xA000000CL +#endif +#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY +#define SYMBOLIC_LINK_FLAG_DIRECTORY 1 +#endif +#ifndef FSCTL_SET_REPARSE_POINT +#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#endif +#ifndef FSCTL_GET_REPARSE_POINT +#define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif +#ifndef FSCTL_DELETE_REPARSE_POINT +#define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS) +#endif + +#define NAME_MAX (4 * FILENAME_MAX) /* Worst case using UTF-8 encoding: 4 bytes/WCHAR */ + +struct dirent { /* Structure used to return information about directory entries. */ + /* OS-specific extensions */ + uint32_t d_attribs; + uint32_t d_ReparseTag; + FILETIME d_CreationTime; + FILETIME d_LastAccessTime; + FILETIME d_LastWriteTime; + uint64_t d_filesize; + char d_shortname[14*sizeof(WCHAR)]; + /* Standard fields */ + _ino_t d_ino; /* We don't need it, but it's required by the spec */ + unsigned char d_type; /* File type. Values defined in macros DT_xxxx */ + /* unsigned char d_namlen; /* File name length, not including NUL */ + char d_name[(NAME_MAX+1)*sizeof(WCHAR)]; /* Null-terminated file name */ +}; + +struct _dirhandle { /* Private structure, not for use by users */ + struct dirent sDirent; + WCHAR wszDirName[MAX_PATH+1]; /* Null-terminated directory name */ + HANDLE hFindFile; /* Search handle */ + WIN32_FIND_DATAW wfd; /* Where Win32 will store the file information */ +}; + +/* Macros to extract size information from a struct dirent */ +#define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN(d)+1) /* Upper bound of the block size to alloc for a name */ + +#endif /* defined(_WIN32) */ + +/************************* OS/2-specific definitions *************************/ + +#ifdef _OS2 /* Automatically defined when targeting an OS/2 application? */ + +#include + +#define INCL_DOSFILEMGR +#define INCL_DOSMISC +#define INCL_VIO +#include "os2.h" + +#define NAME_MAX CCHMAXPATHCOMP + +struct dirent { /* Structure used to return information about directory entries. */ + _ino_t d_ino; /* We don't need it, but it's required by the spec */ + /* Non standard extensions, to ease adapting old DOS/WIN32 apps */ + uintmax_t d_filesize; /* File size */ + uint16_t time; /* MS-DOS time */ + uint16_t date; /* MS-DOS date */ + uint8_t attribs; /* Attributes, the MS-DOS way */ + /* Standard fields */ + unsigned char d_type; /* File type. Values defined in macros DT_xxxx */ + /* unsigned char d_namlen; /* File name length, not including NUL */ + char d_name[NAME_MAX+1]; /* Null-terminated file name. Must be last */ +}; + +struct _dirhandle { /* Private structure, not for use by users */ + struct dirent sDirent; + short hDir; /* Directory handle */ + FILEFINDBUF buf; /* Where OS/2 will store the file information */ +}; + +/* Macros to extract size information from a struct dirent */ +#define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN(d)+1) /* Upper bound of the block size to alloc for a name */ + +#endif /* defined(_OS2) */ + +/********************** End of OS-specific definitions ***********************/ + +typedef struct _dirhandle DIR; /* Directory enumerator handle */ +typedef struct dirent _dirent; /* Directory entry */ + +#define MAXNAMELEN NAME_MAX /* Alias used by some Unix versions */ + +/* File types for struct dirent d_type. Must match the S_IFMT field in sys/stat.h. */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 /* Fifo (not used in DOS/Windows dirs) */ +#define DT_CHR 2 /* Character device (not used in DOS/Windows) */ +#define DT_DIR 4 /* Directory */ +#define DT_BLK 6 /* Block device (not used in DOS/Windows) */ +#define DT_REG 8 /* Normal file */ +#define DT_LNK 10 /* Symbolic link */ +#define DT_SOCK 12 /* Socket (not used in DOS/Windows dirs) */ +#define DT_VOLID 15 /* Volume ID (non-standard extension for MS-DOS FAT) */ + +/* Functions operating on directories */ +#if defined(_MSDOS) + +extern DIR *opendir(const char *name); /* Open a directory */ +extern int closedir(DIR *pDir); /* Close the directory. Return 0 if successful, -1 if not. */ +extern _dirent *readdir(DIR *pDir); /* Read a directory entry. Return pDirEnt, or NULL for EOF or error. */ + +#elif defined(_WIN32) + +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define opendir opendirU +#define readdir readdirU +#define scandir scandirU +#else /* _ANSI_SOURCE */ +#define opendir opendirA +#define readdir readdirA +#define scandir scandirA +#endif +extern DIR *opendirW(const WCHAR *name); /* Open a directory - Wide char version */ +extern DIR *opendirM(const char *name, UINT cp); /* Open a directory - MultiByte char version */ +#define opendirA(name) opendirM(name, CP_ACP) /* Open a directory - ANSI version */ +#define opendirU(name) opendirM(name, CP_UTF8) /* Open a directory - UTF-8 version */ +extern int closedir(DIR *pDir); /* Close the directory. Return 0 if successful, -1 if not. */ +extern _dirent *readdirW(DIR *pDir); /* Read a directory entry. Return pDirEnt, or NULL for EOF or error. */ +extern _dirent *readdirM(DIR *pDir, UINT cp); /* Read a directory entry. Return pDirEnt, or NULL for EOF or error. */ +#define readdirA(pDir) readdirM(pDir, CP_ACP) /* Read a directory entry. Return pDirEnt, or NULL for EOF or error. */ +#define readdirU(pDir) readdirM(pDir, CP_UTF8) /* Read a directory entry. Return pDirEnt, or NULL for EOF or error. */ + +#endif /* defined(_WIN32) */ + +/* extern int readdir_r(DIR *pDir, _dirent *__entry, _dirent **__result); /* Reentrant readdir */ +/* extern void rewinddir(DIR *pDir); /* Rewind DIRP to the beginning of the directory. */ +/* extern void seekdir(DIR *pDir, long lPos); /* Seek to position POS on DIRP. */ +/* extern long telldir(DIR *pDir); /* Return the current position of DIRP. */ +/* extern int dirfd(DIR *pDir); /* Return the file descriptor used by DIRP. */ + +/* Scan the directory dir, calling cbSelect() on each directory entry. + Entries for which cbSelect() returns nonzero are individually malloc'd, + sorted using qsort with cbCompare(), and collected in a malloc'd array in + *namelist. Returns the number of entries selected, or -1 on error. */ +extern int scandir(const char *dir, + _dirent ***namelist, + int (*cbSelect) (const _dirent *), + int (__cdecl *cbCompare) (const _dirent **, + const _dirent **)); + +/* Function to compare two `struct dirent's alphabetically. */ +extern int __cdecl alphasort (const _dirent **ppDE1, const _dirent **ppDEe2); +/* extern int versionsort (const _dirent **ppDE1, const _dirent **ppDEe2); */ + +#ifdef __cplusplus +} +#endif + +#endif /* defined(_DIRENT_H) */ + diff --git a/deps/MsvcLibX/include/error.h b/deps/MsvcLibX/include/error.h new file mode 100644 index 0000000000000000000000000000000000000000..e8edad7c678524ada087e0c69eb35c647416ad10 --- /dev/null +++ b/deps/MsvcLibX/include/error.h @@ -0,0 +1,25 @@ +/*****************************************************************************\ +* * +* Filename: error.h * +* * +* Description: DOS/WIN32 port of the GNU CoreUtils library error funct. * +* * +* Notes: Gotcha: * +* The Windows SDK also contains a file called error.h * +* See C:\Program Files\Microsoft SDKs\Windows\v7.0\INCLUDE * +* * +* History: * +* 2012-10-21 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _ERROR_H_ +#define _ERROR_H_ + +#include "msvclibx.h" + +extern void error(int status, int errnum, const char *format, ...); + +#endif diff --git a/deps/MsvcLibX/include/fadvise.h b/deps/MsvcLibX/include/fadvise.h new file mode 100644 index 0000000000000000000000000000000000000000..37d4c310f053cf61e25343db6f65dfdad048343b --- /dev/null +++ b/deps/MsvcLibX/include/fadvise.h @@ -0,0 +1,30 @@ +/*****************************************************************************\ +* * +* Filename: fadvise.h * +* * +* Description: WIN32 makeshift version of Coreutils' fadvise.h. * +* * +* Notes: Gives hints to the kernel about future uses of a file. * +* Define constants, and replace functions by void macros. * +* * +* History: * +* 2012-10-17 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +enum fadvice_t { + FADVISE_NORMAL, + FADVISE_SEQUENTIAL, + FADVISE_NOREUSE, + FADVISE_DONTNEED, + FADVISE_WILLNEED, + FADVISE_RANDOM +}; + +/* void fdadvise(int fd, off_t offset, off_t len, fadvice_t advice) */ +#define fdadvise(fd, offset, len, advice) + +/* void fadvise(FILE *fp, fadvice_t advice) */ +#define fadvise(fp, advice) diff --git a/deps/MsvcLibX/include/fcntl.h b/deps/MsvcLibX/include/fcntl.h new file mode 100644 index 0000000000000000000000000000000000000000..735287c0d4b9973de79c649541371f98dd42cddb --- /dev/null +++ b/deps/MsvcLibX/include/fcntl.h @@ -0,0 +1,40 @@ +/*****************************************************************************\ +* * +* Filename: fcntl.h * +* * +* Description: MsvcLibX extensions to fcntl.h. * +* * +* Notes: * +* * +* History: * +* 2017-02-16 JFL Created this file. * +* * +* © Copyright 2017 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_FCNTL_H +#define _MSVCLIBX_FCNTL_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(fcntl.h) /* Include MSVC's own file */ + +/* Microsoft defines _open() in io.h */ +#include + +#if defined(_MSDOS) +#define open _open +#endif + +#if defined(_WIN32) +extern int openA(const char *, int, ...); /* MsvcLibX ANSI version of open */ +extern int openU(const char *, int, ...); /* MsvcLibX UTF-8 version of open */ +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define open openU +#else /* _ANSI_SOURCE */ +#define open openA +#endif /* defined(_UTF8_SOURCE) */ +#endif /* defined(_WIN32) */ + +#endif /* defined(_MSVCLIBX_FCNTL_H) */ diff --git a/deps/MsvcLibX/include/fnmatch.h b/deps/MsvcLibX/include/fnmatch.h new file mode 100644 index 0000000000000000000000000000000000000000..b41a2b5305112835996fc0e0aba66b37f1147554 --- /dev/null +++ b/deps/MsvcLibX/include/fnmatch.h @@ -0,0 +1,50 @@ +/*****************************************************************************\ +* * +* Filename: fnmatch.h * +* * +* Description: DOS/WIN32 port of standard C library's fnmatch.h. * +* * +* Notes: Reference for fnmatch and glob: * +* http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_9.html * +* * +* History: * +* 2012-01-17 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +#include "msvclibx.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Bits set in the FLAGS argument to fnmatch() */ +#define FNM_PATHNAME 0x01 /* Wildcards don't match '/' or '\\' */ +#define FNM_FILE_NAME FNM_PATHNAME /* Equivalent GNU name */ +#define FNM_NOESCAPE 0x02 /* Backslashes don't quote special chars (Irrelevant in DOS/Windows) */ +#define FNM_PERIOD 0x04 /* Wildcards don't match leading dots */ +#define FNM_LEADING_DIR 0x08 /* Match up to the first '/' or '\\' */ +#define FNM_CASEFOLD 0x10 /* Case-insentitive comparison */ + +/* Values returned by fnmatch() */ +#define FNM_MATCH 0 /* Non standard, but makes fnmatch.c more readable */ +#define FNM_NOMATCH 1 + +/* Value returned by fnmatch() if unsupported */ +#define FNM_NOSYS (-1) + +/* Match NAME against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch(const char *pszPattern, const char *pszName, int iFlags); + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(_FNMATCH_H) */ + diff --git a/deps/MsvcLibX/include/getopt.h b/deps/MsvcLibX/include/getopt.h new file mode 100644 index 0000000000000000000000000000000000000000..ad4b2f2baac299c5f0b252d4eb0f1dde26929a58 --- /dev/null +++ b/deps/MsvcLibX/include/getopt.h @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ + */ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +/* + * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions + */ +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#ifdef __cplusplus +extern "C" { +#endif + +struct option { + /* name of long option */ + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; +}; + +int getopt_long(int, char * const *, const char *, + const struct option *, int *); + +extern int optreset; +extern char *optarg; +extern int opterr; +extern int optind; +extern int optopt; + +#ifdef __cplusplus +}; +#endif + +#endif /* !_GETOPT_H_ */ + diff --git a/deps/MsvcLibX/include/iconv.h b/deps/MsvcLibX/include/iconv.h new file mode 100644 index 0000000000000000000000000000000000000000..396296fb53be88713f390309cb10d5d3b58dd1c9 --- /dev/null +++ b/deps/MsvcLibX/include/iconv.h @@ -0,0 +1,45 @@ +/*****************************************************************************\ +* * +* Filename iconv.h * +* * +* Description: WIN32 port of standard C library's iconv() * +* * +* Notes: Define here a number of routines, that will eventually * +* be used by iconv(). * +* * +* History: * +* 2014-02-27 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _ICONV_H +#define _ICONV_H 1 + +#include "msvclibx.h" + +#include + +#if defined(_MSDOS) + +/* Count the number of characters (not bytes!) in a string */ +/* For now, assume the # of characters is the same as the # of bytes */ +/* TO DO: Add support for DOS code pages! */ +#define CountCharacters(string, cp) (int)strlen(string) + +#endif /* defined(_MSDOS) */ + + +#if defined(_WIN32) + +#include + +int ConvertString(char *buf, size_t nBytes, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar); +int CountCharacters(const char *string, UINT cp); +char *DupAndConvert(const char *string, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar); + +#endif /* defined(_WIN32) */ + +#endif /* !defined(_ICONV_H) */ + diff --git a/deps/MsvcLibX/include/inttypes.h b/deps/MsvcLibX/include/inttypes.h new file mode 100644 index 0000000000000000000000000000000000000000..51740fade3119b1a5ff1bba5d2f2050130e2fe1f --- /dev/null +++ b/deps/MsvcLibX/include/inttypes.h @@ -0,0 +1,314 @@ +/*****************************************************************************\ +* * +* Filename inttypes.h * +* * +* Description ISO C9x compliant inttypes.h for Microsoft Visual Studio * +* * +* Notes TO DO: Move imaxdiv to its own C file. * +* * +* History * +* 2014-02-07 JFL Added definitions for PRIdMAX and PRIiMAX. * +* 2016-01-07 JFL Restructured and improved support for MS-DOS. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSC_VER +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif + +#ifndef _MSC_INTTYPES_H_ +#define _MSC_INTTYPES_H_ + +#include + +/* 7.8 Format conversion of integer types */ + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +/* 7.8.1 Macros for format specifiers */ + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) /* [ See footnote 185 at page 198 */ + +#if defined(_WIN64) +#define __I64_PREFIX "I64" +#define __I32_PREFIX "I32" +#define __PTR_PREFIX "I64" +#define __MAX_PREFIX "I64" +#elif defined(_WIN32) +#define __I64_PREFIX "I64" +#define __I32_PREFIX "I32" +#define __PTR_PREFIX "I32" +#define __MAX_PREFIX "I64" +#elif defined(_MSDOS) +#define __I64_PREFIX "ll" /* MSVC 1.5 actually ignores the second l */ +#define __I32_PREFIX "l" +#if defined(_M_I86CM) || defined(_M_I86LM) || defined(_M_I86HM) /* Long pointer memory models */ +#define __PTR_PREFIX "l" +#else /* Short pointer memory models */ +#define __PTR_PREFIX "" +#endif +#define __MAX_PREFIX "l" +#endif + +/* printf macros for integers */ +#define PRId8 "d" +#define PRIi8 "i" +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" + +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" + +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" + +#define PRIdLEAST16 PRId16 +#define PRIiLEAST16 PRIi16 +#define PRIoLEAST16 PRIo16 +#define PRIuLEAST16 PRIu16 +#define PRIxLEAST16 PRIx16 +#define PRIXLEAST16 PRIX16 + +#define PRIdFAST16 PRId16 +#define PRIiFAST16 PRIi16 +#define PRIoFAST16 PRIo16 +#define PRIuFAST16 PRIu16 +#define PRIxFAST16 PRIx16 +#define PRIXFAST16 PRIX16 + +#define PRId32 __I32_PREFIX "d" +#define PRIi32 __I32_PREFIX "i" +#define PRIo32 __I32_PREFIX "o" +#define PRIu32 __I32_PREFIX "u" +#define PRIx32 __I32_PREFIX "x" +#define PRIX32 __I32_PREFIX "X" + +#define PRIdLEAST32 PRId32 +#define PRIiLEAST32 PRIi32 +#define PRIoLEAST32 PRIo32 +#define PRIuLEAST32 PRIu32 +#define PRIxLEAST32 PRIx32 +#define PRIXLEAST32 PRIX32 + +#define PRIdFAST32 PRId32 +#define PRIiFAST32 PRIi32 +#define PRIoFAST32 PRIo32 +#define PRIuFAST32 PRIu32 +#define PRIxFAST32 PRIx32 +#define PRIXFAST32 PRIX32 + +#define PRId64 __I64_PREFIX "d" +#define PRIi64 __I64_PREFIX "i" +#define PRIo64 __I64_PREFIX "o" +#define PRIu64 __I64_PREFIX "u" +#define PRIx64 __I64_PREFIX "x" +#define PRIX64 __I64_PREFIX "X" + +#define PRIdLEAST64 PRId64 +#define PRIiLEAST64 PRIi64 +#define PRIoLEAST64 PRIo64 +#define PRIuLEAST64 PRIu64 +#define PRIxLEAST64 PRIx64 +#define PRIXLEAST64 PRIX64 + +#define PRIdFAST64 PRId64 +#define PRIiFAST64 PRIi64 +#define PRIoFAST64 PRIo64 +#define PRIuFAST64 PRIu64 +#define PRIxFAST64 PRIx64 +#define PRIXFAST64 PRIX64 + +#define PRIdMAX __MAX_PREFIX "d" +#define PRIiMAX __MAX_PREFIX "i" +#define PRIoMAX __MAX_PREFIX "o" +#define PRIuMAX __MAX_PREFIX "u" +#define PRIxMAX __MAX_PREFIX "x" +#define PRIXMAX __MAX_PREFIX "X" + +#define PRIdPTR __PTR_PREFIX "d" +#define PRIiPTR __PTR_PREFIX "i" +#define PRIoPTR __PTR_PREFIX "o" +#define PRIuPTR __PTR_PREFIX "u" +#define PRIxPTR __PTR_PREFIX "x" +#define PRIXPTR __PTR_PREFIX "X" + +/* scanf macros for integers */ +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" + +#define SCNdLEAST8 SCNd8 +#define SCNiLEAST8 SCNi8 +#define SCNoLEAST8 SCNo8 +#define SCNuLEAST8 SCNu8 +#define SCNxLEAST8 SCNx8 +#define SCNXLEAST8 SCNX8 + +#define SCNdFAST8 SCNd8 +#define SCNiFAST8 SCNi8 +#define SCNoFAST8 SCNo8 +#define SCNuFAST8 SCNu8 +#define SCNxFAST8 SCNx8 +#define SCNXFAST8 SCNX8 + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" + +#define SCNdLEAST16 SCNd16 +#define SCNiLEAST16 SCNi16 +#define SCNoLEAST16 SCNo16 +#define SCNuLEAST16 SCNu16 +#define SCNxLEAST16 SCNx16 +#define SCNXLEAST16 SCNX16 + +#define SCNdFAST16 SCNd16 +#define SCNiFAST16 SCNi16 +#define SCNoFAST16 SCNo16 +#define SCNuFAST16 SCNu16 +#define SCNxFAST16 SCNx16 +#define SCNXFAST16 SCNX16 + +#define SCNd32 __I32_PREFIX "d" +#define SCNi32 __I32_PREFIX "i" +#define SCNo32 __I32_PREFIX "o" +#define SCNu32 __I32_PREFIX "u" +#define SCNx32 __I32_PREFIX "x" +#define SCNX32 __I32_PREFIX "X" + +#define SCNdLEAST32 SCNd32 +#define SCNiLEAST32 SCNi32 +#define SCNoLEAST32 SCNo32 +#define SCNuLEAST32 SCNu32 +#define SCNxLEAST32 SCNx32 +#define SCNXLEAST32 SCNX32 + +#define SCNdFAST32 SCNd32 +#define SCNiFAST32 SCNi32 +#define SCNoFAST32 SCNo32 +#define SCNuFAST32 SCNu32 +#define SCNxFAST32 SCNx32 +#define SCNXFAST32 SCNX32 + +#define SCNd64 __I64_PREFIX "d" +#define SCNi64 __I64_PREFIX "i" +#define SCNo64 __I64_PREFIX "o" +#define SCNu64 __I64_PREFIX "u" +#define SCNx64 __I64_PREFIX "x" +#define SCNX64 __I64_PREFIX "X" + +#define SCNdLEAST64 SCNd64 +#define SCNiLEAST64 SCNi64 +#define SCNoLEAST64 SCNo64 +#define SCNuLEAST64 SCNu64 +#define SCNxLEAST64 SCNx64 +#define SCNXLEAST64 SCNX64 + +#define SCNdFAST64 SCNd64 +#define SCNiFAST64 SCNi64 +#define SCNoFAST64 SCNo64 +#define SCNuFAST64 SCNu64 +#define SCNxFAST64 SCNx64 +#define SCNXFAST64 SCNX64 + +#define SCNdMAX __MAX_PREFIX "d" +#define SCNiMAX __MAX_PREFIX "i" +#define SCNoMAX __MAX_PREFIX "o" +#define SCNuMAX __MAX_PREFIX "u" +#define SCNxMAX __MAX_PREFIX "x" +#define SCNXMAX __MAX_PREFIX "X" + +#define SCNdPTR __PTR_PREFIX "d" +#define SCNiPTR __PTR_PREFIX "i" +#define SCNoPTR __PTR_PREFIX "o" +#define SCNuPTR __PTR_PREFIX "u" +#define SCNxPTR __PTR_PREFIX "x" +#define SCNXPTR __PTR_PREFIX "X" + +#endif /* __STDC_FORMAT_MACROS ] */ + +/* 7.8.2 Functions for greatest-width integer types */ + +/* 7.8.2.1 imaxabs() */ +#if defined(_WIN32) +#define imaxabs _abs64 +#elif defined(_MSDOS) +#define imaxabs abs +#endif + +/* 7.8.2.2 imaxdiv() */ + +/* This is modified version of div() function from Microsoft's div.c found */ +/* in %MSVC.NET%\crt\src\div.c */ +#if defined(_MSDOS) && !defined(STATIC_IMAXDIV) && !defined(__cplusplus) +/* MSVC 1.52 compiler for MS-DOS does not support inline for C */ +extern imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom); +#else +#ifdef STATIC_IMAXDIV /* [ */ +static +#else /* STATIC_IMAXDIV ][ */ +_inline +#endif /* STATIC_IMAXDIV ] */ +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) { + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + /* did division wrong; must fix up */ + ++result.quot; + result.rem -= denom; + } + + return result; +} +#endif /* defined(_MSDOS) && !defined(STATIC_IMAXDIV) && !defined(__cplusplus) */ + +/* 7.8.2.3 strtoimax() and strtoumax() */ +#if defined(_WIN32) +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 +#elif defined(_MSDOS) +#define strtoimax strtol +#define strtoumax strtoul +#endif + +/* 7.8.2.4 wcstoimax() and wcstoumax() */ +#if defined(_WIN32) +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 +#elif defined(_MSDOS) +#define wcstoimax wcstol +#define wcstoumax wcstoul +#endif + +#endif /* _MSC_INTTYPES_H_ */ diff --git a/deps/MsvcLibX/include/libgen.h b/deps/MsvcLibX/include/libgen.h new file mode 100644 index 0000000000000000000000000000000000000000..f7ce9feff4144884d203cd5bd4d23eedcc589cc2 --- /dev/null +++ b/deps/MsvcLibX/include/libgen.h @@ -0,0 +1,22 @@ +/*****************************************************************************\ +* * +* Filename: libgen.h * +* * +* Description: DOS/WIN32 port of standard C library's libgen.h. * +* * +* Notes: * +* * +* History: * +* 2016-09-08 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _LIBGEN_H +#define _LIBGEN_H + +char *basename(char *pszPathname); /* Modifies pathname; Not thread-safe */ +char *dirname(char *pszPathname); /* Modifies pathname; Not thread-safe */ + +#endif /* !defined(_LIBGEN_H) */ diff --git a/deps/MsvcLibX/include/limits.h b/deps/MsvcLibX/include/limits.h new file mode 100644 index 0000000000000000000000000000000000000000..d4a9e09d5e76241ea985ad88a5e0fa7434e234f9 --- /dev/null +++ b/deps/MsvcLibX/include/limits.h @@ -0,0 +1,54 @@ +/*****************************************************************************\ +* * +* Filename: limits.h * +* * +* Description: MsvcLibX extensions to limits.h. * +* * +* Notes: * +* * +* History: * +* 2014-06-30 JFL Created this file. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_LIMITS_H +#define _MSVCLIBX_LIMITS_H 1 + +#include "msvclibx.h" + +#include MSVC_INCLUDE_FILE(limits.h) /* Include MSVC's own file */ + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + +#define PATH_MAX 255 /* Many APIs actually limit it to 128 bytes, but longer paths paths are legal. */ + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#undef PATH_MAX + +#define ANSI_PATH_MAX 260 /* Number of ANSI characters, including final NUL ( = Windef.h MAX_PATH) */ +#define UNICODE_PATH_MAX 32768 /* Number of Unicode characters, including final NUL */ +#define UTF8_PATH_MAX (4 * UNICODE_PATH_MAX) /* Worst UTF-8 case is 4 bytes / Unicode char */ + +#define PATH_MAX UNICODE_PATH_MAX /* MsvcLibX uses Unicode internally for file management */ + +#endif /* defined(_WIN32) */ + +/************************* OS/2-specific definitions *************************/ + +#ifdef _OS2 /* Automatically defined when targeting an OS/2 application? */ + +#endif /* defined(_OS2) */ + +/********************** End of OS-specific definitions ***********************/ + +#endif /* defined(_MSVCLIBX_LIMITS_H) */ + diff --git a/deps/MsvcLibX/include/msvclibx.h b/deps/MsvcLibX/include/msvclibx.h new file mode 100644 index 0000000000000000000000000000000000000000..6395737f4baed2f9e963b1a0304bfed12d38d445 --- /dev/null +++ b/deps/MsvcLibX/include/msvclibx.h @@ -0,0 +1,117 @@ +/*****************************************************************************\ +* * +* Filename MsvcLibX.h * +* * +* Description MsvcLibX-specific definitions * +* * +* Notes Generates a library search record to load MsvcLibX.lib. * +* * +* History: * +* 2013 JFL Created this file. * +* 2014-05-30 JFL Added macros to work around the lack of a #include_next. * +* 2015-11-15 JFL Added macro UCRT_INCLUDE_FILE for Visual Studio 2015. * +* 2016-09-15 JFL Added macro WINSDK_INCLUDE_FILE for Windows SDK. * +* 2016-09-20 JFL Added workaround preventing warnings in WIN95 builds. * +* 2016-09-28 JFL Can also be included by MS' Resource Compiler. * +* 2017-02-05 JFL Changed the UTF-8 programs initialization method. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* Generate a library search record to load MsvcLibX.lib */ + +#ifndef _MSVCLIBX_H_ +#define _MSVCLIBX_H_ + +#if !(defined(_MSC_VER) || defined(RC_INVOKED)) +#error The msvclibx library is designed for use with the Microsoft Visual C/C++ tools only. +#endif + +/* Compute the OS-specific suffix */ +#if defined(_WIN64) +# define _MSVCLIBX_LIB_OS_SUFFIX "w64" +#elif defined(_WIN95) +# define _MSVCLIBX_LIB_OS_SUFFIX "w95" +#elif defined(_WIN32) +# define _MSVCLIBX_LIB_OS_SUFFIX "w32" +#elif defined(_MSDOS) +# if defined(_M_I86TM) +# define _MSVCLIBX_LIB_OS_SUFFIX "dt" +# elif defined(_M_I86SM) +# define _MSVCLIBX_LIB_OS_SUFFIX "ds" +# elif defined(_M_I86LM) +# define _MSVCLIBX_LIB_OS_SUFFIX "dl" +# else +# error No msvclibx.lib version yet for this DOS memory model. +# endif +#else +# error No msvclibx.lib version for this target OS. +#endif + +/* Compute the debug-mode-specific suffix */ +#if defined(_DEBUG) +# define _MSVCLIBX_LIB_DBG_SUFFIX "d" +#else +# define _MSVCLIBX_LIB_DBG_SUFFIX "" +#endif + +/* Generate the OS-and-debug-mode-specific library name */ +#define _MSVCLIBX_LIB "MsvcLibX" _MSVCLIBX_LIB_OS_SUFFIX _MSVCLIBX_LIB_DBG_SUFFIX ".lib" +#pragma message("Adding pragma comment(lib, \"" _MSVCLIBX_LIB "\")") +#pragma comment(lib, _MSVCLIBX_LIB) + +/* Library-specific routine used internally by many standard routines */ +#if defined(_WIN32) +extern int Win32ErrorToErrno(); /* Converts the last WIN32 error to a Posix error code */ +#ifndef ELOOP /* Defined in VS10's errno.h, but not in VS9 */ +#define ELOOP 114 +#endif +/* Convert an ANSI or UTF-8 or OEM pathname to a Unicode string. Defined in mb2wpath.c. */ +typedef unsigned int UINT; /* Defined in windef.h */ +typedef const char* LPCSTR; /* Defined in winnt.h */ +#ifndef _WCHAR_T_DEFINED +typedef unsigned short wchar_t; /* Defined in crtdefs.h */ +#define _WCHAR_T_DEFINED +#endif +typedef wchar_t* LPWSTR; /* Defined in winnt.h */ +extern int MultiByteToWidePath(UINT nCodePage, LPCSTR pszName, LPWSTR pwszName, int nWideBufSize); +#endif +/* Count the number of elements in an array */ +#define COUNTOF(array) (sizeof(array)/sizeof(array[0])) + +/* Workaround for missing __pragma() directive in old versions of Visual Studio */ +#if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER <= 1400) /* For Visual C++ versions up to Visual Studio 2005 */ +#define __pragma(x) +#endif /* (_MSC_VER <= 1400) */ + +/* Macros for working around the lack of a #include_next directive */ +#define MSVCLIBX_CONCAT1(a,b) a##b /* Concatenate the raw arguments */ +#define MSVCLIBX_CONCAT(a,b) MSVCLIBX_CONCAT1(a,b) /* Substitute the arguments, then concatenate the values */ +#define MSVCLIBX_STRINGIZE1(x) #x /* Convert the raw argument to a string */ +#define MSVCLIBX_STRINGIZE(x) MSVCLIBX_STRINGIZE1(x) /* Substitute the argument, then convert its value to a string */ +/* Up to VS2013, both kinds of include files were in the same directory. Then in VS2015, they were split in two dirs. */ +#define MSVC_INCLUDE_FILE(relpath) MSVCLIBX_STRINGIZE(MSVCLIBX_CONCAT(MSVCINCLUDE,MSVCLIBX_CONCAT(/,relpath))) /* C compiler include files */ +#define UCRT_INCLUDE_FILE(relpath) MSVCLIBX_STRINGIZE(MSVCLIBX_CONCAT(UCRTINCLUDE,MSVCLIBX_CONCAT(/,relpath))) /* C runtime library include files */ +#define WINSDK_INCLUDE_FILE(relpath) MSVCLIBX_STRINGIZE(MSVCLIBX_CONCAT(WSDKINCLUDE,MSVCLIBX_CONCAT(/,relpath))) /* Windows SDK include files */ + +/* Support for external linker symbols */ +#if defined(_WIN64) +#define PUBLIC_SYMBOL_NAME(s) s +#else /* _MSDOS or _WIN32 */ +#define PUBLIC_SYMBOL_NAME(s) _##s +#endif + +/* Support for UTF-8 command lines */ +#if defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +/* Force linking in MsvcLibX' UTF-8 initialization module */ +#pragma comment(linker, "/include:" MSVCLIBX_STRINGIZE(PUBLIC_SYMBOL_NAME(_initU))) +#endif /* defined(_UTF8_SOURCE) ... */ +#endif /* defined(_WIN32) */ + +/* Prevent an incompatibility with . See MsvcLibX' "sys/time.h" for explanations. */ +#define _WINSOCKAPI_ /* Prevent the inclusion of winsock.h in windows.h */ + +#endif /* _MSVCLIBX_H_ */ + diff --git a/deps/MsvcLibX/include/netdb.h b/deps/MsvcLibX/include/netdb.h new file mode 100644 index 0000000000000000000000000000000000000000..417150afc8c3df16594bff21f8de9fd45d86b9e2 --- /dev/null +++ b/deps/MsvcLibX/include/netdb.h @@ -0,0 +1,26 @@ +/*****************************************************************************\ +* * +* Filename: netdb.h * +* * +* Description: Network definitions * +* * +* Notes: * +* * +* History: * +* 2012-01-24 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _NETDB_H +#define _NETDB_H 1 + +/* Absolute file name for network data base files. */ +#define _PATH_HOSTS "C:/Windows/System32/drivers/etc/hosts" +#define _PATH_NETWORKS "C:/Windows/System32/drivers/etc/networks" +#define _PATH_PROTOCOLS "C:/Windows/System32/drivers/etc/protocols" +#define _PATH_SERVICES "C:/Windows/System32/drivers/etc/services" + +#endif /* _NETDB_H */ + diff --git a/deps/MsvcLibX/include/process.h b/deps/MsvcLibX/include/process.h new file mode 100644 index 0000000000000000000000000000000000000000..105b71669b1d885dd1c5e9c6a45d267ec60eb33c --- /dev/null +++ b/deps/MsvcLibX/include/process.h @@ -0,0 +1,34 @@ +/*****************************************************************************\ +* * +* Filename: process.h * +* * +* Description: MsvcLibX extensions to process.h. * +* * +* Notes: * +* * +* History: * +* 2014-03-27 JFL Created this file. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_PROCESS_H +#define _MSVCLIBX_PROCESS_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(process.h) /* Include MSVC's own file */ + +#if defined(_WIN32) +extern intptr_t _spawnvpU(int iMode, const char *pszCommand, char *const *argv); +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define _spawnvp _spawnvpU +#else /* _ANSI_SOURCE */ +#define _spawnvp _spawnvp +#endif /* defined(_UTF8_SOURCE) */ +#endif /* defined(_WIN32) */ + +#endif /* defined(_MSVCLIBX_PROCESS_H) */ + diff --git a/deps/MsvcLibX/include/regex.h b/deps/MsvcLibX/include/regex.h new file mode 100644 index 0000000000000000000000000000000000000000..82158c7b2e0d22039928279e4dfa6e6c0a420f70 --- /dev/null +++ b/deps/MsvcLibX/include/regex.h @@ -0,0 +1,89 @@ +#ifndef _HSREGEX_H_ +#define _HSREGEX_H_ +#ifndef _HSREGEX_H +#define _HSREGEX_H /* never again */ + +#include /* JFL 2012-01-24 Added definition of types used below */ +#pragma comment( lib, "regex.lib" ) + +/* ========= begin header generated by ././mkh ========= */ +#ifdef __cplusplus +extern "C" { +#endif + +/* === regex2.h === */ +#ifdef WIN32 +#define API_EXPORT(type) __declspec(dllexport) type __stdcall +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define API_EXPORT(type) __attribute__ ((visibility("default"))) type +#else +#define API_EXPORT(type) type +#endif + +typedef off_t regoff_t; +typedef struct { + int re_magic; + size_t re_nsub; /* number of parenthesized subexpressions */ + const char *re_endp; /* end pointer for REG_PEND */ + struct re_guts *re_g; /* none of your business :-) */ +} regex_t; +typedef struct { + regoff_t rm_so; /* start of match */ + regoff_t rm_eo; /* end of match */ +} regmatch_t; + + +/* === regcomp.c === */ +API_EXPORT(int) regcomp(regex_t *, const char *, int); +#define REG_BASIC 0000 +#define REG_EXTENDED 0001 +#define REG_ICASE 0002 +#define REG_NOSUB 0004 +#define REG_NEWLINE 0010 +#define REG_NOSPEC 0020 +#define REG_PEND 0040 +#define REG_DUMP 0200 + + +/* === regerror.c === */ +#define REG_OKAY 0 +#define REG_NOMATCH 1 +#define REG_BADPAT 2 +#define REG_ECOLLATE 3 +#define REG_ECTYPE 4 +#define REG_EESCAPE 5 +#define REG_ESUBREG 6 +#define REG_EBRACK 7 +#define REG_EPAREN 8 +#define REG_EBRACE 9 +#define REG_BADBR 10 +#define REG_ERANGE 11 +#define REG_ESPACE 12 +#define REG_BADRPT 13 +#define REG_EMPTY 14 +#define REG_ASSERT 15 +#define REG_INVARG 16 +#define REG_ATOI 255 /* convert name to number (!) */ +#define REG_ITOA 0400 /* convert number to name (!) */ +API_EXPORT(size_t) regerror(int, const regex_t *, char *, size_t); + + +/* === regexec.c === */ +API_EXPORT(int) regexec(const regex_t *, const char *, size_t, regmatch_t [], int); +#define REG_NOTBOL 00001 +#define REG_NOTEOL 00002 +#define REG_STARTEND 00004 +#define REG_TRACE 00400 /* tracing of execution */ +#define REG_LARGE 01000 /* force large representation */ +#define REG_BACKR 02000 /* force use of backref code */ + + +/* === regfree.c === */ +API_EXPORT(void) regfree(regex_t *); + +#ifdef __cplusplus +} +#endif +/* ========= end header generated by ././mkh ========= */ +#endif +#endif diff --git a/deps/MsvcLibX/include/reparsept.h b/deps/MsvcLibX/include/reparsept.h new file mode 100644 index 0000000000000000000000000000000000000000..1f2f7bea0c97db5f1c805d21d716ab348ada6c00 --- /dev/null +++ b/deps/MsvcLibX/include/reparsept.h @@ -0,0 +1,125 @@ +/*****************************************************************************\ +* * +* Filename: reparsept.h * +* * +* Description: Definitions for WIN32 reparse points. * +* * +* Notes: * +* * +* History: * +* 2014-02-28 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* Reparse point iocontrol data buffer */ +/* See http://msdn.microsoft.com/en-us/library/cc232006.aspx */ +/* and http://msdn.microsoft.com/en-us/library/cc232007.aspx */ + +#include + +/* NTFS reparse point definitions */ + +/* Constants from http://msdn.microsoft.com/en-us/library/dd541667.aspx */ +/* Some, but not all, of them also defined in recent versions of winnt.h. */ +/* Since the list varies a lot, redefine them one by one as needed */ + +#ifndef IO_REPARSE_TAG_RESERVED_ZERO +#define IO_REPARSE_TAG_RESERVED_ZERO 0x00000000 /* Reserved reparse tag value */ +#endif +#ifndef IO_REPARSE_TAG_RESERVED_ONE +#define IO_REPARSE_TAG_RESERVED_ONE 0x00000001 /* Reserved reparse tag value */ +#endif +#ifndef IO_REPARSE_TAG_MOUNT_POINT +#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003 /* Used for mount point support */ +#endif +#ifndef IO_REPARSE_TAG_HSM +#define IO_REPARSE_TAG_HSM 0xC0000004 /* Obsolete. Used by legacy Hierarchical Storage Manager Product */ +#endif +#ifndef IO_REPARSE_TAG_DRIVER_EXTENDER +#define IO_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 /* Home server drive extender */ +#endif +#ifndef IO_REPARSE_TAG_HSM2 +#define IO_REPARSE_TAG_HSM2 0x80000006 /* Obsolete. Used by legacy Hierarchical Storage Manager Product */ +#endif +#ifndef IO_REPARSE_TAG_SIS +#define IO_REPARSE_TAG_SIS 0x80000007 /* Used by single-instance storage (SIS) filter driver. Server-side interpretation only, not meaningful over the wire */ +#endif +#ifndef IO_REPARSE_TAG_WIM +#define IO_REPARSE_TAG_WIM 0x80000008 /* Mounted Windows boot Image File? */ +#endif +#ifndef IO_REPARSE_TAG_CSV +#define IO_REPARSE_TAG_CSV 0x80000009 /* Cluster Shared Volume? */ +#endif +#ifndef IO_REPARSE_TAG_DFS +#define IO_REPARSE_TAG_DFS 0x8000000A /* Used by the DFS filter. The DFS is described in the Distributed File System (DFS): Referral Protocol Specification [MS-DFSC]. Server-side interpretation only, not meaningful over the wire */ +#endif +#ifndef IO_REPARSE_TAG_FILTER_MANAGER +#define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B /* Used by filter manager test harness */ +#endif +#ifndef IO_REPARSE_TAG_SYMLINK +#define IO_REPARSE_TAG_SYMLINK 0xA000000C /* Used for symbolic link support */ +#endif +#ifndef IO_REPARSE_TAG_DFSR +#define IO_REPARSE_TAG_DFSR 0x80000012 /* Used by the DFS filter. The DFS is described in [MS-DFSC]. Server-side interpretation only, not meaningful over the wire */ +#endif +#ifndef IO_REPARSE_TAG_DEDUP +#define IO_REPARSE_TAG_DEDUP 0x80000013 /* Mounted deduplicated volume? */ +#endif +#ifndef IO_REPARSE_TAG_NFS +#define IO_REPARSE_TAG_NFS 0x80000014 /* Mounted NFS share? */ +#endif + +#if 0 +#define IO_REPARSE_TAG_DRIVER_EXTENDER 0x80000005 /* Home server drive extender */ +#define IO_REPARSE_TAG_FILTER_MANAGER 0x8000000B /* Used by filter manager test harness */ +#endif + +#pragma pack(1) +typedef struct _REPARSE_READ_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + UCHAR DataBuffer[1]; +} REPARSE_READ_BUFFER, *PREPARSE_READ_BUFFER; +#define REPARSE_READ_BUFFER_HEADER_SIZE (sizeof(REPARSE_READ_BUFFER) - sizeof(UCHAR)) + +typedef struct _REPARSE_SYMLINK_READ_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; +} SYMLINK_READ_BUFFER, *PSYMLINK_READ_BUFFER; +#define SYMLINK_READ_BUFFER_HEADER_SIZE (sizeof(SYMLINK_READ_BUFFER) - sizeof(WCHAR)) + +typedef struct _REPARSE_MOUNTPOINT_READ_BUFFER { + DWORD ReparseTag; + WORD ReparseDataLength; + WORD Reserved; + WORD SubstituteNameOffset; + WORD SubstituteNameLength; + WORD PrintNameOffset; + WORD PrintNameLength; + WCHAR PathBuffer[1]; +} MOUNTPOINT_READ_BUFFER, *PMOUNTPOINT_READ_BUFFER; +#define MOUNTPOINT_READ_BUFFER_HEADER_SIZE (sizeof(MOUNTPOINT_READ_BUFFER) - sizeof(WCHAR)) + +typedef struct _REPARSE_MOUNTPOINT_WRITE_BUFFER { + DWORD ReparseTag; + DWORD ReparseDataLength; + WORD Reserved; + WORD ReparseTargetLength; + WORD ReparseTargetMaximumLength; + WORD Reserved1; + WCHAR ReparseTarget[1]; +} MOUNTPOINT_WRITE_BUFFER, *PMOUNTPOINT_WRITE_BUFFER; +#define MOUNTPOINT_WRITE_BUFFER_HEADER_SIZE (sizeof(MOUNTPOINT_WRITE_BUFFER) - sizeof(WCHAR)) +#pragma pack() + + diff --git a/deps/MsvcLibX/include/stdbool.h b/deps/MsvcLibX/include/stdbool.h new file mode 100644 index 0000000000000000000000000000000000000000..4697fd52556c739768095a15d5df1b39663b0ded --- /dev/null +++ b/deps/MsvcLibX/include/stdbool.h @@ -0,0 +1,25 @@ +/*****************************************************************************\ +* * +* Filename: stdbool.h * +* * +* Description: Standard boolean definitions * +* * +* Notes: Set standard values. May need to be adapted for C++? * +* * +* History: * +* 2012-10-17 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _STDBOOL_H +#define _STDBOOL_H + +/* #define bool int /* Spec says _Bool */ +typedef int bool; +#define true 1 +#define false 0 +#define __bool_true_false_are_defined 1 + +#endif diff --git a/deps/MsvcLibX/include/stdint.h b/deps/MsvcLibX/include/stdint.h new file mode 100644 index 0000000000000000000000000000000000000000..db321df86a6f130afae8cdf4b4ca7c23c00413f0 --- /dev/null +++ b/deps/MsvcLibX/include/stdint.h @@ -0,0 +1,322 @@ +/*****************************************************************************\ +* * +* Filename stdint.h * +* * +* Description ISO C9x compliant stdint.h for Microsoft Visual Studio * +* * +* Notes * +* * +* ISO C9x compliant stdint.h for Microsoft Visual Studio * +* Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 * +* * +* Copyright (c) 2006-2008 Alexander Chemeris * +* * +* 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. The name of the author may be used to endorse or promote products * +* derived from this software without specific prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * +* * +* History * +* 2008-07-17 AC Initial implementation by Alexander Chemeris. * +* 2011-05-23 JFL Added support for 16-bits compilers for MS-DOS. * +* 2011-05-28 JFL Added support for 16-bits compilers for MS-DOS. * +* 2012-01-18 JFL Added error messages if target is not DOS or Windows. * +* 2015-12-04 JFL Define _UINTPTR_T_DEFINED to tell MSVC99 it's done already* +* * +\*****************************************************************************/ + +#ifndef _MSC_VER +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif /* _MSC_VER */ + +#ifndef _MSC_STDINT_H_ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +/* +// For Visual Studio 6 in C++ mode wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +*/ +/* 2015-12-04 JFL Bug fix: With VS14/VC19, MSVC's wchar.h includes inttypes.h, + which in turn includes this stdint.h, causing loop issues */ +#if (_MSC_VER < 1900) && defined(_WIN32) /* Both WIN32 and WIN64 */ +# if (_MSC_VER < 1300) && defined(__cplusplus) + extern "C++" { +# endif +# include +# if (_MSC_VER < 1300) && defined(__cplusplus) + } +# endif +#endif + +/* Define _W64 macros to mark types changing their size, like intptr_t. */ +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +/* 7.18.1 Integer types */ + +#ifndef _INTEGRAL_MAX_BITS +#define _INTEGRAL_MAX_BITS 32 +#endif + +/* 7.18.1.1 Exact-width integer types */ +#if defined(_WIN32) /* Both WIN32 and WIN64 */ +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +#elif defined(_MSDOS) /* MS-DOS */ +typedef char int8_t; +typedef short int16_t; +typedef long int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#else +#error "I don't know what the integer types are in this case!" +#endif + +/* 7.18.1.2 Minimum-width integer types */ +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +#ifdef LLONG_MAX +typedef int64_t int_least64_t; +#endif +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +#ifdef LLONG_MAX +typedef uint64_t uint_least64_t; +#endif + +/* 7.18.1.3 Fastest minimum-width integer types */ +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +#ifdef LLONG_MAX +typedef int64_t int_fast64_t; +#endif +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +#ifdef LLONG_MAX +typedef uint64_t uint_fast64_t; +#endif + +/* 7.18.1.4 Integer types capable of holding object pointers */ +#if defined(_WIN64) /* _WIN64 */ +# define _POINTER_BITS 64 + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#elif defined(_WIN32) /* _WIN32 */ +# define _POINTER_BITS 32 + typedef _W64 int intptr_t; + typedef _W64 unsigned int uintptr_t; +#elif defined(_MSDOS) /* _MSDOS */ +# if defined(_M_I86TM) || defined(_M_I86SM) /* Tiny or short memory models */ +# define _POINTER_BITS 16 + typedef int intptr_t; + typedef unsigned int uintptr_t; +# else /* Compact, medium, large or huge memory models */ +# define _POINTER_BITS 32 + typedef long intptr_t; + typedef unsigned long uintptr_t; +# endif +#else +#error "I don't know what the pointer types are in this case!" +#endif /* _WIN64 */ +#define _INTPTR_T_DEFINED +#define _UINTPTR_T_DEFINED /* Prevent MSVC99 from redefining it */ + +/* 7.18.1.5 Greatest-width integer types */ +#ifdef LLONG_MAX +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; +#else +typedef int32_t intmax_t; +typedef uint32_t uintmax_t; +#endif + + +/* 7.18.2 Limits of specified-width integer types */ + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) /* See footnote 220 at page 257 and footnote 221 at page 259 */ + +#ifdef _MSDOS +#define _I8_MIN SCHAR_MIN /* minimum signed 8 bit value */ +#define _I8_MAX SCHAR_MAX /* maximum signed 8 bit value */ +#define _UI8_MAX UCHAR_MAX /* maximum unsigned 8 bit value */ + +#define _I16_MIN SHRT_MIN /* minimum signed 16 bit value */ +#define _I16_MAX SHRT_MAX /* maximum signed 16 bit value */ +#define _UI16_MAX USHRT_MAX /* maximum unsigned 16 bit value */ + +#define _I32_MIN LONG_MIN /* minimum signed 32 bit value */ +#define _I32_MAX LONG_MAX /* maximum signed 32 bit value */ +#define _UI32_MAX ULONG_MAX /* maximum unsigned 32 bit value */ +#endif + +/* 7.18.2.1 Limits of exact-width integer types */ +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#ifdef LLONG_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#endif +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#ifdef LLONG_MAX +#define UINT64_MAX _UI64_MAX +#endif + +/* 7.18.2.2 Limits of minimum-width integer types */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#ifdef LLONG_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#endif +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#ifdef LLONG_MAX +#define UINT_LEAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.3 Limits of fastest minimum-width integer types */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#ifdef LLONG_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#endif +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#ifdef LLONG_MAX +#define UINT_FAST64_MAX UINT64_MAX +#endif + +/* 7.18.2.4 Limits of integer types capable of holding object pointers */ +#define INTPTR_MIN INT##_POINTER_BITS##MIN +#define INTPTR_MAX INT##_POINTER_BITS##_MAX +#define UINTPTR_MAX UINT##_POINTER_BITS##_MAX + +/* 7.18.2.5 Limits of greatest-width integer types */ +#ifdef LLONG_MAX +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX +#else +#define INTMAX_MIN INT32_MIN +#define INTMAX_MAX INT32_MAX +#define UINTMAX_MAX UINT32_MAX +#endif + +/* 7.18.3 Limits of other integer types */ +#define PTRDIFF_MIN _I##_POINTER_BITS##_MIN +#define PTRDIFF_MAX _I##_POINTER_BITS##_MAX + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX +# define SIZE_MAX _UI##_POINTER_BITS##_MAX +#endif + +/* WCHAR_MIN and WCHAR_MAX are also defined in */ +#ifndef WCHAR_MIN +# define WCHAR_MIN 0 +#endif +#ifndef WCHAR_MAX +# define WCHAR_MAX _UI16_MAX +#endif + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif /* __STDC_LIMIT_MACROS */ + + +/* 7.18.4 Limits of other integer types */ + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) /* See footnote 224 at page 260 */ + +/* 7.18.4.1 Macros for minimum-width integer constants */ + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#ifdef LLONG_MAX +#define INT64_C(val) val##i64 +#endif + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#ifdef LLONG_MAX +#define UINT64_C(val) val##ui64 +#endif + +/* 7.18.4.2 Macros for greatest-width integer constants */ +#ifdef LLONG_MAX +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C +#else +#define INTMAX_C INT32_C +#define UINTMAX_C UINT32_C +#endif + +#endif /* __STDC_CONSTANT_MACROS */ + + +#endif /* _MSC_STDINT_H_ */ diff --git a/deps/MsvcLibX/include/stdio--.h b/deps/MsvcLibX/include/stdio--.h new file mode 100644 index 0000000000000000000000000000000000000000..66b7e6e326c14cdfa74e06ff80cf71de9a765a75 --- /dev/null +++ b/deps/MsvcLibX/include/stdio--.h @@ -0,0 +1,17 @@ +/*****************************************************************************\ +* * +* Filename: stdio--.h * +* * +* Description: front-end to stdio.h that redefines some unsafe functions * +* * +* Notes: This header is part of the GNU CoreUtils library. * +* msvclibx: Pass through to the standard stdio.h. * +* * +* History: * +* 2012-10-17 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include diff --git a/deps/MsvcLibX/include/stdio.h b/deps/MsvcLibX/include/stdio.h new file mode 100644 index 0000000000000000000000000000000000000000..e819d131898e94c6587f701676efaa4b533e1578 --- /dev/null +++ b/deps/MsvcLibX/include/stdio.h @@ -0,0 +1,125 @@ +/*****************************************************************************\ +* * +* Filename: stdio.h * +* * +* Description: MsvcLibX extensions to stdio.h. * +* * +* Notes: * +* * +* History: * +* 2014-06-03 JFL Created this file. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* 2015-12-09 JFL Alias fputs to fputsU, and vfprintf to vfprintfU. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_stdio_H +#define _MSVCLIBX_stdio_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(stdio.h) /* Include MSVC's own file */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define snprintf _snprintf /* This one _is_ standard */ +#define popen _popen /* This one _is_ standard */ +#define pclose _pclose /* This one _is_ standard */ + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + +/* Define functions fseeko and ftello */ +#if defined(_LARGEFILE_SOURCE) + #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + /* TO DO: Windows 95 has extended functions for handling 64-bits files sizes */ + #else + #endif + /* For now, use the MSVC 32-bits functions in all cases */ + #define fseeko fseek + #define ftello ftell +#endif + +/* Define standard 64-bits functions */ +#if defined(_LARGEFILE_SOURCE64) + #define fseeko64 _fseek + #define ftello64 _ftell +#endif + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define vfprintf vfprintfU /* For outputing UTF-8 strings */ +#define fprintf fprintfU /* For outputing UTF-8 strings */ +#define printf printfU /* For outputing UTF-8 strings */ +#define fputs fputsU /* For outputing UTF-8 strings */ +/* The UTF-8 output routines are defined in iconv.c */ +extern int vfprintfU(FILE *f, const char *pszFormat, va_list vl); +extern int fprintfU(FILE *f, const char *pszFormat, ...); +extern int printfU(const char *pszFormat, ...); +extern int fputsU(const char *buf, FILE *f); +extern UINT codePage; +#endif + +/* Define functions fseeko and ftello */ +#if defined(_LARGEFILE_SOURCE) + #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + #define fseeko _fseeki64 /* _CONCAT(_fseeki64,_NS_SUFFIX) */ + #define ftello _ftelli64 /* _CONCAT(_ftelli64,_NS_SUFFIX) */ + #else + #define fseeko fseek + #define ftello ftell + #endif +#endif + +/* Define standard 64-bits functions */ +#if defined(_LARGEFILE_SOURCE64) + #define fseeko64 _fseeki64 /* _CONCAT(_fseeki64,_NS_SUFFIX) */ + #define ftello64 _ftelli64 /* _CONCAT(_ftelli64,_NS_SUFFIX) */ +#endif + +#define fileno _fileno /* Avoid a warning about the deprecated name */ + +#endif /* defined(_WIN32) */ + +/************************* OS/2-specific definitions *************************/ + +#ifdef _OS2 /* Automatically defined when targeting an OS/2 application? */ + +/* Define functions fseeko and ftello */ +#if defined(_LARGEFILE_SOURCE) + #if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + #else + #endif + #define fseeko fseek + #define ftello ftell +#endif + +/* Define standard 64-bits functions */ +#if defined(_LARGEFILE_SOURCE64) + /* For now, hide the fact that DOS does not support 64-bits lengths */ + #define fseeko64 _fseek + #define ftello64 _ftell +#endif + +#endif /* defined(_OS2) */ + +/********************** End of OS-specific definitions ***********************/ + +#ifdef __cplusplus +} +#endif + +#endif /* defined(_MSVCLIBX_stdio_H) */ + diff --git a/deps/MsvcLibX/include/stdlib.h b/deps/MsvcLibX/include/stdlib.h new file mode 100644 index 0000000000000000000000000000000000000000..110641d4273e18ab310b1fe794754824467c54ba --- /dev/null +++ b/deps/MsvcLibX/include/stdlib.h @@ -0,0 +1,52 @@ +/*****************************************************************************\ +* * +* Filename: stdlib.h * +* * +* Description: MsvcLibX extensions to stdlib.h. * +* * +* Notes: * +* * +* History: * +* 2016-09-13 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_stdlib_H +#define _MSVCLIBX_stdlib_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(stdlib.h) /* Include MSVC's own file */ + +#ifdef __cplusplus +extern "C" { +#endif + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +extern char *_fullpathU(char *absPath, const char *relPath, size_t maxLength); + +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define _fullpath _fullpathU /* For processing UTF-8 pathnames */ +#endif + +#endif /* defined(_WIN32) */ + +/********************** End of OS-specific definitions ***********************/ + +#ifdef __cplusplus +} +#endif + +#endif /* defined(_MSVCLIBX_stdlib_H) */ + diff --git a/deps/MsvcLibX/include/sys/param.h b/deps/MsvcLibX/include/sys/param.h new file mode 100644 index 0000000000000000000000000000000000000000..ebb0430fc98893503d0baee11af57e9f8736bb6c --- /dev/null +++ b/deps/MsvcLibX/include/sys/param.h @@ -0,0 +1,36 @@ +/*****************************************************************************\ +* * +* Filename sys/param.h * +* * +* Description DOS/WIN32 port of standard C library's sys/param.h. * +* * +* Notes * +* * +* History * +* 2014-06-10 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _SYS_PARAM_H +#define _SYS_PARAM_H + + +#ifdef _MSDOS + +#define _POSIX_ARG_MAX 127 /* Maximum command line size */ + +#endif + + +#ifdef _WIN32 + +/* #include MSVC_INCLUDE_FILE(sys\param.h) /* Include MSVC's own file */ + +#define _POSIX_ARG_MAX 8191 + +#endif /* defined(_WIN32) */ + +#endif /* !defined(_SYS_PARAM_H) */ + diff --git a/deps/MsvcLibX/include/sys/stat.h b/deps/MsvcLibX/include/sys/stat.h new file mode 100644 index 0000000000000000000000000000000000000000..2cbe7151481a408b008cc9485672c9507289b050 --- /dev/null +++ b/deps/MsvcLibX/include/sys/stat.h @@ -0,0 +1,422 @@ +/*****************************************************************************\ +* * +* Filename: stat.h * +* * +* Description: MsvcLibX extensions to sys/stat.h. * +* * +* Notes: * +* * +* History: * +* 2014-02-06 JFL Moved stat extensions from dirent.h. * +* 2014-02-26 JFL Added proprietary routines for managing file times. * +* 2014-03-24 JFL Added a mechanism to also include MSVC's own sys/stat.h. * +* Renamed this file from statx.h to sys/stat.h. * +* 2014-05-27 JFL Added dummy definitions for S_TYPEISSHM() & S_TYPEISTMO().* +* 2014-06-03 JFL Moved struct timespec definition to sys/time.h. * +* 2014-06-06 JFL Moved mode_t & off*_t definition to sys/types.h. * +* Moved fseeko* & ftello* functions definitions to stdio.h. * +* 2014-06-24 JFL Added fstat and fstat64 external references. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* 2016-09-15 JFL Fixed a warning in Visual Studio 2015. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_STAT_H +#define _MSVCLIBX_STAT_H 1 + +#include "msvclibx.h" + +#include +#include UCRT_INCLUDE_FILE(sys\stat.h) /* Include MSVC's own file */ +#include /* For dirent2stat() arguments definitions */ +#include /* for time_t definition */ +#include /* for timespec definition */ +/* Include MsvcLibX's override, to avoid conflict with the standard mkdir defined here, + should be manually included later on in the C source */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + +/* Define stat and fstat to use 32 or 64 file lengths, as defined by _FILE_OFFSET_BITS */ +/* #undef stat /* Not normally defined by MSVC */ +/* #undef fstat /* Not normally defined by MSVC */ +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + /* TO DO: Windows 95 has extended functions for handling 64-bits files sizes */ +#else +#endif +/* For now, use the MSVC 32-bits functions in all cases */ +#define stat _stat +#define fstat _fstat +#define lstat stat + +/* Define standard 64-bits structures and functions */ +#if defined(_LARGEFILE_SOURCE64) + /* For now, hide the fact that DOS does not support 64-bits lengths */ + #define off64_t _off_t + #define stat64 _stat + #define fstat64 _fstat + #define lstat64 stat64 +#endif + +/* Proprietary function for recovering available infos without calling stat */ +extern int dirent2stat(struct dirent *pDE, struct _stat *pStat); +#define dirent2stat64 dirent2stat /* The current versions are the same */ +#define _DIRENT2STAT_DEFINED 1 + +/* MS-DOS always reports local file times. MsvcLibX DOS version generates a + pseudo GMT time for files using mktime(), which can then be undone by localtime(). */ +#define LocalFileTime localtime + +/* Proprietary function for converting a DOS date/time to a Posix time_t */ +extern time_t Filetime2Timet(uint16_t date, uint16_t time); +/* Proprietary function for generating a string with the local file time, in the ISO 8601 date/time format */ +extern char *Filetime2String(uint16_t date, uint16_t time, char *pBuf, size_t nBufSize); + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +/* Visual C++ sys/stat.h defines a series of _statXY functions and structures: + XY = 32 st_*time is 32-bits __time32_t & st_size is 32-bits _off_t + XY = 32i64 st_*time is 32-bits __time32_t & st_size is 64-bits __int64 + XY = 64i32 st_*time is 64-bits __time64_t & st_size is 32-bits _off_t + XY = 64 st_*time is 64-bits __time64_t & st_size is 64-bits __int64 + Then it defines additional _statZ macros generating _statXY, based on: + XY = 32 if _USE_32BIT_TIME_T defined & Z is "" + XY = 32i64 if _USE_32BIT_TIME_T defined & Z is i64 + XY = 64i32 if _USE_32BIT_TIME_T undefined & Z is "" + XY = 64 if _USE_32BIT_TIME_T undefined & Z is i64 + Special case: In 64-bits windows, _USE_32BIT_TIME_T defined is ignored and #undef(ined) +*/ + +/* Define stat and fstat to use 32 or 64 file lengths, as defined by _FILE_OFFSET_BITS */ +/* #undef stat /* Not normally defined by MSVC */ +/* #undef fstat /* Not normally defined by MSVC */ + +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + #define _STAT_FILE_SIZE 64 + #define _STAT_SUFFIX i64 +#else + #define _STAT_FILE_SIZE 32 + #define _STAT_SUFFIX +#endif + +#define _USE_EXTENDED_STAT_STRUCT 1 + +#define _VALUEOF(a) a /* Get the token value */ +#define _CONCAT2T(a,b) a##b /* Concatenate two tokens (does not expand their values) */ +#define _CONCAT3T(a,b,c) a##b##c /* Concatenate three tokens (does not expand their values) */ +#define _CONCAT4T(a,b,c,d) a##b##c##d /* Concatenate four tokens (does not expand their values) */ +#define _CONCAT(a,b) _CONCAT2T(a,b) /* Concatenate two tokens values */ +#define _CONCAT3(a,b,c) _CONCAT3T(a,b,c) /* Concatenate three tokens values */ +#define _CONCAT4(a,b,c,d) _CONCAT4T(a,b,c,d) /* Concatenate four tokens values */ +#define _CON_STAT_CAT1(pre,post) pre##stat##post +#define _CON_STAT_CAT(pre,post) _CON_STAT_CAT1(pre,post) + +/* Define what stat, fstat, lstat, stat64 macros would be, + if we were to use MSVC's own stat structures and routines */ +/* Avoid concatenating tokens _stat and _fstat, as these are already macros + that would be expanded, and we do not want this as this stage. */ +#define _MSVC_stat _CON_STAT_CAT(_ , _STAT_SUFFIX) +#define _MSVC_fstat _CON_STAT_CAT(_f, _STAT_SUFFIX) +#define _MSVC_lstat _CON_STAT_CAT(_l, _STAT_SUFFIX) +#define _MSVC_stat64 _CON_STAT_CAT(_ , i64) +#define _MSVC_lstat64 _CON_STAT_CAT(_l, i64) + +#ifdef _USE_32BIT_TIME_T +#define _lstat _lstat32 +#define _lstati64 _lstat32i64 +#define _lstat_ns _lstat32_ns +#define _lstati64_ns _lstat32i64_ns +#else +#define _lstat _lstat64i32 +#define _lstati64 _lstat64 +#define _lstat_ns _lstat64i32_ns +#define _lstati64_ns _lstat64_ns +#endif + +#if !_USE_EXTENDED_STAT_STRUCT + #define _NS_SUFFIX +#else /* _USE_EXTENDED_STAT_STRUCT */ + #define _MSVCLIBX_STAT_DEFINED 1 + #define _NS_SUFFIX _ns + /* Define what stat, fstat, lstat, stat64 macros and structures would be, + if we were to use MsvcLibX extended stat structures and routines */ + #define _LIBX_stat _CONCAT(_MSVC_stat,_ns) + #define _LIBX_stat64 _CONCAT(_MSVC_stat64,_ns) +#include "debugm.h" +#pragma message("Defining type struct " VALUEIZE(_LIBX_stat)) + struct _LIBX_stat { + /* MSVC standard stat structure fields */ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + off_t st_size; + /* End of MSVC standard stat structure fields */ + struct timespec st_ctim; /* File creation date/time, w. ns resolution */ + struct timespec st_mtim; /* File modification date/time, w. ns resolution */ + struct timespec st_atim; /* File access date/time, w. ns resolution */ + unsigned int st_Win32Attrs; /* Win32 file attributes */ + unsigned int st_ReparseTag; /* Reparse point tag */ + }; + /* Compatibility with old Unix fields */ + #define st_ctime st_ctim.tv_sec + #define st_mtime st_mtim.tv_sec + #define st_atime st_atim.tv_sec + /* Compatibility with intermediate Unix fields */ + #define st_ctimensec st_ctim.tv_nsec /* Nanosecond part of the file creation time */ + #define st_mtimensec st_mtim.tv_nsec /* Nanosecond part of the file modification time */ + #define st_atimensec st_atim.tv_nsec /* Nanosecond part of the file access time */ + + #if (_STAT_FILE_SIZE != 64) /* Else it's the same as struct stat */ +#pragma message("Defining type struct " VALUEIZE(_LIBX_stat64)) + struct _LIBX_stat64 { + /* MSVC standard stat structure fields */ + _dev_t st_dev; + _ino_t st_ino; + unsigned short st_mode; + short st_nlink; + short st_uid; + short st_gid; + _dev_t st_rdev; + off64_t st_size; + /* End of MSVC standard stat structure fields */ + struct timespec st_ctim; /* File creation date/time, w. ns resolution */ + struct timespec st_mtim; /* File modification date/time, w. ns resolution */ + struct timespec st_atim; /* File access date/time, w. ns resolution */ + unsigned int st_Win32Attrs; /* Win32 file attributes */ + unsigned int st_ReparseTag; /* Reparse point tag */ + }; + #endif +#endif /* !_USE_EXTENDED_STAT_STRUCT */ + +/* Define standard stat, fstat, lstat macros */ +#define stat _CONCAT(_MSVC_stat,_NS_SUFFIX) +#define fstat _CONCAT(_MSVC_fstat,_NS_SUFFIX) +#define lstat _CONCAT(_MSVC_lstat,_NS_SUFFIX) + +/* Reference standard stat, fstat, lstat functions that we redefine */ +#if _USE_EXTENDED_STAT_STRUCT /* Else we'll use MSVC's version */ +extern int stat(const char *path, struct stat *buf); +extern int fstat(int nFile, struct stat *buf); +#endif +extern int lstat(const char *path, struct stat *buf); + +/* Define standard 64-bits macros and functions */ +#if defined(_LARGEFILE_SOURCE64) + #define stat64 _CONCAT(_stati64,_NS_SUFFIX) + #define fstat64 _CONCAT(_fstati64,_NS_SUFFIX) + #define lstat64 _CONCAT(_lstati64,_NS_SUFFIX) + + #if (_STAT_FILE_SIZE != 64) /* Else they're the same as functions stat & lstat */ + #if _USE_EXTENDED_STAT_STRUCT /* Else we'll use MSVC's version */ + extern int stat64(const char *path, struct stat64 *buf); + extern int fstat64(int nFile, struct stat *buf); + #endif + extern int lstat64(const char *path, struct stat64 *buf); + #endif +#endif + +/* Proprietary function for recovering dirent infos without calling stat */ +/* Note: MSDOS has a single stat version, and its dirent2stat implementation is in dirent.c */ +#ifdef _USE_32BIT_TIME_T +#if (_STAT_FILE_SIZE != 64) /* Else if _STAT_FILE_SIZE=64, then struct _stat32_ns isn't defined */ +extern int _CONCAT(_dirent2_stat32,_NS_SUFFIX)(struct dirent *pDE, struct _CONCAT(_stat32,_NS_SUFFIX) *pStat); +#endif +extern int _CONCAT(_dirent2_stat32i64,_NS_SUFFIX)(struct dirent *pDE, struct _CONCAT(_stat32i64,_NS_SUFFIX) *pStat); +#else +#if (_STAT_FILE_SIZE != 64) /* Else if _STAT_FILE_SIZE=64, then struct _stat64i32_ns isn't defined */ +extern int _CONCAT(_dirent2_stat64i32,_NS_SUFFIX)(struct dirent *pDE, struct _CONCAT(_stat64i32,_NS_SUFFIX) *pStat); +#endif +extern int _CONCAT(_dirent2_stat64,_NS_SUFFIX)(struct dirent *pDE, struct _CONCAT(_stat64,_NS_SUFFIX) *pStat); +#endif +#define dirent2stat _CONCAT(_dirent2,stat) +#define _DIRENT2STAT_DEFINED 1 + +#define unlink _CONCAT(_unlink_, stat) +#define rmdir _CONCAT(_rmdir_, stat) +extern int unlink(const char *path); +extern int rmdir(const char *path); + +/* Proprietary function for generating a printable local file time, + using Windows' specific algorithm, to match cmd.exe dir output. */ +extern struct tm *LocalFileTime(const time_t *pt); + +/* Proprietary function for converting a Win32 FILETIME to a Posix time_t */ +extern time_t Filetime2Timet(const FILETIME *pFT); +/* Proprietary function for converting a Posix time_t to a Win32 FILETIME */ +extern void Timet2Filetime(time_t s, FILETIME *pFT); + +/* Proprietary function for converting a Win32 FILETIME to a Posix {time_t,nanosecond} */ +extern void Filetime2Timespec(const FILETIME *pFT, struct timespec *pTS); +/* Proprietary function for converting a Posix {time_t,nanosecond} to a Win32 FILETIME */ +extern void Timespec2Filetime(const struct timespec *pTS, FILETIME *pFT); + +/* Proprietary function for generating a string with the local file time, in the ISO 8601 date/time format */ +extern char *Filetime2String(const FILETIME *pFT, char *pBuf, size_t nBufSize); + +#endif /* defined(_WIN32) */ + +/************************* OS/2-specific definitions *************************/ + +#ifdef _OS2 /* Automatically defined when targeting an OS/2 application? */ + +/* Define stat and fstat to use 32 or 64 file lengths, as defined by _FILE_OFFSET_BITS */ +/* #undef stat /* Not normally defined by MSVC */ +/* #undef fstat /* Not normally defined by MSVC */ +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + /* TO DO: Windows 95 has extended functions for handling 64-bits files sizes */ +#else +#endif +/* For now, use the MSVC 32-bits functions in all cases */ +#define off_t _off_t +#define stat _stat +#define fstat _fstat +#define lstat stat + +/* Define standard 64-bits functions */ +#if defined(_LARGEFILE_SOURCE64) + /* For now, hide the fact that DOS does not support 64-bits lengths */ + #define off64_t _off_t + #define stat64 _stat + #define fstat64 _fstat + #define lstat64 stat64 +#endif + +/* Proprietary function for recovering available infos without calling stat */ +/* extern int dirent2stat(struct dirent *pDE, struct _stat *pStat); */ +/* #define dirent2stat64 dirent2stat /* The current versions are the same */ +/* #define _DIRENT2STAT_DEFINED 1 */ + +/* To do: Check if OS/2 uses local or GMT times, and implement LocalFileTime() if needed. */ +#define LocalFileTime localtime + +#endif /* defined(_OS2) */ + +/********************** End of OS-specific definitions ***********************/ + +#define lchmod chmod /* MSVC is buggy and chmod() applies to the link itself */ + +/* Structure stat standard st_mode values not defined in DOS/Windows' sys/stat.h */ +/* Must match the d_type field types in dirent.h. */ +/* #define S_IFMT 0xF000 /* Mask for the 4-bit file type */ +#define S_IFIFO 0x1000 /* FIFO */ +/* #define S_IFCHR 0x2000 /* Character device */ +/* #define S_IFDIR 0x4000 /* Directory */ +#define S_IFBLK 0x6000 /* Block device */ +/* #define S_IFREG 0x8000 /* Regular file */ +#define S_IFLNK 0xA000 /* Symbolic link */ +#define S_IFSOCK 0xC000 /* Socket */ + +/* Structure stat standard st_mode type test macros */ +/* The existence of these macros can be used to test for the OS support of the feature */ +#define S_ISTYPE(m, TYPE) ((m & S_IFMT) == TYPE) +/* Both DOS and Windows support these file types */ +#define S_ISCHR(m) S_ISTYPE(m, S_IFCHR) /* Test for a character device */ +#define S_ISDIR(m) S_ISTYPE(m, S_IFDIR) /* Test for a directory */ +#define S_ISREG(m) S_ISTYPE(m, S_IFREG) /* Test for a regular file */ +#ifdef _WIN32 /* Only Windows supports these */ +#define S_ISLNK(m) S_ISTYPE(m, S_IFLNK) /* Test for a symbolic link */ +#endif +#if 0 /* Only Unix supports these? At least MsvcLibX does not support them now. */ +#define S_ISBLK(m) S_ISTYPE(m, S_IFBLK) /* Test for a block device */ +#define S_ISFIFO(m) S_ISTYPE(m, S_IFIFO) /* Test for a pipe or FIFO */ +#define S_ISSOCK(m) S_ISTYPE(m, S_IFSOCK) /* Test for a socket */ +#endif + +#define S_ISBLK(m) 0 /* Test for a block device */ +#define S_ISCTG(m) 0 /* Test for a high performance ("contiguous data") file */ +#define S_ISDOOR(m) 0 /* Test for a door */ +#define S_ISFIFO(m) 0 /* Test for a pipe or FIFO */ +#define S_ISMPB(m) 0 /* Test for a multiplexed block device */ +#define S_ISMPC(m) 0 /* Test for a multiplexed character device */ +#define S_ISNWK(m) 0 /* Test for a network special file (HP-UX) */ +#define S_ISPORT(m) 0 /* Test for a port */ +#define S_ISSOCK(m) 0 /* Test for a socket */ +#define S_ISWHT(m) 0 /* Test for a whiteout (4.4BSD) */ + + +/* Other optional file types that some operating systems support */ +#define S_TYPEISMQ(pStat) 0 /* Test for a message queue */ +#define S_TYPEISSEM(pStat) 0 /* Test for a semaphore */ +#define S_TYPEISSHM(pStat) 0 /* Test for a shared memory object */ +#define S_TYPEISTMO(pStat) 0 /* Test for a typed memory object */ + +/* Structure stat standard st_mode flags */ +#define S_ISUID 04000 /* Set UID bit */ +#define S_ISGID 02000 /* Set-group-ID bit */ +#define S_ISVTX 01000 /* Sticky bit */ + +#define S_IRWXU 0700 /* Mask for file owner permissions */ +#define S_IRUSR 0400 /* Owner has read permission. Alias S_IREAD */ +#define S_IWUSR 0200 /* Owner has write permission. Alias S_IWRITE */ +#define S_IXUSR 0100 /* Owner has execute permission. Alias S_IEXEC */ + +#define S_IRWXG 070 /* Mask for group permissions */ +#define S_IRGRP 040 /* Group has read permission */ +#define S_IWGRP 020 /* Group has write permission */ +#define S_IXGRP 010 /* Group has execute permission */ + +#define S_IRWXO 07 /* Mask for permissions for others (not in group) */ +#define S_IROTH 04 /* Others have read permission */ +#define S_IWOTH 02 /* Others have write permission */ +#define S_IXOTH 01 /* Others have execute permission */ + +#define S_IRWXUGO 00777 /* S_IRWXU|S_IRWXG|S_IRWXO */ +#define S_IALLUGO 07777 /* S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO */ +#define S_IRUGO 00444 /* S_IRUSR|S_IRGRP|S_IROTH */ +#define S_IWUGO 00222 /* S_IWUSR|S_IWGRP|S_IWOTH */ +#define S_IXUGO 00111 /* S_IXUSR|S_IXGRP|S_IXOTH */ + +/* Structure stat extensions for DOS/Windows file attributes */ +#define S_IFVOLID 0xF000 /* Volume ID pseudo-file, defined in FAT root dir */ +#define S_ISVOLID(m) S_ISTYPE(m, S_IFVOLID) /* Test for a FAT volume ID */ +#define S_HIDDEN 01 /* Reuse permissions bit not used in DOS/Windows */ +#define S_ARCHIVE 02 /* Reuse permissions bit not used in DOS/Windows */ +#define S_SYSTEM 04 /* Reuse permissions bit not used in DOS/Windows */ +#define S_COMPRESSED 010 /* Reuse permissions bit not used in DOS/Windows */ +#define S_ENCRYPTED 020 /* Reuse permissions bit not used in DOS/Windows */ +#define S_NOT_CONTENT_INDEXED 040 /* Reuse permissions bit not used in DOS/Windows */ +#define S_OFFLINE 01000 /* Reuse sticky bit, not used in DOS/Windows */ +#define S_SPARSE_FILE 02000 /* Reuse GID bit, not used in DOS/Windows */ +#define S_MOUNT_POINT 04000 /* Reuse UID bit, not used in DOS/Windows */ +/* #define S_TEMPORARY /* Reuse UID bit, not used in DOS/Windows */ +/* #define S_VIRTUAL /* No bit left for this one */ + +#if defined(_MSDOS) +#define _mkdirx(path, mode) _mkdir(path) +#elif defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define _mkdirx(path, mode) mkdirU(path, mode) +#else /* _ANSI_SOURCE */ +#define _mkdirx(path, mode) mkdirA(path, mode) +#endif /* defined(_UTF8_SOURCE) */ +extern int mkdirU(const char *path, mode_t mode); +extern int mkdirA(const char *path, mode_t mode); +#endif /* defined(_MSDOS) */ +#define mkdir(path, mode) _mkdirx(path, mode) + +/* Special values for futimens() and utimensat(). Must not be in [0...((10^9)-1)] */ +#define UTIME_NOW 1000000001 +#define UTIME_OMIT 1000000002 + +#ifdef __cplusplus +} +#endif + +#endif /* defined(_MSVCLIBX_STAT_H) */ + diff --git a/deps/MsvcLibX/include/sys/time.h b/deps/MsvcLibX/include/sys/time.h new file mode 100644 index 0000000000000000000000000000000000000000..2dd8f4a5e439147d91f3ee1af28ce9f55de7d3d0 --- /dev/null +++ b/deps/MsvcLibX/include/sys/time.h @@ -0,0 +1,114 @@ +/*****************************************************************************\ +* * +* Filename sys/time.h * +* * +* Description DOS/WIN32 port of standard C library's sys/time.h. * +* * +* Notes MUST be included before any direct or indirect inclusion * +* of , as this sys/time.h file has a definition * +* of struct timeval conflicting with that in , * +* and as a workaround it defines _WINSOCKAPI_ to prevent * +* from loading . * +* * +* The same conflict exists with , but this one * +* is not loaded automatically, and hence should not be * +* visible to Unix apps built with the MsvcLibX library. * +* * +* History * +* 2014-02-11 JFL Created this file. * +* 2014-05-30 JFL Added the workaround for the conflict with . * +* 2014-06-03 JFL Moved struct timespec definition from sys/stat.h. * +* Added macros TIMEVAL_TO_TIMESPEC & TIMESPEC_TO_TIMEVAL. * +* 2016-07-06 JFL Avoid error if winsocks2.h has been previously included. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include /* for time_t definition */ + +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#ifdef _MSDOS +/* MS-DOS only has a 2-second resolution on file times. + Use the existence of macro _STRUCT_TIMEVAL to test if it's possible + to use utimes(), else use utime(), which is supported by all OSs */ +#endif + +#ifdef _WIN32 + +/* There's a conflict with the timeval definition in winsock.h, which uses + a long instead of a time_t for tv_sec. See: + C:\Pgm64\Microsoft SDKs\Windows\v7.0\INCLUDE\winsock.h +*/ +#define _WINSOCKAPI_ /* Prevent the inclusion of winsock.h in windows.h */ +/* Could also #define WIN32_LEAN_AND_MEAN /* Avoid including many optional Windows features, including winsock.h */ + +#include /* For WCHAR */ + +#ifndef _STRUCT_TIMEVAL +#define _STRUCT_TIMEVAL 1 + +#ifndef _WINSOCK2API_ /* Prevent compilation errors if winsocks2.h has been previously included */ +/* A time value with microsecond precision */ +struct timeval { + time_t tv_sec; /* Seconds */ + int tv_usec; /* Signed count of microseconds */ +}; +#endif /* _WINSOCK2API */ + +#endif /* !defined(_STRUCT_TIMEVAL) */ + +/* 2015-12-04 JFL Bug fix: With VS14/VC19, the UCRT defines timespec, with a long tv_nsec */ +#ifndef _UCRT +#ifndef _STRUCT_TIMESPEC +#define _STRUCT_TIMESPEC + +/* A time value with nanosecond precision */ +struct timespec { + time_t tv_sec; /* Seconds */ + int tv_nsec; /* Signed count of nanoseconds */ +}; +#define _TIMESPEC_DEFINED /* Some packages test this before redefining it */ + +#endif /* !defined(_STRUCT_TIMESPEC) */ +#endif /* !defined(_UCRT) */ + +#define TIMEVAL_TO_TIMESPEC(ptv, pts) { \ + (pts)->tv_sec = (ptv)->tv_sec; \ + (pts)->tv_nsec = (ptv)->tv_usec * 1000; \ +} +#define TIMESPEC_TO_TIMEVAL(ptv, pts) { \ + (ptv)->tv_sec = (pts)->tv_sec; \ + (ptv)->tv_usec = (pts)->tv_nsec / 1000; \ +} + +/* Change the file access time to tvp[0] and its modification time to tvp[1]. */ +int utimesA(const char *file, const struct timeval tvp[2]); +int utimesU(const char *file, const struct timeval tvp[2]); +int utimesW(const WCHAR *file, const struct timeval tvp[2]); + +/* Same as 'utimes', but does not follow symbolic links. */ +int lutimesA(const char *path, const struct timeval tvp[2]); +int lutimesU(const char *path, const struct timeval tvp[2]); +int lutimesW(const WCHAR *path, const struct timeval tvp[2]); + +/* Same as 'utimes', but takes an open file descriptor instead of a name. */ +int futimes(int fd, const struct timeval tvp[2]); + +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define utimes utimesU +#define lutimes lutimesU +#else /* _ANSI_SOURCE */ +#define utimes utimesA +#define lutimes lutimesA +#endif + +/* Get the current date and time into a struct timeval */ +int gettimeofday(struct timeval *ptv, void *pTimeZone); + +#endif /* defined(_WIN32) */ + +#endif /* !defined(_SYS_TIME_H) */ + diff --git a/deps/MsvcLibX/include/sys/types.h b/deps/MsvcLibX/include/sys/types.h new file mode 100644 index 0000000000000000000000000000000000000000..5b0f4133229721c9eb1cd86e0723a5f8f4238120 --- /dev/null +++ b/deps/MsvcLibX/include/sys/types.h @@ -0,0 +1,98 @@ +/*****************************************************************************\ +* * +* Filename: sys/types.h * +* * +* Description: Add missing definitions in MSVC's sys/types.h. * +* * +* Notes: * +* * +* History: * +* 2014-05-26 JFL Created this file. * +* 2014-06-06 JFL Moved mode_t & off*_t definitions here, from sys\stat.h. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_SYS_TYPES_H +#define _MSVCLIBX_SYS_TYPES_H 1 + +#include "msvclibx.h" + +#include UCRT_INCLUDE_FILE(sys\types.h) /* Include MSVC's own file */ + +/************************ MS-DOS-specific definitions ************************/ + +#ifdef _MSDOS /* Automatically defined when targeting an MS-DOS application */ + + + +/* File offset type */ +/* For now, use the MSVC 32-bits functions in all cases */ +#define off_t _off_t + +typedef int pid_t; /* The pid is the PSP segment. MSVC's process.h defines it as int. */ + +#endif /* defined(_MSDOS) */ + +/************************ Win32-specific definitions *************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +/* File offset types */ +#define off64_t __int64 /* Don't use a typedef because MSVC's _fseeki64 doesn't like it */ + +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) + #define off_t off64_t +#else + #define off_t _off_t +#endif + +typedef unsigned long DWORD; /* Don't include to get DWORD definition, as this draws too much, + including things we want to override in other parts of MsvcLibX */ + +typedef DWORD pid_t; /* Windows defines it as a DWORD */ + +#endif /* defined(_WIN32) */ + +/************************* OS/2-specific definitions *************************/ + +#ifdef _OS2 /* Automatically defined when targeting an OS/2 application? */ + +/* File offset type */ +/* For now, use the MSVC 32-bits functions in all cases */ +#define off_t _off_t + + +#endif /* defined(_OS2) */ + +/********************** End of OS-specific definitions ***********************/ + +/* Signed size type */ +#ifndef _SSIZE_T_DEFINED +#if defined(_MSDOS) +typedef int ssize_t; +#elif defined(_WIN32) +#include +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif /* defined(_WIN64) */ +#endif /* defined(_WIN32) */ +#define _SSIZE_T_DEFINED +#endif /* !_SSIZE_T_DEFINED */ + +/* MsvcLibX handles uid_t and gid_t in pwd.c and grp.c */ +typedef int gid_t; +typedef int uid_t; + +/* MsvcLibX uses mode_t in sys/stat.h */ +typedef int mode_t; + +/* File link counts type (not used by MsvcLibX so far) */ +typedef int nlink_t; /* Is short in some Unix versions */ + +#endif /* !defined(_MSVCLIBX_SYS_TYPES_H) */ + diff --git a/deps/MsvcLibX/include/sys/utsname.h b/deps/MsvcLibX/include/sys/utsname.h new file mode 100644 index 0000000000000000000000000000000000000000..4b2a85527ffdaf8c2c3cede3350b70e37996d77b --- /dev/null +++ b/deps/MsvcLibX/include/sys/utsname.h @@ -0,0 +1,31 @@ +/*****************************************************************************\ +* * +* Filename: sys/utsname.h * +* * +* Description: Defines structure utsname and function uname(). * +* * +* Notes: * +* * +* History: * +* 2014-05-30 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H 1 + +#include "msvclibx.h" + +struct utsname { + char *sysname; /* Name of this implementation of the operating system */ + char *nodename; /* Name of this node on the network */ + char *release; /* Current release level of this implementation */ + char *version; /* Current version level of this release */ + char *machine; /* Name of the hardware type on which the system is running */ +}; + +int uname(struct utsname *); + +#endif /* _SYS_UTSNAME_H */ diff --git a/deps/MsvcLibX/include/system.h b/deps/MsvcLibX/include/system.h new file mode 100644 index 0000000000000000000000000000000000000000..56f102c33d4d0185fc0ba3bf22bf60d1a168a8a4 --- /dev/null +++ b/deps/MsvcLibX/include/system.h @@ -0,0 +1,2 @@ +/* CoreUtils global system configuration definitions */ + diff --git a/deps/MsvcLibX/include/time.h b/deps/MsvcLibX/include/time.h new file mode 100644 index 0000000000000000000000000000000000000000..f95ec6ddfa5905e822fe20c7d466624a4ad4ea74 --- /dev/null +++ b/deps/MsvcLibX/include/time.h @@ -0,0 +1,47 @@ +/*****************************************************************************\ +* * +* Filename: time.h * +* * +* Description: MsvcLibX extensions to time.h. * +* * +* Notes: * +* * +* History: * +* 2014-06-04 JFL Created this file. * +* 2015-11-15 JFL Visual Studio 2015 moved this file to the Windows Kit UCRT. +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_TIME_H +#define _MSVCLIBX_TIME_H 1 + +#include "msvclibx.h" + +#include WINSDK_INCLUDE_FILE(winsock2.h) +#include UCRT_INCLUDE_FILE(time.h) /* Include MSVC's own file */ + + +#ifdef _MSDOS + +/* Check for the definition of _STRUCT_TIMESPEC before using clock_gettime(). + If it's not defined, use time() instead, which is supported by all OSs. */ + +#endif /* defined(_MSDOS) */ + + +#ifdef _WIN32 + +#include "sys\time.h" /* for struct timespec */ + +typedef int clockid_t; +/* Supported values for clockid_t */ +#define CLOCK_REALTIME 0 + +int clock_gettime(clockid_t clock_id, struct timespec *tp); + +#endif /* defined(_WIN32) */ + +#endif /* defined(_MSVCLIBX_TIME_H) */ + diff --git a/deps/MsvcLibX/include/unistd.h b/deps/MsvcLibX/include/unistd.h new file mode 100644 index 0000000000000000000000000000000000000000..748de62d2425fca989637d53a5e16a19d739b5a8 --- /dev/null +++ b/deps/MsvcLibX/include/unistd.h @@ -0,0 +1,182 @@ +/*****************************************************************************\ +* * +* Filename: unistd.h * +* * +* Description: DOS/WIN32 port of standard C library's unistd.h. * +* * +* Notes: * +* * +* History: * +* 2012-01-18 JFL Created this file. * +* 2012-10-17 JFL Added standard functions getcwd, chdir, getpid, access. * +* Added Microsoft-specific functions getdrive, chdrive. * +* 2013-03-27 JFL Updated getpid() and added getppid(). * +* 2014-02-03 JFL Added readlink(). * +* 2014-03-20 JFL Restructured Windows link management functions into Wide * +* and MultiByte versions, and changed the Unicode and Ansi * +* versions to macros. * +* 2014-06-30 JFL Moved PATH_MAX definition to limits.h. * +* 2016-08-25 JFL Implemented ResolveLinksA(). * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#ifndef _MSC_VER +#error This include file is designed for use with the Microsoft C tools only. +#endif + +#include "msvclibx.h" /* Generate a library search record to load MsvcLibX.lib. */ +#include "sys/types.h" /* Define pid_t and getppid(). */ +#include "dirent.h" /* Define pid_t and getppid(). */ +#include /* For functions like _chdir() and _getcwd() */ +#include /* For _getpid() */ + +/* Microsoft tools think these are non standard, but they are standard! */ +/* #define getcwd _getcwd */ +/* #define chdir _chdir */ +/* Actually use the improved versions in MsvcLibX */ +#undef getcwd /* MSVC _does_ define a getcwd macro, in addition to the getcwd function! */ +#if defined(_MSDOS) +#define getcwd(path, size) _getcwd(path, (int)(size)) /* Use MSVC LIB's own, changing argument 2 type */ +#elif defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define getcwd getcwdU +#define _getdcwd _getdcwdU +#define chdir chdirU +#else /* _ANSI_SOURCE */ +#define getcwd getcwdA +#define _getdcwd _getdcwdA +#define chdir chdirA +#endif +char *getcwdA(char *buf, size_t bufSize); /* Can't use the getcwd name, as MSVC has an incompatible prototype for it */ +char *_getdcwdA(int iDrive, char *buf, int iBuflen); +char *getcwdU(char *buf, size_t bufSize); /* Can't use the getcwd name, as MSVC has an incompatible prototype for it */ +char *_getdcwdU(int iDrive, char *buf, int iBuflen); +#endif /* defined(_MSDOS) */ +int chdir(const char *path); + +/* These are non standard indeed, but the leading _ is annoying */ +#define getdrive _getdrive +#define chdrive _chdrive + +#include /* For low level I/O functions like read() & write() */ + +/* Microsoft tools think access is non standard, but it is standard! */ +#if defined(_MSDOS) +#define access _access +#elif defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define access _accessU +int _accessU(const char *pszFilename, int iAccessMode); +#else /* _ANSI_SOURCE */ +#define access _access +#endif +#endif +#define F_OK 0 /* test for the existence of the file */ +#define X_OK 1 /* test for execute permission */ +#define R_OK 2 /* test for read permission */ +#define W_OK 4 /* test for read permission */ + +/* getpid() and getppid() */ +#define getpid() ((pid_t)(_getpid())) +pid_t getppid(void); /* Get parent PID */ +/* Contrary to in Unix, the above functions can fail in Windows. In this case they return INVALID_PID. */ +#define INVALID_PID ((pid_t)-1L) + +/* Path management */ +#if defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define realpath realpathU +#define CompactPath CompactPathU +#else /* _ANSI_SOURCE */ +#define realpath realpathA +#define CompactPath CompactPathA +#endif +#endif /* defined(_WIN32) */ +char *realpath(const char *path, char *buf); /* Posix routine, normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */ +int CompactPath(const char *path, char *outbuf, size_t bufsize); /* A proprietary subroutine, that cleans up . and .. parts. */ + +/* Signed size type */ +#ifndef _SSIZE_T_DEFINED +#if defined(_MSDOS) +typedef int ssize_t; +#elif defined(_WIN32) +#include +#ifdef _WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif /* defined(_WIN64) */ +#endif /* defined(_WIN32) */ +#define _SSIZE_T_DEFINED +#endif /* !_SSIZE_T_DEFINED */ + +/* Link management functions */ +#if defined(_WIN32) +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define readlink readlinkU +#define symlink symlinkU +#define symlinkd symlinkdU +#define junction junctionU +#define GetReparseTag GetReparseTagU +#define ResolveLinks ResolveLinksU +#else /* _ANSI_SOURCE */ +#define readlink readlinkA +#define symlink symlinkA +#define symlinkd symlinkdA +#define junction junctionA +#define GetReparseTag GetReparseTagA +#define ResolveLinks ResolveLinksA +#endif +ssize_t readlinkW(const WCHAR *path, WCHAR *buf, size_t bufsiz); /* Posix routine readlink - Wide char version */ +ssize_t readlinkM(const char *path, char *buf, size_t bufsiz, UINT cp); /* Posix routine readlink - Multibyte char version */ +#define readlinkA(path, buf, bufsiz) readlinkM(path, buf, bufsiz, CP_ACP) /* Posix routine readlink - ANSI version */ +#define readlinkU(path, buf, bufsiz) readlinkM(path, buf, bufsiz, CP_UTF8) /* Posix routine readlink - UTF-8 version */ +int symlinkW(const WCHAR *targetname, const WCHAR *newlinkname); /* Posix routine symlink - Wide char version */ +int symlinkM(const char *targetname, const char *newlinkname, UINT cp); /* Posix routine symlink - Multibyte char version */ +#define symlinkA(target, newlink) symlinkM(target, newlink, CP_ACP) /* Posix routine symlink - ANSI version */ +#define symlinkU(target, newlink) symlinkM(target, newlink, CP_UTF8) /* Posix routine symlink - UTF-8 version */ +int symlinkdW(const WCHAR *targetname, const WCHAR *newlinkname); /* MsvcLibX Create an NTFS symlinkd - Wide char version */ +int symlinkdM(const char *targetname, const char *newlinkname, UINT cp); /* MsvcLibX Create an NTFS symlinkd - Multibyte char version */ +#define symlinkdA(target, newlink) symlinkdM(target, newlink, CP_ACP) /* MsvcLibX Create an NTFS symlinkd - ANSI version */ +#define symlinkdU(target, newlink) symlinkdM(target, newlink, CP_UTF8) /* MsvcLibX Create an NTFS symlinkd - UTF-8 version */ +int junctionW(const WCHAR *targetname, const WCHAR *junctionName); /* MsvcLibX Create an NTFS junction - Wide char version */ +int junctionM(const char *targetname, const char *junctionName, UINT cp); /* MsvcLibX Create an NTFS junction - Multibyte char version */ +#define junctionA(target, newjunc) junctionM(target, newjunc, CP_ACP) /* MsvcLibX Create an NTFS junction - ANSI version */ +#define junctionU(target, newjunc) junctionM(target, newjunc, CP_UTF8) /* MsvcLibX Create an NTFS junction - UTF-8 version */ +DWORD GetReparseTagW(const WCHAR *path); /* MsvcLibX Get a Repase Point tag - Wide char version */ +DWORD GetReparseTagM(const char *path, UINT cp); /* MsvcLibX Get a Repase Point tag - MultiByte char version */ +#define GetReparseTagA(path) GetReparseTagM(path, CP_ACP) /* MsvcLibX Get a Repase Point tag - ANSI version */ +#define GetReparseTagU(path) GetReparseTagM(path, CP_UTF8) /* MsvcLibX Get a Repase Point tag - ANSI version */ +int ResolveLinksA(const char *path, char *buf, size_t bufsize); /* Resolve pathnames with symlinks, symlinkds, and junctions */ +int ResolveLinksU(const char *path, char *buf, size_t bufsize); /* Resolve pathnames with symlinks, symlinkds, and junctions */ +#ifndef ELOOP +/* +// Unix defines ELOOP as errno 40. +// MS Visual C++ 1.52 for DOS is standard up to errno 34, then diverges up to errno 36. +// Many errnos within the list are actually unused, and for them _sys_errlist[] = "". +// MS Visual C++ 9 for Windows is standard up to errno 34, then diverges up to errno 43. +// Also MSVC9 does not define errno: +// 15 // The posix standard ENOTBLK "Block device required" +// 26 // The posix standard ETXTBSY "Text file busy" +// 35 // Positioned between standard ERANGE and EDEADLK +// 37 // Positioned between standard EDEADLK and ENAMETOOLONG +// 43 // Positioned last, after standard ENOTEMPTY +// The _sys_errlist[] pointer for all the above points to a single string "Unknown error". +*/ +#define ELOOP 35 /* Using the first available slot */ /* Update _sys_errlist[ELOOP] accordingly in any routine that generates ELOOP! */ +#endif /* !defined(ELOOP) */ +#define SYMLOOP_MAX 31 /* Maximum depth of symbolic name resolution, to avoid stack overflows. Windows is documented to allow 31: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365460(v=vs.85).aspx */ +#endif /* defined(_WIN32) */ + +/* Standard file descriptor numbers, for low level I/O functions */ +#define STDIN_FILENO 0 /* Standard input file number */ +#define STDOUT_FILENO 1 /* Standard output file number */ +#define STDERR_FILENO 2 /* Standard error file number */ + +#endif /* _UNISTD_H */ + diff --git a/deps/MsvcLibX/include/utime.h b/deps/MsvcLibX/include/utime.h new file mode 100644 index 0000000000000000000000000000000000000000..e6771fa7a88d25b0a4312a4630108e63507aedf2 --- /dev/null +++ b/deps/MsvcLibX/include/utime.h @@ -0,0 +1,86 @@ +/*****************************************************************************\ +* * +* Filename: utime.h * +* * +* Description: DOS/WIN32 adaptation of standard C library's utime.h. * +* * +* Notes: The Unix standard now standardizes utime.h location in * +* the include directory itself. * +* Microsoft put it in the include/sys subdirectory. * +* * +* History: * +* 2014-12-13 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVXLIBX_UTIME_H +#define _MSVXLIBX_UTIME_H + +/* In MS-DOS, simply use MSVC's sys/utime.h. */ + +#ifdef _MSDOS + +#include + +#define lutime utime /* There are no links in MS-DOS, so lutime() is the same as utime() */ + +#endif /* _MSDOS */ + + +/* In Windows, we use MSVC's sys/utime.h, but redefine the utime*() functions. */ + +#ifdef _WIN32 + +#include "msvclibx.h" /* Generate a library search record to load MsvcLibX.lib. */ + +/* Save the initial definition and value of __STDC__ */ +#ifdef __STDC__ +#define _UTIME__STDC__WAS_DEFINED 1 +#pragma push_macro("__STDC__") +#undef __STDC__ +#else +#define _UTIME__STDC__WAS_DEFINED 0 +#endif + +#define __STDC__ 1 /* Prevents from defining structures and functions without _ */ + +#include + +#ifdef _USE_32BIT_TIME_T +#define utimbuf __utimbuf32 +#define utime _utime32x +#error "32-bits time_t not supported in MsvcLibX' utime." +#else +#define utimbuf __utimbuf64 +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) +#define utime utimeU +#define lutime lutimeU +#else /* _ANSI_SOURCE */ +#define utime utimeA +#define lutime lutimeA +#endif +#endif + +/* Our redefinition in utime.c */ +int utimeA(const char * pszFilename, const struct utimbuf * pUtimbuf); +int lutimeA(const char * pszFilename, const struct utimbuf * pUtimbuf); +int utimeU(const char * pszFilename, const struct utimbuf * pUtimbuf); +int lutimeU(const char * pszFilename, const struct utimbuf * pUtimbuf); +int utimeW(const WCHAR * pszFilename, const struct utimbuf * pUtimbuf); +int lutimeW(const WCHAR * pszFilename, const struct utimbuf * pUtimbuf); +int futime(int fd, const struct utimbuf * pUtimbuf); + +#undef __STDC__ + +/* Restore the initial definition and value of __STDC__ */ +#if _UTIME__STDC__WAS_DEFINED +#pragma pop_macro("__STDC__") +#endif +#undef _UTIME__STDC__WAS_DEFINED + +#endif /* _WIN32 */ + +#endif /* _MSVXLIBX_UTIME_H */ + diff --git a/deps/MsvcLibX/include/windows.h b/deps/MsvcLibX/include/windows.h new file mode 100644 index 0000000000000000000000000000000000000000..03404d7653490866dc7ea34c7b4442bcc57b42df --- /dev/null +++ b/deps/MsvcLibX/include/windows.h @@ -0,0 +1,60 @@ +/*****************************************************************************\ +* * +* Filename: windows.h * +* * +* Description: Define MsvcLibX' extensions to the WIN32 API functions * +* * +* Notes: * +* * +* History: * +* 2016-09-12 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _MSVCLIBX_WINDOWS_H +#define _MSVCLIBX_WINDOWS_H 1 + +#include "msvclibx.h" + +#ifdef _WIN32 + +#include WINSDK_INCLUDE_FILE(windows.h) /* Include Windows SDK's own windows.h */ + +/****************** Define UTF-8 versions of WIN32 routines ******************/ + +#ifdef __cplusplus +extern "C" { +#endif + +DWORD WINAPI GetFileAttributesU(LPCTSTR lpFileName); +BOOL WINAPI GetFileAttributesExU(LPCTSTR lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, LPVOID lpFileInformation); +DWORD WINAPI GetFullPathNameU(LPCTSTR lpName, DWORD nBufferLength, LPTSTR lpBuf, LPTSTR *lpFilePart); +DWORD WINAPI GetLongPathNameU(LPCTSTR lpShortName, LPTSTR lpBuf, DWORD nBufferLength); + +#ifdef __cplusplus +} +#endif + +/********** Redefine the legacy names to point to the UTF-8 version **********/ + +#if defined(_UTF8_SOURCE) || defined(_BSD_SOURCE) || defined(_GNU_SOURCE) + +#undef GetFileAttributes +#define GetFileAttributes GetFileAttributesU + +#undef GetFileAttributesEx +#define GetFileAttributesEx GetFileAttributesExU + +#undef GetFullPathName +#define GetFullPathName GetFullPathNameU + +#undef GetLongPathName +#define GetLongPathName GetLongPathNameU + +#endif /* defined(_UTF8_SOURCE) ... */ + +#endif /* defined(_WIN32) */ + +#endif /* defined(_MSVCLIBX_WINDOWS_H) */ diff --git a/deps/MsvcLibX/include/xfreopen.h b/deps/MsvcLibX/include/xfreopen.h new file mode 100644 index 0000000000000000000000000000000000000000..9ec6e493e9eb7df361fff0b425623d08ca00f018 --- /dev/null +++ b/deps/MsvcLibX/include/xfreopen.h @@ -0,0 +1,19 @@ +/*****************************************************************************\ +* * +* Filename: error.h * +* * +* Description: DOS/WIN32 port of the GNU CoreUtils library xfreopen func.* +* * +* Notes: msvclibx: Implement using freopen or _setmode. * +* * +* History: * +* 2014-02-10 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "msvclibx.h" /* Generate a library search record to load MsvcLibX.lib. */ + +extern FILE *xfreopen(const char *filename, const char *mode, FILE *stream); + diff --git a/deps/MsvcLibX/make.bat b/deps/MsvcLibX/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..7a272561228129410dcba670dee0ddb723553647 --- /dev/null +++ b/deps/MsvcLibX/make.bat @@ -0,0 +1,35 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: make.bat * +:# * +:# Description: Build DOS and Windows targets * +:# * +:# Notes: Proxy script for %STINCLUDE%\make.bat. * +:# * +:# If any change is needed, put it in %STINCLUDE%\make.bat. * +:# * +:# History: * +:# 2016-10-10 JFL jf.larvoire@hpe.com created this file. * +:# 2016-12-15 JFL Search for the real make.bat in [.|..|../..]\include. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +:# Get the full pathname of the STINCLUDE library directory +if defined STINCLUDE if not exist "%STINCLUDE%\make.bat" set "STINCLUDE=" &:# Allow overriding with another alias name, but ignore invalid overrides +for %%p in (. .. ..\..) do if not defined STINCLUDE if exist %%p\include\make.bat ( :# Default: Search it the current directory, and 2 levels above. + for /f "delims=" %%d in ('"pushd %%p\include & cd & popd"') do SET "STINCLUDE=%%d" +) +if not defined STINCLUDE ( :# Try getting the copy in the master environment + for /f "tokens=3" %%v in ('reg query "HKCU\Environment" /v STINCLUDE 2^>NUL') do set "STINCLUDE=%%v" +) + +if not exist %STINCLUDE%\make.bat ( + >&2 echo %0 Error: Cannot find SysToolsLib's global C include directory. Please define variable STINCLUDE. + exit /b 1 +) + +if [%1]==[-d] echo "%STINCLUDE%\make.bat" %* +"%STINCLUDE%\make.bat" %* diff --git a/deps/MsvcLibX/src/Files.mak b/deps/MsvcLibX/src/Files.mak new file mode 100644 index 0000000000000000000000000000000000000000..0b9ad8ee8c8c7476d02c089f4eb9c8157df4b518 --- /dev/null +++ b/deps/MsvcLibX/src/Files.mak @@ -0,0 +1,261 @@ +############################################################################### +# # +# File name Files.mak # +# # +# Description MsvcLibX Specific file dependancies # +# # +# Notes # +# # +# History # +# 2012-10-21 JFL Initial version # +# 2013-03-27 JFL Added debugv.obj and getppid.obj. # +# 2014-02-03 JFL Added readlink.obj. # +# 2014-02-05 JFL Added symlink.obj. # +# 2014-02-06 JFL Added lstat*.obj. # +# 2014-02-10 JFL Added realpath.obj. # +# 2014-02-17 JFL Added err2errno.obj. # +# 2014-02-26 JFL Added filetime.obj. # +# 2014-02-27 JFL Added iconv.obj. # +# 2014-02-28 JFL Added chdir.obj and getcwd.obj. # +# 2014-03-04 JFL Added fopen.obj. # +# 2014-03-06 JFL Added strerror.obj. # +# 2014-03-24 JFL Added access.obj. # +# 2014-03-27 JFL Added spawn.obj. # +# 2014-05-30 JFL Moved here the OBJECTS macro definition from NMakeFile. # +# Added uname.obj and utimes.obj. # +# 2014-06-04 JFL Added clock_gettime.obj and gettimeofday.obj. # +# 2014-06-24 JFL Added fstat64.obj and fstat64i32.obj. # +# 2014-07-01 JFL Added mb2wpath.obj. # +# 2016-09-08 JFL Added basename.obj and dirname.obj. # +# 2016-09-12 JFL Added WIN32_OBJECTS, and several WIN32 UTF-8 routines. # +# 2016-10-11 JFL moved debugm.h to SysToolsLib global C include dir. # +# 2017-02-16 JFL Added open.obj. # +# # +# © Copyright 2016 Hewlett Packard Enterprise Development LP # +# Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 # +############################################################################### + +# List of object files to build and include in the MsvcLibX library +# IMPORTANT NOTE: Every time you add an object file in the list here, also +# store its specific source file dependancies below. +OBJECTS = \ + +access.obj \ + +basename.obj \ + +chdir.obj \ + +clock_gettime.obj \ + +debugv.obj \ + +dirent.obj \ + +dirname.obj \ + +err2errno.obj \ + +filetime.obj \ + +fnmatch.obj \ + +fopen.obj \ + +fstat64i32.obj \ + +fstat64.obj \ + +getcwd.obj \ + +getopt.obj \ + +getppid.obj \ + +gettimeofday.obj \ + +iconv.obj \ + +lstat64i32.obj \ + +lstat64.obj \ + +main.obj \ + +mb2wpath.obj \ + +mkdir.obj \ + +mkdtemp.obj \ + +mkstemp.obj \ + +open.obj \ + +readlink.obj \ + +realpath.obj \ + +spawn.obj \ + +strerror.obj \ + +strndup.obj \ + +strptime.obj \ + +symlink.obj \ + +uname.obj \ + +utime.obj \ + +utimes.obj \ + +xfreopen.obj \ +# +lstat32.obj \ +# +lstat32i64.obj \ + +# WIN32 UTF-8 extension routines, used for implementing UTF-8 support for WIN32 libc. +WIN32_OBJECTS = \ + +GetFileAttributes.obj \ + +GetFileAttributesEx.obj \ + +GetFullPathName.obj \ + +GetLongPathName.obj \ + +fullpath.obj \ + +# GnuLib routines that I mistakenly defined here +REMOVED_OBJECTS = \ + +error.obj \ + +initmain.obj \ + +xnmalloc.obj \ + +############################################################################### +# Include files dependancies # +############################################################################### + +I=..\include +CI=$(STINCLUDE) + +$(I)\chdir.h: $(I)\unistd.h $(I)\iconv.h $(CI)\debugm.h + +$(I)\config.h: $(I)\msvclibx.h $(I)\stdbool.h $(I)\unistd.h + +$(I)\direct.h: $(I)\msvclibx.h + +$(I)\dirent.h: $(I)\inttypes.h $(I)\sys\stat.h + +$(I)\error.h: $(I)\msvclibx.h + +# $(I)\fadvise.h: + +$(I)\fcntl.h: $(I)\msvclibx.h + +$(I)\fnmatch.h: $(I)\msvclibx.h + +$(I)\getcwd.h: $(I)\unistd.h $(CI)\debugm.h + +# $(I)\getopt.h: + +$(I)\grp.h: $(I)\msvclibx.h + +# $(I)\inttypes.h: + +# $(I)\msvclibx.h: + +# $(I)\netdb.h: + +$(I)\process.h: $(I)\msvclibx.h + +$(I)\pwd.h: $(I)\msvclibx.h + +# $(I)\regex.h: + +$(I)\sys\stat.h: $(I)\msvclibx.h $(I)\sys\types.h + +# $(I)\stdbool.h: + +# $(I)\stdint.h: + +$(I)\stdio.h: $(I)\msvclibx.h + +# $(I)\stdio--.h: + +$(I)\stdlib.h: $(I)\msvclibx.h + +# $(I)\system.h: + +$(I)\unistd.h: $(I)\msvclibx.h $(I)\dirent.h + +# $(I)\utime.h: + +$(I)\windowsU.h: $(I)\msvclibx.h + +$(I)\xfreopen.h: $(I)\msvclibx.h + +$(I)\sys\types.h: $(I)\msvclibx.h + + +############################################################################### +# Source files dependancies # +############################################################################### + +access.c: $(I)\MsvcLibX.h $(CI)\debugm.h + +basename.c: $(I)\libgen.h + +chdir.c: $(CI)\debugm.h $(I)\iconv.h $(I)\unistd.h + +clock_gettime.c: $(I)\MsvcLibX.h $(I)\time.h $(I)\sys\stat.h + +debugv.c: $(CI)\debugm.h + +dirent.c: $(CI)\debugm.h $(I)\dirent.h $(I)\sys\stat.h $(I)\unistd.h + +dirname.c: $(I)\libgen.h + +err2errno.c: $(I)\MsvcLibX.h $(CI)\debugm.h + +error.c: $(I)\config.h $(I)\error.h + +filetime.c: $(I)\sys\stat.h + +fnmatch.c: $(CI)\debugm.h $(I)\fnmatch.h + +fopen.c: $(I)\MsvcLibX.h + +fstat64.c: fstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h + +fstat64i32.c: fstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h + +fullpath.c: $(I)\stdlib.h $(I)\limits.h + +getcwd.c: $(CI)\debugm.h $(I)\unistd.h + +GetFileAttributesU.c: $(I)\windowsU.h $(I)\limits.h + +GetFileAttributesExU.c: $(I)\windowsU.h $(I)\limits.h + +GetFullPathNameU.c: $(I)\windowsU.h $(I)\limits.h + +GetLongPathNameU.c: $(I)\windowsU.h $(I)\limits.h + +getopt.c: $(I)\getopt.h + +# getppid.c: + +gettimeofday.c: $(I)\MsvcLibX.h $(I)\time.h $(I)\sys\time.h + +grp.c: $(I)\grp.h + +iconv.c: $(I)\iconv.h + +initmain.c: $(I)\config.h + +lstat32.c: lstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h $(I)\unistd.h + +lstat32i64.c: lstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h $(I)\unistd.h + +lstat64.c: lstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h $(I)\unistd.h + +lstat64i32.c: lstat.c $(CI)\debugm.h $(I)\dirent.h $(I)\MsvcLibX.h $(I)\sys\stat.h $(I)\stdint.h $(I)\unistd.h + +main.c: $(I)\MsvcLibX.h + +mb2wpath.c: $(I)\MsvcLibX.h $(CI)\debugm.h + +mkdir.c: $(I)\MsvcLibX.h $(I)\sys\stat.h + +mkdtemp.c: $(I)\unistd.h + +mkstemp.c: $(I)\unistd.h + +open.c: $(I)\MsvcLibX.h $(I)\fcntl.h $(CI)\debugm.h + +pwd.c: $(I)\pwd.h + +readlink.c: $(CI)\debugm.h $(I)\unistd.h $(I)\reparsept.h + +realpath.c: $(CI)\debugm.h $(I)\unistd.h + +spawm.c: $(CI)\debugm.h $(I)\MsvcLibX.h $(I)\process.h + +strerror.c: $(I)\MsvcLibX.h + +# strndup.c: + +# strptime.c: + +symlink.c: $(CI)\debugm.h $(I)\reparsept.h $(I)\unistd.h + +uname.c: $(I)\MsvcLibX.h $(I)\sys\utsname.h + +utime.c: $(CI)\debugm.h $(I)\unistd.h $(I)\utime.h $(I)\sys\time.h + +xfreopen.c: $(I)\xfreopen.h + +xnmalloc.c: $(I)\config.h + diff --git a/deps/MsvcLibX/src/GetFileAttributes.c b/deps/MsvcLibX/src/GetFileAttributes.c new file mode 100644 index 0000000000000000000000000000000000000000..8bf3a53e8699b76e24c0ca0f6804c237d37fc5ad --- /dev/null +++ b/deps/MsvcLibX/src/GetFileAttributes.c @@ -0,0 +1,67 @@ +/*****************************************************************************\ +* * +* Filename GetFileAttributes.c * +* * +* Description: UTF-8 version of WIN32's GetFileAttributes() * +* * +* Notes: * +* * +* History: * +* 2016-09-12 JFL Created this file. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: GetFileAttributesU | +| | +| Description: Get atributes for a UTF-8 path. | +| | +| Parameters: See WIN32's GetFileAttributes() | +| | +| Return value: The file attributes flags | +| | +| Notes: | +| | +| History: | +| 2014-07-02 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +DWORD WINAPI GetFileAttributesU(LPCTSTR lpFileName) { + WCHAR *pwszName; + DWORD dwAttrs; + int n; + + /* Allocate a buffer large enough for any Unicode pathname */ + pwszName = (void *)LocalAlloc(LMEM_FIXED, UNICODE_PATH_MAX * sizeof(WCHAR)); + if (!pwszName) return 0; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + lpFileName, /* lpMultiByteStr, */ + pwszName, /* lpWideCharStr, */ + UNICODE_PATH_MAX /* cchWideChar, */ + ); + if (!n) { + LocalFree((HLOCAL)pwszName); + return 0; + } + + /* Get the file attributes, using the Unicode version of the function */ + dwAttrs = GetFileAttributesW(pwszName); + + /* Cleanup and return */ + LocalFree((HLOCAL)pwszName); + return dwAttrs; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/GetFileAttributesEx.c b/deps/MsvcLibX/src/GetFileAttributesEx.c new file mode 100644 index 0000000000000000000000000000000000000000..c24664e8fa89f8be324e7d5ab2bb66aa8bc1b714 --- /dev/null +++ b/deps/MsvcLibX/src/GetFileAttributesEx.c @@ -0,0 +1,72 @@ +/*****************************************************************************\ +* * +* Filename GetFileAttributesEx.c * +* * +* Description: UTF-8 version of WIN32's GetFileAttributesEx() * +* * +* Notes: * +* * +* History: * +* 2016-09-12 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: GetFileAttributesExU | +| | +| Description: Get file information for a UTF-8 pathname. | +| | +| Parameters: See WIN32's GetFileAttributesEx() | +| | +| Return value: 1 = done, or 0 if error | +| | +| Notes: Sets the file length, dates, attributes, etc. | +| | +| History: | +| 2016-09-12 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +BOOL WINAPI GetFileAttributesExU( + LPCTSTR lpFileName, + GET_FILEEX_INFO_LEVELS fInfoLevelId, + LPVOID lpFileInformation +) { + WIN32_FILE_ATTRIBUTE_DATA *lpFileData = lpFileInformation; + WCHAR *pwszName; + BOOL bDone; + int n; + + /* Allocate a buffer large enough for any Unicode pathname */ + pwszName = (void *)LocalAlloc(LMEM_FIXED, UNICODE_PATH_MAX * sizeof(WCHAR)); + if (!pwszName) return 0; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + lpFileName, /* lpMultiByteStr, */ + pwszName, /* lpWideCharStr, */ + UNICODE_PATH_MAX /* cchWideChar, */ + ); + if (!n) { + LocalFree((HLOCAL)pwszName); + return 0; + } + + /* Get the file information, using the Unicode version of the function */ + bDone = GetFileAttributesExW(pwszName, fInfoLevelId, lpFileData); + + /* Cleanup and return */ + LocalFree((HLOCAL)pwszName); + return bDone; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/GetFullPathName.c b/deps/MsvcLibX/src/GetFullPathName.c new file mode 100644 index 0000000000000000000000000000000000000000..2f87f36fdf17b21b2e1ebb084c3ca469622a9f87 --- /dev/null +++ b/deps/MsvcLibX/src/GetFullPathName.c @@ -0,0 +1,96 @@ +/*****************************************************************************\ +* * +* Filename GetFullPathName.c * +* * +* Description: UTF-8 version of WIN32's GetFullPathName() * +* * +* Notes: * +* * +* History: * +* 2016-09-12 JFL Created this file, from the routine in truename.c. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ +#include +#include "debugm.h" /* MsvcLibX debugging macros */ + +/*---------------------------------------------------------------------------*\ +* * +| Function: GetFullPathNameU | +| | +| Description: Get the absolute pathname for a relative UTF-8 path. | +| | +| Parameters: See WIN32's GetFullPathName() | +| | +| Return value: The length of the full pathname, or 0 if error | +| | +| Notes: Warning: Windows' GetFullPathname trims trailing dots and | +| spaces from the path. | +| This derived function reproduces the bug. | +| The caller MUST add trailing dots & spaces back if needed.| +| | +| History: | +| 2014-02-07 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +DWORD WINAPI GetFullPathNameU(LPCTSTR lpName, DWORD nBufferLength, LPTSTR lpBuf, LPTSTR *lpFilePart) { + WCHAR wszName[MAX_PATH]; + WCHAR wszBuf[MAX_PATH]; + char szName[MAX_PATH*4]; /* Worst case for UTF-8 is 4 bytes/Unicode character */ + int n; + DWORD dwResult; + WCHAR *wlpFilePart; + + DEBUG_ENTER(("GetFullPathNameU(\"%s\", %d, %p, %p);\n", lpName, nBufferLength, lpBuf, lpFilePart)); + + n = MultiByteToWideChar(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + lpName, /* lpMultiByteStr, */ + lstrlen(lpName)+1, /* cbMultiByte, */ + wszName, /* lpWideCharStr, */ + MAX_PATH /* cchWideChar, */ + ); + if (!n) RETURN_INT_COMMENT(0, ("Failed to convert the name to Unicode\n")); + + dwResult = GetFullPathNameW(wszName, MAX_PATH, wszBuf, &wlpFilePart); + if (!dwResult) RETURN_INT_COMMENT(0, ("GetFullPathNameW() failed\n")); + + /* nRead = UnicodeToBytes(pwStr, len, buf, bufsize); */ + n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wszBuf, /* lpWideCharStr, */ + (int)dwResult + 1, /* cchWideChar, */ + lpBuf, /* lpMultiByteStr, */ + (int)nBufferLength, /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) RETURN_INT_COMMENT(0, ("Failed to convert the full name from Unicode\n")); + + if (lpFilePart) { /* Convert the file part, and get the length of the converted string */ + int m; /* Length of the converted string */ + m = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wlpFilePart, /* lpWideCharStr, */ + lstrlenW(wlpFilePart), /* cchWideChar, */ + szName, /* lpMultiByteStr, */ + sizeof(szName), /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + /* (n-1) is the length of the full UTF-8 pathname */ + /* So ((n-1) - m) is the offset of the file part in the full UTF-8 pathname */ + *lpFilePart = lpBuf + (n - 1) - m; + } + + RETURN_INT_COMMENT(n-1, ("\"%s\" \"%s\"\n", lpBuf, lpFilePart?*lpFilePart:"(NULL)")); +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/GetLongPathName.c b/deps/MsvcLibX/src/GetLongPathName.c new file mode 100644 index 0000000000000000000000000000000000000000..58a10b616e5a661fa5a8064ca89dc97e0bcd3a20 --- /dev/null +++ b/deps/MsvcLibX/src/GetLongPathName.c @@ -0,0 +1,75 @@ +/*****************************************************************************\ +* * +* Filename GetLongPathName.c * +* * +* Description: UTF-8 version of WIN32's GetLongPathName() * +* * +* Notes: * +* * +* History: * +* 2016-09-12 JFL Created this file, from the routine in truename.c. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ +#include +#include "debugm.h" /* MsvcLibX debugging macros */ + +/*---------------------------------------------------------------------------*\ +* * +| Function: GetLongPathNameU | +| | +| Description: Get the long pathname for a short UTF-8 path. | +| | +| Parameters: See WIN32's GetLongPathName() | +| | +| Return value: The length of the full pathname, or 0 if error | +| | +| Notes: | +| | +| History: | +| 2015-12-18 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +DWORD WINAPI GetLongPathNameU(LPCTSTR lpShortName, LPTSTR lpBuf, DWORD nBufferLength) { + WCHAR wszShortName[MAX_PATH]; + WCHAR wszBuf[MAX_PATH]; + int n; + DWORD dwResult; + + DEBUG_ENTER(("GetLongPathNameU(\"%s\", %p, %d);\n", lpShortName, lpBuf, nBufferLength)); + + n = MultiByteToWideChar(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + lpShortName, /* lpMultiByteStr, */ + lstrlen(lpShortName)+1, /* cbMultiByte, */ + wszShortName, /* lpWideCharStr, */ + MAX_PATH /* cchWideChar, */ + ); + if (!n) RETURN_INT_COMMENT(0, ("Failed to convert the short name to Unicode\n")); + + dwResult = GetLongPathNameW(wszShortName, wszBuf, MAX_PATH); + if (!dwResult) RETURN_INT_COMMENT(0, ("GetLongPathNameW() failed\n")); + + /* nRead = UnicodeToBytes(pwStr, len, buf, bufsize); */ + n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wszBuf, /* lpWideCharStr, */ + (int)dwResult + 1, /* cchWideChar, */ + lpBuf, /* lpMultiByteStr, */ + (int)nBufferLength, /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) RETURN_INT_COMMENT(0, ("Failed to convert the Long name from Unicode\n")); + + RETURN_INT_COMMENT(n-1, ("\"%s\"\n", lpBuf)); +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/NMakefile b/deps/MsvcLibX/src/NMakefile new file mode 100644 index 0000000000000000000000000000000000000000..398576c9156516db9f85b677b4ac6a39b8f7c177 --- /dev/null +++ b/deps/MsvcLibX/src/NMakefile @@ -0,0 +1,239 @@ +############################################################################### +# # +# File name NMakefile # +# # +# Description An NMake file for making all MsvcLibX library versions # +# # +# Notes make.bat looks for a default nmake file called nmakefile. # +# # +# History # +# 2012-10-21 JFL Initial version # +# 2014-03-05 JFL Generate the DOS version only if DOS tools are present. # +# 2014-04-22 JFL Fixed the clean target to work even without 16-bits tools.# +# 2014-05-30 JFL Moved the OBJECTS macro definition to Files.mak. # +# 2014-12-03 JFL Fixed the zip target creation. # +# 2015-11-06 JFL Added support for a Win95 version. # +# 2016-01-11 JFL Added a rule to create the common ..\lib directory. # +# 2016-07-05 JFL Fixed a typo preventing the build of DOS S Debug version. # +# 2016-09-26 JFL Added macro LIBDIR, depending on OUTDIR. # +# Copy the include files to $(OUTDIR). # +# 2016-10-04 JFL Make sure nothing is displayed when doing a make clean. # +# 2016-10-06 JFL Added targets mostlyclean & distclean. # +# 2016-10-11 JFL Adapted for use with make files in the global include dir.# +# 2016-10-13 JFL Added target cleanenv. # +# 2016-11-03 JFL Added target config. # +# Updated the cleanenv: script to display the reg command # +# it uses to delete the global environment variable. # +# 2016-11-07 JFL Place LIBDIR in the parent directory even if OUTDIR defnd.# +# Do not copy include files to OUTDIR anymore. # +# 2016-11-16 JFL Removed the rule for copying INCDIR, not used anymore. # +# 2017-02-16 JFL Default goals now depend on the existence of their # +# corresponding make file. # +# # +# © Copyright 2016 Hewlett Packard Enterprise Development LP # +# Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 # +############################################################################### + +!IF DEFINED(MESSAGES) +!MESSAGE Started MsvcLibX/src/NMakefile in $(MAKEDIR) # Display this make file name +!ENDIF + +!IF DEFINED(OUTDIR) +OD=$(OUTDIR)^\ +!IF "$(OUTDIR:\=)"=="$(OUTDIR)" +LIBDIR=..\$(OUTDIR)\lib # If OUTDIR is relative, put it in MsvcLibX top directory +!ELSE +LIBDIR=$(OUTDIR)\lib # If OUTDIR is absolute, use it as is +!ENDIF +!ELSE +OD= +LIBDIR=..\lib +!ENDIF + +MSG=>con echo # Command for writing a progress message on the console +HEADLINE=$(MSG).&$(MSG) # Output a blank line, then a message + +# Default goal: Generate all versions +all: headline \ +!IF DEFINED(DOS_CC) && EXIST("$(STINCLUDE)\DOS.mak") + $(OD)DOS\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN95_CC) && EXIST("$(STINCLUDE)\WIN95.mak") + $(OD)WIN95\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN32_CC) && EXIST("$(STINCLUDE)\WIN32.mak") + $(OD)WIN32\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN64_CC) && EXIST("$(STINCLUDE)\WIN64.mak") + $(OD)WIN64\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(DOS_CC) && EXIST("$(STINCLUDE)\DOS.mak") + $(OD)DOS\DEBUG\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN95_CC) && EXIST("$(STINCLUDE)\WIN95.mak") + $(OD)WIN95\DEBUG\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN32_CC) && EXIST("$(STINCLUDE)\WIN32.mak") + $(OD)WIN32\DEBUG\MsvcLibX.lib \ +!ENDIF +!IF DEFINED(WIN64_CC) && EXIST("$(STINCLUDE)\WIN64.mak") + $(OD)WIN64\DEBUG\MsvcLibX.lib \ +!ENDIF + +headline: + $(HEADLINE) Building all MsvcLibX library versions + +# Define the OBJECTS macro = the list of object files to include in the library +!INCLUDE "Files.mak" + +# Create the common libs directory +$(LIBDIR): + $(HEADLINE) Creating directory $(LIBDIR:..=MsvcLibX) + md $(LIBDIR) + +# Rules for building specific versions of the MsvcLibX library +$(OD)DOS\MsvcLibX.lib: $(OD)DOS\BIN\T\MsvcLibX.lib $(OD)DOS\BIN\S\MsvcLibX.lib $(OD)DOS\BIN\L\MsvcLibX.lib + @echo Done building all DOS release libraries + +$(OD)DOS\DEBUG\MsvcLibX.lib: $(OD)DOS\DEBUG\BIN\T\MsvcLibX.lib $(OD)DOS\DEBUG\BIN\S\MsvcLibX.lib $(OD)DOS\DEBUG\BIN\L\MsvcLibX.lib + @echo Done building all DOS debug libraries + +$(OD)DOS\BIN\T\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS tiny release version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\OBJ\T\%" "MEM=T" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXdt.lib + +$(OD)DOS\BIN\S\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS small release version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\OBJ\S\%" "MEM=S" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXds.lib + +$(OD)DOS\BIN\L\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS large release version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\OBJ\L\%" "MEM=L" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXdl.lib + +$(OD)WIN95\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN95 release version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN95.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN95\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw95.lib + +$(OD)WIN32\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN32 release version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + set OD=$(OD) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN32.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN32\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw32.lib + +$(OD)WIN64\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN64 release version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN64.mak "DEBUG=0" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN64\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw64.lib + +$(OD)DOS\DEBUG\BIN\T\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS tiny debug version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\DEBUG\OBJ\T\%" "MEM=T" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXdtd.lib + +$(OD)DOS\DEBUG\BIN\S\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS small debug version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\DEBUG\OBJ\S\%" "MEM=S" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXdsd.lib + +$(OD)DOS\DEBUG\BIN\L\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library DOS large debug version + set OBJECTS=$(OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)DOS\DEBUG\OBJ\L\%" "MEM=L" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXdld.lib + +$(OD)WIN95\DEBUG\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN95 debug version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN95.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN95\DEBUG\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw95d.lib + +$(OD)WIN32\DEBUG\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN32 debug version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN32.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN32\DEBUG\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw32d.lib + +$(OD)WIN64\DEBUG\MsvcLibX.lib: $(LIBDIR) NUL + $(HEADLINE) Building MsvcLibX library WIN64 debug version + set OBJECTS=$(OBJECTS) $(WIN32_OBJECTS) + $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN64.mak "DEBUG=1" "PROGRAM=MsvcLibX" "OBJECTS=%OBJECTS:+=+$(OD)WIN64\DEBUG\OBJ\%" dirs $@ + if exist $@ copy $@ $(LIBDIR)\MsvcLibXw64d.lib + +# Erase all global environment variables created by this build +VARS=MSVCLIBX # Global environment variables generated here +cleanenv: + call <<"$(TMP)\cleanenv-$(PID).bat" &:# Delete variables created here + @echo off + setlocal EnableExtensions EnableDelayedExpansion + set "KEY=HKCU\Environment" + if not "$(VARS)"=="" for %%v in ($(VARS)) do @( + >>"$(TMP)\cleanenv-$(PID).lst" (echo %%v) &:# Pass the name back to make.bat, for deleting it in the current shell environment + set "VALUE=" + for /f "tokens=1,3" %%a in ('reg query "%KEY%" ^| findstr /i /b /r /c:" *%%v "') do set VALUE="%%b" + if defined VALUE ( :# The global environment variable exists. Delete it, using its actual name with the correct case. + set CMD=reg delete "%KEY%" /v %%v /f + echo !CMD! + !CMD! >NUL + ) + ) +<< + +# Dummy target, to delete all files built by these make files +clean mostlyclean distclean: + rem # Delete temporary files + -for /f "delims=" %f in ('dir /b /s *~ *.bak #*# 2^>NUL') do @del "%f" + rem # Delete files built by this nmakefile + -for /f "delims=" %f in ('dir /b /s ..\*.zip *.log 2^>NUL') do @del "%f" + rem # Delete files built by the DOS.mak, WIN32.mak, WIN64.mak make files + rem # But make DOS.mak will fail if 16-bit tools are missing. Workaround: + -if exist $(STINCLUDE)\DOS.mak $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\DOS.mak clean + if exist $(OD)DOS rd /s /q $(OD)DOS + rem # No such problem with the others, but just in case, do the same. + -if exist $(STINCLUDE)\WIN95.mak $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN95.mak clean + if exist $(OD)WIN95 rd /s /q $(OD)WIN95 + -if exist $(STINCLUDE)\WIN32.mak $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN32.mak clean + if exist $(OD)WIN32 rd /s /q $(OD)WIN32 + -if exist $(STINCLUDE)\WIN64.mak $(MAKE) /$(MAKEFLAGS) /f $(STINCLUDE)\WIN64.mak clean + if exist $(OD)WIN64 rd /s /q $(OD)WIN64 +!IF DEFINED(OUTDIR) + -rd /S /Q $(OUTDIR) >NUL 2>&1 +!ENDIF + -if "$@"=="distclean" del /Q config.*.bat >NUL 2>&1 + +# Dummy target, to build a source archive +dist zip: + $(MSG) Building ..\MsvcLibX.zip + cd .. + if exist MsvcLibX.zip del MsvcLibX.zip + set PATH=$(PATH);C:\Program Files\7-zip + 7z.exe a MsvcLibX.zip *.txt src\*.bat src\*.mak src\*makefile src\exe src\*.c -r include\*.h lib\ + rem # Delete files that got dragged in by wild cards, but that we don't want in the source zip. + 7z.exe d MsvcLibX.zip src\config.*.bat lib\*.lib + cd src + +# Run the configure.bat script in every subdirectory +config: + rem Nothing to do in $(MAKEDIR) as there is no further child level + +# Dummy target, to display a help screen +help: + type << +Targets: + all Rebuild all library versions (Default) + clean Delete all files built here, and all backup files + distclean Do a clean, then delete config.*.bat files + zip Build a source archive in ..\MsvcLibX.zip. Requires 7-zip. +<= 260 characters. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include +#include +#include "msvclibx.h" +#include "debugm.h" + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function access | +| | +| Description UTF-8 version of access | +| | +| Parameters char *pszName File name | +| int iMode Access mode to test | +| | +| Returns File handle | +| | +| Notes | +| | +| History | +| 2014-03-24 JFL Created this routine. | +| 2014-07-02 JFL Added support for pathnames >= 260 characters. | +* * +\*---------------------------------------------------------------------------*/ + +int _accessU(const char *pszName, int iMode) { + WCHAR wszName[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszName, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + COUNTOF(wszName) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + + return _waccess(wszName, iMode); +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/basename.c b/deps/MsvcLibX/src/basename.c new file mode 100644 index 0000000000000000000000000000000000000000..f89aa22e1f2d8def34c9f770eb6519b9bfbd103f --- /dev/null +++ b/deps/MsvcLibX/src/basename.c @@ -0,0 +1,59 @@ +/*****************************************************************************\ +* * +* Filename basename.c * +* * +* Description Get the file name part of a file pathname * +* * +* Notes Uses a static buffer in some cases. Not thread safe! * +* Posix spec authorizes this, and also authorizes to modify * +* the input string, which we do. => Always do an strdup() * +* before calling basename(), and call basename(copy). * +* * +* History * +* 2016-09-08 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "msvclibx.h" + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ 2005 security warnings */ + +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +char *basename(char *pszPathname) { + char *pszPath = pszPathname; + size_t len; + char *pc; + char *pc2; + + /* A NULL pathname is assumed to refer to the current directory */ + if (!pszPathname) return "."; + /* Skip the drive if present */ + len = strlen(pszPathname); + if ((len >= 2) && (pszPathname[1] == ':')) { + pszPath += 2; + len -= 2; + } + if (!len) return "."; + /* Remove trailing path separators */ + while ((len > 1) && ((pszPath[len-1] == '\\') || (pszPath[len-1] == '/'))) { + pszPath[--len] = '\0'; + } + /* Find the beginning of the file name */ + pc = strrchr(pszPath, '\\'); + pc2 = strrchr(pszPath, '/'); + if (pc2 > pc) pc = pc2; + if (pc) pc += 1; else pc = pszPath; + if (!*pc) return pszPath; /* No file name left. This is the root directory */ + /* Done */ + return pc; +} diff --git a/deps/MsvcLibX/src/chdir.c b/deps/MsvcLibX/src/chdir.c new file mode 100644 index 0000000000000000000000000000000000000000..48ab62fe06f4a461e6100fb7778c375907937c2a --- /dev/null +++ b/deps/MsvcLibX/src/chdir.c @@ -0,0 +1,147 @@ +/*****************************************************************************\ +* * +* Filename chdir.c * +* * +* Description: WIN32 port of standard C library's chdir() * +* * +* Notes: * +* * +* History: * +* 2014-02-28 JFL Created this module. * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +/* Microsoft C libraries include files */ +#include +#include +#include +/* MsvcLibX library extensions */ +#include +#include +#include "debugm.h" + +#if defined(_MSDOS) + +/*---------------------------------------------------------------------------*\ +| * +| Function: chdir | +| | +| Description: Change directory, overcoming the 64-character DOS limit | +| | +| Parameters: char *pszDir Target directory pathname | +| | +| Returns: 0=Done; Else OS error code. | +| | +| Notes: Unfortunately this works only in a DOS box within Win9X. | +| | +| History: | +| 2000-12-04 JFL Initial implementation. | +* * +\*---------------------------------------------------------------------------*/ + +int chdir(const char *pszDir) + { + char szBuf[64]; + char *pszBuf = szBuf; + char *pc; + int iDirLen; + int iStrLen; + int iErr = 0; + + iDirLen = strlen(pszDir); + /* Copy the drive letter if specified, and leave it ahead of the buffer. */ + if ((iDirLen>2) && (pszDir[1]==':')) + { + szBuf[0] = pszDir[0]; + szBuf[1] = ':'; + pszDir += 2; + pszBuf += 2; + } + /* Repeat relative moves down the directory tree */ + while (iDirLen > 60) + { + pc = strchr(pszDir+45, '\\'); /* There has to be one in segment [45:60]. */ + iStrLen = pc-pszDir; /* Segment length */ + strncpy(pszBuf, pszDir, iStrLen); /* Copy until the \ found */ + pszBuf[iStrLen] = '\0'; + iErr = chdir(szBuf); + if (iErr) return iErr; + pszDir += iStrLen+1; + iDirLen -= iStrLen+1; + } ; + + if (iDirLen) + { + strcpy(pszBuf, pszDir); + iErr = chdir(szBuf); + } + + return iErr; + } + +#endif /* defined(_MSDOS) */ + + +#if defined(_WIN32) + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: chdir | +| | +| Description: Set the current directory, encoded in UTF-8 | +| | +| Parameters: const char *pszDir Target directory pathname | +| | +| Returns: 0=Done; Else OS error code. | +| | +| History: | +| 2014-02-28 JFL Created this routine | +| 2014-07-02 JFL Added support for pathnames >= 260 characters. | +* * +\*---------------------------------------------------------------------------*/ + +int chdirA(const char *pszDir) { + WCHAR wszDir[PATH_MAX]; + BOOL bDone; + int n; + DEBUG_PRINTF(("chdir(\"%s\");\n", pszDir)); + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszDir, /* lpMultiByteStr, */ + wszDir, /* lpWideCharStr, */ + COUNTOF(wszDir) /* cchWideChar, */ + ); + bDone = SetCurrentDirectoryW(wszDir); + if (!bDone) { + errno = Win32ErrorToErrno(); + } + return bDone ? 0 : -1; +} + +int chdirU(const char *pszDir) { + WCHAR wszDir[PATH_MAX]; + BOOL bDone; + int n; + DEBUG_PRINTF(("chdir(\"%s\");\n", pszDir)); + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszDir, /* lpMultiByteStr, */ + wszDir, /* lpWideCharStr, */ + COUNTOF(wszDir) /* cchWideChar, */ + ); + bDone = SetCurrentDirectoryW(wszDir); + if (!bDone) { + errno = Win32ErrorToErrno(); + } + return bDone ? 0 : -1; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/clock_gettime.c b/deps/MsvcLibX/src/clock_gettime.c new file mode 100644 index 0000000000000000000000000000000000000000..02202e5d2e44e56d73848875e9fd007289749268 --- /dev/null +++ b/deps/MsvcLibX/src/clock_gettime.c @@ -0,0 +1,48 @@ +/*****************************************************************************\ +* * +* Filename: clock_gettime.c * +* * +* Description: WIN32 port of standard C library's clock_gettime(). * +* * +* Notes: * +* * +* History: * +* 2014-06-04 JFL Created this file. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "msvclibx.h" + +#include +#include + + +#ifdef _MSDOS + +/* Check for the definition of _STRUCT_TIMESPEC before using clock_gettime(). + If it's not defined, use time() instead, which is supported by all OSs. */ + +#endif /* defined(_MSDOS) */ + + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN /* Avoid lots of unnecessary inclusions */ +#include + +#include /* For MsvcLibX's Filetime2Timespec */ + +int clock_gettime(clockid_t clock_id, struct timespec *pTS) { + FILETIME ft; + if (clock_id != CLOCK_REALTIME) { + errno = EINVAL; + return -1; + } + GetSystemTimeAsFileTime(&ft); + Filetime2Timespec(&ft, pTS); + return 0; +} + +#endif /* defined(_WIN32) */ diff --git a/deps/MsvcLibX/src/config.DESKTOP-U79TD6T.bat b/deps/MsvcLibX/src/config.DESKTOP-U79TD6T.bat new file mode 100644 index 0000000000000000000000000000000000000000..6d57a1358a82104a40218466707cd066352f159d --- /dev/null +++ b/deps/MsvcLibX/src/config.DESKTOP-U79TD6T.bat @@ -0,0 +1,151 @@ +:# config.DESKTOP-U79TD6T.bat generated by configure.bat on 2020/05/19 Öܶþ 7:50:15.02 +:# +:# If changes are needeed, do not edit this file, but instead create a new script +:# called configure.YOURCHOICE.bat. This new script will be invoked automatically +:# by configure.bat while creating this file. Then your script can write extra +:# definitions, or change some of the variables before configure.bat writes them. +:# +:# Invoke configure.bat manually if anything changes in the tools config, such as +:# installing a Visual Studio update, or updating a configure.XXX.bat script. + +set "HAS_STINCLUDE=1" &:# Found the System Tools global C includes +set "STINCLUDE=C:\Users\admin\Desktop\temp\MyGitHub\C\include" &:# System Tools global C includes +set "HAS_MSVCLIBX=1" &:# Found the MSVC Library eXtensions library +set "MSVCLIBX=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX" &:# MSVC Library eXtensions library +set "HAS_SDK_FLAGS=/DHAS_STINCLUDE=1 /DHAS_MSVCLIBX=1" &:# SDK detection flags for the C compiler + +SET "PF32=C:\Program Files (x86)" &:# 32-bits Program Files +SET "PF64=C:\Program Files" &:# 64-bits Program Files +SET "ARCH=AMD64" &:# PROCESSOR_ARCHITECTURE + +SET "MASM=" &:# Microsoft 16-bits Assembler base path +SET "MSVC=" &:# Microsoft 16-bits Visual C++ base path +SET "MAPSYM=" &:# 16-bits debugging symbols generator + +SET "VSTUDIOLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0" &:# Microsoft Visual Studio (Long path) +SET "VSTUDIO=C:\PROGRA~2\MICROS~2.0" &:# Microsoft Visual Studio (Short path) +SET "VSCOMMONLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7" &:# Microsoft Visual Studio Common Files (Long path) +SET "VSCOMMON=C:\PROGRA~2\MICROS~2.0\Common7" &:# Microsoft Visual Studio Common Files (Short path) +SET "VSIDELONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE" &:# Microsoft Visual Studio IDE Files (Long path) +SET "VSIDE=C:\PROGRA~2\MICROS~2.0\Common7\IDE" &:# Microsoft Visual Studio IDE Files (Short path) +SET "VSTOOLSLONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools" &:# Microsoft Visual Studio Tools (Long paths) +SET "VSTOOLS=C:\PROGRA~2\MICROS~2.0\Common7\Tools" &:# Microsoft Visual Studio Tools (Short paths) +SET "MSVC32LONG=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC" &:# Microsoft Visual C++ 32/64 bits (Long path) +SET "MSVC32=C:\PROGRA~2\MICROS~2.0\VC" &:# Microsoft Visual C++ 32/64 bits (Short path) + +SET "WIN_CP=936" &:# Windows Code Page +SET "WIN_CS=gb2312" &:# Windows Character Set +SET "DOS_CP=936" &:# DOS Code Page +SET "DOS_CS=gb2312" &:# DOS Character Set + +SET "AS=" &:# Assembler +SET "CC=" &:# C compiler +SET "INCLUDE=C:\Users\admin\Desktop\temp\MyGitHub\C\include" &:# Include paths. Define USER_INCLUDE if needed. +SET "LK=" &:# Linker +SET "LIB=" &:# Libraries paths. Define USER_LIBS if needed. +SET "LB=" &:# Library manager +SET "RC=" &:# Resource compiler +SET "MT=" &:# Manifest tool + +SET "DOS_CC=" &:# Microsoft Visual C++ 16-bits compiler +SET "DOS_AS=" &:# Microsoft 16-bits assembler +SET "DOS_LK=" &:# Microsoft 16-bits linker +SET "DOS_LB=" &:# Microsoft 16-bits librarian +SET "DOS_RC=" &:# Microsoft 16-bits resource compiler +SET "DOS_MT=" &:# Microsoft 16-bits manifest tool +SET "DOS_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for 16-bits compilation +SET "DOS_VCINC=" &:# Visual C++ 16-bits compiler include dir for MsvcLibX include_next +SET "DOS_CRTINC=" &:# Visual C++ 16-bits CRT library include dir for MsvcLibX include_next +SET "DOS_INCPATH=" &:# Include paths for 16-bits compilation +SET "DOS_LIBPATH=" &:# Libraries paths for 16-bits linking +SET "DOS_WINSDK=" &:# Microsoft Windows 16-bits SDK +SET "DOS_WINSDKINC=" &:# Microsoft Windows 16-bits SDK Include directory + +SET "WIN95_CC=" &:# Microsoft Visual C++ 32-bits compiler +SET "WIN95_AS=" &:# Microsoft 32-bits assembler +SET "WIN95_LK=" &:# Microsoft 32-bits linker +SET "WIN95_LB=" &:# Microsoft 32-bits librarian +SET "WIN95_RC=" &:# Microsoft 32-bits resource compiler +SET "WIN95_MT=" &:# Microsoft 32-bits manifest tool +SET "WIN95_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for 32-bits compilation +SET "WIN95_VCINC=" &:# Visual C++ 32-bits compiler include dir for MsvcLibX include_next +SET "WIN95_CRTINC=" &:# Visual C++ 32-bits CRT library include dir for MsvcLibX include_next +SET "WIN95_INCPATH=" &:# Include paths for 32-bits compilation +SET "WIN95_LIBPATH=" &:# Libraries paths for 32-bits linking +SET "WIN95_WINSDK=" &:# Microsoft Windows 32-bits SDK +SET "WIN95_WINSDKINC=" &:# Microsoft Windows 32-bits SDK Include directory + +SET "WIN32_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.EXE"" &:# Microsoft Visual C++ 32-bits compiler +SET "WIN32_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\ML.EXE"" &:# Microsoft 32-bits assembler +SET "WIN32_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\LINK.EXE"" &:# Microsoft 32-bits linker +SET "WIN32_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\LIB.EXE"" &:# Microsoft 32-bits librarian +SET "WIN32_RC=" &:# Microsoft 32-bits resource compiler +SET "WIN32_MT=" &:# Microsoft 32-bits manifest tool +SET "WIN32_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for 32-bits compilation +SET "WIN32_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ 32-bits compiler include dir for MsvcLibX include_next +SET "WIN32_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ 32-bits CRT library include dir for MsvcLibX include_next +SET "WIN32_INCPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\include;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for 32-bits compilation +SET "WIN32_LIBPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\lib;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x86" &:# Libraries paths for 32-bits linking +SET "WIN32_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows 32-bits SDK +SET "WIN32_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows 32-bits SDK Include directory + +SET "IA64_CC=" &:# Microsoft Visual C++ IA64 compiler +SET "IA64_AS=" &:# Microsoft IA64 assembler +SET "IA64_LK=" &:# Microsoft IA64 linker +SET "IA64_LB=" &:# Microsoft IA64 librarian +SET "IA64_RC=" &:# Microsoft IA64 resource compiler +SET "IA64_MT=" &:# Microsoft IA64 manifest tool +SET "IA64_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for IA64 compilation +SET "IA64_VCINC=" &:# Visual C++ IA64 compiler include dir for MsvcLibX include_next +SET "IA64_CRTINC=" &:# Visual C++ IA64 CRT library include dir for MsvcLibX include_next +SET "IA64_INCPATH=" &:# Include paths for IA64 compilation +SET "IA64_LIBPATH=" &:# Libraries paths for IA64 linking +SET "IA64_WINSDK=" &:# Microsoft Windows IA64 SDK +SET "IA64_WINSDKINC=" &:# Microsoft Windows IA64 SDK Include directory + +SET "WIN64_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\CL.EXE"" &:# Microsoft Visual C++ 64-bits compiler +SET "WIN64_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\ML64.EXE"" &:# Microsoft 64-bits assembler +SET "WIN64_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\LINK.EXE"" &:# Microsoft 64-bits linker +SET "WIN64_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\LIB.EXE"" &:# Microsoft 64-bits librarian +SET "WIN64_RC=" &:# Microsoft 64-bits resource compiler +SET "WIN64_MT=" &:# Microsoft 64-bits manifest tool +SET "WIN64_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for 64-bits compilation +SET "WIN64_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ 64-bits compiler include dir for MsvcLibX include_next +SET "WIN64_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ 64-bits CRT library include dir for MsvcLibX include_next +SET "WIN64_INCPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\include;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for 64-bits compilation +SET "WIN64_LIBPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\lib;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64" &:# Libraries paths for 64-bits linking +SET "WIN64_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows 64-bits SDK +SET "WIN64_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows 64-bits SDK Include directory + +SET "ARM_CC="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\CL.EXE"" &:# Microsoft Visual C++ ARM compiler +SET "ARM_AS="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\ARMASM.EXE"" &:# Microsoft ARM assembler +SET "ARM_LK="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\LINK.EXE"" &:# Microsoft ARM linker +SET "ARM_LB="C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm\LIB.EXE"" &:# Microsoft ARM librarian +SET "ARM_RC=" &:# Microsoft ARM resource compiler +SET "ARM_MT=" &:# Microsoft ARM manifest tool +SET "ARM_PATH=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64_arm;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE;C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools;C:\Windows\System32;C:\Windows" &:# All tools paths for ARM compilation +SET "ARM_VCINC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" &:# Visual C++ ARM compiler include dir for MsvcLibX include_next +SET "ARM_CRTINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt" &:# Visual C++ ARM CRT library include dir for MsvcLibX include_next +SET "ARM_INCPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\include;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include;:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\shared;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\um;C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\winrt" &:# Include paths for ARM compilation +SET "ARM_LIBPATH=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX\lib;C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\arm;C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\arm" &:# Libraries paths for ARM linking +SET "ARM_WINSDK=C:\Program Files (x86)\Windows Kits\10" &:# Microsoft Windows ARM SDK +SET "ARM_WINSDKINC=C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0" &:# Microsoft Windows ARM SDK Include directory + +SET "ARM64_CC=" &:# Microsoft Visual C++ ARM64 compiler +SET "ARM64_AS=" &:# Microsoft ARM64 assembler +SET "ARM64_LK=" &:# Microsoft ARM64 linker +SET "ARM64_LB=" &:# Microsoft ARM64 librarian +SET "ARM64_RC=" &:# Microsoft ARM64 resource compiler +SET "ARM64_MT=" &:# Microsoft ARM64 manifest tool +SET "ARM64_PATH=;C:\Windows\System32;C:\Windows" &:# All tools paths for ARM64 compilation +SET "ARM64_VCINC=" &:# Visual C++ ARM64 compiler include dir for MsvcLibX include_next +SET "ARM64_CRTINC=" &:# Visual C++ ARM64 CRT library include dir for MsvcLibX include_next +SET "ARM64_INCPATH=" &:# Include paths for ARM64 compilation +SET "ARM64_LIBPATH=" &:# Libraries paths for ARM64 linking +SET "ARM64_WINSDK=" &:# Microsoft Windows ARM64 SDK +SET "ARM64_WINSDKINC=" &:# Microsoft Windows ARM64 SDK Include directory + +:# List of commands to run when make.bat exits +SET "POST_MAKE_ACTIONS=set "MSVCLIBX=C:\Users\admin\Desktop\temp\MyGitHub\C\MsvcLibX"" + +exit /b 0 &:# Configuration done successfully diff --git a/deps/MsvcLibX/src/configure.MsvcLibX.bat b/deps/MsvcLibX/src/configure.MsvcLibX.bat new file mode 100644 index 0000000000000000000000000000000000000000..767225480ace29ec7306d771560d9a416f3174bf --- /dev/null +++ b/deps/MsvcLibX/src/configure.MsvcLibX.bat @@ -0,0 +1,36 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: configure.MsvcLibX.bat * +:# * +:# Description: Special make actions for rebuilding the MsvcLibX library * +:# * +:# Notes: * +:# * +:# History: * +:# 2015-11-06 JFL Created this script. * +:# 2016-09-27 JFL Correct the final MSVCLIBX if there's a different OUTDIR. * +:# 2016-11-03 JFL Removed the side effect creating %OUTDIR%. * +:# 2016-11-07 JFL Removed the dependency on OUTDIR. * +:# Immediately set the system environment. * +:# 2016-11-16 JFL Allow using a predefined alias for this lib base path. * +:# 2016-12-16 JFL Only use setx if requested by user, with PERSISTENT_VARS. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +:# Get the full pathname of the MsvcLibX library base directory +if defined MSVCLIBX if not exist "%MSVCLIBX%\include\msvclibx.h" set "MSVCLIBX=" &:# Allow overriding with another alias name, but ignore invalid overrides +if not defined MSVCLIBX for /f "delims=" %%d in ('"pushd .. & cd & popd"') do SET "MSVCLIBX=%%d" &:# Default: Use the current directory + +:# Declare the SDKs and libraries we need +%BEGIN_SDK_DEFS% +%USE_SDK% MSVCLIBX &:# Triggers the emission of a %CONFIG% record for MSVCLIBX +%END_SDK_DEFS% + +:# Set the local environment variable just before make exits, so that future commands in this CMD window have it. +%ADD_POST_MAKE_ACTION% set "MSVCLIBX=%MSVCLIBX%" + +:# Set the system environment variable, so that other CMD windows opened later on inherit it +if defined PERSISTENT_VARS setx MSVCLIBX "%MSVCLIBX%" >NUL diff --git a/deps/MsvcLibX/src/configure.bat b/deps/MsvcLibX/src/configure.bat new file mode 100644 index 0000000000000000000000000000000000000000..7037eb92afccbfe2e0d6872a108799d56538c490 --- /dev/null +++ b/deps/MsvcLibX/src/configure.bat @@ -0,0 +1,35 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: configure.bat * +:# * +:# Description: Detect system-specific settings and create config.*.bat * +:# * +:# Notes: Proxy script for %STINCLUDE%\configure.bat. * +:# * +:# Make any change needed in %STINCLUDE%\configure.bat. * +:# * +:# History: * +:# 2016-10-10 JFL jf.larvoire@hpe.com created this file. * +:# 2016-12-15 JFL Search for the real make.bat in [.|..|../..]\include. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +:# Get the full pathname of the STINCLUDE library directory +if defined STINCLUDE if not exist "%STINCLUDE%\make.bat" set "STINCLUDE=" &:# Allow overriding with another alias name, but ignore invalid overrides +for %%p in (. .. ..\..) do if not defined STINCLUDE if exist %%p\include\make.bat ( :# Default: Search it the current directory, and 2 levels above. + for /f "delims=" %%d in ('"pushd %%p\include & cd & popd"') do SET "STINCLUDE=%%d" +) +if not defined STINCLUDE ( :# Try getting the copy in the master environment + for /f "tokens=3" %%v in ('reg query "HKCU\Environment" /v STINCLUDE 2^>NUL') do set "STINCLUDE=%%v" +) + +if not exist %STINCLUDE%\make.bat ( + >&2 echo %0 Error: Cannot find SysToolsLib's global C include directory. Please define variable STINCLUDE. + exit /b 1 +) + +if [%1]==[-d] echo "%STINCLUDE%\configure.bat" %* +"%STINCLUDE%\configure.bat" %* diff --git a/deps/MsvcLibX/src/debugv.c b/deps/MsvcLibX/src/debugv.c new file mode 100644 index 0000000000000000000000000000000000000000..a0a757032ca51429f33b5685ad5f6bb0be67b1a7 --- /dev/null +++ b/deps/MsvcLibX/src/debugv.c @@ -0,0 +1,23 @@ +/*****************************************************************************\ +* * +* Filename: debugv.c * +* * +* Description: Define debug variables used by MsvcLibX.lib in debug mode * +* * +* Notes: * +* * +* History: * +* 2013-03-27 JFL jf.larvoire@hp.com created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "debugm.h" + +#if defined(_DEBUG) + +DEBUG_GLOBALS + +#endif /* !defined(_DEBUG) */ + diff --git a/deps/MsvcLibX/src/dirent.c b/deps/MsvcLibX/src/dirent.c new file mode 100644 index 0000000000000000000000000000000000000000..5fbf3be6cabb38bf2dd75836aa27a4a4964661da --- /dev/null +++ b/deps/MsvcLibX/src/dirent.c @@ -0,0 +1,708 @@ +/*****************************************************************************\ +* * +* Filename: dirent.c * +* * +* Description: DOS/WIN32 port of standard C library's dirent.h functions * +* * +* Notes: TO DO: Make Wide & MultiByte versions of scandir 4 Windows* +* * +* There are also remains of an OS/2 implementation here. * +* It's not maintained anymore. Left in as a historic * +* reference, in the unlikely case somebody needs it. * +* * +* History: * +* 2012-01-09 JFL Created this file, based on dirc and other programs. * +* 2012-01-19 JFL Added standard errno management. * +* 2012-05-22 JFL Fixed a bug in the DOS version, which failed if the * +* directory name was longer than 12 bytes. * +* 2012-05-23 JFL Fixed opendir to return errors as per the C lib spec. * +* 2013-02-12 JFL Added code to filter reparse points, and keep only * +* real junctions and symlinks. * +* 2013-02-13 JFL Moved dirent2stat() to lstat.c, as there must actually * +* be 4 WIN32 versions, for the four versions of struct stat.* +* 2013-02-26 JFL Moved the proprietary file time management routines to * +* the new filetime.c module. * +* 2014-02-27 JFL Changed the WIN32 output name encoding to UTF-8. * +* 2014-03-20 JFL Restructured Windows opendir and readdir functions into * +* Wide and MultiByte versions, and changed the Unicode and * +* Ansi versions to macros. * +* 2014-03-24 JFL Renamed "statx.h" as the standard . * +* 2015-12-14 JFL Bug fix: WIN32 readdirW always read the root on "D:". * +* Bug fix: DOS opendir failed on root dirs, like "D:\". * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of WIN32 printf & scandir */ + +#include "dirent.h" /* Include our associated .h, in the same dir as this .c. Do not use <>. */ +#ifndef _DIRENT_FOR_DOS_WINDOWS +#error "This requires MsvcLibX own version of dirent.h for DOS/Windows" +#endif +/* Microsoft C libraries include files */ +#include +#include +#include +#include +#include +/* MsvcLibX library extensions */ +#include /* For readlink() */ +#include /* For Filetime2String() */ +#include "debugm.h" /* Use our house debugging framework */ + +/*****************************************************************************\ +* * +* MS_DOS Version * +* * +\*****************************************************************************/ + +#ifdef _MSDOS + +#define OFFSET_OF(pointer) ((uint16_t)(uint32_t)(void far *)pointer) +#define SEGMENT_OF(pointer) ((uint16_t)(((uint32_t)(void far *)pointer) >> 16)) + +void put_dta(char *p_dta) { /* Set the MS-DOS Disk Transfer Address */ + union REGS inreg; + union REGS outreg; + struct SREGS sregs; + + inreg.h.ah = 0x1a; + inreg.x.dx = OFFSET_OF(p_dta); + sregs.ds = SEGMENT_OF(p_dta); + + intdosx(&inreg, &outreg, &sregs); +} + +#define CF 0x0001 /* Carry flag bit mask */ + +int get_file_attributes(const char *name, unsigned *pAttr) { /* Get File Attributes */ + union REGS inreg; + union REGS outreg; + struct SREGS sregs; + + inreg.x.ax = 0x4300; + inreg.x.dx = OFFSET_OF(name); + sregs.ds = SEGMENT_OF(name); + + intdosx(&inreg, &outreg, &sregs); + + if (CF & outreg.x.cflag) { + errno = outreg.x.ax; + return errno; + } + + *pAttr = outreg.x.cx; + return 0; +} + +/* Workaround for a VMWare player shared folders bug: + DOS function 4e (search next) sometimes returns several times the same entry. */ +static fileinfo previousFI; +#ifdef _DEBUG +static int report_workaround(char *s) { + DEBUG_PRINTF((s)); + return 1; +} +#define REPORT_WORKAROUND(args) report_workaround args +#else +#define REPORT_WORKAROUND(args) 1 +#endif + +int srch1st(char *pszFile, uint16_t wAttr, fileinfo *pInfo) { /* Search first matching file */ + union REGS inreg; + union REGS outreg; + struct SREGS sregs; + + DEBUG_ENTER(("srch1st(\"%s\", 0x%04X, 0x%p);\n", pszFile, wAttr, pInfo)); + + /* Make sure the DTA is assigned before calling DOS functions 4E and 4F */ + put_dta((char *)pInfo); + + inreg.h.ah = 0x4e; + inreg.x.cx = wAttr; + inreg.x.dx = OFFSET_OF(pszFile); + sregs.ds = SEGMENT_OF(pszFile); + + intdosx(&inreg, &outreg, &sregs); + + if (CF & outreg.x.cflag) { + DEBUG_LEAVE(("return %d; // DOS error code\n", outreg.x.ax)); + return (int)(outreg.x.ax); + } + + previousFI = *pInfo; /* Save it for the workaround for the VMWare player bug */ + + DEBUG_LEAVE(("return 0; // Success\n")); + return 0; +} + +int srchnext(fileinfo *pInfo) { /* Search next matching file */ + union REGS inreg; + union REGS outreg; + + DEBUG_ENTER(("srchnext(0x%p);\n", pInfo)); + + /* Make sure the DTA is assigned before calling DOS functions 4E and 4F */ + put_dta((char *)pInfo); + + inreg.h.ah = 0x4f; + + do { + intdos(&inreg, &outreg); + + if (CF & outreg.x.cflag) { + DEBUG_LEAVE(("return %d; // DOS error code\n", outreg.x.ax)); + return(outreg.x.ax); + } + } while ((!strncmp(previousFI.fiFileName, pInfo->fiFileName, sizeof(previousFI))) + && REPORT_WORKAROUND(("// Skipped one duplicate entry\n"))); + + previousFI = *pInfo; /* Save it for the workaround for the VMWare player bug */ + + DEBUG_LEAVE(("return 0; // Success\n")); + return 0; +} + +DIR *opendir(const char *name) { /* Open a directory */ + DIR *pDir = NULL; + size_t lName; + unsigned attr; + char *pszWildCards = "\\*.*"; + char *pszCopy; + DEBUG_ENTER(("opendir(\"%s\");\n", name)); + lName = strlen(name); + if (lName == 0) { +opendir_noent: + errno = ENOENT; +opendir_failed: + if (!_sys_errlist[ENOTDIR][0]) _sys_errlist[ENOTDIR] = "Not a directory"; /* Workaround for the missing entry in MSVC list */ + if (pDir) free(pDir); + DEBUG_LEAVE(("return NULL; // errno=%d - %s\n", errno, strerror(errno))); + return NULL; + } + pDir = (DIR *)malloc(sizeof(DIR) + lName + 5); /* + 5 for wildcards suffix */ + if (!pDir) goto opendir_failed; + /* Work on a copy of the directory name */ + pszCopy = (char *)(pDir + 1); + strcpy(pszCopy, name); + /* First change: Except for the root, Remove the trailing \s, which confuses get_file_attributes() */ + while ((lName > 1) && (name[lName-1] == '\\') && (name[lName-2] != ':')) pszCopy[--lName] = '\0'; + if (get_file_attributes(pszCopy, &attr)) goto opendir_noent; + if (!(attr & _A_SUBDIR)) { + errno = ENOTDIR; + goto opendir_failed; + } + if (name[lName-1] == '\\') pszWildCards += 1; /* Avoid duplicating the \ */ + strcpy(pszCopy+lName, pszWildCards); + pDir->first = 1; + DEBUG_LEAVE(("return 0x%p;\n", pDir)); + return pDir; +} + +int closedir(DIR *pDir) { /* Close the directory. Return 0 if successful, -1 if not. */ + DEBUG_PRINTF(("closedir(0x%p);\n", pDir)); + if (pDir) free(pDir); + return 0; +} + +_dirent *readdir(DIR *pDir) { /* Read a directory entry. Return pDir, or NULL for EOF or error. */ + int iErr; + _dirent *pDirent = &pDir->sDirent; + fileinfo *pFI = (fileinfo *)(pDirent->d_reserved); /* Address of the fileinfo structure embedded there */ +#ifdef _DEBUG + char szTime[40]; +#endif + + DEBUG_ENTER(("readdir(0x%p);\n", pDir)); + if (pDir->first) { /* First search */ + iErr = srch1st((char *)(pDir+1), 0x3F, pFI); + pDir->first = 0; + } else { + iErr = srchnext(pFI); + } + if (!iErr) { + pDirent->d_type = DT_REG; /* A normal file by default */ + if (pDirent->d_attribs & _A_SUBDIR) pDirent->d_type = DT_DIR; /* Subdirectory */ + if (pDirent->d_attribs & _A_VOLID) pDirent->d_type = DT_VOLID; /* Volume ID file */ + DEBUG_LEAVE(("return 0x%p; // %s %02X %10ld %s\n", + pDirent, + Filetime2String(pDirent->d_date, pDirent->d_time, szTime, sizeof(szTime)), + pDirent->d_attribs, + pDirent->d_filesize, + pDirent->d_name)); + return &pDir->sDirent; + } + switch (iErr) { /* Correct a few errors that do not map well to C library errors */ + case ESRCH: iErr = ENOTDIR; break; + case EXDEV: iErr = 0; break; /* End of files is NOT an error */ + } + if (iErr) { + errno = iErr; /* MS-DOS' errno.h maps C-library errnos to DOS' errors */ + DEBUG_LEAVE(("return NULL; // errno=%d - %s\n", errno, strerror(errno))); + } else { + DEBUG_LEAVE(("return NULL; // End of directory\n")); + } + return NULL; +} + +#endif /* defined(_MSDOS) */ + +/*****************************************************************************\ +* * +* WIN32 Version * +* * +\*****************************************************************************/ + +#ifdef _WIN32 + +#include + +/* Requires including windows.h and especially the kernel section */ + +DIR *opendirW(const WCHAR *wszName) { /* Open a directory - Wide char version */ + DIR *pDir; + int err; + DWORD dw; + DEBUG_CODE( + char szUtf8[UTF8_PATH_MAX]; + ) + + DEBUG_WSTR2UTF8(wszName, szUtf8, sizeof(szUtf8)); + DEBUG_ENTER(("opendir(\"%s\");\n", szUtf8)); + + dw = GetFileAttributesW(wszName); + err = 0; + if (dw == INVALID_FILE_ATTRIBUTES) { + err = errno = Win32ErrorToErrno(); + } else { + if (!(dw & _A_SUBDIR)) { + err = errno = ENOTDIR; + } + } + if (err) { + RETURN_CONST_COMMENT(NULL, ("errno=%d - %s\n", errno, strerror(errno))); + } + if (lstrlenW(wszName) >= sizeof(pDir->wszDirName)) { + errno = ENAMETOOLONG; + RETURN_CONST_COMMENT(NULL, ("errno=%d - %s\n", errno, strerror(errno))); + } + pDir = malloc(sizeof(DIR)); + if (!pDir) { + errno = ENOMEM; + RETURN_CONST_COMMENT(NULL, ("errno=%d - %s\n", errno, strerror(errno))); + } + pDir->hFindFile = INVALID_HANDLE_VALUE; + lstrcpyW(pDir->wszDirName, wszName); + DEBUG_LEAVE(("return 0x%p; // Success\n", pDir)); + return pDir; +} + +DIR *opendirM(const char *name, UINT cp) { /* Open a directory - MultiByte char version */ + WCHAR wszName[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + name, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + COUNTOF(wszName) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("opendirM(\"%s\"); // Can't convert name to Unicode: errno=%d - %s\n", name, errno, strerror(errno))); + return NULL; + } + + return opendirW(wszName); +} + +int closedir(DIR *pDir) { /* Close the directory. Return 0 if successful, -1 if not. */ + DEBUG_PRINTF(("closedir(0x%p);\n", pDir)); + if (pDir) { + if (pDir->hFindFile != INVALID_HANDLE_VALUE) FindClose(pDir->hFindFile); + pDir->hFindFile = INVALID_HANDLE_VALUE; + free(pDir); + } + return 0; +} + +/* Read a directory entry. Return pDir, or NULL for EOF or error. Wide char version. */ +_dirent *readdirW(DIR *pDir) { + int iErr = 0; + _dirent *pDirent = &pDir->sDirent; + int bIsJunction = FALSE; + int bIsMountPoint = FALSE; + DWORD dwTag = 0; /* Reparse points tag */ + DWORD dwAttr; + int n; + DEBUG_CODE( + char szTime[40]; + char szUtf8[UTF8_PATH_MAX]; + ) + + DEBUG_ENTER(("readdir(0x%p);\n", pDir)); + + if (pDir->hFindFile == INVALID_HANDLE_VALUE) { + WCHAR wszPattern[MAX_PATH+5]; + lstrcpyW(wszPattern, pDir->wszDirName); + n = lstrlenW(wszPattern); + if (n && (wszPattern[n-1] != L'\\') && (wszPattern[n-1] != L':')) wszPattern[n++] = L'\\'; + lstrcpyW(wszPattern+n, L"*.*"); + pDir->hFindFile = FindFirstFileW(wszPattern, &pDir->wfd); + if (pDir->hFindFile == INVALID_HANDLE_VALUE) { + iErr = Win32ErrorToErrno(); + if (!iErr) iErr = ENOENT; + } + } else { + iErr = !FindNextFileW(pDir->hFindFile, &pDir->wfd); + if (iErr) { + iErr = Win32ErrorToErrno(); + if (!iErr) iErr = ENOENT; + } + } + if (iErr) { + switch (iErr) { /* Correct a few errors that do not map well to C library errors */ + case ESRCH: iErr = ENOTDIR; break; + case EXDEV: iErr = 0; break; /* End of files is NOT an error */ + } + if (iErr) { + errno = iErr; /* Windows' errno.h maps C-library errnos to Windows' errors */ + DEBUG_LEAVE(("return NULL; // errno=%d - %s\n", errno, strerror(errno))); + } else { + DEBUG_LEAVE(("return NULL; // End of directory\n")); + } + return NULL; + } + + /* Set the standard fields */ + lstrcpyW((WCHAR *)(pDirent->d_name), pDir->wfd.cFileName); + dwAttr = pDir->wfd.dwFileAttributes; +check_attr_again: + if (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) { + /* JUNCTIONs and SYMLINKDs both have the FILE_ATTRIBUTE_DIRECTORY flag also set. + // Test the FILE_ATTRIBUTE_REPARSE_POINT flag first, to make sure they're seen as symbolic links. + // + // All symlinks are reparse points, but not all reparse points are symlinks. */ + dwTag = pDir->wfd.dwReserved0; /* No need to call GetReparseTag(), we got it already. */ + switch (dwTag) { + case IO_REPARSE_TAG_MOUNT_POINT: /* NTFS junction or mount point */ + { /* We must read the link to distinguish junctions from mount points. */ + WCHAR wszPath[PATH_MAX]; + WCHAR wszBuf[PATH_MAX]; + ssize_t n = lstrlenW(pDir->wszDirName); + if ((n + 1 + lstrlenW(pDir->wfd.cFileName)) >= PATH_MAX) { + errno = ENAMETOOLONG; /* DIRNAME\LINKNAME won't fit in wszPath[] */ + DEBUG_LEAVE(("return NULL; // errno=%d - %s\n", errno, strerror(errno))); + } + bIsMountPoint = TRUE; + lstrcpyW(wszPath, pDir->wszDirName); + if (n && (wszPath[n-1] != L'\\')) wszPath[n++] = L'\\'; + lstrcpyW(wszPath+n, pDir->wfd.cFileName); + n = readlinkW(wszPath, wszBuf, COUNTOF(wszBuf)); + /* Junction targets are absolute pathnames, starting with a drive letter. Ex: C: */ + /* readlink() fails if the reparse point does not target a valid pathname */ + if (n < 0) goto this_is_not_a_symlink; /* This is not a junction. */ + bIsJunction = TRUE; /* Else this is a junction. Fall through to the symlink case. */ + } + case IO_REPARSE_TAG_SYMLINK: /* NTFS symbolic link */ + pDirent->d_type = DT_LNK; /* Symbolic link */ + break; + default: /* Anything else is definitely not like a Unix symlink */ +this_is_not_a_symlink: + dwAttr &= ~FILE_ATTRIBUTE_REPARSE_POINT; + goto check_attr_again; + } + } else if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) + pDirent->d_type = DT_DIR; /* Subdirectory */ + else if (dwAttr & FILE_ATTRIBUTE_DEVICE) + pDirent->d_type = DT_CHR; /* Device (we don't know if character or block) */ + else + pDirent->d_type = DT_REG; /* A normal file by default */ + + /* Set the OS-specific extensions */ + lstrcpyW((WCHAR *)(pDirent->d_shortname), pDir->wfd.cAlternateFileName); + pDirent->d_attribs = dwAttr; + pDirent->d_ReparseTag = dwTag; + pDirent->d_CreationTime = pDir->wfd.ftCreationTime; + pDirent->d_LastAccessTime = pDir->wfd.ftLastAccessTime; + pDirent->d_LastWriteTime = pDir->wfd.ftLastWriteTime; + (*(ULARGE_INTEGER *)&(pDirent->d_filesize)).LowPart = pDir->wfd.nFileSizeLow; + (*(ULARGE_INTEGER *)&(pDirent->d_filesize)).HighPart = pDir->wfd.nFileSizeHigh; + + DEBUG_WSTR2UTF8((WCHAR *)(pDirent->d_name), szUtf8, sizeof(szUtf8)); + DEBUG_LEAVE(("return 0x%p; // %s 0x%05X %10lld %s\n", + pDirent, + Filetime2String(&pDirent->d_LastWriteTime, szTime, sizeof(szTime)), + (int)(pDirent->d_attribs), + pDirent->d_filesize, + szUtf8)); + return &(pDir->sDirent); +} + +/* Read a directory entry. Return pDir, or NULL for EOF or error. MultiByte char version. */ +_dirent *readdirM(DIR *pDir, UINT cp) { + _dirent *pDirent; + int n; + char *pszDefaultChar; + + pDirent = readdirW(pDir); + if (!pDirent) return NULL; + + /* Convert the name field back to MultiByte encoding */ + pszDefaultChar = (cp == CP_UTF8) ? NULL : "?"; + n = WideCharToMultiByte(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + pDir->wfd.cFileName, /* lpWideCharStr, */ + lstrlenW(pDir->wfd.cFileName)+1, /* cchWideChar, */ + pDirent->d_name, /* lpMultiByteStr, */ + sizeof(pDirent->d_name), /* cbMultiByte, */ + pszDefaultChar, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("readdirM(0x%p); // Error converting name back from Unicode. errno=%d - %s\n", pDir, errno, strerror(errno))); + return NULL; + } + + /* Convert the short name field back to MultiByte encoding */ + n = WideCharToMultiByte(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + pDir->wfd.cAlternateFileName, /* lpWideCharStr, */ + lstrlenW(pDir->wfd.cAlternateFileName)+1, /* cchWideChar, */ + pDirent->d_shortname, /* lpMultiByteStr, */ + sizeof(pDirent->d_shortname), /* cbMultiByte, */ + pszDefaultChar, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("readdirM(0x%p); // Error converting short name back from Unicode. errno=%d - %s\n", pDir, errno, strerror(errno))); + return NULL; + } + + return pDirent; +} + +#endif + +/*****************************************************************************\ +* * +* OS/2 1.x Version * +* * +\*****************************************************************************/ + +#ifdef _OS2 + +/* Requires including os2.h at the beginning of this file, and before that + defining the INCL_DOSFILEMGR constant to enable the necessary section */ + +int SetDirent(DIR *pDir) { /* Convert the FILEFINDBUF to a dirent structure */ + char *pc; + _dirent *pDirent = &pDir->sDirent; + FILEFINDBUF *pbuf = &pDir->buf; + + pbuf->achName[pbuf->cchName] = '\0'; + pc = strrchr(pbuf->achName, '\\'); /* Directory separator character */ + if (!pc) + pc = &pbuf->achName[0]; + else + pc += 1; /* Skip the \ */ + + pDirent->d_name = malloc(strlen(pc)+1); + if (!pDirent->d_name) return ENOMEM; + strcpy(pDirent->d_name, pc); + pDirent->attribs = pbuf->attrFile; + pDirent->d_type = Atype2Dtype(pDirent->attribs); + pDirent->time = *(uint16_t *)&pbuf->ftimeLastWrite; + pDirent->date = *(uint16_t *)&pbuf->fdateLastWrite; + pDirent->filesize = pbuf->cbFile; + + return 0; +} + +int srch1st(char *pszFile, uint8_t bAttrReq, uint8_t bAttrCmp, DIR *pDir) { /* Search first matching file */ + int n; + int err; + + pDir->hDir = -1; + + n = 1; /* Get one file */ + err = DosFindFirst2(pszFile, &pDir->hDir, bAttrReq & 0x7F, &pDir->buf, + sizeof(FILEFINDBUF), &n, FIL_STANDARD, 0L); + if (err || !n) return 1; + + return SetDirent(pDir); +} + +int srchnext(DIR *pDir) { /* Search next matching file */ + int n; + int err; + + n = 1; /* Get one file */ + err = DosFindNext(pDir->hDir, &pDir->buf, sizeof(FILEFINDBUF), &n); + if (err || !n) return 1; + + return SetDirent(&buf); +} + +int srchdone(DIR *pDir) { + int err; + + err = DosFindClose(pDir->hDir); + pDir->hDir = -1; + + return err; +} + +DIR *opendir(const char *name) { /* Open a directory */ + DIR *pDir; + DEBUG_ENTER(("opendir(\"%s\");\n", name)); + err = _access(name, 0); + /* To do: Get the file attributes, and check that it's a directory */ + if (err) { + DEBUG_LEAVE(("return NULL; // errno=%d - %s\n", errno, strerror(errno))); + return NULL; + } + pDir = malloc(sizeof(DIR)); + if (pDir) { + pDir->hDir = -1; + pDir->bAttrReq = _A_HIDDEN | _A_SYSTEM | _A_SUBDIR; + pDir->bAttrCmp = 0; + strcpy(pDir->sDirent.d_name, name); + } + DEBUG_LEAVE(("return 0x%p;\n", pDir)); + return pDir; +} + +int closedir(DIR *pDir) { /* Close the directory. Return 0 if successful, -1 if not. */ + DEBUG_PRINTF(("closedir(0x%p);\n", pDir)); + if (pDir) { + srchdone(pDir); + free(pDir); + } + return 0; +} + +_dirent *readdir(DIR *pDir) { /* Read a directory entry. Return pDir, or NULL for EOF or error. */ + int iErr; + DEBUG_ENTER(("readdir(0x%p);\n", pDir)); + if (pDir->hDir == -1) { + iErr = srch1st(pDir->sDirent.d_name, pDir->bAttrReq, pDir->bAttrCmp, pDir); + } else { + iErr = srchnext(pDir); + } + if (iErr) { + DEBUG_LEAVE(("return NULL; // OS/2 found nothing\n", + return NULL; + } + + DEBUG_LEAVE(("return 0x%p; // OS/2 found: %04X %04X %02X %10lld %s\n", + &pDir->sDirent + (int)(pDirent->time), + (int)(pDirent->date), + (int)(pDirent->attribs), + pDirent->filesize, + pDirent->d_name)); + + + return &pDir->sDirent; +} + +#endif + +/*****************************************************************************\ +* * +* End of OS-specific opendir/readdir/closedir versions * +* * +\*****************************************************************************/ + +/*****************************************************************************\ +* * +* Function: scandir * +* * +* Description: Select entries in a directory * +* * +* Arguments: const char *name Directory name * +* _dirent ***namelist where to store the result array * +* int (*cbSelect)() Selection callback function * +* int (*cbCompare)() Comparison function for sorting it * +* * +* Return value: # of entries in the array, or -1 if error. * +* * +* Notes: * +* * +* History: * +* 2012-01-11 JFL Initial implementation * +* * +\*****************************************************************************/ + +#pragma warning(disable:4706) /* Ignore the "assignment within conditional expression" warning */ +int scandir(const char *pszName, + _dirent ***resultList, + int (*cbSelect) (const _dirent *), + int (__cdecl *cbCompare) (const _dirent **, + const _dirent **)) { + int n = 0; + DIR *pDir; + _dirent *pDirent; + _dirent *pDirent2; + _dirent **pList = NULL; + _dirent **pList2; + + DEBUG_ENTER(("scandir(\"%s\", 0x%p, 0x%p, 0x%p);\n", pszName, resultList, cbSelect, cbCompare)); + + pDir = opendir(pszName); + if (!pDir) { + DEBUG_LEAVE(("return -1; // errno=%d\n", errno)); + return -1; + } + + while (pDirent = readdir(pDir)) { + if (cbSelect && !cbSelect(pDirent)) continue; /* We don't want this one. Continue search. */ + /* OK, we've selected this one. So append a copy of this _dirent to the list. */ + n += 1; + pList2 = (_dirent **)realloc(pList, n * sizeof(_dirent *)); + pDirent2 = malloc(sizeof(_dirent)); + if (!pList2 || !pDirent2) { + if (pDirent2) free(pDirent2); + for (n-=1; n>0; ) free(pList[--n]); + /* errno = ENOMEM; /* Out of memory. Should already be set by malloc failure */ + DEBUG_LEAVE(("return -1; // errno=%d\n", errno)); + return -1; + } + *pDirent2 = *pDirent; + pList = pList2; + pList[n-1] = pDirent2; + } + + closedir(pDir); + +/* 2016-09-23 JFL I don't understand why this warning still fires, so leaving it enabled for now */ +#ifdef M_I86TM /* This warning appears only when compiling for the DOS tiny memory model ?!? */ +/* #pragma warning(disable:4220) /* Ignore the "varargs matches remaining parameters" warning */ +#endif + if (cbCompare) qsort(pList, n, sizeof(_dirent *), cbCompare); +#ifdef M_I86TM +#pragma warning(default:4220) /* Ignore the "varargs matches remaining parameters" warning */ +#endif + *resultList = pList; + DEBUG_LEAVE(("return %d;\n", n)); + return n; +} +#pragma warning(default:4706) + +int __cdecl alphasort(const _dirent **ppDE1, const _dirent **ppDE2) { + int ret; + /* Sort names a-la Windows, that is case insensitive */ + ret = _strnicmp((*ppDE1)->d_name, (*ppDE2)->d_name, NAME_MAX); + if (ret) return ret; + /* For the remote chance that we're accessing a Unix share */ + ret = _strnicmp((*ppDE1)->d_name, (*ppDE2)->d_name, NAME_MAX); + if (ret) return ret; + return 0; +} + diff --git a/deps/MsvcLibX/src/dirname.c b/deps/MsvcLibX/src/dirname.c new file mode 100644 index 0000000000000000000000000000000000000000..97fffcfe8c98ee111800bf3f790d2138313b3a5b --- /dev/null +++ b/deps/MsvcLibX/src/dirname.c @@ -0,0 +1,74 @@ +/*****************************************************************************\ +* * +* Filename dirname.c * +* * +* Description Get the parent directory name of a file pathname * +* * +* Notes Uses a static buffer in some cases. Not thread safe! * +* Posix spec authorizes this, and also authorizes to modify * +* the input string, which we do. => Always do an strdup() * +* before calling dirname(), and call dirname(copy). * +* * +* History * +* 2016-09-08 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "msvclibx.h" + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ 2005 security warnings */ + +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +char szLastDriveDirName[4] = "C:."; + +char *dirname(char *pszPathname) { + char *pszPath = pszPathname; + size_t len; + char *pc; + char *pc2; + + /* A NULL pathname is assumed to refer to the current directory */ + if (!pszPathname) return szLastDriveDirName + 2; /* "." */ + /* Skip the drive if present */ + len = strlen(pszPathname); + if (!len) return szLastDriveDirName + 2; /* "." */ + if ((len >= 2) && (pszPathname[1] == ':')) { + pszPath += 2; + len -= 2; + if (!len) { + szLastDriveDirName[0] = pszPathname[0]; /* Warning: Not thread safe! */ + return szLastDriveDirName; /* "D:." */ + } + } + /* Remove trailing path separators */ + while ((len > 1) && ((pszPath[len-1] == '\\') || (pszPath[len-1] == '/'))) { + pszPath[--len] = '\0'; + } + /* Remove the file name */ + pc = strrchr(pszPath, '\\'); + pc2 = strrchr(pszPath, '/'); + if (pc2 > pc) pc = pc2; + if (pc) pc += 1; else pc = pszPath; + *pc = '\0'; + len = pc - pszPath; + if (!len) { + strcpy(pc, "."); /* Yes, the spec says that the dirname of .. is . */ + len = 1; + } + /* Remove trailing path separators */ + while ((len > 1) && ((pszPath[len-1] == '\\') || (pszPath[len-1] == '/'))) { + pszPath[--len] = '\0'; + } + /* Done */ + return pszPathname; +} diff --git a/deps/MsvcLibX/src/err2errno.c b/deps/MsvcLibX/src/err2errno.c new file mode 100644 index 0000000000000000000000000000000000000000..ec4260df0b1e59422e3802d770c4805cab910499 --- /dev/null +++ b/deps/MsvcLibX/src/err2errno.c @@ -0,0 +1,121 @@ +/*****************************************************************************\ +* * +* Filename err2errno.c * +* * +* Description: Convert a WIN32 error to a Unix errno * +* * +* Notes: * +* * +* History: * +* 2014-02-17 JFL Created this module. * +* 2016-10-05 JFL Fixed compatibility with Visual Studio 2003 and older. * +* Removed a few useless special cases, and added EZERO case.* +* Make sure the global errno is _not_ changed by this funct.* +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* Microsoft C libraries include files */ +#include +#include +/* MsvcLibX library extensions */ +#include "debugm.h" + + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: Win32ErrorToErrno | +| | +| Description: Convert a Win32 system error code to a Posix errno | +| | +| Parameters: DWORD dwError The Win32 error code | +| | +| Returns: The corresponding Posix errno | +| | +| Notes: There's no 1-to-1 correspondance between Windows and | +| Posix errors. This routine attempts to convert codes for | +| the most likely errors for MsvcLibX. | +| Please add those you encounter, that end up in the | +| default category, and incorrectly return EIO by default. | +| | +| Does not change errno. (Contrary to _dosmaperr, etc) | +| You must set errno thereafter if desired. | +| | +| History: | +| 2014-02-05 JFL Created this routine | +| 2014-03-05 JFL Added the default call to _get_errno_from_oserr(). | +| 2015-12-07 JFL Use the new error conversion routine name in the UCRT. | +* * +\*---------------------------------------------------------------------------*/ + +#if defined(_UCRT) /* Visual Studio 14 and later */ +#define _get_errno_from_oserr __acrt_errno_from_os_error /* The name changed in the UCRT */ +#endif + +#if (_MSC_VER < 1400) /* Anything older than Visual Studio 8 (= VS 2003 and older) */ +#pragma message("Defining our own _get_errno_from_oserr()") +extern void __cdecl _dosmaperr(unsigned long); +int _get_errno_from_oserr(unsigned long dwErr) { + _dosmaperr(dwErr); /* Sets errno from WIN32 error */ + return errno; +} +#else +#pragma message("Using the default " MSVCLIBX_STRINGIZE(_get_errno_from_oserr) "()") +/* Equivalent function in MSVC library. Does not know about symlink errors. */ +extern int __cdecl _get_errno_from_oserr(unsigned long oserrno); +#endif + +int Win32ErrorToErrno() { + DWORD dwError = GetLastError(); + + DEBUG_CODE({ + LPVOID lpMsgBuf; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, 0, NULL); + DEBUG_PRINTF(("// Win32 error %d (0x%X): %s", dwError, dwError, lpMsgBuf ? lpMsgBuf : "Unknown\n")); + LocalFree( lpMsgBuf ); + }); + + switch (dwError) { + case ERROR_SUCCESS: + return 0; + case ERROR_PRIVILEGE_NOT_HELD: /* Not running with the SE_CREATE_SYMBOLIC_LINK_NAME privilege */ + case ERROR_REPARSE_ATTRIBUTE_CONFLICT: + return EACCES; + case ERROR_INSUFFICIENT_BUFFER: + return E2BIG; + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + return EEXIST; + case ERROR_WRITE_PROTECT: + return EROFS; + case ERROR_HANDLE_DISK_FULL: + return ENOSPC; + case ERROR_NOT_A_REPARSE_POINT: + case ERROR_REPARSE_TAG_MISMATCH: + case ERROR_INVALID_FLAGS: + case ERROR_INVALID_PARAMETER: + return EINVAL; + case ERROR_INVALID_REPARSE_DATA: + case ERROR_REPARSE_TAG_INVALID: + return EBADF; /* Not supposed to happen in Posix OSs, but may happen when experimenting with junction() IOCTLs. */ + case ERROR_NO_UNICODE_TRANSLATION: + return EILSEQ; + default: { + int errno0, errno1; + errno0 = errno; /* Preserve the initial errno */ + errno1 = _get_errno_from_oserr(dwError); /* Let MSVC library decide. May change errno. */ + errno = errno0; /* Restore the initial errno */ + return errno1; + } + } +} + +#endif /* _WIN32 */ + diff --git a/deps/MsvcLibX/src/exe b/deps/MsvcLibX/src/exe new file mode 100644 index 0000000000000000000000000000000000000000..0afeaf5d6bc239ffe1178b6dad8efead29490228 --- /dev/null +++ b/deps/MsvcLibX/src/exe @@ -0,0 +1,99 @@ +#!/bin/bash +#*****************************************************************************# +# # +# Filename: exe # +# # +# Description: Build simple C/C++ programs for Unix/Linux # +# # +# Notes: Usage: ./exe PROGRAM # +# # +# Stores the executables in $OS.$PROC/[Debug/] for # +# consistency with the Windows build tools. # +# This allows sharing sources in a host system, and # +# using VMs for building the various Windows and Linux # +# versions in a set of OS-specific subdirectories. # +# # +# History: # +# 2013-12-16 JFL Added support for MinGW64. # +# 2015-12-12 JFL Help now displays the output directory name. # +# 2016-01-07 JFL Added compilation option -Wall. # +# # +# © Copyright 2016 Hewlett Packard Enterprise Development LP # +# Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 # +#*****************************************************************************# + +FileNoCase() # Case-independant search for a file. +{ + find . -type f | grep -i -E "./$1$" | sed s=./== +} + +# Identify the OS +OS=`uname -s` +PROC=`uname -p` +if [[ "$OS" == "OSF1" && "`uname -m`" == "alpha" ]] ; then + OS=Tru64 +fi +if [[ "$OS" == "WindowsNT" ]] ; then + OS=WIN32 +fi +OUTDIR=$OS.$PROC +if [[ "${OS:0:7}" == "MINGW32" ]] ; then # Ex: "MINGW32_NT-6.1" + OUTDIR=MINGW32 # MigGW shell if NOT case sensitive + # 2013-12-16 Actually, the 64-bits tool chain also reports MINGW32_NT-6.1 + # So distinguish the two by whether /mingw is mounted on C:\MinGW or C:\MinGW64 + if mount | grep /mingw | grep 64 > /dev/null ; then + OUTDIR=MINGW64 # MigGW shell if NOT case sensitive + fi +fi +if [[ "${OS:0:7}" == "MINGW64" ]] ; then # Ex: ? + OUTDIR=MINGW64 +fi +if [[ "${OS:0:6}" == "CYGWIN" ]] ; then # Ex: "CYGWIN_NT-6.1-WOW64" + OUTDIR=cygwin # Cygwin shell if case sensitive, so use lower case +fi + +# Command line analysis. +case "$1" in + "" | "-h" | "-?" | --help) + echo "Build simple C/C++ programs, storing the executables in $OUTDIR/" + echo "Usage: ./exe PROGRAM" + exit 0 + ;; +esac + +# Identify the source file and program to build. +PROGRAM=$1 +shift +SOURCES=`FileNoCase ${PROGRAM}.c` +CFLAGS="-std=c99 -Wall" # Force compilation in C, even if there are // comments. +if [[ "${SOURCES}" == "" ]] ; then + SOURCES=`FileNoCase ${PROGRAM}.cpp` + CFLAGS="-std=gnu++98 -lstdc++" # Force compilation in C++, even if plain C. + # -lstdc++ prevents error "undefined reference to '__gxx_personality_v0'" +fi +if [[ "${SOURCES}" == "" ]] ; then + echo "Failed to find ${PROGRAM} source." + exit 1 +fi + +# Make sure our include directories are accessible +if [[ -d "/u/JFL/SRC/Include" ]] ; then + if [[ ":$C_INCLUDE_PATH:" != *:/u/JFL/SRC/Include:* ]] ; then + if [[ "$C_INCLUDE_PATH" == "" ]] ; then + export C_INCLUDE_PATH="/u/JFL/SRC/Include" + else + export C_INCLUDE_PATH="$C_INCLUDE_PATH:/u/JFL/SRC/Include" + fi + fi +fi +echo "# C_INCLUDE_PATH=\"$C_INCLUDE_PATH\"" + +# Build it. +# gmake CC=gcc CFLAGS="$CFLAGS" SOURCES="$SOURCES" PROGRAM="$PROGRAM" OS="$OS" $* +mkdir -p $OUTDIR +echo "gcc $CFLAGS -U_DEBUG $SOURCES -o $OUTDIR/$PROGRAM" +gcc $CFLAGS -U_DEBUG $SOURCES -o $OUTDIR/$PROGRAM +mkdir -p $OUTDIR/debug +echo "gcc $CFLAGS -D_DEBUG $SOURCES -o $OUTDIR/debug/$PROGRAM" +gcc $CFLAGS -D_DEBUG $SOURCES -o $OUTDIR/debug/$PROGRAM + diff --git a/deps/MsvcLibX/src/exe.bat b/deps/MsvcLibX/src/exe.bat new file mode 100644 index 0000000000000000000000000000000000000000..f93d6ba3993fbf425ae8c778b60df6abd4589cb1 --- /dev/null +++ b/deps/MsvcLibX/src/exe.bat @@ -0,0 +1,82 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: exe.bat * +:# * +:# Description: Front end to make.bat, to simply build multiple targets * +:# * +:# Arguments: Use option -? to display a help screen * +:# * +:# Notes: Builds the 16-bits MS-DOS version if Visual C++ 1.52 is * +:# installed in its default location in C:\MSVC. * +:# * +:# History: * +:# 2003-03-31 JFL Adapted from previous projects * +:# 2014-03-21 JFL Builds the 16-bits MS-DOS version if Visual C++ 1.52 is * +:# installed in its default location in C:\MSVC. * +:# 2014-03-27 JFL Changed option -f to use nmake option /A. * +:# Added option -r for completeness. * +:# 2015-11-13 JFL Adapted to the new multitarget make system. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +setlocal enableextensions enabledelayedexpansion +goto main + +:main +set "FORCE=0" +set "ACTION=default" +set "EXEC=" +set "MAKEOPTS=" + +goto get_arg +:next_arg +shift +:get_arg +if .%1.==.-?. goto help +if .%1.==./?. goto help +if .%1.==.-a. set "ACTION=all" & goto next_arg +if .%1.==.-d. set "ACTION=debug" & goto next_arg +if .%1.==.-f. set "FORCE=1" & goto next_arg +if .%1.==.-r. set "ACTION=release" & goto next_arg +if .%1.==.-X. set "EXEC=echo" & goto next_arg +set MAKEOPTS=%2 %3 %4 %5 %6 %7 %8 %9 +if "%FORCE%"=="1" set "MAKEOPTS=%MAKEOPTS% /A" +goto %ACTION% + +:help +echo. +echo..exe program builder from a C or C++ source +echo. +echo.Usage: exe [options] program [nmake_options] +echo. +echo.Options: +echo. +echo. -? Display this help page +echo. -a Builds all release ^& debug versions (default) +echo. -d Builds all debug versions only +echo. -f Force building all program targets, irrespective of file dates +echo. -r Builds all release versions only +echo. -X Display the make command generated and exit +echo. +echo.Notes: +echo.* exe myprog ^<==^> make myprog.exe debug\myprog.exe +echo.* This builds all possible OS targets +echo.* To force rebuilding all targets, irrespective of their date, +echo. use nmake option /A. So: exe -f myprog ^<==^> exe myprog /A +goto :eof + +:release +%EXEC% make %MAKEOPTS% %1.exe +goto :eof + +:debug +%EXEC% make %MAKEOPTS% debug\%1.exe +goto :eof + +:default +:all +%EXEC% make %MAKEOPTS% %1.exe debug\%1.exe +goto :eof diff --git a/deps/MsvcLibX/src/filetime.c b/deps/MsvcLibX/src/filetime.c new file mode 100644 index 0000000000000000000000000000000000000000..7531ba3daa9aee9c2653559dd1b5d2da3bc1cf84 --- /dev/null +++ b/deps/MsvcLibX/src/filetime.c @@ -0,0 +1,261 @@ +/*****************************************************************************\ +* * +* Filename filetime.c * +* * +* Description: MsvcLibX internal routines for managing file times * +* * +* Notes: * +* * +* History: * +* 2014-02-26 JFL Created this module. * +* 2014-03-24 JFL Renamed "statx.h" as the standard . * +* 2014-07-03 JFL Filetime2String: Output time with µs precision if possib. * +* 2016-09-13 JFL Fixed a warning. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include /* Define time_t */ +#include + +#ifdef _MSDOS + +/* + Convert a DOS date/time to a Unix time_t + DOS dates start from January 1, 1980. DOS times have a 2-second resolution. + A Unix time_t is the number of 1-second intervals since January 1, 1970. + time_ts are expressed in the GMT time zone. DOS times in the current local time. +*/ +time_t Filetime2Timet(uint16_t date, uint16_t time) { + unsigned int year, month, day, hour, minute, second; + struct tm stm; + + /* Decode fields */ + year = 1980 + ((date & 0xFE00) >> 9); + month = (date & 0x1E0) >> 5; + day = date & 0x1F; + hour = (time & 0xF800) >> 11; + minute = (time & 0x7E0) >> 5; + second = 2 * (time & 0x1F); + + stm.tm_year = (int)year - 1900; + stm.tm_mon = (int)month - 1; + stm.tm_mday = (int)day; + stm.tm_hour = (int)hour; + stm.tm_min = (int)minute; + stm.tm_sec = (int)second; + stm.tm_isdst = -1; /* Let mktime decide if DST is in effect or not */ + + return mktime(&stm); +} + +#if 0 +/* Older version of the same, trying to generate the time_t manually. + Did not handle DST well */ +time_t Filetime2Timet(uint16_t date, uint16_t time) { + unsigned int year, month, day, hour, minute, second; + unsigned int olympiads; /* 4-year periods */ + unsigned long t = 0; + + /* Decode fields */ + year = 1980 + ((date & 0xFE00) >> 9); + month = (date & 0x1E0) >> 5; + day = date & 0x1F; + hour = (time & 0xF800) >> 11; + minute = (time & 0x7E0) >> 5; + second = 2 * (time & 0x1F); + + /* Count days */ + year -= 1970; /* Start of Unix time_t epoch */ + olympiads = year / 4; + year = year % 4; + t = olympiads * (365 + 365 + 366 + 365); + switch (year) { + case 3: t += 366; + case 2: t += 365; + case 1: t += 365; + } + switch (month) { + case 12: t += 30; + case 11: t += 31; + case 10: t += 30; + case 9: t += 31; + case 8: t += 31; + case 7: t += 30; + case 6: t += 31; + case 5: t += 30; + case 4: t += 31; + case 3: t += (year == 2) ? 29 : 28; + case 2: t += 31; + } + t += day-1; + + /* Count seconds */ + t *= 24; + t += hour; + t *= 60; + t += minute; + t *= 60; + t += second; + + /* Correct for the timezone (As DOS returns local times, but time_t is UTC-based) */ + t += timezone; + + /* Still need correction for DST */ + + return (time_t)t; +} +#endif + +/* Generate a string with the local file time, in the ISO 8601 date/time format */ +char *Filetime2String(uint16_t date, uint16_t time, char *pBuf, size_t nBufSize) { + unsigned int year, month, day, hour, minute, second; + + /* Decode fields */ + year = 1980 + ((date & 0xFE00) >> 9); + month = (date & 0x1E0) >> 5; + day = date & 0x1F; + hour = (time & 0xF800) >> 11; + minute = (time & 0x7E0) >> 5; + second = 2 * (time & 0x1F); + + if (nBufSize >= 20) { + sprintf(pBuf, "%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second); + } else { + return "Buffer too small"; + } + return pBuf; +} + +#endif /* defined(_MSDOS) */ + +/*****************************************************************************/ + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: LocalFileTime | +| | +| Description: Convert a file GMT time to the local struct tm to display | +| | +| Parameters: const time_t *t The file GMT time_t | +| | +| Returns: struct tm * | +| | +| Notes: This routine is a replacement for Posix' localtime(), | +| using Windows' specific algorithm for generating local | +| file times. | +| | +| Windows displays file times based on the current | +| difference between the local time and GMT. | +| Linux displays file times as the local time when the | +| the file was created. | +| The two times shown may be different if DST was different | +| then and now. (Ex: Displaying in winter the date/time of | +| a file created the previous summer.) | +| The advantage of Windows' method is that apparent | +| relative times will always be correct, even for files | +| created around the winter/summer time transitions. | +| The advantage of Linux method is that the time displayed | +| for a file never changes. The drawback is that files | +| created 1 hour apart around the Winter/summer time | +| transition may be shown with the exact same time. | +| | +| History: | +| 2014-02-26 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +/* + Convert a Windows FILETIME to a Unix time_t. + A FILETIME is the number of 100-nanosecond intervals since January 1, 1601. + A time_t is the number of 1-second intervals since January 1, 1970. + Both Windows and Linux file times are expressed in the GMT time zone. +*/ +time_t Filetime2Timet(const FILETIME *pFT) { + ULARGE_INTEGER ull; + ull.LowPart = pFT->dwLowDateTime; + ull.HighPart = pFT->dwHighDateTime; + return ull.QuadPart / 10000000ULL - 11644473600ULL; +} + +/* Convert a Unix time_t to a Windows FILETIME */ +void Timet2Filetime(time_t t, FILETIME *pFT) { + ULARGE_INTEGER ull; + ull.QuadPart = (t * 10000000ULL) + 116444736000000000ULL; + pFT->dwLowDateTime = ull.LowPart; + pFT->dwHighDateTime = ull.HighPart; + return; +} + +/* + Convert a Windows FILETIME to a Unix struct timespec. + A FILETIME is the number of 100-nanosecond intervals since January 1, 1601. + A struct timespec contains a time_t and a number of nanoseconds. + Both Windows and Linux file times are expressed in the GMT time zone. +*/ +void Filetime2Timespec(const FILETIME *pFT, struct timespec *pTS) { + ULARGE_INTEGER ull; + ull.LowPart = pFT->dwLowDateTime; + ull.HighPart = pFT->dwHighDateTime; + pTS->tv_sec = (time_t)(ull.QuadPart / 10000000ULL - 11644473600ULL); + pTS->tv_nsec = (int)(ull.QuadPart % 10000000ULL) * 100; + return; +} + +/* Convert a Unix time_t to a Windows FILETIME */ +void Timespec2Filetime(const struct timespec *pTS, FILETIME *pFT) { + ULARGE_INTEGER ull; + ull.QuadPart = (pTS->tv_sec * 10000000ULL) + 116444736000000000ULL + (pTS->tv_nsec / 100); + pFT->dwLowDateTime = ull.LowPart; + pFT->dwHighDateTime = ull.HighPart; + return; +} + +/* Convert a file GMT time to a struct tm with the local time to display */ +struct tm *LocalFileTime(const time_t *pt) { + FILETIME ft, lft; + time_t lt; + + Timet2Filetime(*pt, &ft); + FileTimeToLocalFileTime(&ft, &lft); + lt = Filetime2Timet(&lft); + return gmtime(<); +} + +/* Generate a string with the local file time, in the ISO 8601 date/time format */ +/* 2014-07-03 Output time with µs precision if possible */ +char *Filetime2String(const FILETIME *pFT, char *pBuf, size_t nBufSize) { + FILETIME lft; + SYSTEMTIME sTime; + + FileTimeToLocalFileTime(pFT, &lft); + FileTimeToSystemTime(&lft, &sTime); + if (nBufSize >= 20) { + wsprintf(pBuf, "%04d-%02d-%02d %02d:%02d:%02d", sTime.wYear, sTime.wMonth, sTime.wDay, + sTime.wHour, sTime.wMinute, sTime.wSecond); + if (nBufSize >= 27) { + ULARGE_INTEGER uli; + int iFraction; /* Fraction of a second */ + uli.LowPart = lft.dwLowDateTime; + uli.HighPart = lft.dwHighDateTime; + iFraction = (int)(uli.QuadPart % 10000000); /* FILETIME has 100ns resolution */ + iFraction /= 10; /* Convert 100ns resolution to 1µs resolution */ + wsprintf(pBuf+19, ".%06d", iFraction); + } else if (nBufSize >= 24) { + wsprintf(pBuf+19, ".%03d", sTime.wMilliseconds); + } + } else { + return NULL; /* Buffer too small */ + } + return pBuf; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/fnmatch.c b/deps/MsvcLibX/src/fnmatch.c new file mode 100644 index 0000000000000000000000000000000000000000..20c22560089ea0383dbc9f72690585fc5a663e3d --- /dev/null +++ b/deps/MsvcLibX/src/fnmatch.c @@ -0,0 +1,124 @@ +/*****************************************************************************\ +* * +* Filename: fnmatch.c * +* * +* Description: DOS/WIN32 port of standard C library's fnmatch() * +* * +* Notes: TO DO: Manage FNM_PATHNAME, FNM_PERIOD, FNM_LEADING_DIR. * +* * +* History: * +* 2012-01-17 JFL Created this file. * +* 2013-03-10 JFL In DOS/Windows, the pattern "*.*" actually means "*". * +* 2014-02-13 JFL Removed warnings. * +* 2014-02-14 JFL In DOS/Windows, the pattern "*." means no extension. * +* 2014-02-17 JFL Wildcards match the empty string. * +* 2014-02-20 JFL Fixed "*." pattern matching. * +* 2014-02-28 JFL Added support for UTF-8 pathnames. * +* 2014-03-05 JFL In debug mode, hide recursive calls. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +#include +#include +#include + +#include "fnmatch.h" /* Include our associated .h, in the same dir as this .c. Do not use <>. */ +#include "debugm.h" + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#pragma warning(disable:4706) /* Ignore the "assignment within conditional expression" warning */ +int fnmatch(const char *pszPattern, const char *pszName, int iFlags) { + char cp, cn; + size_t l; + const char *pc; + int iErr; + DEBUG_CODE( + int iHideRecursions = FALSE; + ) + + DEBUG_ENTER(("fnmatch(\"%s\", \"%s\", 0x%x);\n", pszPattern, pszName, iFlags)); + + DEBUG_CODE(if(DEBUG_IS_ON() && !XDEBUG_IS_ON()) iHideRecursions = TRUE;) + + /* Special case in DOS/Windows: "*.*" will actually match any name, even without a dot */ + if (!strcmp(pszPattern, "*.*")) pszPattern = "*"; + + /* Special case in DOS/Windows: "anything." means anything without extension */ + l = strlen(pszPattern); + if (l && (pszPattern[l-1] == '.')) { + int i; + int lName = (int)strlen(pszName); + /* First eliminate the case of forbidden extensions <==> A '.' anywhere before the last character */ + for (i=0; i<(lName-1); i++) { /* Search for a '.' in the name */ + if (pszName[i] == '.') RETURN_CONST_COMMENT(FNM_NOMATCH, ("Forbidden extension found\n")); + } + /* If the name doesn't end with a dot, Remove the pattern's trailing '.' */ + if (lName && (pszName[lName-1] != '.')) { + char *pszPattern2; + pszPattern2 = _strdup(pszPattern); + pszPattern2[--l] = '\0'; + /* Recursively do the pattern matching with the new pattern */ + DEBUG_CODE(if (iHideRecursions) iDebug -= 1;) + iErr = fnmatch(pszPattern2, pszName, iFlags); + DEBUG_CODE(if (iHideRecursions) iDebug += 1;) + free(pszPattern2); + RETURN_INT(iErr); + } + } + + for ( ; (cp = *pszPattern) && (cn = *pszName); pszPattern++, pszName++) { + XDEBUG_PRINTF(("// cp='%c' cn='%c'\n", cp, cn)); + switch (cp) { + case '?': + if (cn == '.') RETURN_CONST_COMMENT(FNM_NOMATCH, ("? does not match a .\n")); + break; /* Anything else matches. Continue analysing the pattern. */ + case '*': + cp = *(++pszPattern); + if (!cp) RETURN_CONST_COMMENT(FNM_MATCH, ("'*' matches whatever remains in the string\n")); + for ( ; cn = *pszName; pszName++) { + DEBUG_CODE(if (iHideRecursions) iDebug -= 1;) + iErr = fnmatch(pszPattern, pszName, iFlags); + DEBUG_CODE(if (iHideRecursions) iDebug += 1;) + if (iErr == FNM_MATCH) RETURN_CONST(FNM_MATCH); + } + RETURN_CONST_COMMENT(FNM_NOMATCH, ("No tail string matches the remainder of the pattern\n")); + default: + if (iFlags & FNM_CASEFOLD) { + cp = (char)toupper(cp); + cn = (char)toupper(cn); + } + if (cp != cn) RETURN_CONST_COMMENT(FNM_NOMATCH, ("Character mismatch\n")); + break; /* The character matches. Continue analysing the pattern. */ + } + } + /* '*' and '?' match the empty string */ + if (*pszPattern && !*pszName) { + int bOnlyWildCards = TRUE; + for (pc=pszPattern; cp=*pc; pc++) { + if ((cp != '*') && (cp != '?')) { + bOnlyWildCards = FALSE; + break; + } + } + if (bOnlyWildCards) { + RETURN_CONST_COMMENT(FNM_MATCH, ("WildCards match the empty string\n")); + } + } + + /* Special case in DOS/Windows: trailing dot allowed in pattern */ + if ((*pszPattern == '.') && (!*(pszPattern+1)) && (!*pszName)) RETURN_CONST_COMMENT(FNM_MATCH, ("trailing dot matches empty string\n")); + + if (*pszPattern || *pszName) RETURN_CONST_COMMENT(FNM_NOMATCH, ("Something remains that did not match\n")); + + RETURN_CONST_COMMENT(FNM_MATCH, ("Complete match\n")); +} +#pragma warning(default:4706) + diff --git a/deps/MsvcLibX/src/fstat.c b/deps/MsvcLibX/src/fstat.c new file mode 100644 index 0000000000000000000000000000000000000000..ba6a635bb0939fd9d7d187dba3accf3b9b329766 --- /dev/null +++ b/deps/MsvcLibX/src/fstat.c @@ -0,0 +1,118 @@ +/*****************************************************************************\ +* * +* Filename fstat.c * +* * +* Description: Redefinitions of standard C library's fstat() * +* * +* Notes: * +* * +* History: * +* 2014-06-24 JFL Created this module. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +/* Microsoft C libraries include files */ +#include +#include +#include +/* MsvcLibX library extensions */ +#include +#include "debugm.h" +#include + + +#if defined(_MSDOS) + +/* Nothing needs to be redefined */ + +#endif /* defined(_MSDOS) */ + + +#if defined(_WIN32) + +/* ------------ Display the *stat* macro values at compile time ------------ */ + +#pragma message(MACRODEF(_MSVC_stat)) +#pragma message(MACRODEF(_MSVC_fstat)) +#pragma message(MACRODEF(_MSVC_lstat)) +#pragma message(MACRODEF(_MSVC_stat64)) + +#if _MSVCLIBX_STAT_DEFINED + #pragma message(MACRODEF(_LIBX_stat)) + #pragma message(MACRODEF(_LIBX_stat64)) +#endif + +#pragma message(MACRODEF(stat)) +#pragma message(MACRODEF(fstat)) +#pragma message(MACRODEF(lstat)) + +#if defined(_LARGEFILE_SOURCE64) + #pragma message(MACRODEF(stat64)) + #pragma message(MACRODEF(fstat64)) + #pragma message(MACRODEF(lstat64)) +#endif + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: fstat | +| | +| Description: Redefine the standard _fstatXY() functions | +| | +| Parameters: int nFile The file handle | +| struct stat *buf Output buffer | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: See sys/stat.h for a description of how the stat and fstat| +| macros work. | +| | +| History: | +| 2014-06-24 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +int fstat(int nFile, struct stat *pStat) { + int iErr; + struct _MSVC_stat msStat; + DEBUG_CODE( + struct tm *pTime; + char szTime[100]; + ) + + DEBUG_ENTER((STRINGIZE(fstat) "(%d, 0x%p);\n", nFile, pStat)); + + iErr = _MSVC_fstat(nFile, &msStat); + if (!iErr) { + ZeroMemory(pStat, sizeof(struct stat)); + pStat->st_mode = msStat.st_mode; + pStat->st_size = msStat.st_size; + pStat->st_ctime = +#undef st_ctime + msStat.st_ctime; + pStat->st_mtime = +#undef st_mtime + msStat.st_mtime; + pStat->st_atime = +#undef st_atime + msStat.st_atime; + DEBUG_CODE( + pTime = LocalFileTime(&(msStat.st_mtime)); + strftime(szTime, sizeof(szTime), "%Y-%m-%d %H:%M:%S", pTime); + ) + RETURN_INT_COMMENT(0, ("%s mode = 0x%04X size = %I64d bytes\n", szTime, pStat->st_mode, (__int64)(pStat->st_size))); + } + /* TO DO: Get the nanosecond time resolution using Windows functions */ + + RETURN_INT_COMMENT(iErr, ("%s\n", strerror(errno))); +} + +#endif /* _WIN32 */ + diff --git a/deps/MsvcLibX/src/fstat64.c b/deps/MsvcLibX/src/fstat64.c new file mode 100644 index 0000000000000000000000000000000000000000..de6a2c6dcd6cc817224baf414bd4bb978d87c092 --- /dev/null +++ b/deps/MsvcLibX/src/fstat64.c @@ -0,0 +1,21 @@ +/*****************************************************************************\ +* * +* Filename fstat64.c * +* * +* Description: Redefinitions of standard C library's fstat64() * +* * +* Notes: * +* * +* History: * +* 2014-06-24 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* st_*time is 64-bits __time64_t & st_size is 64-bits __off64_t */ + +#undef _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 64 + +#include "fstat.c" diff --git a/deps/MsvcLibX/src/fstat64i32.c b/deps/MsvcLibX/src/fstat64i32.c new file mode 100644 index 0000000000000000000000000000000000000000..6275260720a63d13d39c28dda82627851684866e --- /dev/null +++ b/deps/MsvcLibX/src/fstat64i32.c @@ -0,0 +1,21 @@ +/*****************************************************************************\ +* * +* Filename fstat64i32.c * +* * +* Description: Redefinitions of standard C library's fstat64i32() * +* * +* Notes: * +* * +* History: * +* 2014-06-24 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* st_*time is 64-bits __time64_t & st_size is 32-bits __off32_t */ + +#undef _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 32 + +#include "fstat.c" diff --git a/deps/MsvcLibX/src/fullpath.c b/deps/MsvcLibX/src/fullpath.c new file mode 100644 index 0000000000000000000000000000000000000000..8d94d159db4857c0c8a7176d94ff70080f8435af --- /dev/null +++ b/deps/MsvcLibX/src/fullpath.c @@ -0,0 +1,68 @@ +/*****************************************************************************\ +* * +* Filename fullpath.c * +* * +* Description Get the absolute pathname for a relative UTF-8 path * +* * +* Notes * +* * +* History * +* 2016-09-13 JFL Created this module with routine from truename.c. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +#include +#include +#include + +#ifdef _WIN32 /* Automatically defined when targeting a Win32 application */ + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ + +/*---------------------------------------------------------------------------*\ +* * +| Function: _fullpathU | +| | +| Description: Get the absolute pathname for a relative UTF-8 path | +| | +| Parameters: See MSVC's _fullpath() in stdlib.h | +| | +| Return value: Pointer to the full pathname, or NULL if error | +| | +| Notes: Warning: Windows' GetFullPathname and MSVC's _fullpath | +| trim trailing dots and spaces from the path. | +| This derived function reproduces the bug. | +| The caller MUST add trailing dots & spaces back if needed.| +| | +| History: | +| 2014-03-25 JFL Created this routine. | +| 2017-01-30 JFL Fixed bug when the output buffer is allocated here. | +* * +\*---------------------------------------------------------------------------*/ + +char *_fullpathU(char *absPath, const char *relPath, size_t maxLength) { + char *absPath0 = absPath; + DWORD n; + if (!absPath) { /* Then allocate a buffer for the output string */ + maxLength = UTF8_PATH_MAX; + absPath = malloc(maxLength); /* Worst case for UTF-8 is 4 bytes/Unicode character */ + if (!absPath) return NULL; + } + n = GetFullPathNameU(relPath, (DWORD)maxLength, absPath, NULL); + if (!n) { + errno = Win32ErrorToErrno(); + if (!absPath0) free(absPath); + return NULL; + } + if (!absPath0) absPath = realloc(absPath, strlen(absPath) + 1); + return absPath; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/getcwd.c b/deps/MsvcLibX/src/getcwd.c new file mode 100644 index 0000000000000000000000000000000000000000..b04127c211a7acd4bab0fb4c841a48b9aed180c3 --- /dev/null +++ b/deps/MsvcLibX/src/getcwd.c @@ -0,0 +1,152 @@ +/*****************************************************************************\ +* * +* Filename getcwd.c * +* * +* Description: WIN32 port of standard C library's getcwd() * +* * +* Notes: * +* * +* History: * +* 2014-02-28 JFL Created this module. * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +/* Microsoft C libraries include files */ +#include +#include +/* MsvcLibX library extensions */ +#include +#include "debugm.h" + +#if defined(_MSDOS) + +/* DOS own getcwd() is OK. */ + +#endif /* defined(_MSDOS) */ + + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: getcwd | +| | +| Description: Get the current directory, encoded in UTF-8 | +| | +| Parameters: char *buf Buffer for the output | +| size_t bufSize Buffer size | +| | +| Returns: The converted string size. -1=error, and errno set. | +| | +| Notes: We can't use the getcwd name, as MSVC has an incompatible | +| prototype for it. So a getcwd macro calls this routine. | +| | +| History: | +| 2014-02-28 JFL Created this routine | +| 2014-07-02 JFL Added support for pathnames >= 260 characters. | +* * +\*---------------------------------------------------------------------------*/ + +char *getcwdA(char *buf, size_t bufSize) { + int n; + WCHAR wbuf[PATH_MAX]; + DWORD dwSize; + + dwSize = GetCurrentDirectoryW(COUNTOF(wbuf), wbuf); + if (!dwSize) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: GetCurrentDirectoryW() Failed\n", buf, bufSize)); + return NULL; + } + + n = WideCharToMultiByte(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wbuf, /* lpWideCharStr, */ + dwSize+1, /* cchWideChar, */ + buf, /* lpMultiByteStr, */ + (int)bufSize, /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: WideCharToMultiByte() Failed\n", buf, bufSize)); + return NULL; + } + + DEBUG_PRINTF(("getcwd(0x%p, %d); // \"%s\"\n", buf, bufSize, buf)); + return buf; +} + +char *getcwdU(char *buf, size_t bufSize) { + int n; + WCHAR wbuf[PATH_MAX]; + DWORD dwSize; + + dwSize = GetCurrentDirectoryW(COUNTOF(wbuf), wbuf); + if (!dwSize) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: GetCurrentDirectoryW() Failed\n", buf, bufSize)); + return NULL; + } + + n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wbuf, /* lpWideCharStr, */ + dwSize+1, /* cchWideChar, */ + buf, /* lpMultiByteStr, */ + (int)bufSize, /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("getcwd(0x%p, %d); // Error: WideCharToMultiByte() Failed\n", buf, bufSize)); + return NULL; + } + + DEBUG_PRINTF(("getcwd(0x%p, %d); // \"%s\"\n", buf, bufSize, buf)); + return buf; +} + +char *_getdcwdA(int iDrive, char *buf, int iBuflen) { + char *pBuf; + int iDrive0 = _getdrive(); + if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive); + pBuf = getcwdA(buf, iBuflen); + if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive0); + DEBUG_CODE( + if (pBuf) { + DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // \"%s\"\n", iDrive, buf, iBuflen, pBuf)); + } else { + DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // Failed\n", iDrive, buf, iBuflen, pBuf)); + } + ) + return pBuf; +} + +char *_getdcwdU(int iDrive, char *buf, int iBuflen) { + char *pBuf; + int iDrive0 = _getdrive(); + if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive); + pBuf = getcwdU(buf, iBuflen); + if (iDrive && (iDrive != iDrive0)) _chdrive(iDrive0); + DEBUG_CODE( + if (pBuf) { + DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // \"%s\"\n", iDrive, buf, iBuflen, pBuf)); + } else { + DEBUG_PRINTF(("_getdcwd(%d, 0x%p, %d); // Failed\n", iDrive, buf, iBuflen, pBuf)); + } + ) + return pBuf; +} + +#endif /* _WIN32 */ + diff --git a/deps/MsvcLibX/src/getopt.c b/deps/MsvcLibX/src/getopt.c new file mode 100644 index 0000000000000000000000000000000000000000..81976204ccd3cd5eba6d62536dbae9abaf90f3f6 --- /dev/null +++ b/deps/MsvcLibX/src/getopt.c @@ -0,0 +1,500 @@ +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + * $NetBSD: getopt_long.c,v 1.11 2009/04/14 17:34:41 joerg Exp $ + * 2016-09-15 JFL Adapted v 1.11 for use in the MsvcLibX library + */ + +/* 2016-09-15 JFL Begin changes */ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include +#include +#include +#include +#include +#include "getopt.h" + +#ifndef _DIAGASSERT +#ifdef NDEBUG +#define _DIAGASSERT(test) +#else +#define _DIAGASSERT(test) assert(test) +#endif +#endif + +#undef __UNCONST +#define __UNCONST(a) ((void *)/*(size_t)*/(const void *)(a)) + +static const char *progname; + +/* Replacement for warnx(3) for systems without it. */ +static void warnx(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + if (progname) + (void) fprintf(stderr, "%s: ", progname); + if (fmt) + (void) vfprintf(stderr, fmt, ap); + (void) fprintf(stderr, "\n"); + va_end(ap); +} + +#define REPLACE_GETOPT + +/* 2016-09-15 JFL End of changes */ + +#ifdef REPLACE_GETOPT +#ifdef __weak_alias +__weak_alias(getopt,_getopt) +#endif +int opterr = 1; /* if error message should be printed */ +int optind = 1; /* index into parent argv vector */ +int optopt = '?'; /* character checked for validity */ +char *optarg; /* argument associated with option */ +#endif +#if !HAVE_DECL_OPTRESET +int optreset; /* reset getopt */ +#endif + +#if 0 +#ifdef __weak_alias +__weak_alias(getopt_long,_getopt_long) +#endif +#endif + +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_CORRECT") != NULL) +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +#define EMSG "" + +static int getopt_internal(int, char **, const char *); +static int gcd(int, int); +static void permute_args(int, int, int, char **); + +static const char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(int a, int b) +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return b; +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(int panonopt_start, int panonopt_end, int opt_end, char **nargv) +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + _DIAGASSERT(nargv != NULL); + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + nargv[pos] = nargv[cstart]; + nargv[cstart] = swap; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(int nargc, char **nargv, const char *options) +{ + char *oli; /* option letter list index */ + int optchar; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((*(place = nargv[optind]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!PERMUTE) { + /* + * if no permutation wanted, stop parsing + * at first non-option + */ + return -1; + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + if (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = __UNCONST(place); + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return BADARG; + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the real getopt] + */ +int +getopt(int nargc, char * const *nargv, const char *options) +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + retval = getopt_internal(nargc, __UNCONST(nargv), options); + if (retval == -2) { + ++optind; + /* + * We found an option (--), so if we skipped non-options, + * we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, + (char **)nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + retval = -1; + } + return retval; +} +#endif + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(int nargc, char * const *nargv, const char *options, + const struct option *long_options, int *idx) +{ + int retval; + +#define IDENTICAL_INTERPRETATION(_x, _y) \ + (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \ + long_options[(_x)].flag == long_options[(_y)].flag && \ + long_options[(_x)].val == long_options[(_y)].val) + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* idx may be NULL */ + + retval = getopt_internal(nargc, __UNCONST(nargv), options); + if (retval == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, ambiguous, match; + + current_argv = __UNCONST(place); + match = -1; + ambiguous = 0; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, __UNCONST(nargv)); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + ambiguous = 0; + break; + } + if (match == -1) /* partial match */ + match = i; + else if (!IDENTICAL_INTERPRETATION(i, match)) + ambiguous = 1; + } + if (ambiguous) { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return BADCH; + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of + * flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return BADARG; + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use + * next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' + * indicates no error should be generated + */ + if (PRINT_ERROR) + warnx(recargstring, current_argv); + /* + * XXX: GNU sets optopt to val regardless + * of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return BADARG; + } + } else { /* unknown option */ + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +#undef IDENTICAL_INTERPRETATION +} diff --git a/deps/MsvcLibX/src/getppid.c b/deps/MsvcLibX/src/getppid.c new file mode 100644 index 0000000000000000000000000000000000000000..73f66e51443339e2e3768a96e7166f661a18e5ac --- /dev/null +++ b/deps/MsvcLibX/src/getppid.c @@ -0,0 +1,66 @@ +/*****************************************************************************\ +* * +* Filename getppid.c * +* * +* Description: WIN32 port of standard C library's getppid() * +* * +* Notes: TO DO: Add a DOS version, using the PSP for the pid. * +* * +* During the development of this routine, I found a bug * +* in Windows SDK's tlhelp32.h include file in WIN64: * +* If packcking has been changed somewhere before including * +* tlhelp32.h, either due to a #pragma pack directive, or to * +* a compiler /Zp option, it will generate a PROCESSENTRY32 * +* structure with the wrong size. Then anything can happen, * +* including Process32First failures, or even crashes. * +* * +* History: * +* 2013-03-27 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include + +#ifdef _WIN32 + +#include +#pragma pack(push,8) /* Work around a bug in tlhelp32.h in WIN64, which generates the wrong structure if packing has been changed */ +#include +#pragma pack(pop) + +/* +pid_t getpid(void) { + return (pid_t)GetCurrentProcessId(); +} +*/ + +pid_t getppid(void) { + pid_t ppid = INVALID_PID; + pid_t pid = getpid(); + HANDLE h; + BOOL bFound; + PROCESSENTRY32 pe = {0}; + + h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (h == INVALID_HANDLE_VALUE) { + return ppid; + } + + pe.dwSize = sizeof(PROCESSENTRY32); + for (bFound=Process32First(h, &pe); bFound; bFound=Process32Next(h, &pe)) { + if ((pid_t)(pe.th32ProcessID) == pid) { + ppid = pe.th32ParentProcessID; + break; + } + } + + CloseHandle(h); + + return ppid; +} + +#endif + + diff --git a/deps/MsvcLibX/src/gettimeofday.c b/deps/MsvcLibX/src/gettimeofday.c new file mode 100644 index 0000000000000000000000000000000000000000..9cc548366b3602b662570889060f7e2ed976859f --- /dev/null +++ b/deps/MsvcLibX/src/gettimeofday.c @@ -0,0 +1,40 @@ +/*****************************************************************************\ +* * +* Filename gettimeofday.c * +* * +* Description DOS/WIN32 port of standard C library's gettimeofday(). * +* * +* Notes * +* * +* History * +* 2014-06-04 JFL Created this file. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "msvclibx.h" + +#include +#include + +#ifdef _MSDOS +/* MS-DOS only has a 1-second resolution on system time. + Use the existence of macro _STRUCT_TIMEVAL to test if it's possible + to use gettimeofday(), else use time(), which is supported by all OSs */ +#endif + +#if 0 + +/* Get the current date and time into a struct timeval */ +int gettimeofday(struct timeval *ptv, void *pTimeZone) { + struct timespec ts; + int iErr; + if (pTimeZone) pTimeZone = _timezone; /* Ignore it, and prevent compilation warning */ + iErr = clock_gettime(CLOCK_REALTIME, &ts); + if (iErr) return iErr; + TIMESPEC_TO_TIMEVAL(ptv, &ts); + return 0; +} + +#endif /* defined(_WIN32) */ diff --git a/deps/MsvcLibX/src/iconv.c b/deps/MsvcLibX/src/iconv.c new file mode 100644 index 0000000000000000000000000000000000000000..b60ed61029559ec87e8ba12990c216fc6c97165a --- /dev/null +++ b/deps/MsvcLibX/src/iconv.c @@ -0,0 +1,228 @@ +/*****************************************************************************\ +* * +* Filename iconv.c * +* * +* Description: WIN32 port of standard C library's iconv() * +* * +* Notes: Define here a number of routines, that will eventually * +* be used by iconv(). * +* * +* History: * +* 2014-02-27 JFL Created this module. * +* 2015-12-09 JFL Added routines fputsU and vfprintfU. * +* 2016-09-13 JFL Fixed warnings in fputsU. Do not change the input buffer. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +/* Microsoft C libraries include files */ +#include +#include +#include +/* MsvcLibX library extensions */ +#include "iconv.h" +#include "debugm.h" + +#if defined(_MSDOS) + +/* TO DO: Add support for DOS code pages! */ + +#endif /* defined(_MSDOS) */ + + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: ConvertString | +| | +| Description: Convert a string from one MBCS encoding to another | +| | +| Parameters: char *buf Buffer containg a NUL-terminated string | +| size_t nBytes Buffer size | +| UINT cpFrom Initial Windows code page identifier | +| UINT cpTo Final Windows code page identifier | +| LPCSTR lpDfltC Pointer to the Default Character to use | +| (NULL = Use the default default!) | +| | +| Returns: The converted string size. -1=error, and errno set. | +| | +| Notes: See the list of Windows code page identifiers there: | +| http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx +| | +| History: | +| 2014-02-27 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +int ConvertString(char *buf, size_t nBytes, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar) { + int n = (int)lstrlen(buf); + if (cpFrom != cpTo) { + WCHAR *pWBuf = (WCHAR *)malloc(sizeof(WCHAR)*nBytes); + if (!pWBuf) { + errno = ENOMEM; + return -1; + } + n = MultiByteToWideChar(cpFrom, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + buf, /* lpMultiByteStr, */ + n+1, /* cbMultiByte, +1 to copy the final NUL */ + pWBuf, /* lpWideCharStr, */ + (int)nBytes /* cchWideChar, */ + ); + n = WideCharToMultiByte(cpTo, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + pWBuf, /* lpWideCharStr, */ + n, /* cchWideChar, */ + buf, /* lpMultiByteStr, */ + (int)nBytes, /* cbMultiByte, */ + lpDefaultChar, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + free(pWBuf); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + n -= 1; /* Output string size, not counting the final NUL */ + } + return n; +} + +char *DupAndConvert(const char *string, UINT cpFrom, UINT cpTo, LPCSTR lpDefaultChar) { + int nBytes; + char *pBuf; + nBytes = 4 * ((int)lstrlen(string) + 1); /* Worst case for the size needed */ + pBuf = (char *)malloc(nBytes); + if (!pBuf) { + errno = ENOMEM; + return NULL; + } + lstrcpy(pBuf, string); + nBytes = ConvertString(pBuf, nBytes, cpFrom, cpTo, lpDefaultChar); + if (nBytes == -1) { + free(pBuf); + return NULL; + } + pBuf = realloc(pBuf, nBytes+1); + return pBuf; +} + +int CountCharacters(const char *string, UINT cp) { + int n; + WCHAR *pWBuf; + + n = (int)lstrlen(string); + if (!n) return 0; + + pWBuf = (WCHAR *)malloc(sizeof(WCHAR)*n); + if (!pWBuf) { + errno = ENOMEM; + return -1; + } + + n = MultiByteToWideChar(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + string, /* lpMultiByteStr, */ + n, /* cbMultiByte, */ + pWBuf, /* lpWideCharStr, */ + n /* cchWideChar, */ + ); + free(pWBuf); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + return n; +} + +UINT codePage = 0; + +/*---------------------------------------------------------------------------*\ +* * +| Functions: fputsU, vfprintfU, fprintfU, printfU | +| | +| Description: Output UTF-8 strings | +| | +| Parameters: Same as fputs, vfprintf, fprintf, printf | +| | +| Returns: Same as fputs, vfprintf, fprintf, printf | +| | +| Notes: Converts the string to the output code page if needed. | +| | +| History: | +| 2014-02-27 JFL Created fprintfU and printfU. | +| 2015-12-09 JFL Restructured them over vfprintfU, itself over fputsU. | +| 2016-09-13 JFL Fixed warnings. | +| Do not change the input buffer. | +* * +\*---------------------------------------------------------------------------*/ + +/* Make sure we're calling Microsoft routines, not our aliases */ +#undef printf +#undef fprintf +#undef vfprintf +#undef fputs + +int fputsU(const char *buf, FILE *f) { /* fputs a UTF-8 string */ + int iRet; + char *pBuf = NULL; + + if (!codePage) codePage = GetConsoleOutputCP(); + if (codePage != CP_UTF8) { + pBuf = DupAndConvert(buf, CP_UTF8, codePage, NULL); + } else { + pBuf = (char *)buf; + } + if (pBuf) { /* If no error, and something to output */ + iRet = fputs(pBuf, f); + if ((iRet >= 0) && DEBUG_IS_ON()) fflush(f); /* Slower, but ensures we get everything before crashes! */ + if (pBuf != buf) free(pBuf); + } else { + iRet = -1; /* Could not convert the string to output */ + } + return iRet; /* Return the error (n<0) or success (n>=0) */ +} + +int vfprintfU(FILE *f, const char *pszFormat, va_list vl) { /* vfprintf UTF-8 strings */ + int n; + char buf[UNICODE_PATH_MAX + 4096]; + + n = _vsnprintf(buf, sizeof(buf), pszFormat, vl); + if (n > 0) { /* If no error (n>=0), and something to output (n>0), do output */ + int iErr = fputsU(buf, f); + if (iErr < 0) n = iErr; + } + + return n; +} + +int fprintfU(FILE *f, const char *pszFormat, ...) { /* fprintf UTF-8 strings */ + va_list vl; + int n; + + va_start(vl, pszFormat); + n = vfprintfU(f, pszFormat, vl); + va_end(vl); + + return n; +} + +int printfU(const char *pszFormat, ...) { /* printf UTF-8 strings */ + va_list vl; + int n; + + va_start(vl, pszFormat); + n = vfprintfU(stdout, pszFormat, vl); + va_end(vl); + + return n; +} + +#endif /* _WIN32 */ + diff --git a/deps/MsvcLibX/src/lstat.c b/deps/MsvcLibX/src/lstat.c new file mode 100644 index 0000000000000000000000000000000000000000..bd688c13b9166f0f716d7e27fecfa1dc69ed3796 --- /dev/null +++ b/deps/MsvcLibX/src/lstat.c @@ -0,0 +1,431 @@ +/*****************************************************************************\ +* * +* Filename lstat.c * +* * +* Description: WIN32 port of standard C library's lstat() * +* Also contains unlink() and rmdir(), which do use lstat. * +* * +* Notes: TO DO: Make 3 versions for Windows: ANSI, WSTR, UTF8 * +* * +* History: * +* 2014-02-06 JFL Created this module. * +* 2014-02-12 JFL Added code to filter reparse points, and keep only * +* real junctions and symlinks. * +* 2014-02-13 JFL Moved dirent2stat() from dirent.c, as there must actually * +* be 4 WIN32 versions, for the four versions of struct stat.* +* 2014-02-28 JFL Added support for UTF-8 pathnames. * +* 2014-03-24 JFL Renamed "statx.h" as the standard . * +* 2014-06-30 JFL Added support for 32K Unicode paths. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +/* Microsoft C libraries include files */ +#include +#include +#include +/* MsvcLibX library extensions */ +#include "msvclibx.h" +#include +#include +#include /* For ResolveLinks() definition */ +#include "debugm.h" +#include + +#if defined(_MSDOS) +/* Make sure it's only defined it in one of the lstatxxx versions */ +#if !defined(_USE_32BIT_TIME_T) && (_FILE_OFFSET_BITS == 32) + +int dirent2stat(_dirent *pDirent, struct _stat *pStat) { + memset(pStat, 0, sizeof(struct stat)); + + /* Set times */ + pStat->st_mtime = Filetime2Timet(pDirent->d_date, pDirent->d_time); + /* Size */ + pStat->st_size = pDirent->d_filesize; + /* Standard attributes */ + pStat->st_mode |= (pDirent->d_type << 12); /* Set the 4-bit type field */ + pStat->st_mode |= _S_IREAD | _S_IWRITE | _S_IEXEC; /* Assume it's fully accessible */ + if (pDirent->d_attribs & _A_RDONLY) pStat->st_mode &= ~_S_IWRITE; + /* DOS-specific attributes */ + if (pDirent->d_attribs & _A_HIDDEN) pStat->st_mode |= S_HIDDEN; + if (pDirent->d_attribs & _A_ARCH) pStat->st_mode |= S_ARCHIVE; + if (pDirent->d_attribs & _A_SYSTEM) pStat->st_mode |= S_SYSTEM; + + return 0; +} + +#endif /* defined(_USE_32BIT_TIME_T) && (_FILE_OFFSET_BITS == 32) */ +#endif /* defined(_MSDOS) */ + + +#ifdef _WIN32 + +/* ------------ Display the *stat* macro values at compile time ------------ */ + +#pragma message(MACRODEF(_MSVC_stat)) +#pragma message(MACRODEF(_MSVC_fstat)) +#pragma message(MACRODEF(_MSVC_lstat)) +#pragma message(MACRODEF(_MSVC_stat64)) + +#if _MSVCLIBX_STAT_DEFINED + #pragma message(MACRODEF(_LIBX_stat)) + #pragma message(MACRODEF(_LIBX_stat64)) +#endif + +#pragma message(MACRODEF(stat)) +#pragma message(MACRODEF(fstat)) +#pragma message(MACRODEF(lstat)) + +#if 0 +#pragma message(MACRODEF(_lstat)) +#pragma message(MACRODEF(_lstati64)) +#if _MSVCLIBX_STAT_DEFINED + #pragma message(MACRODEF(_lstat_ns)) + #pragma message(MACRODEF(_lstati64_ns)) +#endif +#endif + +#if defined(_LARGEFILE_SOURCE64) + #pragma message(MACRODEF(stat64)) + #pragma message(MACRODEF(fstat64)) + #pragma message(MACRODEF(lstat64)) +#endif + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function: lstat | +| | +| Description: Common definition of all _lstatXY() functions | +| | +| Parameters: const char *path The symlink name | +| struct stat *buf Output buffer | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: See statx.h for a description of how the stat and lstat | +| macros work. | +| | +| History: | +| 2014-02-06 JFL Created this routine | +| 2014-02-28 JFL Added support for UTF-8 pathnames. | +* * +\*---------------------------------------------------------------------------*/ + +int lstat(const char *path, struct stat *pStat) { + BOOL bDone; + DWORD dwAttr; + WIN32_FILE_ATTRIBUTE_DATA fileData; + unsigned __int64 qwSize; + int bIsJunction = FALSE; + int bIsMountPoint = FALSE; + DWORD dwTag = 0; + DEBUG_CODE( + char szTime[100]; + ) + WCHAR wszName[UNICODE_PATH_MAX]; + int n; + + DEBUG_ENTER((STRINGIZE(lstat) "(\"%s\", 0x%p);\n", path, pStat)); + +#if USE_MSVC_STAT + dwAttr = GetFileAttributes(path); + DEBUG_PRINTF(("GetFileAttributes() = 0x%lX\n", dwAttr)); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + RETURN_INT_COMMENT(-1, ("File does not exist\n")); + } + + if (!(dwAttr & FILE_ATTRIBUTE_REPARSE_POINT)) { + int iErr = stat(path, pStat); + RETURN_INT(iErr); + } +#endif + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + UNICODE_PATH_MAX /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + + bDone = GetFileAttributesExW(wszName, GetFileExInfoStandard, &fileData); + if (!bDone) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("GetFileAttributesEx(); // Failed\n")); + } + XDEBUG_PRINTF(("GetFileAttributesEx(); // Success\n")); + dwAttr = fileData.dwFileAttributes; + XDEBUG_PRINTF(("dwFileAttributes = 0x%lX\n", dwAttr)); + DEBUG_CODE_IF_ON(Filetime2String(&fileData.ftLastWriteTime, szTime, sizeof(szTime));); + XDEBUG_PRINTF(("ftLastWriteTime = %s\n", szTime)); + qwSize = ((unsigned __int64)fileData.nFileSizeHigh << 32) | fileData.nFileSizeLow; + XDEBUG_PRINTF(("nFileSize = %I64d\n", qwSize)); + + ZeroMemory(pStat, sizeof(struct stat)); + /* Set times */ +#if _MSVCLIBX_STAT_DEFINED + Filetime2Timespec(&fileData.ftCreationTime, &(pStat->st_ctim)); /* Windows = Create time; Unix = Permissions change time */ + Filetime2Timespec(&fileData.ftLastWriteTime, &(pStat->st_mtim)); + Filetime2Timespec(&fileData.ftLastAccessTime, &(pStat->st_atim)); +#else + Filetime2Timet(&fileData.ftCreationTime, &(pStat->st_ctime)); /* Windows = Create time; Unix = Permissions change time */ + Filetime2Timet(&fileData.ftLastWriteTime, &(pStat->st_mtime)); + Filetime2Timet(&fileData.ftLastAccessTime, &(pStat->st_atime)); +#endif + /* Size */ + /* NOTE: There is loss of data here if the file size is > 2GB, and off_t is 32-bits */ + pStat->st_size = (off_t)qwSize; +#if (_STAT_FILE_SIZE < 64) +#define _MAX_FILE_SIZE 0x7FFFFFFFL + if (qwSize > _MAX_FILE_SIZE) pStat->st_size = (off_t)_MAX_FILE_SIZE; +#endif + /* Standard attributes */ + /* File type */ +check_attr_again: + if (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) { + /* JUNCTIONs and SYMLINKDs both have the FILE_ATTRIBUTE_DIRECTORY flag also set. + // Test the FILE_ATTRIBUTE_REPARSE_POINT flag first, to make sure they're seen as symbolic links. + // + // All symlinks are reparse points, but not all reparse points are symlinks. */ + dwTag = GetReparseTagU(path); + switch (dwTag) { + case IO_REPARSE_TAG_MOUNT_POINT: /* NTFS junction or mount point */ + { /* We must read the link to distinguish junctions from mount points. */ + WCHAR wbuf[UNICODE_PATH_MAX]; + ssize_t n; + bIsMountPoint = TRUE; + n = readlinkW(wszName, wbuf, UNICODE_PATH_MAX); + /* Junction targets are absolute pathnames, starting with a drive letter. Ex: C: */ + /* readlink() fails if the reparse point does not target a valid pathname */ + if (n < 0) goto this_is_not_a_symlink; /* This is not a junction. */ + bIsJunction = TRUE; /* Else this is a junction. Fall through to the symlink case. */ + } + case IO_REPARSE_TAG_SYMLINK: /* NTFS symbolic link */ + pStat->st_mode |= S_IFLNK; /* Symbolic link */ + break; + default: /* Anything else is definitely not like a Unix symlink */ +this_is_not_a_symlink: + dwAttr &= ~FILE_ATTRIBUTE_REPARSE_POINT; + goto check_attr_again; + } + } else if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) + pStat->st_mode |= S_IFDIR; /* Subdirectory */ + else if (dwAttr & FILE_ATTRIBUTE_DEVICE) + pStat->st_mode |= S_IFCHR; /* Device (we don't know if character or block) */ + else + pStat->st_mode |= S_IFREG; /* A normal file by default */ + /* pStat->st_mode |= (pDirent->d_type << 12); /* Set the 4-bit type field */ + pStat->st_mode |= _S_IREAD | _S_IWRITE | _S_IEXEC; /* Assume it's fully accessible */ + if (dwAttr & FILE_ATTRIBUTE_READONLY) pStat->st_mode &= ~_S_IWRITE; + /* DOS-specific attributes */ + if (dwAttr & FILE_ATTRIBUTE_HIDDEN) pStat->st_mode |= S_HIDDEN; + if (dwAttr & FILE_ATTRIBUTE_ARCHIVE) pStat->st_mode |= S_ARCHIVE; + if (dwAttr & FILE_ATTRIBUTE_SYSTEM) pStat->st_mode |= S_SYSTEM; + /* Windows-specific attributes */ + if (dwAttr & FILE_ATTRIBUTE_COMPRESSED) pStat->st_mode |= S_COMPRESSED; + if (dwAttr & FILE_ATTRIBUTE_ENCRYPTED) pStat->st_mode |= S_ENCRYPTED; + if (dwAttr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) pStat->st_mode |= S_NOT_CONTENT_INDEXED; + if (dwAttr & FILE_ATTRIBUTE_OFFLINE) pStat->st_mode |= S_OFFLINE; + if (dwAttr & FILE_ATTRIBUTE_SPARSE_FILE) pStat->st_mode |= S_SPARSE_FILE; + if (bIsMountPoint) pStat->st_mode |= S_MOUNT_POINT; /* Will allow to distinguish junctions from mount points */ + /* if (dwAttr & FILE_ATTRIBUTE_TEMPORARY) pStat->st_mode |= S_TEMPORARY; */ + /* if (dwAttr & FILE_ATTRIBUTE_VIRTUAL) pStat->st_mode |= S_VIRTUAL; */ +#if _MSVCLIBX_STAT_DEFINED + pStat->st_Win32Attrs = dwAttr; + pStat->st_ReparseTag = dwTag; +#endif + + RETURN_INT_COMMENT(0, ("%s mode = 0x%04X size = %I64d bytes\n", szTime, pStat->st_mode, qwSize)); +} + +#if !USE_MSVC_STAT +int stat(const char *path, struct stat *pStat) { + char buf[UTF8_PATH_MAX]; + int iErr; + + DEBUG_ENTER((STRINGIZE(stat) "(\"%s\", 0x%p);\n", path, pStat)); + + iErr = ResolveLinksU(path, buf, sizeof(buf)); + if (!iErr) lstat(buf, pStat); + + RETURN_INT(iErr); +} +#endif /* !USE_MSVC_STAT */ + +int dirent2stat(_dirent *pDirent, struct stat *pStat) { + memset(pStat, 0, sizeof(struct stat)); + + /* Set times */ +#if _MSVCLIBX_STAT_DEFINED + Filetime2Timespec(&pDirent->d_CreationTime, &(pStat->st_ctim)); /* Windows = Create time; Unix = Permissions change time */ + Filetime2Timespec(&pDirent->d_LastWriteTime, &(pStat->st_mtim)); + Filetime2Timespec(&pDirent->d_LastAccessTime, &(pStat->st_atim)); +#else + Filetime2Timet(&pDirent->d_CreationTime, &(pStat->st_ctime)); /* Windows = Create time; Unix = Permissions change time */ + Filetime2Timet(&pDirent->d_LastWriteTime, &(pStat->st_mtime)); + Filetime2Timet(&pDirent->d_LastAccessTime, &(pStat->st_atime)); +#endif + /* Size */ + /* NOTE: There is loss of data here if the file size is > 2GB, and off_t is 32-bits */ + pStat->st_size = (off_t)(pDirent->d_filesize); +#if (_STAT_FILE_SIZE < 64) +#define _MAX_FILE_SIZE 0x7FFFFFFFL + if (pDirent->d_filesize > _MAX_FILE_SIZE) pStat->st_size = (off_t)_MAX_FILE_SIZE; +#endif + /* Standard attributes */ + pStat->st_mode |= (pDirent->d_type << 12); /* Set the 4-bit type field */ + pStat->st_mode |= _S_IREAD | _S_IWRITE | _S_IEXEC; /* Assume it's fully accessible */ + if (pDirent->d_attribs & FILE_ATTRIBUTE_READONLY) pStat->st_mode &= ~_S_IWRITE; + /* DOS-specific attributes */ + if (pDirent->d_attribs & FILE_ATTRIBUTE_HIDDEN) pStat->st_mode |= S_HIDDEN; + if (pDirent->d_attribs & FILE_ATTRIBUTE_ARCHIVE) pStat->st_mode |= S_ARCHIVE; + if (pDirent->d_attribs & FILE_ATTRIBUTE_SYSTEM) pStat->st_mode |= S_SYSTEM; + /* Windows-specific attributes */ + if (pDirent->d_attribs & FILE_ATTRIBUTE_COMPRESSED) pStat->st_mode |= S_COMPRESSED; + if (pDirent->d_attribs & FILE_ATTRIBUTE_ENCRYPTED) pStat->st_mode |= S_ENCRYPTED; + if (pDirent->d_attribs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) pStat->st_mode |= S_NOT_CONTENT_INDEXED; + if (pDirent->d_attribs & FILE_ATTRIBUTE_OFFLINE) pStat->st_mode |= S_OFFLINE; + if (pDirent->d_attribs & FILE_ATTRIBUTE_SPARSE_FILE) pStat->st_mode |= S_SPARSE_FILE; + /* Special case of junction and mount points */ + if (pDirent->d_ReparseTag) pStat->st_mode |= S_MOUNT_POINT; + /* if (pDirent->d_attribs & FILE_ATTRIBUTE_TEMPORARY) pStat->st_mode |= S_TEMPORARY; */ + /* if (pDirent->d_attribs & FILE_ATTRIBUTE_VIRTUAL) pStat->st_mode |= S_VIRTUAL; */ +#if _MSVCLIBX_STAT_DEFINED + pStat->st_Win32Attrs = pDirent->d_attribs; + pStat->st_ReparseTag = pDirent->d_ReparseTag; +#endif + + return 0; +} + +/*---------------------------------------------------------------------------*\ +* * +| Function: unlink | +| | +| Description: Remove a file or a symbolic link | +| | +| Parameters: const char *path The file or symlink name | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: | +| | +| History: | +| 2014-02-17 JFL Created this routine | +| 2014-02-28 JFL Added support for UTF-8 pathnames. | +* * +\*---------------------------------------------------------------------------*/ + +int unlink(const char *path) { + int iErr; + BOOL bDone; + struct stat st; + WCHAR wszName[UNICODE_PATH_MAX]; + int n; + + DEBUG_ENTER(("unlink(\"%s\");\n", path)); + + iErr = lstat(path, &st); + if (iErr) RETURN_INT(iErr); + + if ((!S_ISREG(st.st_mode)) && (!S_ISLNK(st.st_mode))) { + errno = ENOENT; + RETURN_INT_COMMENT(-1, ("Pathname exists, but is not a file or a link\n")); + } + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + UNICODE_PATH_MAX /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + +#if _MSVCLIBX_STAT_DEFINED + if (S_ISLNK(st.st_mode) && (st.st_Win32Attrs & FILE_ATTRIBUTE_DIRECTORY)) { + /* This link is a junction or a symlinkd */ + bDone = RemoveDirectoryW(wszName); + } else +#endif + bDone = DeleteFileW(wszName); + + if (bDone) { + RETURN_INT_COMMENT(0, ("Success\n")); + } else { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("Failed\n")); + } +} + +/*---------------------------------------------------------------------------*\ +* * +| Function: rmdir | +| | +| Description: Remove a directory | +| | +| Parameters: const char *path The directory name | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: | +| | +| History: | +| 2014-03-05 JFL Created this routine with support for UTF-8 pathnames. | +* * +\*---------------------------------------------------------------------------*/ + +int rmdir(const char *path) { + int iErr; + BOOL bDone; + struct stat st; + WCHAR wszName[UNICODE_PATH_MAX]; + int n; + + DEBUG_ENTER(("rmdir(\"%s\");\n", path)); + + iErr = lstat(path, &st); + if (iErr) RETURN_INT(iErr); + + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + RETURN_INT_COMMENT(-1, ("Pathname exists, but is not a directory\n")); + } + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + UNICODE_PATH_MAX /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + + bDone = RemoveDirectoryW(wszName); + + if (bDone) { + RETURN_INT_COMMENT(0, ("Success\n")); + } else { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("Failed\n")); + } +} + +#endif /* _WIN32 */ + diff --git a/deps/MsvcLibX/src/lstat32.c b/deps/MsvcLibX/src/lstat32.c new file mode 100644 index 0000000000000000000000000000000000000000..5486f45b8eb1e2698a9c33e26f938e4e30f21cef --- /dev/null +++ b/deps/MsvcLibX/src/lstat32.c @@ -0,0 +1,24 @@ +/*****************************************************************************\ +* * +* Filename lstat32.c * +* * +* Description: Redefinitions of standard C library's lstat32() * +* * +* Notes: * +* * +* History: * +* 2014-02-14 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _WIN64 /* WIN64 does not support 32-bits time_t */ + +/* st_*time is 32-bits __time32_t & st_size is 32-bits __off32_t */ + +#define _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 32 + +#include "lstat.c" +#endif diff --git a/deps/MsvcLibX/src/lstat32i64.c b/deps/MsvcLibX/src/lstat32i64.c new file mode 100644 index 0000000000000000000000000000000000000000..8eafed1d3eb5ec83cb6189ab8cc9146fe0be4762 --- /dev/null +++ b/deps/MsvcLibX/src/lstat32i64.c @@ -0,0 +1,24 @@ +/*****************************************************************************\ +* * +* Filename lstat32i64.c * +* * +* Description: Redefinitions of standard C library's lstat32i64() * +* * +* Notes: * +* * +* History: * +* 2014-02-14 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#ifndef _WIN64 /* WIN64 does not support 32-bits time_t */ + +/* st_*time is 32-bits __time32_t & st_size is 64-bits __off64_t */ + +#define _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 64 + +#include "lstat.c" +#endif diff --git a/deps/MsvcLibX/src/lstat64.c b/deps/MsvcLibX/src/lstat64.c new file mode 100644 index 0000000000000000000000000000000000000000..b84b3271e34eb6f2bdc64f0901d006baf551524a --- /dev/null +++ b/deps/MsvcLibX/src/lstat64.c @@ -0,0 +1,21 @@ +/*****************************************************************************\ +* * +* Filename lstat.c * +* * +* Description: Redefinitions of standard C library's lstat() * +* * +* Notes: * +* * +* History: * +* 2014-02-14 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* st_*time is 64-bits __time64_t & st_size is 64-bits __off64_t */ + +#undef _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 64 + +#include "lstat.c" diff --git a/deps/MsvcLibX/src/lstat64i32.c b/deps/MsvcLibX/src/lstat64i32.c new file mode 100644 index 0000000000000000000000000000000000000000..f5325d18327d18d9a3673fdaaf52742944cc7453 --- /dev/null +++ b/deps/MsvcLibX/src/lstat64i32.c @@ -0,0 +1,21 @@ +/*****************************************************************************\ +* * +* Filename lstat64i32.c * +* * +* Description: Redefinitions of standard C library's lstat64i32() * +* * +* Notes: * +* * +* History: * +* 2014-02-14 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +/* st_*time is 64-bits __time64_t & st_size is 32-bits __off32_t */ + +#undef _USE_32BIT_TIME_T +#define _FILE_OFFSET_BITS 32 + +#include "lstat.c" diff --git a/deps/MsvcLibX/src/main.c b/deps/MsvcLibX/src/main.c new file mode 100644 index 0000000000000000000000000000000000000000..7c87c7fb7edf7d961110e32efeb4d076781cad75 --- /dev/null +++ b/deps/MsvcLibX/src/main.c @@ -0,0 +1,225 @@ +/*****************************************************************************\ +* * +* Filename main.c * +* * +* Description: Main routine for WIN32 UTF-8 programs * +* * +* Notes: TO DO: Also set the environment with _setenvp() ? * +* * +* History: * +* 2014-03-03 JFL Created this module. * +* 2016-09-20 JFL Bug fix: Empty arguments "" did not get recorded. * +* 2017-02-05 JFL Redesigned to override libc's _setargv(). This avoids * +* having to encapsulate the main() routine with one here. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE +#define _CRT_SECURE_NO_WARNINGS /* Avoid depreciation warnings */ + +#include +#include "msvclibx.h" + +#ifdef _WIN32 + +#include +#include /* For MsvcLibX' codePage global variable */ + +/*---------------------------------------------------------------------------*\ +* * +| Function BreakArgLine | +| | +| Description Break the Windows command line into standard C arguments | +| | +| Parameters LPSTR pszCmdLine NUL-terminated argument line | +| char *pszArg[] Array of arguments pointers | +| | +| Returns int argc Number of arguments found. -1 = Error | +| | +| Notes MSVC library startup \" parsing rule is: | +| 2N backslashes + " ==> N backslashes and begin/end quote | +| 2N+1 backslashes + " ==> N backslashes + literal " | +| N backslashes ==> N backslashes | +| | +| History | +| 1993-10-05 JFL Initial implementation within devmain(). | +| 1994-04-14 JFL Extracted from devmain, and created this routine. | +| 1995-04-07 JFL Extracted from llkinit.c. | +| 1996-09-26 JFL Adapted to Win32 programs. | +| 1996-12-11 JFL Use Windows string routines. | +| 2001-09-18 JFL Set argv[0] with actual module file name. | +| Manage quoted strings as a single argument. | +| 2001-09-25 JFL Only process \x inside strings. | +| 2014-03-04 JFL Removed the C-style \-quoting of characters, which was | +| convenient, but incompatible with MSVC argument parsing. | +| Removed the limitation on the # of arguments. | +| Made the code compatible with ANSI and UTF-8 encodings. | +| 2017-02-05 JFL Check memory allocation errors, and if so return -1. | +* * +\*---------------------------------------------------------------------------*/ + +int BreakArgLine(LPSTR pszCmdLine, char ***pppszArg) { + int i, j; + int argc = 0; + char c, c0; + char *pszCopy; + int iString = FALSE; /* TRUE = string mode; FALSE = non-string mode */ + int nBackslash = 0; + char **ppszArg; + int iArg = FALSE; /* TRUE = inside an argument; FALSE = between arguments */ + + ppszArg = (char **)malloc((argc+1)*sizeof(char *)); + if (!ppszArg) return -1; + + /* Make a local copy of the argument line */ + /* Break down the local copy into standard C arguments */ + + pszCopy = malloc(lstrlen(pszCmdLine) + 1); + if (!pszCopy) return -1; + /* Copy the string, managing quoted characters */ + for (i=0, j=0, c0='\0'; ; i++) { + c = pszCmdLine[i]; + if (!c) { /* End of argument line */ + for ( ; nBackslash; nBackslash--) pszCopy[j++] = '\\'; /* Output pending \s */ + pszCopy[j++] = c; + break; + } + if ((!iArg) && (c != ' ') && (c != '\t')) { /* Beginning of a new argument */ + iArg = TRUE; + ppszArg[argc++] = pszCopy+j; + ppszArg = (char **)realloc(ppszArg, (argc+1)*sizeof(char *)); + if (!ppszArg) return -1; + pszCopy[j] = c0 = '\0'; + } + if (c == '\\') { /* Escaped character in string (maybe) */ + nBackslash += 1; + continue; + } + if (c == '"') { + if (nBackslash & 1) { /* Output N/2 \ and a literal " */ + for (nBackslash >>= 1; nBackslash; nBackslash--) pszCopy[j++] = '\\'; + pszCopy[j++] = c0 = c; + continue; + } + if (nBackslash) { /* Output N/2 \ and switch string mode */ + for (nBackslash >>= 1; nBackslash; nBackslash--) pszCopy[j++] = '\\'; + } + iString = !iString; + continue; + } + for ( ; nBackslash; nBackslash--) pszCopy[j++] = '\\'; /* Output pending \s */ + if ((!iString) && ((c == ' ') || (c == '\t'))) { /* End of an argument */ + iArg = FALSE; + c = '\0'; + } + pszCopy[j++] = c0 = c; + } + + ppszArg[argc] = NULL; + *pppszArg = ppszArg; + + return argc; +} + +/*---------------------------------------------------------------------------*\ +* * +| Function _setargv | +| | +| Description Msft standard CRT routine for parsing the command line. | +| | +| Parameters char *_acmdln Command line parameters. | +| | +| Returns __argc = Number of arguments. -1 = Error. | +| __argv = Array of arguments | +| _pgmptr = The program pathname | +| | +| Notes When linked in, replaces the default routine from the CRT.| +| | +| History | +| 2001-09-25 JFL Created this routine | +| 2016-12-31 JFL Changed the return type from void to int, else the WIN64 | +| version fails with message: | +| runtime error R6008 - not enough space for arguments | +| 2017-02-05 JFL Adapted for UTF-8 arguments initialization. | +* * +\*---------------------------------------------------------------------------*/ + +/* Global CRT variables defined in stdlib.h */ +/* Do not include stdlib.h here, to avoid getting unwanted macros hiding these */ +_CRTIMP extern int __argc; +_CRTIMP extern char **__argv; +_CRTIMP extern char *_acmdln; +_CRTIMP extern char *_pgmptr; + +int _initU(void); /* Forward reference */ + +int _setargv(void) { + int err = _initU(); + if (err) return err; + __argc = BreakArgLine(_acmdln, &__argv); + _pgmptr = __argv[0]; + return __argc; +} + +/*---------------------------------------------------------------------------*\ +* * +| Function _initU | +| | +| Description UTF-8 program initializations | +| | +| Parameters None | +| | +| Returns 0=Success. -1 = Error. | +| _acmdln = UTF-8 command line | +| codePage = Console Code Page | +| | +| Notes Forcibly linked in C programs that define _UTF8_SOURCE, | +| etc, which drags in _setargv() above with it. | +| | +| History | +| 2017-02-05 JFL Adapted from the abandonned _mainU0 routine. | +* * +\*---------------------------------------------------------------------------*/ + +int _initU(void) { + LPWSTR lpwCommandLine; + int n; + WCHAR wc; + + /* Get the Unicode command line */ + lpwCommandLine = GetCommandLineW(); + /* Trim tail spaces */ + n = lstrlenW(lpwCommandLine); + while (n && ((wc = lpwCommandLine[n-1]) != L'\0') && ((wc == L' ') || (wc == L'\t'))) lpwCommandLine[--n] = L'\0'; + /* Allocate space for the UTF8 copy */ + n += 1; /* Count the final NUL */ + _acmdln = malloc(4 * n); /* Worst case */ + if (!_acmdln) return -1; /* Memory allocation failed */ + /* Convert the Unicode command line to UTF-8 */ + n = WideCharToMultiByte(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + lpwCommandLine, /* lpWideCharStr, */ + n, /* cchWideChar, */ + _acmdln, /* lpMultiByteStr, */ + (4 * n), /* cbMultiByte, */ + NULL, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { +#undef fprintf /* Use the real fprintf, to avoid further conversion errors! */ + fprintf(stderr, "Warning: Can't convert the argument line to UTF-8\n"); + _acmdln[0] = '\0'; + } + realloc(_acmdln, n+1); /* Resize the memory block to fit the UTF-8 line */ + /* Should not fail since we make it smaller */ + + /* Record the console code page, to allow converting the output accordingly */ + codePage = GetConsoleOutputCP(); + + return 0; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/make.bat b/deps/MsvcLibX/src/make.bat new file mode 100644 index 0000000000000000000000000000000000000000..7a272561228129410dcba670dee0ddb723553647 --- /dev/null +++ b/deps/MsvcLibX/src/make.bat @@ -0,0 +1,35 @@ +@echo off +:#***************************************************************************** +:# * +:# Filename: make.bat * +:# * +:# Description: Build DOS and Windows targets * +:# * +:# Notes: Proxy script for %STINCLUDE%\make.bat. * +:# * +:# If any change is needed, put it in %STINCLUDE%\make.bat. * +:# * +:# History: * +:# 2016-10-10 JFL jf.larvoire@hpe.com created this file. * +:# 2016-12-15 JFL Search for the real make.bat in [.|..|../..]\include. * +:# * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:#***************************************************************************** + +:# Get the full pathname of the STINCLUDE library directory +if defined STINCLUDE if not exist "%STINCLUDE%\make.bat" set "STINCLUDE=" &:# Allow overriding with another alias name, but ignore invalid overrides +for %%p in (. .. ..\..) do if not defined STINCLUDE if exist %%p\include\make.bat ( :# Default: Search it the current directory, and 2 levels above. + for /f "delims=" %%d in ('"pushd %%p\include & cd & popd"') do SET "STINCLUDE=%%d" +) +if not defined STINCLUDE ( :# Try getting the copy in the master environment + for /f "tokens=3" %%v in ('reg query "HKCU\Environment" /v STINCLUDE 2^>NUL') do set "STINCLUDE=%%v" +) + +if not exist %STINCLUDE%\make.bat ( + >&2 echo %0 Error: Cannot find SysToolsLib's global C include directory. Please define variable STINCLUDE. + exit /b 1 +) + +if [%1]==[-d] echo "%STINCLUDE%\make.bat" %* +"%STINCLUDE%\make.bat" %* diff --git a/deps/MsvcLibX/src/mb2wpath.c b/deps/MsvcLibX/src/mb2wpath.c new file mode 100644 index 0000000000000000000000000000000000000000..a41ff75d94f578dc9eff8e3fdb94c638268dfff3 --- /dev/null +++ b/deps/MsvcLibX/src/mb2wpath.c @@ -0,0 +1,86 @@ +/*****************************************************************************\ +* * +* Filename mb2wpath.c * +* * +* Description: WIN32 utility routine MultiByteToWidePath() * +* * +* Notes: Used to overcome the 260-byte limitation of many Windows * +* file management APIs. * +* * +* History: * +* 2014-07-01 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of printf routines */ + +#include "msvclibx.h" +#include "debugm.h" + +#if defined(_WIN32) + +#include +#include /* For _getdrive() */ + +int MultiByteToWidePath( + UINT nCodePage, + LPCSTR pszName, + LPWSTR pwszName, + int nWideBufSize +) { + int n; + int iNameLength = lstrlen(pszName); + DEBUG_CODE( + LPWSTR pwszName0 = pwszName; + ); + + if (iNameLength >= MAX_PATH) { /* Then processing this pathname requires prepending a special prefix */ + /* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx */ + if (!strncmp(pszName, "\\\\?\\", 4)) { /* The name is in the Win32 file namespace */ + /* Do nothing, the "\\?\" extended-length prefix is already there */ + } else if (!strncmp(pszName, "\\\\.\\", 4)) { /* The name is in the Win32 device namespace */ + /* Do nothing, devices names should not be changed */ + } else if (!strncmp(pszName, "\\\\", 2)) { /* The name is a UNC path */ + /* Then prepend it with "\\?\UNC\" to get 32K Unicode paths instead of 260-byte ANSI paths */ + lstrcpyW(pwszName, L"\\\\?\\UNC\\"); + pwszName += 8; + nWideBufSize -= 8; + pszName += 2; /* Skip the initial \\ in the UNC name */ + iNameLength -= 2; + } else if (pszName[0] == '\\') { /* The name is an absolute path with no drive */ + /* Then prepend it with "\\?\" to get 32K Unicode paths instead of 260-byte ANSI paths */ + lstrcpyW(pwszName, L"\\\\?\\"); + /* And also add the drive, as it's required in the Win32 file namespace */ + pwszName[4] = L'@' + (wchar_t)_getdrive(); /* _getdrive() returns 1 for drive A, 2 for B, etc */ + pwszName[5] = L':'; + pwszName += 6; + nWideBufSize -= 6; + } else if (pszName[0] && (pszName[1] == ':') && (pszName[2] == '\\')) { /* The name is an absolute path */ + /* Then prepend it with "\\?\" to get 32K Unicode paths instead of 260-byte ANSI paths */ + lstrcpyW(pwszName, L"\\\\?\\"); + pwszName += 4; + nWideBufSize -= 4; + } /* Else this is a relative pathname. Extended-length is not supported for them. */ + } + + n = MultiByteToWideChar(nCodePage, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + pszName, /* lpMultiByteStr, */ + iNameLength+1, /* cbMultiByte, */ /* +1 to include the final NUL */ + pwszName, /* lpWideCharStr, */ + nWideBufSize /* cchWideChar, */ + ); + DEBUG_CODE( + if (pwszName != pwszName0) { + char szUtf8[UTF8_PATH_MAX]; + DEBUG_WSTR2UTF8(pwszName0, szUtf8, sizeof(szUtf8)); + DEBUG_PRINTF(("MultiByteToWidePath(); // Long name changed to \"%s\"\n", szUtf8)); + } + ); + return n; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/mkdir.c b/deps/MsvcLibX/src/mkdir.c new file mode 100644 index 0000000000000000000000000000000000000000..e83f4c1773cff3134f6852501f2864ba61f152dc --- /dev/null +++ b/deps/MsvcLibX/src/mkdir.c @@ -0,0 +1,102 @@ +/*****************************************************************************\ +* * +* Filename mkdir.c * +* * +* Description: WIN32 UTF-8 version of mkdir * +* * +* Notes: * +* * +* History: * +* 2014-03-04 JFL Created this module. * +* 2014-03-24 JFL Renamed "statx.h" as the standard . * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +/* Microsoft C libraries include files */ +#include +#include /* For _mkdir() */ +#include +/* MsvcLibX library extensions */ +#include +#include "msvclibx.h" + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function mkdir | +| | +| Description UTF-8 version of mkdir | +| | +| Parameters char *pszName File name | +| mode_t iMode File permission bits | +| | +| Returns 0 = Success; -1 = Error and errno set. | +| | +| Notes | +| | +| History | +| 2014-03-04 JFL Created this routine. | +| 2014-07-02 JFL Added support for pathnames >= 260 characters. | +* * +\*---------------------------------------------------------------------------*/ + +#pragma warning(disable:4100) /* Ignore the "unreferenced formal parameter" warning */ + +int mkdirU(const char *pszName, mode_t iMode) { + WCHAR wszName[PATH_MAX]; + int n; + BOOL bDone; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszName, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + COUNTOF(wszName) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + + bDone = CreateDirectoryW(wszName, NULL); + if (!bDone) { + errno = Win32ErrorToErrno(); + return -1; + } + return 0; +} + +int mkdirA(const char *pszName, mode_t iMode) { + WCHAR wszName[PATH_MAX]; + int n; + BOOL bDone; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszName, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + COUNTOF(wszName) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + + bDone = CreateDirectoryW(wszName, NULL); + if (!bDone) { + errno = Win32ErrorToErrno(); + return -1; + } + return 0; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/mkdtemp.c b/deps/MsvcLibX/src/mkdtemp.c new file mode 100644 index 0000000000000000000000000000000000000000..602cdd4b5524d03fe28846a8cb8cfa22bd808b46 --- /dev/null +++ b/deps/MsvcLibX/src/mkdtemp.c @@ -0,0 +1,50 @@ +/*****************************************************************************\ +* * +* Filename mkdtemp.c * +* * +* Description: WIN32 port of standard C library's mkdtemp() * +* * +* Notes: * +* * +* History: * +* 2014-02-13 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include +#include +#include +#include +#include + +char *mkdtemp(char *pszName) { + char *pszXXX, *pc; + int iErr = 0; + char *base32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; + int i; + + /* Find the XXX placeholder at the end of the string */ + for (pszXXX=pszName; pszXXX && *pszXXX; pszXXX++) ; + while ((pszXXX > pszName) && (*(pszXXX-1) == 'X')) pszXXX--; + if (!pszXXX || (*pszXXX != 'X')) { + errno = EINVAL; + return NULL; + } + + /* Seed the random number generator */ + srand((unsigned)getpid() + ((unsigned)time(NULL) << 10)); + + /* Try random file names until one file gets successfully created */ + for (i=0; i<10; i++) { + for (pc = pszXXX; *pc; pc++) { + *pc = base32[rand() % 32]; + } + iErr = _mkdir(pszName); + if (!iErr) break; + } + + return iErr ? NULL : pszName; +} + diff --git a/deps/MsvcLibX/src/mkstemp.c b/deps/MsvcLibX/src/mkstemp.c new file mode 100644 index 0000000000000000000000000000000000000000..ab576b65421b18a24deb6eafe89de24e870dbdd5 --- /dev/null +++ b/deps/MsvcLibX/src/mkstemp.c @@ -0,0 +1,53 @@ +/*****************************************************************************\ +* * +* Filename mkstemp.c * +* * +* Description: WIN32 port of standard C library's mkstemp() * +* * +* Notes: * +* * +* History: * +* 2014-03-03 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int mkstemp(char *pszName) { + char *pszXXX, *pc; + int hFile = -1; + char *base32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; + + /* Find the XXX placeholder at the end of the string */ + for (pszXXX=pszName; pszXXX && *pszXXX; pszXXX++) ; + while ((pszXXX > pszName) && (*(pszXXX-1) == 'X')) pszXXX--; + if (!pszXXX || (*pszXXX != 'X')) { + errno = EINVAL; + return -1; + } + + /* Seed the random number generator */ + srand((unsigned)getpid() + ((unsigned)time(NULL) << 10)); + + /* Try random file names until one file gets successfully created */ + while (hFile == -1) { + for (pc = pszXXX; *pc; pc++) { + *pc = base32[rand() % 32]; + } + hFile = _open(pszName, O_CREAT|O_EXCL|O_RDWR, S_IREAD|S_IWRITE); + } + + return hFile; +} + diff --git a/deps/MsvcLibX/src/open.c b/deps/MsvcLibX/src/open.c new file mode 100644 index 0000000000000000000000000000000000000000..8876ff43eb2f248e7f4c3e551ba1d1e609308f62 --- /dev/null +++ b/deps/MsvcLibX/src/open.c @@ -0,0 +1,83 @@ +/*****************************************************************************\ +* * +* Filename open.c * +* * +* Description: WIN32 UTF-8 version of open * +* * +* Notes: * +* * +* History: * +* 2017-02-16 JFL Created this module. * +* * +* © Copyright 2017 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of printf routines */ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include "msvclibx.h" +#include "fcntl.h" +#include "debugm.h" + +#ifdef _WIN32 + +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function open | +| | +| Description UTF-8 or ANSI file name open(), with long path support | +| | +| Parameters char *pszName File name | +| int iFlags Opening mode | +| int iPerm Permission mode for file creation | +| | +| Returns File number | +| | +| Notes Prefixes long names with "\\?\" to enable long path suppt.| +| | +| History | +| 2017-02-16 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +int openM(UINT cp, const char *pszName, int iFlags, int iPerm) { + WCHAR wszName[UNICODE_PATH_MAX]; + int n; + int iFile; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszName, /* lpMultiByteStr, */ + wszName, /* lpWideCharStr, */ + COUNTOF(wszName) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + +/* return _wopen(wszName, iFlags, iPerm); */ + DEBUG_PRINTF(("_wopen(\"%s\", 0x%X, 0x%X);\n", pszName, iFlags, iPerm)); + iFile = _wopen(wszName, iFlags, iPerm); + DEBUG_PRINTF((" return %d;\n", iFile)); + return iFile; +} + +#pragma warning(disable:4212) /* Ignore the "nonstandard extension used : function declaration used ellipsis" warning */ + +int openA(const char *pszName, int iFlags, int iPerm) { + return openM(CP_ACP, pszName, iFlags, iPerm); +} + +int openU(const char *pszName, int iFlags, int iPerm) { + return openM(CP_UTF8, pszName, iFlags, iPerm); +} + +#pragma warning(default:4212) /* Restore the "nonstandard extension used : function declaration used ellipsis" warning */ + +#endif /* defined(_WIN32) */ diff --git a/deps/MsvcLibX/src/readlink.c b/deps/MsvcLibX/src/readlink.c new file mode 100644 index 0000000000000000000000000000000000000000..d7c728c9fc6bfcba32b77e68cd997ba325e5635c --- /dev/null +++ b/deps/MsvcLibX/src/readlink.c @@ -0,0 +1,508 @@ +/*****************************************************************************\ +* * +* Filename readlink.c * +* * +* Description: WIN32 port of standard C library's readlink() * +* * +* Notes: * +* * +* History: * +* 2014-02-03 JFL Created this module. * +* 2014-02-27 JFL Changed the output name encoding to UTF-8. * +* 2014-03-02 JFL Split the functions into a WSTR and an UTF-8 version. * +* 2014-03-11 JFL Bug fix in junctions targets relativization. * +* 2014-03-13 JFL Allow reading junctions targets in first level shares. * +* 2014-03-19 JFL Split routine ReadReparsePointW() from readlinkW(). * +* 2014-03-20 JFL Restructured Windows readlink function into Wide and * +* MultiByte versions, and changed the Unicode and Ansi * +* versions to macros. * +* 2014-07-03 JFL Added support for pathnames >= 260 characters. * +* 2016-09-09 JFL Fixed a crash in debug mode, due to stack overflows. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +#include +#pragma comment(lib, "Mpr.lib") + +#include +#include "debugm.h" + +#ifdef _WIN32 + +#include +#include "reparsept.h" + +/* Get the Reparse Point Tag for a mount point - Wide char version */ +/* See http://msdn.microsoft.com/en-us/library/windows/desktop/aa365511(v=vs.85).aspx */ +DWORD GetReparseTagW(const WCHAR *pwszPath) { + HANDLE hFind; + WIN32_FIND_DATAW findFileData; + DWORD dwTag = 0; + + hFind = FindFirstFileW(pwszPath, &findFileData); + if (hFind == INVALID_HANDLE_VALUE ) return 0; + CloseHandle(hFind); + if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + dwTag = findFileData.dwReserved0; + } + return dwTag; +} + +/* Get the Reparse Point Tag for a mount point - MultiByte char version */ +DWORD GetReparseTagM(const char *path, UINT cp) { + WCHAR wszPath[PATH_MAX]; + int n; + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("GetReparseTagM(\"%s\", %d); // Conversion to Unicode failed. errno=%d - %s\n", path, cp, errno, strerror(errno))); + return 0; + } + return GetReparseTagW(wszPath); +} + +/*---------------------------------------------------------------------------*\ +* * +| Function: readlink | +| | +| Description: WIN32 port of standard C library's readlink() | +| | +| Parameters: const TCHAR *path The link name | +| TCHAR *buf Buffer for the link target | +| size_t bufsize Number of TCHAR in buf | +| | +| Returns: >0 = Link target size in TCHARS, Success, -1 = Failure | +| | +| Notes: Supports NTFS link types: symlink, symlinkd, junction. | +| | +| Converts junction targets to relative links if possible. | +| | +| On network drives, junctions that cannot be resolved on | +| the client side are returned unchanged: readlink() | +| returns the link name as its own target. This allows | +| resolving pathnames with such junctions successfully, | +| and still accessing files behind these junctions. | +| Note that this is incompatible with Unix, which fails | +| with errno = ELOOP if a link points to itself. | +| Windows-aware applications supporting this can detect | +| this case by comparing linkName and targetName when | +| readlink() succeeds. | +| Function ResolveLinks() in resolvelinks.c relies on this. | +| | +| Using XDEBUG macros to debug readlink() itself, | +| and DEBUG macros to display information useful for | +| debugging applications using readlink(). | +| | +| History: | +| 2014-02-04 JFL Created this routine | +| 2014-02-18 JFL Fix junctions targets on network drives. | +| Convert junction targets to relative paths, if they're | +| on the same drive as the junction itself. | +| 2014-03-11 JFL Bug fix in junctions targets relativization: Use a case- | +| insensitive path comparison. | +| 2014-03-13 JFL Allow reading junctions targets in \\server\Public shares.| +| 2014-03-19 JFL Split routine ReadReparsePointW() from readlinkW(). | +| Fail in case a junction target is on another server drive.| +| | +* * +\*---------------------------------------------------------------------------*/ + +#pragma warning(disable:4706) /* Ignore the "assignment within conditional expression" warning */ + +/* Get the reparse point target, and return the tag. 0=failure */ +DWORD ReadReparsePointW(const WCHAR *path, WCHAR *buf, size_t bufsize) { + DWORD dwAttr; + HANDLE hLink; + BOOL done; + DWORD dwRead; + char iobuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + DWORD dwFlagsAndAttributes; + DWORD dwTag; + WCHAR *pwStr; + PREPARSE_READ_BUFFER pIoctlBuf; + PMOUNTPOINT_READ_BUFFER pMountpointBuf; + PSYMLINK_READ_BUFFER pSymlinkBuf; + unsigned short offset, len = 0; + DEBUG_CODE( + char *pszUtf8; + ) + + DEBUG_WSTR2NEWUTF8(path, pszUtf8); + DEBUG_ENTER(("ReadReparsePointW(\"%s\", 0x%p, %d);\n", pszUtf8, buf, bufsize)); + DEBUG_FREEUTF8(pszUtf8); + + dwAttr = GetFileAttributesW(path); + XDEBUG_PRINTF(("GetFileAttributes() = 0x%lX\n", dwAttr)); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + RETURN_INT_COMMENT(0, ("File does not exist\n")); + } + + if (!(dwAttr & FILE_ATTRIBUTE_REPARSE_POINT)) { + errno = EINVAL; + RETURN_INT_COMMENT(0, ("File is not a link\n")); + } + + dwFlagsAndAttributes = FILE_FLAG_OPEN_REPARSE_POINT; + if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) dwFlagsAndAttributes |= FILE_FLAG_BACKUP_SEMANTICS; + hLink = CreateFileW(path, /* lpFileName, */ + 0, /* dwDesiredAccess, */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode, */ + NULL, /* lpSecurityAttributes, */ + OPEN_EXISTING, /* dwCreationDisposition, */ + dwFlagsAndAttributes, /* dwFlagsAndAttributes, */ + NULL /* hTemplateFile */ + ); + XDEBUG_PRINTF(("CreateFile() = 0x%lX\n", hLink)); + if (hLink == INVALID_HANDLE_VALUE) { + errno = EPERM; + RETURN_INT_COMMENT(0, ("Cannot open the link\n")); + } + + done = DeviceIoControl(hLink, /* hDevice, */ + FSCTL_GET_REPARSE_POINT, /* dwIoControlCode, */ + NULL, /* lpInBuffer, */ + 0, /* nInBufferSize, */ + iobuf, /* lpOutBuffer, */ + sizeof(iobuf), /* nOutBufferSize, */ + &dwRead, /* lpBytesReturned, */ + NULL /* lpOverlapped */ + ); + CloseHandle(hLink); + + if (!done) { + errno = EPERM; + RETURN_INT_COMMENT(0, ("DeviceIoControl() failed\n")); + } + + XDEBUG_PRINTF(("DeviceIoControl() returned %d bytes\n", dwRead)); + + /* Make sur the header tag & length fields are valid */ + if (dwRead < 8) { + errno = EBADF; + RETURN_INT_COMMENT(0, ("Invalid reparse data buffer\n")); + } + pIoctlBuf = (PREPARSE_READ_BUFFER)iobuf; + dwTag = pIoctlBuf->ReparseTag; + DEBUG_CODE_IF_ON( + char *pType = ""; + switch (dwTag) { + case IO_REPARSE_TAG_RESERVED_ZERO: pType = "Reserved"; break; + case IO_REPARSE_TAG_RESERVED_ONE: pType = "Reserved"; break; + case IO_REPARSE_TAG_MOUNT_POINT: pType = "Mount point or junction"; break; + case IO_REPARSE_TAG_HSM: pType = "Hierarchical Storage Manager"; break; + case IO_REPARSE_TAG_DRIVER_EXTENDER: pType = "Home server drive extender"; break; + case IO_REPARSE_TAG_HSM2: pType = "Hierarchical Storage Manager Product #2"; break; + case IO_REPARSE_TAG_SIS: pType = "Single-instance storage filter driver"; break; + case IO_REPARSE_TAG_WIM: pType = "Windows boot Image File"; break; + case IO_REPARSE_TAG_CSV: pType = "Cluster Shared Volume"; break; + case IO_REPARSE_TAG_DFS: pType = "Distributed File System"; break; + case IO_REPARSE_TAG_FILTER_MANAGER: pType = "Filter manager test harness"; break; + case IO_REPARSE_TAG_SYMLINK: pType = "Symbolic link"; break; + case IO_REPARSE_TAG_DFSR: pType = "Distributed File System R filter"; break; + case IO_REPARSE_TAG_DEDUP: pType = "Deduplicated volume"; break; + case IO_REPARSE_TAG_NFS: pType = "NFS share"; break; + default: pType = "Unknown type! Please report its value and update readlink.c."; break; + } + DEBUG_PRINT_INDENT(); + printf("ReparseTag = 0x%04X; // %s\n", (unsigned)(dwTag), pType); + ) + XDEBUG_PRINTF(("ReparseDataLength = 0x%04X\n", (unsigned)(pIoctlBuf->ReparseDataLength))); + + /* Process the supported tag types */ + switch (dwTag) { + case IO_REPARSE_TAG_SYMLINK: + pSymlinkBuf = (PSYMLINK_READ_BUFFER)iobuf; + XDEBUG_PRINTF(("SubstituteNameOffset = 0x%04X\n", (unsigned)(pSymlinkBuf->SubstituteNameOffset))); + XDEBUG_PRINTF(("SubstituteNameLength = 0x%04X\n", (unsigned)(pSymlinkBuf->SubstituteNameLength))); + XDEBUG_PRINTF(("PrintNameOffset = 0x%04X\n", (unsigned)(pSymlinkBuf->PrintNameOffset))); + XDEBUG_PRINTF(("PrintNameLength = 0x%04X\n", (unsigned)(pSymlinkBuf->PrintNameLength))); + XDEBUG_PRINTF(("Flags = 0x%04X\n", (unsigned)(pSymlinkBuf->Flags))); + + pwStr = pSymlinkBuf->PathBuffer; + offset = pSymlinkBuf->SubstituteNameOffset / 2; /* Convert byte offset to wide characters offset */ + len = pSymlinkBuf->SubstituteNameLength / 2; /* Convert bytes to wide characters count */ + break; + + case IO_REPARSE_TAG_MOUNT_POINT: /* aka. junctions */ + pMountpointBuf = (PMOUNTPOINT_READ_BUFFER)iobuf; + XDEBUG_PRINTF(("SubstituteNameOffset = 0x%04X\n", (unsigned)(pMountpointBuf->SubstituteNameOffset))); + XDEBUG_PRINTF(("SubstituteNameLength = 0x%04X\n", (unsigned)(pMountpointBuf->SubstituteNameLength))); + XDEBUG_PRINTF(("PrintNameOffset = 0x%04X\n", (unsigned)(pMountpointBuf->PrintNameOffset))); + XDEBUG_PRINTF(("PrintNameLength = 0x%04X\n", (unsigned)(pMountpointBuf->PrintNameLength))); + + pwStr = pMountpointBuf->PathBuffer; + offset = pMountpointBuf->SubstituteNameOffset / 2; /* Convert byte offset to wide characters offset */ + len = pMountpointBuf->SubstituteNameLength / 2; /* Convert bytes to wide characters count */ + break; + + default: + errno = EINVAL; + RETURN_INT_COMMENT(0, ("Unsupported reparse point type\n")); + } + if (len) { + if (len >= bufsize) { + errno = ENAMETOOLONG; + RETURN_INT_COMMENT(0, ("The output buffer is too small. The link size is %d bytes.\n", len)); + } + CopyMemory(buf, pwStr+offset, len*sizeof(WCHAR)); + } + buf[len] = L'\0'; + + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + DEBUG_LEAVE(("return 0x%X; // \"%s\"\n", dwTag, pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + return dwTag; +} + +/* Posix routine readlink - Wide char version */ +ssize_t readlinkW(const WCHAR *path, WCHAR *buf, size_t bufsize) { + ssize_t nRead; + UINT drvType; + DWORD dwTag; + DEBUG_CODE( + char *pszUtf8; + ) + + DEBUG_WSTR2NEWUTF8(path, pszUtf8); + DEBUG_ENTER(("readlink(\"%s\", 0x%p, %d);\n", pszUtf8, buf, bufsize)); + DEBUG_FREEUTF8(pszUtf8); + + dwTag = ReadReparsePointW(path, buf, bufsize); + if (!dwTag) { + RETURN_INT_COMMENT(-1, ("ReadReparsePointW() failed.\n")); + } + + /* Special case for junctions to other local directories: Remove their '\??\' header. + // Note: Also seen once on a symlink. I don't know why in most cases symlinks don't have it. + // Note: These junctions begin with '\??\C:\' (or another drive letter). + // Other types of junctions/mount points do not continue with a drive letter. + // For example: '\??\Volume{5e58015c-ba64-4048-928d-06aa03c983f9}\' */ + nRead = lstrlenW(buf); +#define strncmpW(s1, s2, l) (CompareStringW(LOCALE_INVARIANT, 0, s1, l, s2, l)-2) + if ((nRead >= 7) && (!strncmpW(buf, L"\\??\\", 4))) { + if (!strncmpW(buf+5, L":\\", 2)) { + nRead -= 4; + CopyMemory(buf, buf+4, (nRead+1)*sizeof(WCHAR)); + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + XDEBUG_PRINTF(("buf = \"%s\"; // Removed '\\\\?\\': \n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + } else { /* Return an error for other types, as Posix SW cannot handle them successfully. */ + errno = EINVAL; + DEBUG_WSTR2NEWUTF8(buf+4, pszUtf8); + DEBUG_LEAVE(("return -1; // Unsupported mount point type: %s\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + return -1; + } + } + + /* Fix junctions targets */ + /* Windows resolves junctions on the server side, + but symlinks and symlinkds on the client side. */ + if (dwTag == IO_REPARSE_TAG_MOUNT_POINT) { + char szRootDir[4] = "C:\\"; + WCHAR wszAbsPath[PATH_MAX]; + WCHAR wszAbsPath2[PATH_MAX]; + WCHAR *p1; + WCHAR *p2; + WCHAR *pc1 = L"A"; + WCHAR *pc2 = L"a"; + + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + XDEBUG_PRINTF(("rawJunctionTarget = \"%s\"\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + + GetFullPathNameW(path, PATH_MAX, wszAbsPath, NULL); /* Get the drive letter in the full path */ + szRootDir[0] = (char)(wszAbsPath[0]); /* Copy the drive letter */ + drvType = GetDriveType(szRootDir); + XDEBUG_PRINTF(("GetDriveType(\"%s\") = %d // %s drive\n", szRootDir, drvType, (drvType == DRIVE_REMOTE) ? "Network" : "Local")); + + /* 1) On network drives, the target should reference the network drive itself, + not a local drive on the remote machine */ + if (drvType == DRIVE_REMOTE) { + /* Then check if the junction target is relative to the same network drive. (Not always true!) */ + int iTargetFound = FALSE; + if (buf[0] && (buf[1] == L':')) { + WCHAR wszLocalName[] = L"X:"; + WCHAR wszRemoteName[PATH_MAX]; + DWORD dwErr; + DWORD dwLength = PATH_MAX; + wszLocalName[0] = wszAbsPath[0]; + dwErr = WNetGetConnectionW(wszLocalName, wszRemoteName, &dwLength); + if (dwErr == NO_ERROR) { + WCHAR *pwsz; + DEBUG_WSTR2NEWUTF8(wszRemoteName, pszUtf8); + XDEBUG_PRINTF(("net use %c: %s\n", (char)(wszLocalName[0]), pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + if ((wszRemoteName[0] == L'\\') && (wszRemoteName[1] == L'\\')) { + pwsz = wcschr(wszRemoteName+2, L'\\'); + if (pwsz) { + if ((pwsz[2] == L'$') && !pwsz[3]) { /* This is the root of a shared drive. Ex: \\server\D$ -> D: */ + char c1, c2; + XDEBUG_PRINTF(("// Checking if it's the root of an X$ shared drive\n")); + c1 = (char)toupper((char)pwsz[1]); /* The server-side drive letter of the network share */ + c2 = (char)toupper((char)buf[0]); /* The server-side drive letter of the junction target */ + if (c1 == c2) { /* OK, the target is in the same share drive */ + buf[0] = wszLocalName[0]; /* Make the target accessible locally */ + iTargetFound = TRUE; + XDEBUG_PRINTF(("// Confirmed it's the root of the shared drive\n")); + } /* Else the target is not accessible locally via its target name */ + } else { /* Heuristic: Assume the share name is an alias to the root on the network drive. Ex: \\server\DROOT -> D:\ */ + DWORD dwAttr; + XDEBUG_PRINTF(("// Checking if it's an alias of the root of the shared drive\n")); + buf[0] = wszAbsPath[0]; + dwAttr = GetFileAttributesW(buf); + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + XDEBUG_PRINTF(("GetFileAttributes(\"%s\") = 0x%lX\n", pszUtf8, dwAttr)); + DEBUG_FREEUTF8(pszUtf8); + if (dwAttr != INVALID_FILE_ATTRIBUTES) { + iTargetFound = TRUE; + XDEBUG_PRINTF(("// Confirmed it's an alias of the root of the shared drive\n")); + } else { /* Heuristic: Assume the share name is a subdirectory name on the network drive. Ex: \\server\Public -> C:\Public */ + WCHAR *pwsz2; + XDEBUG_PRINTF(("// Checking if it's first level shared directory\n")); + pwsz2 = wcschr(buf+3, L'\\'); + if (pwsz2) { + CopyMemory(buf+2, pwsz2, (lstrlenW(pwsz2)+1)*sizeof(WCHAR)); + dwAttr = GetFileAttributesW(buf); + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + XDEBUG_PRINTF(("GetFileAttributes(\"%s\") = 0x%lX\n", pszUtf8, dwAttr)); + DEBUG_FREEUTF8(pszUtf8); + if (dwAttr != INVALID_FILE_ATTRIBUTES) { + iTargetFound = TRUE; + XDEBUG_PRINTF(("// Confirmed it's a first level shared directory\n")); + } + } + } + } + /* To do: + The above code works for network drives shared at the root level and one level below. + Ex: N: is \\server\C$ + junction target C:\Public\Temp\target.txt on N: + Resolves to N:\Public\Temp\target.txt + Ex: If N: is \\server\Public, which is shared directory C:\Public, + junction target C:\Public\Temp\target.txt on N: + Should resolve to N:\Temp\target.txt + Actually this could be extended by checking every possible parent path, + to support cases where the junction is on a shared level2 or below subdirectory. + Note that the share name is not always the same as the subdirectory + name, nor is it even in the server's root. + */ + } + } + } + } + if (!iTargetFound) { +#if 0 /* Initial implementation, which would have cause problems */ + lstrcpynW(buf, path, (int)bufsize); /* Report the target as identical to the source, to allow resolving it on the server side */ + buf[bufsize-1] = L'\0'; + nRead = lstrlenW(path); + RETURN_INT_COMMENT((int)nRead, ("Cannot get to the real target, which is on another server drive.\n")); +#else + errno = EINVAL; + RETURN_INT_COMMENT(-1, ("Inaccessible junction target, on another server drive.\n")); +#endif + } + } + + /* 2) Convert absolute junction targets to relative links, if possible. + This is useful because junctions are often used as substitutes + for symlinkds. But Windows always records absolute target paths, + even when relative paths were used for creating them. */ + GetFullPathNameW(buf, PATH_MAX, wszAbsPath2, NULL); + DEBUG_WSTR2NEWUTF8(wszAbsPath, pszUtf8); + XDEBUG_PRINTF(("szAbsPath = \"%s\"\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + DEBUG_WSTR2NEWUTF8(wszAbsPath2, pszUtf8); + XDEBUG_PRINTF(("szAbsPath2 = \"%s\"\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + /* Find the first (case insensitive) difference */ + for (p1=wszAbsPath, p2=wszAbsPath2; (*pc1 = *p1) && (*pc2 = *p2); p1++, p2++) { + CharLowerW(pc1); + CharLowerW(pc2); + if (*pc1 != *pc2) break; + } + if (p1 != wszAbsPath) { /* Both are on the same drive. Can be made relative. */ + WCHAR *pc; + /* Backtrack to the last \ */ + for ( ; *(p1-1) != L'\\'; p1--, p2--) ; + DEBUG_WSTR2NEWUTF8(p1, pszUtf8); + XDEBUG_PRINTF(("szRelPath1 = \"%s\"\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + DEBUG_WSTR2NEWUTF8(p2, pszUtf8); + XDEBUG_PRINTF(("szRelPath2 = \"%s\"\n", pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + buf[0] = '\0'; + /* Count the # of parent directories that remain in path 1 */ + for (pc=p1; *pc; pc++) if (*pc == L'\\') lstrcatW(buf, L"..\\"); + /* Append what remains in path 2 */ + lstrcatW(buf, p2); + /* That's the relative link */ + nRead = lstrlenW(buf); + } /* Else the drives differ. Paths cannot be relative. Don't change buf. */ + } + + DEBUG_WSTR2NEWUTF8(buf, pszUtf8); + DEBUG_LEAVE(("return %d; // \"%s\"\n", (int)nRead, pszUtf8)); + DEBUG_FREEUTF8(pszUtf8); + return (int)nRead; +} + +#pragma warning(default:4706) + +/* Posix routine readlink - MultiByte char version */ +ssize_t readlinkM(const char *path, char *buf, size_t bufsize, UINT cp) { + WCHAR wszPath[PATH_MAX]; + WCHAR wszTarget[PATH_MAX]; + int n; + ssize_t nResult; + char *pszDefaultChar; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("readlinkM(\"%s\", ...); // Conversion to Unicode failed. errno=%d - %s\n", path, errno, strerror(errno))); + return -1; + } + + nResult = readlinkW(wszPath, wszTarget, PATH_MAX); + if (nResult <= 0) return nResult; + + pszDefaultChar = (cp == CP_UTF8) ? NULL : "?"; + n = WideCharToMultiByte(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + wszTarget, /* lpWideCharStr, */ + (int)nResult + 1, /* cchWideChar, */ + buf, /* lpMultiByteStr, */ + (int)bufsize, /* cbMultiByte, */ + pszDefaultChar, /* lpDefaultChar, */ + NULL /* lpUsedDefaultChar */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_PRINTF(("readlinkM(\"%s\", ...); // Conversion back from Unicode failed. errno=%d - %s\n", path, errno, strerror(errno))); + return -1; + } + + return n; +} + +#endif + + diff --git a/deps/MsvcLibX/src/realpath.c b/deps/MsvcLibX/src/realpath.c new file mode 100644 index 0000000000000000000000000000000000000000..8d60c9f554367ad79aa7d778471d06c030378197 --- /dev/null +++ b/deps/MsvcLibX/src/realpath.c @@ -0,0 +1,598 @@ +/*****************************************************************************\ +* * +* Filename realpath.c * +* * +* Description Resolve links and remove . and .. parts in pathnames * +* * +* Notes TO DO: Make Wide & MultiByte versions for Windows * +* * +* TO DO: Microsoft provides a convenient routine, for which * +* we could provide a MultiByte version: (in MSVC's stdlib.h)* +* char *_fullpath(char *absPath, const char *relPath, size_t maxLength); * +* * +* History * +* 2014-02-10 JFL Created this module with routine ResolveLinks() for Win32.* +* 2014-02-19 JFL Added OS-independant CompactPath() subroutine. * +* 2014-02-20 JFL Implemented realpath() for both DOS and Windows. * +* 2014-03-06 JFL Check for buffer overflows, and return ENAMETOOLONG. * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* 2016-08-25 JFL Added routine ResolveLinksA(). * +* 2016-09-12 JFL Moved GetFileAttributesU() to its own module. * +* Bug fix: Add the drive letter if it's not specified. * +* Bug fix: Detect and report output buffer overflows. * +* Convert short WIN32 paths to long paths. * +* 2016-09-13 JFL Resize output buffers, to avoid wasting lots of memory. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +#include +#include +#include +#include +#include /* For _getdcwd() */ +#include /* For toupper() */ +#include "debugm.h" + +#define TRUE 1 +#define FALSE 0 + +/*---------------------------------------------------------------------------*\ +* * +| Function CompactPath | +| | +| Description Remove all ., .., and extra / or \ separators in a path | +| | +| Parameters const char *path Pathname to cleanup | +| char *buf Output buffer | +| size_t bufsize Size of the output buffer | +| | +| Notes Allows having path = outbuf, ie. in-place compacting. | +| Supports both relative and absolute paths. | +| | +| Returns 0 = success, or -1 = error, with errno set | +| | +| History | +| 2014-02-19 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +int CompactPath(const char *path, char *outbuf, size_t bufsize) { + const char *pcIn; + char *pcOut; + int i, j, inSize, outSize; + char c = '\0'; + char lastc = '\0'; +#define MAX_SUBDIRS (PATH_MAX / 2) /* Worst case is: \1\1\1\1\1\1... */ + const char *pParts[MAX_SUBDIRS]; + int lParts[MAX_SUBDIRS]; + int lPart = 0; + int nParts = 0; + int isAbsolute = FALSE; + int nDotDotParts = 0; + + pcIn = path; + inSize = (int)strlen(path) + 1; + pcOut = outbuf; + outSize = (int)bufsize; + + if (*pcIn && (pcIn[1] == ':')) { /* There's a drive letter */ + *(pcOut++) = *(pcIn++); /* Copy it */ + *(pcOut++) = *(pcIn++); + inSize -= 2; + outSize -= 2; + } + + /* Scan the input pathname, recording pointers to every part of the pathname */ + for (i=0; i outSize) goto not_compact_enough; + if (pcOut != pParts[0]) strncpy(pcOut, pParts[0], lParts[0]); + pcOut += lParts[0]; + outSize -= lParts[0]; + } else { + if (pcOut == outbuf) { + if (!outSize) goto not_compact_enough; + *(pcOut++) = '.'; /* Special case for "subdir\..", which is "." and not "" */ + outSize -= 1; + } + } + for (i=1; i outSize) goto not_compact_enough; + if (pcOut != pParts[i]) strncpy(pcOut, pParts[i], lParts[i]); + pcOut += lParts[i]; + outSize -= lParts[i]; + } + *pcOut = '\0'; + + return (int)(pcOut - outbuf); +} + + +#ifdef _MSDOS + +/* Standard C library routine realpath() */ +/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */ +char *realpath(const char *path, char *outbuf) { + char *pOutbuf = outbuf; + int iErr; + const char *pc; + + if (!pOutbuf) pOutbuf = malloc(PATH_MAX); + if (!pOutbuf) { + errno = ENOMEM; + return NULL; + } + + /* Convert relative paths to absolute paths */ + pc = path; + if (pc[0] && (pc[1] == ':')) pc += 2; /* Skip the drive letter, if any */ + if ((*pc != '/') && (*pc != '\\')) { /* This is a relative path */ + int iDrive = 0; + if (pc != path) { /* A drive was specified */ + iDrive = _toupper(path[0]) - '@'; /* A=1, B=2, ... */ + } + _getdcwd(iDrive, pOutbuf, PATH_MAX); + if ((strlen(pOutbuf) + strlen(pc) + 2) > PATH_MAX) { +realpath_failed: + errno = ENAMETOOLONG; + if (!outbuf) free(pOutbuf); + return NULL; + } + strcat(pOutbuf, "\\"); + strcat(pOutbuf, pc); + path = pOutbuf; + } else if (pc == path) { /* This is an absolute path without a drive letter */ + pOutbuf[0] = (char)(_getdrive() + 0x40); + pOutbuf[1] = ':'; + if ((strlen(path) + 3) > PATH_MAX) goto realpath_failed; + strcpy(pOutbuf+2, path); + path = pOutbuf; + } + + /* TO DO: Resolve substituted drives */ + + /* TO DO: Convert short paths to long paths, and correct the name case */ + + /* Remove useless parts in the absolute path */ + iErr = CompactPath(path, pOutbuf, PATH_MAX); + if (iErr == -1) { /* CompactPath() sets errno */ + if (!outbuf) free(pOutbuf); + return NULL; + } + + if (!outbuf) pOutbuf = realloc(pOutbuf, strlen(pOutbuf) + 1); + return pOutbuf; +} + +#endif + + +#ifdef _WIN32 + +#include /* Also includes MsvcLibX' WIN32 UTF-8 extensions */ + +/*---------------------------------------------------------------------------*\ +* * +| Function ResolveLinks | +| | +| Description Resolve all link names within a pathname | +| | +| Parameters const char *path Pathname to resolve | +| char *buf Output buffer | +| size_t bufsize Size of the output buffer | +| | +| Notes Description of the official path resolution process: | +| http://man7.org/linux/man-pages/man7/path_resolution.7.html +| | +| This function always returns a valid string in the output | +| buffer, even when it fails. This allows displaying a clue | +| about at which stage of the resolution things went wrong. | +| | +| Returns 0 = success, or -1 = error, with errno set | +| | +| History | +| 2014-02-07 JFL Created this routine | +| 2014-07-02 JFL Added support for pathnames >= 260 characters. | +* * +\*---------------------------------------------------------------------------*/ + +/* Linked list of previous pathnames */ +typedef struct _NAMELIST { + struct _NAMELIST *prev; + char *path; +} NAMELIST; + +/* Get the canonic name of a file, after resolving all links in its pathname */ +int ResolveLinksU1(const char *path, char *buf, size_t bufsize, NAMELIST *prev, int iDepth) { + char target[UTF8_PATH_MAX]; + int i; + int iErr = 0; + DWORD dwAttr; + char c = '\0'; + int iPath = 0; + int bFirst = 1; + ssize_t nRead; + int iBuf = 0; + NAMELIST list; + NAMELIST *pList; + + DEBUG_ENTER(("ResolveLinks1(\"%s\", 0x%p, %ld, 0x%p, %d);\n", path, buf, bufsize, prev, iDepth)); + + while (path[iPath]) { + /* int iPath0 = iPath; */ + /* int iBuf0 = iBuf; */ + int iBuf1; + /* Append the first name section to the output buffer */ + if (bFirst) { + bFirst = 0; + /* Special case of absolute pathnames */ + if (path[0] == '\\') { + if ((iBuf+1U) >= bufsize) { +resolves_too_long: + errno = ENAMETOOLONG; + RETURN_INT_COMMENT(-1, ("Name too long\n")); + } + c = buf[iBuf++] = path[iPath++]; /* Copy the root \ . */ + /* DEBUG_PRINTF(("buf[%d] = %c\n", iBuf-1, c)); */ + } else if (path[0] && (path[1] == ':')) { + if ((iBuf+1U) >= bufsize) goto resolves_too_long; + c = buf[iBuf++] = path[iPath++]; /* Copy the drive letter */ + /* DEBUG_PRINTF(("buf[%d] = %c\n", iBuf-1, c)); */ + if ((iBuf+1U) >= bufsize) goto resolves_too_long; + c = buf[iBuf++] = path[iPath++]; /* and the : */ + /* DEBUG_PRINTF(("buf[%d] = %c\n", iBuf-1, c)); */ + if (path[iPath] == '\\') { + if ((iBuf+1U) >= bufsize) goto resolves_too_long; + c = buf[iBuf++] = path[iPath++]; + /* DEBUG_PRINTF(("buf[%d] = %c\n", iBuf-1, c)); */ + } + } /* Else it's a relative pathname, handled in the common code below */ + } else { /* It's a continuation section in the path */ + if ((iBuf+1U) >= bufsize) goto resolves_too_long; + buf[iBuf++] = '\\'; + } + iBuf1 = iBuf; /* Index of the beginning of the node name we're about to add */ + for (i=0; (size_t)(iBuf+i) < (bufsize-1) ;i++) { + c = path[iPath+i]; + if (!c) break; + /* if (c == '/') break; */ + if (c == '\\') break; + /* DEBUG_PRINTF(("buf[%d] = %c\n", iBuf+i, c)); */ + buf[iBuf+i] = c; + } + iBuf += i; + buf[iBuf] = '\0'; + while (c && (/* (c == '/') || */ (c == '\\'))) c=path[iPath + ++i]; /* Skip extra /, if any */ + iPath += i; + /* DEBUG_PRINTF(("// Removed %d characters from path\n", iPath - iPath0)); */ + /* Get the file type */ + dwAttr = GetFileAttributesU(buf); + DEBUG_PRINTF(("// \"%s\" is %s\n", buf, (dwAttr == INVALID_FILE_ATTRIBUTES)?"not found":( + (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT)?"a reparse point":( + (dwAttr & FILE_ATTRIBUTE_DIRECTORY)?"a directory":"a file")))); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + if (path[iPath]) { /* Append the remainder of the input path, even though we know it's invalid */ + if ((iBuf+1U+lstrlen(path+iPath)) < bufsize) { + buf[iBuf++] = '\\'; + lstrcpy(buf+iBuf, path+iPath); + } + } + RETURN_INT_COMMENT(-1, ("No such file: \"%s\"\n", buf)); + } + if (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT) { + nRead = readlinkU(buf, target, sizeof(target)); + if (nRead == -1) { + if (errno == EINVAL) { /* This is a reparse point, but not a symlink or a junction */ + goto file_or_directory; + } + /* Anything else is a real error, and resolution cannot be done. */ + if (path[iPath]) { /* Append the remainder of the input path, even though we know it's invalid */ + if ((iBuf+1U+lstrlen(path+iPath)) < bufsize) { + buf[iBuf++] = '\\'; + lstrcpy(buf+iBuf, path+iPath); + } + } + RETURN_INT_COMMENT(-1, ("Dangling link: \"%s\"\n", buf)); + } + if ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && !lstrcmp(buf, target)) { + /* This is probably a junction pointing to an otherwise inaccessible area. + (See readlink() header in readlink.c for details about this case.) + Handle this junction like if it were a real directory, instead of a symlink. */ + goto file_or_directory; + } + if ( ((target[0] == '\\') /* || (target[0] == '/') */ ) + || (target[1] == ':')) { /* This is an absolute pathname */ + DEBUG_PRINTF(("// Absolute link to \"%s\"\n", target)); + iBuf = (int)lstrlen(target); /* Anticipate the new position after copying */ + if ((size_t)iBuf >= bufsize) goto resolves_too_long; + lstrcpy(buf, target); + } else { /* This is a relative pathname */ + DEBUG_PRINTF(("// Relative link to \"%s\"\n", target)); + /* So it'll replace the tail name in the output path */ + iBuf = iBuf1; /* The index right after the last path separator */ + DEBUG_PRINTF(("AppendPath(\"%.*s\", \"%s\"); // Target tail\n", iBuf, buf, target)); + if (((size_t)iBuf+lstrlen(target)) >= bufsize) goto resolves_too_long; + lstrcpy(buf+iBuf, target); + iBuf = CompactPath(buf, buf, bufsize); + } + /* Append the remainder of the input path, if any */ + DEBUG_PRINTF(("AppendPath(\"%s\", \"%s\"); // Path tail\n", buf, path+iPath)); + if (path[iPath]) { + if (iBuf && (buf[iBuf-1] != '\\')) { + if ((iBuf+1U) >= bufsize) goto resolves_too_long; + buf[iBuf++] = '\\'; + } + if (((size_t)iBuf+lstrlen(path+iPath)) >= bufsize) goto resolves_too_long; + lstrcpy(buf+iBuf, path+iPath); + iBuf = CompactPath(buf, buf, bufsize); + } + /* Check for max depth */ + if (iDepth == SYMLOOP_MAX) { + errno = ELOOP; + RETURN_INT_COMMENT(-1, ("Max symlink depth reached: \"%s\"\n", buf)); + } + /* Check for loops */ + for (pList = prev ; pList; pList = pList->prev) { + if (!lstrcmpi(buf, pList->path)) { + errno = ELOOP; + RETURN_INT_COMMENT(-1, ("Loop found: \"%s\"\n", buf)); + } + } + /* OK, no loop, so repeat the process for that new path */ + lstrcpy(target, buf); /* Keep that as a reference in the linked list, in case there are further links */ + list.prev = prev; + list.path = target; + iErr = ResolveLinksU1(target, buf, bufsize, &list, iDepth+1); + RETURN_INT_COMMENT(iErr, ("\"%s\"\n", buf)); + } else { /* It's a normal file or directory */ +file_or_directory: + if ((path[iPath]) && !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) { + errno = ENOTDIR; + if ((iBuf+1U+lstrlen(path+iPath)) < bufsize) { + buf[iBuf++] = '\\'; + lstrcpy(buf+iBuf, path+iPath); + } + RETURN_INT_COMMENT(-1, ("File where dir expected: \"%s\"\n", buf)); + } + } + } + + RETURN_INT_COMMENT(0, ("Success: \"%s\"\n", buf)); +} + +int ResolveLinksU(const char *path, char *buf, size_t bufsize) { + char path1[UTF8_PATH_MAX]; + int nSize; + NAMELIST root; + int iErr; + + DEBUG_ENTER(("ResolveLinks(\"%s\", 0x%p, %ld);\n", path, buf, bufsize)); + + buf[0] = '\0'; /* Always output a valid string */ + + if (!*path) { /* Spec says an empty pathname is invalid */ + errno = ENOENT; + RETURN_INT_COMMENT(-1, ("Empty pathname\n")); + } + + /* Normalize the input path, using a single \ as path separator */ + nSize = CompactPath(path, path1, sizeof(path1)); + if (nSize == -1) { /* CompactPath() already sets errno = ENAMETOOLONG */ + RETURN_INT_COMMENT(-1, ("Path too long\n")); + } + if (path1[nSize-1] == '\\') { /* Spec says resolution must implicitly add a trailing dot, */ + if (nSize == sizeof(path1)) { /* to ensure that the last component is a directory. */ + errno = ENAMETOOLONG; + RETURN_INT_COMMENT(-1, ("Path too long after adding .\n")); + } + path1[nSize++] = '.'; /* So add it explicitely */ + path1[nSize] = '\0'; + } + root.path = path1; + root.prev = NULL; + iErr = ResolveLinksU1(path1, buf, bufsize, &root, 0); + nSize = lstrlen(buf); + /* Remove the final dot added above, if needed. */ + if ((nSize >= 2) && (buf[nSize-2] == '\\') && (buf[nSize-1] == '.')) buf[--nSize] = '\0'; + RETURN_INT_COMMENT(iErr, ("\"%s\"\n", buf)); +} + +/* ANSI version of the same, built upon the UTF-8 version */ +int ResolveLinksA(const char *path, char *buf, size_t bufsize) { + char pathU[UTF8_PATH_MAX]; + char pathU2[UTF8_PATH_MAX]; + WCHAR wszPath[PATH_MAX]; + int n; + int iErr; + + /* Convert the pathname to a unicode string */ + n = MultiByteToWideChar(CP_ACP, 0, path, (int)strlen(path) + 1, wszPath, PATH_MAX); + /* Convert it back to UTF-8 characters */ + if (n) n = WideCharToMultiByte(CP_UTF8, 0, wszPath, n, pathU, UTF8_PATH_MAX, NULL, NULL); + /* Check (unlikely) conversion errors */ + if (!n) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + + /* Resolve the links */ + iErr = ResolveLinksU(pathU, pathU2, UTF8_PATH_MAX); + + /* Convert the result back to ANSI */ + if (!iErr) { + n = MultiByteToWideChar(CP_UTF8, 0, pathU2, (int)strlen(pathU2) + 1, wszPath, PATH_MAX); + if (n) n = WideCharToMultiByte(CP_ACP, 0, wszPath, n, buf, (int)bufsize, NULL, NULL); + if (!n) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + } + + return iErr; +} + +/* Normally defined in stdlib.h. Output buf must contain PATH_MAX bytes */ +char *realpathU(const char *path, char *outbuf) { + char *pOutbuf = outbuf; + char *pPath1 = NULL; + char *pPath2 = NULL; + int iErr; + const char *pc; + size_t nSize; + DEBUG_CODE( + char *pszCause = "Out of memory"; + ) + int n; + + DEBUG_ENTER(("realpath(\"%s\", 0x%p);\n", path, outbuf)); + + if (!pOutbuf) pOutbuf = malloc(UTF8_PATH_MAX); + if (!pOutbuf) { +realpathU_failed: + if (!outbuf) free(pOutbuf); + free(pPath1); + free(pPath2); + errno = ENOMEM; + RETURN_CONST_COMMENT(NULL, ("%s\n", pszCause)); + } + + pPath1 = malloc(UTF8_PATH_MAX); + if (!pPath1) goto realpathU_failed; + + pPath2 = malloc(UTF8_PATH_MAX); + if (!pPath2) goto realpathU_failed; + + /* Convert relative paths to absolute paths */ + pc = path; + if (pc[0] && (pc[1] == ':')) pc += 2; /* Skip the drive letter, if any */ + if ((*pc != '/') && (*pc != '\\')) { /* This is a relative path */ + int iDrive = 0; + if (pc != path) { /* A drive was specified */ + iDrive = toupper(path[0]) - '@'; /* A=1, B=2, ... */ + } + _getdcwdU(iDrive, pPath1, UTF8_PATH_MAX); + nSize = UTF8_PATH_MAX - lstrlen(pPath1); + if ((lstrlen(pc) + 2U) > nSize) { + errno = ENAMETOOLONG; + DEBUG_CODE(pszCause = "Path too long after concatenating current dir"); + goto realpathU_failed; + } + strcat(pPath1, "\\"); + strcat(pPath1, pc); + path = pPath1; + } else if (pc == path) { /* This is an absolute path without a drive letter */ + pPath1[0] = (char)(_getdrive() + 0x40); + pPath1[1] = ':'; + if (strlen(path) > (UTF8_PATH_MAX-3)) { + errno = ENAMETOOLONG; + DEBUG_CODE(pszCause = "Path too long after adding drive"); + goto realpathU_failed; + } + strcpy(pPath1+2, path); + path = pPath1; + } + + /* Resolve links in the absolute path */ + iErr = ResolveLinksU(path, pPath2, UTF8_PATH_MAX); + if (iErr == -1) { + DEBUG_CODE(pszCause = "Resolution failed"); + goto realpathU_failed; + } + + /* Change short names to long names, and correct the name case */ + n = GetLongPathNameU(pPath2, pOutbuf, UTF8_PATH_MAX); /* This will NOT correct long names case */ + if (!n) { + DEBUG_CODE(pszCause = "Can't get long pathnames";) + goto realpathU_failed; + } + + DEBUG_LEAVE(("return 0x%p; // \"%s\"\n", pOutbuf, pOutbuf)); + if (!outbuf) pOutbuf = realloc(pOutbuf, strlen(pOutbuf) + 1); + free(pPath1); + free(pPath2); + return pOutbuf; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/spawn.c b/deps/MsvcLibX/src/spawn.c new file mode 100644 index 0000000000000000000000000000000000000000..ab70172b3e0e3212c990c013bfee6e94a3ac3125 --- /dev/null +++ b/deps/MsvcLibX/src/spawn.c @@ -0,0 +1,117 @@ +/*****************************************************************************\ +* * +* Filename spawn.c * +* * +* Description: WIN32 UTF-8 version of spawn * +* * +* Notes: * +* * +* History: * +* 2014-03-27 JFL Created this module. * +* 2014-07-03 JFL Added support for pathnames >= 260 characters. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +/* Microsoft C libraries include files */ +#include +/* MsvcLibX library extensions */ +#include "debugm.h" +#include "msvclibx.h" + +#ifdef _WIN32 + +#include +#include + +/*---------------------------------------------------------------------------*\ +* * +| Function _spawnvpU | +| | +| Description UTF-8 version of Microsoft's _spawnvp | +| | +| Parameters: int iMode Spawning mode. P_WAIT or P_NOWAIT | +| char *pszCommand Program to start | +| char **argv List of arguments, terminated by NULL | +| | +| Returns: The exit code (if P_WAIT) or the process ID (if P_NOWAIT) | +| | +| Notes | +| | +| History | +| 2014-03-04 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +intptr_t _spawnvpU(int iMode, const char *pszCommand, char *const *argv) { + WCHAR wszCommand[PATH_MAX]; + WCHAR **wszArgv; + int n; + int nArgs; + int iArg; + intptr_t iRet; + + DEBUG_CODE({ + int i; + DEBUG_PRINTF(("_spawnvpU(%d, \"%s\", {", iMode, pszCommand)); + if (DEBUG_IS_ON()) { + for (i=0; argv[i]; i++) { + if (i) printf(", "); + printf("\"%s\"", argv[i]); + } + printf("});\n"); + } + }) + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + pszCommand, /* lpMultiByteStr, */ + wszCommand, /* lpWideCharStr, */ + COUNTOF(wszCommand) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + + for (nArgs=0; argv[nArgs]; nArgs++) ; /* Count the number of arguments */ + wszArgv = (WCHAR **)malloc((nArgs+1) * sizeof(WCHAR *)); + if (!wszArgv) return -1; /* errno already set by malloc */ + + for (iArg=0; argv[iArg]; iArg++) { /* Convert every argument */ + int iArgBufSize = lstrlen(argv[iArg]) + 1; + wszArgv[iArg] = malloc(sizeof(WCHAR)*iArgBufSize); + if (!wszArgv[iArg]) { + while (iArg) free(wszArgv[--iArg]); /* Free the partial arg list */ + free(wszArgv); + return -1; /* errno already set by malloc */ + } + /* Convert the argument to a unicode string. This is not a pathname, so just do a plain conversion */ + n = MultiByteToWideChar(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + 0, /* dwFlags, */ + argv[iArg], /* lpMultiByteStr, */ + iArgBufSize, /* cbMultiByte, */ + wszArgv[iArg], /* lpWideCharStr, */ + iArgBufSize /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + while (iArg >= 0) free(wszArgv[iArg--]); /* Free the partial arg list */ + free(wszArgv); + return -1; + } + } + wszArgv[nArgs] = NULL; + + iRet = _wspawnvp(iMode, wszCommand, wszArgv); + + while (nArgs) free(wszArgv[--nArgs]); /* Free the full arg list */ + free(wszArgv); + return iRet; +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/src2objs.bat b/deps/MsvcLibX/src/src2objs.bat new file mode 100644 index 0000000000000000000000000000000000000000..b840e308c4f6a6c824bda023eb3907665f95f0d2 --- /dev/null +++ b/deps/MsvcLibX/src/src2objs.bat @@ -0,0 +1,125 @@ +@echo off +:****************************************************************************** +:* * +:* Filename: src2objs.bat * +:* * +:* Description: Generate object files names from source files names * +:* * +:* Notes: * +:* * +:* History: * +:* 2010-04-07 JFL Created this batch. * +:* * +:# © Copyright 2016 Hewlett Packard Enterprise Development LP * +:# Licensed under the Apache 2.0 license www.apache.org/licenses/LICENSE-2.0 * +:****************************************************************************** + +setlocal 2>NUL +set ARG0=%0 + +:# Mechanism for calling subroutines. Done by {call %0 _call_ label [arguments]}. +if .%1.==._call_. shift /2 & goto %2 +set CALL=call %0 _call_ +set RETURN=goto end +:# Silent return. Used for routines silently called via call :label. +set _RETURN=goto _end +set PUTVARS=call :putvars + +:# Set global defaults +setlocal +set OUTFILE=obj\objects.mak +set OUTPATH=obj +set NO_EXEC=0 +goto get_args + +:help +echo Generate object files names from source files names +echo. +echo Usage: %ARG0% [options] source ... +echo. +echo Options: +echo -?^|-h This help +echo -o {pathname} Output file pathname. Default: %OUTFILE% +echo -X Display object files names, but do not create the output file +goto end + +:get_args +if .%1.==.. goto help +if .%1.==.-?. goto help +if .%1.==./?. goto help +if %1==-o shift & goto set_out +if %1==-X shift & goto no_exec +goto go + +:set_out +set OUTFILE=%1 +:# Split the path. Uses a fake drive @ to prevent prepending the current path on an existing drive. +for %%F in (@:"%OUTFILE%") do ( + set "OUTPATH=%%~dpF" +) +:# Remove the head "@:\ and tail \ to the path +set "OUTPATH=%OUTPATH:~4,-1%" +shift +goto get_args + +:no_exec +set NO_EXEC=1 +goto get_args + +:# Check prerequisites +:check +verify other 2>nul +setlocal enableextensions +if errorlevel 1 ( + echo>&2 Error: Unable to enable command extensions. + exit /b 1 +) +set VAR=before +if "%VAR%" == "before" ( + set VAR=after + if not "!VAR!" == "after" ( + echo>&2 Error: Delayed environment variable expansion must be enabled. + echo>&2 Please restart your cmd.exe shell with the /V option, + echo>&2 or set HKLM\Software\Microsoft\Command Processor\DelayedExpansion=1 + exit /b 1 + ) +) +%_RETURN% + +:go +%CALL% check +if errorlevel 1 exit /b 1 +set OBJECTS= +:next +if .%1.==.. goto done +for %%s in (%1) do ( + set EXT=%%~xs + set OBJ= + if .!EXT!.==..c. set OBJ=obj + if .!EXT!.==..C. set OBJ=obj + if .!EXT!.==..cpp. set OBJ=obj + if .!EXT!.==..CPP. set OBJ=obj + if .!EXT!.==..asm. set OBJ=obj + if .!EXT!.==..ASM. set OBJ=obj + if .!EXT!.==..rc. set OBJ=res + if .!EXT!.==..RC. set OBJ=res + if .!OBJ!.==.. ( + echo>&2 Error: Unsupported source type: !EXT! + echo>&2 Please add a conversion rule in %ARG0% + ) else ( + if .!OBJECTS!.==.. ( + set OBJECTS=%OUTPATH%\%%~ns.!OBJ! + ) else ( + set OBJECTS=!OBJECTS! %OUTPATH%\%%~ns.!OBJ! + ) + ) +) +shift +goto next +:done +echo OBJECTS=%OBJECTS% +if %NO_EXEC%==0 echo>%OUTFILE% OBJECTS=%OBJECTS% + +:end +:_end + diff --git a/deps/MsvcLibX/src/strerror.c b/deps/MsvcLibX/src/strerror.c new file mode 100644 index 0000000000000000000000000000000000000000..2f8f3248290738c7c0819aa33308101e23209d48 --- /dev/null +++ b/deps/MsvcLibX/src/strerror.c @@ -0,0 +1,54 @@ +/*****************************************************************************\ +* * +* Filename strerror.c * +* * +* Description: WIN32 update of strerror * +* * +* Notes: MSVC defines error messages only up to errno 42 EILSEQ * +* * +* History: * +* 2014-03-06 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include +#include "msvclibx.h" + +#ifdef _WIN32 + +/*---------------------------------------------------------------------------*\ +* * +| Function strerror | +| | +| Description UTF-8 version of strerror | +| | +| Parameters int errnum Error number | +| | +| Returns Pointer to the corresponding error message. | +| | +| Notes | +| | +| History | +| 2014-03-06 JFL Created this routine. | +* * +\*---------------------------------------------------------------------------*/ + +#pragma warning(disable:4100) /* Ignore the "unreferenced formal parameter" warning */ + +char *strerror(int errnum) { + switch (errnum) { + case ELOOP: + return "Symbolic links loop found"; /* Workaround for the missing entry in MSVC list */ + default: + if (errnum > _sys_nerr) errnum = _sys_nerr; + return _sys_errlist[errnum]; + } +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/strndup.c b/deps/MsvcLibX/src/strndup.c new file mode 100644 index 0000000000000000000000000000000000000000..5f68b8e5fcbace69990d0e0dd1a20fe7ade46162 --- /dev/null +++ b/deps/MsvcLibX/src/strndup.c @@ -0,0 +1,34 @@ +/*****************************************************************************\ +* * +* Filename strndup.c * +* * +* Description: WIN32 port of standard C library's strndup() * +* * +* Notes: * +* * +* History: * +* 2014-02-13 JFL Created this module. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include + +/* Duplicate a string, up to at most size characters */ +char *strndup(const char *s, size_t size) { + size_t l; + char *s2; + l = strlen(s); + if (l > size) l=size; + s2 = malloc(l+1); + if (s2) { + strncpy(s2, s, l); + s2[l] = '\0'; + } + return s2; +} + diff --git a/deps/MsvcLibX/src/strptime.c b/deps/MsvcLibX/src/strptime.c new file mode 100644 index 0000000000000000000000000000000000000000..142a2408ddd94521dd33d23d24f20b9695be4fca --- /dev/null +++ b/deps/MsvcLibX/src/strptime.c @@ -0,0 +1,396 @@ +/*****************************************************************************\ +* * +* Filename strptime.c * +* * +* Description: WIN32 port of standard C library's strptime() * +* * +* Notes: * +* * +* History: * +* 2014-02-17 JFL Created this module. * +* * +\*****************************************************************************/ + +#include +#include +#include + +/* + * We do not implement alternate representations. However, we always + * check whether a given modifier is allowed for a certain conversion. + */ +#define ALT_E 0x01 +#define ALT_O 0x02 +/* #define LEGAL_ALT(x) { if (alt_format & ~(x)) return (0); } */ +#define LEGAL_ALT(x) { ; } +#define TM_YEAR_BASE (1970) + +static int conv_num(const char **, int *, int, int); +static int strncasecmp(char *s1, char *s2, size_t n); + +static const char *day[7] = { + "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", + "Friday", "Saturday" +}; +static const char *abday[7] = { + "Sun","Mon","Tue","Wed","Thu","Fri","Sat" +}; +static const char *mon[12] = { + "January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December" +}; +static const char *abmon[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; +static const char *am_pm[2] = { + "AM", "PM" +}; + + +#pragma warning(disable:4706) /* Ignore the "assignment within conditional expression" warning */ +char * strptime(const char *buf, const char *fmt, struct tm *tm) +{ + char c; + const char *bp; + size_t len = 0; + int alt_format, i, split_year = 0; + + bp = buf; + + while ((c = *fmt) != '\0') + { + /* Clear `alternate' modifier prior to new conversion. */ + alt_format = 0; + + /* Eat up white-space. */ + if (isspace(c)) + { + while (isspace(*bp)) + bp++; + + fmt++; + continue; + } + + if ((c = *fmt++) != '%') + goto literal; + + +again: switch (c = *fmt++) + { + case '%': /* "%%" is converted to "%". */ + literal: + if (c != *bp++) + return (0); + break; + + /* + * "Alternative" modifiers. Just set the appropriate flag + * and start over again. + */ + case 'E': /* "%E?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_E; + goto again; + + case 'O': /* "%O?" alternative conversion modifier. */ + LEGAL_ALT(0); + alt_format |= ALT_O; + goto again; + + /* + * "Complex" conversion rules, implemented through recursion. + */ + case 'c': /* Date and time, using the locale's format. */ + LEGAL_ALT(ALT_E); + if (!(bp = strptime(bp, "%x %X", tm))) + return (0); + break; + + case 'D': /* The date as "%m/%d/%y". */ + LEGAL_ALT(0); + if (!(bp = strptime(bp, "%m/%d/%y", tm))) + return (0); + break; + + case 'R': /* The time as "%H:%M". */ + LEGAL_ALT(0); + if (!(bp = strptime(bp, "%H:%M", tm))) + return (0); + break; + + case 'r': /* The time in 12-hour clock representation. */ + LEGAL_ALT(0); + if (!(bp = strptime(bp, "%I:%M:%S %p", tm))) + return (0); + break; + + case 'T': /* The time as "%H:%M:%S". */ + LEGAL_ALT(0); + if (!(bp = strptime(bp, "%H:%M:%S", tm))) + return (0); + break; + + case 'X': /* The time, using the locale's format. */ + LEGAL_ALT(ALT_E); + if (!(bp = strptime(bp, "%H:%M:%S", tm))) + return (0); + break; + + case 'x': /* The date, using the locale's format. */ + LEGAL_ALT(ALT_E); + if (!(bp = strptime(bp, "%m/%d/%y", tm))) + return (0); + break; + + /* + * "Elementary" conversion rules. + */ + case 'A': /* The day of week, using the locale's form. */ + case 'a': + LEGAL_ALT(0); + for (i = 0; i < 7; i++) + { + /* Full name. */ + len = strlen(day[i]); + if (strncasecmp((char *)(day[i]), (char *)bp, len) == 0) + break; + + /* Abbreviated name. */ + len = strlen(abday[i]); + if (strncasecmp((char *)(abday[i]), (char *)bp, len) == 0) + break; + } + + /* Nothing matched. */ + if (i == 7) + return (0); + + tm->tm_wday = i; + bp += len; + break; + + case 'B': /* The month, using the locale's form. */ + case 'b': + case 'h': + LEGAL_ALT(0); + for (i = 0; i < 12; i++) + { + /* Full name. */ + + len = strlen(mon[i]); + if (strncasecmp((char *)(mon[i]), (char *)bp, len) == 0) + break; + + /* Abbreviated name. */ + len = strlen(abmon[i]); + if (strncasecmp((char *)(abmon[i]),(char *) bp, len) == 0) + break; + } + + /* Nothing matched. */ + if (i == 12) + return (0); + + tm->tm_mon = i; + bp += len; + break; + + case 'C': /* The century number. */ + LEGAL_ALT(ALT_E); + if (!(conv_num(&bp, &i, 0, 99))) + return (0); + + if (split_year) + { + tm->tm_year = (tm->tm_year % 100) + (i * 100); + } else { + tm->tm_year = i * 100; + split_year = 1; + } + break; + + case 'd': /* The day of month. */ + case 'e': + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_mday, 1, 31))) + return (0); + break; + + case 'k': /* The hour (24-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'H': + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_hour, 0, 23))) + return (0); + break; + + case 'l': /* The hour (12-hour clock representation). */ + LEGAL_ALT(0); + /* FALLTHROUGH */ + case 'I': + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_hour, 1, 12))) + return (0); + if (tm->tm_hour == 12) + tm->tm_hour = 0; + break; + + case 'j': /* The day of year. */ + LEGAL_ALT(0); + if (!(conv_num(&bp, &i, 1, 366))) + return (0); + tm->tm_yday = i - 1; + break; + + case 'M': /* The minute. */ + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_min, 0, 59))) + return (0); + break; + + case 'm': /* The month. */ + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &i, 1, 12))) + return (0); + tm->tm_mon = i - 1; + break; +/* +// case 'p': /* The locale's equivalent of AM/PM. */ +/* LEGAL_ALT(0); +// /* AM? */ +/* if (strcasecmp(am_pm[0], bp) == 0) +// { +// if (tm->tm_hour > 11) +// return (0); +// +// bp += strlen(am_pm[0]); +// break; +// } +// /* PM? */ +/* else if (strcasecmp(am_pm[1], bp) == 0) +// { +// if (tm->tm_hour > 11) +// return (0); +// +// tm->tm_hour += 12; +// bp += strlen(am_pm[1]); +// break; +// } +// +// /* Nothing matched. */ +/* return (0); +*/ + case 'S': /* The seconds. */ + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_sec, 0, 61))) + return (0); + break; + + case 'U': /* The week of year, beginning on sunday. */ + case 'W': /* The week of year, beginning on monday. */ + LEGAL_ALT(ALT_O); + /* + * XXX This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so just check the + * range for now. + */ + if (!(conv_num(&bp, &i, 0, 53))) + return (0); + break; + + case 'w': /* The day of week, beginning on sunday. */ + LEGAL_ALT(ALT_O); + if (!(conv_num(&bp, &tm->tm_wday, 0, 6))) + return (0); + break; + + case 'Y': /* The year. */ + LEGAL_ALT(ALT_E); + if (!(conv_num(&bp, &i, 0, 9999))) + return (0); + + tm->tm_year = i - TM_YEAR_BASE; + break; + + case 'y': /* The year within 100 years of the epoch. */ + LEGAL_ALT(ALT_E | ALT_O); + if (!(conv_num(&bp, &i, 0, 99))) + return (0); + + if (split_year) + { + tm->tm_year = ((tm->tm_year / 100) * 100) + i; + break; + } + split_year = 1; + if (i <= 68) + tm->tm_year = i + 2000 - TM_YEAR_BASE; + else + tm->tm_year = i + 1900 - TM_YEAR_BASE; + break; + + /* + * Miscellaneous conversions. + */ + case 'n': /* Any kind of white-space. */ + case 't': + LEGAL_ALT(0); + while (isspace(*bp)) + bp++; + break; + + + default: /* Unknown/unsupported conversion. */ + return (0); + } + + } + + /* LINTED functional specification */ + return ((char *)bp); +} +#pragma warning(default:4706) + + +static int conv_num(const char **buf, int *dest, int llim, int ulim) +{ + int result = 0; + + /* The limit also determines the number of valid digits. */ + int rulim = ulim; + + if (**buf < '0' || **buf > '9') + return (0); + + do { + result *= 10; + result += *(*buf)++ - '0'; + rulim /= 10; + } while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); + + if (result < llim || result > ulim) + return (0); + + *dest = result; + return (1); +} + +int strncasecmp(char *s1, char *s2, size_t n) +{ + if (n == 0) + return 0; + + while (n-- != 0 && tolower(*s1) == tolower(*s2)) + { + if (n == 0 || *s1 == '\0' || *s2 == '\0') + break; + s1++; + s2++; + } + + return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); +} diff --git a/deps/MsvcLibX/src/symlink.c b/deps/MsvcLibX/src/symlink.c new file mode 100644 index 0000000000000000000000000000000000000000..e791cea35aa15725e7e94125fe300e4bce1b6a32 --- /dev/null +++ b/deps/MsvcLibX/src/symlink.c @@ -0,0 +1,454 @@ +/*****************************************************************************\ +* * +* Filename symlink.c * +* * +* Description: WIN32 port of standard C library's symlink() * +* * +* Notes: Requires SE_CREATE_SYMBOLIC_LINK_NAME privilege. * +* * +* * +* History: * +* 2014-02-05 JFL Created this module. * +* 2014-03-02 JFL Split the functions into a WSTR and an UTF-8 version. * +* 2014-03-20 JFL Restructured Windows link management functions into Wide * +* and MultiByte versions, and changed the Unicode and Ansi * +* versions to macros. * +* 2014-07-03 JFL Added support for pathnames >= 260 characters. * +* 2015-12-14 JFL Added a workaround allowing to link support for symlinks * +* in all apps, even when targeting XP or older systems that * +* do not support symlinks. * +* 2016-08-25 JFL Fixed two warnings. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of routines */ + +#include +#pragma comment(lib, "Mpr.lib") + +#include +#include "debugm.h" + +#ifdef _WIN32 + +#include + +#include "reparsept.h" + +/*---------------------------------------------------------------------------*\ +* * +| Function: junction | +| | +| Description: Create an NTFS junction | +| | +| Parameters: const char *targetName The junction target name | +| const char *junctionName The junction name | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: Uses the undocumented FSCTL_SET_REPARSE_POINT structure | +| Win2K uses for mount points and junctions. | +| | +| History: | +| 2014-02-05 JFL Adapted from Mark Russinovitch CreateJuction sample | +* * +\*---------------------------------------------------------------------------*/ + +/* MsvcLibX-specific routine to create an NTFS junction - Wide char version */ +int junctionW(const WCHAR *targetName, const WCHAR *junctionName) { + WCHAR wszReparseBuffer[PATH_MAX*3]; + WCHAR wszVolumeName[] = L"X:\\"; + WCHAR wszJunctionFullName[PATH_MAX]; + WCHAR wszFileSystem[PATH_MAX] = L""; + WCHAR wszTargetTempName[PATH_MAX]; + WCHAR wszTargetFullName[PATH_MAX]; + WCHAR wszTargetNativeName[PATH_MAX]; + WCHAR *pwszFilePart; + size_t lNativeName; + HANDLE hFile; + DWORD dwReturnedLength; + PMOUNTPOINT_WRITE_BUFFER reparseInfo = (PMOUNTPOINT_WRITE_BUFFER)wszReparseBuffer; + DEBUG_CODE( + char szJunction8[UTF8_PATH_MAX]; + char szTarget8[UTF8_PATH_MAX]; + char szTemp8[UTF8_PATH_MAX]; + ) + UINT uiDriveType; + DWORD dwFileSystemFlags; + + DEBUG_WSTR2UTF8(junctionName, szJunction8, sizeof(szJunction8)); + DEBUG_WSTR2UTF8(targetName, szTarget8, sizeof(szTarget8)); + DEBUG_ENTER(("junction(\"%s\", \"%s\");\n", szTarget8, szJunction8)); + + /* Get the full path of the junction */ + if (!GetFullPathNameW(junctionName, PATH_MAX, wszJunctionFullName, &pwszFilePart)) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("%s is an invalid junction name\n", junctionName)); + } + + /* Convert relative paths to absolute paths relative to the junction. */ + /* Note: I tested creating relative targets: They can be created, but Windows can't follow them. */ + if ((targetName[0] != '\\') && (targetName[1] != ':')) { + size_t lTempName = PATH_MAX; + lstrcpyW(wszTargetTempName, wszJunctionFullName); + lTempName -= lstrlenW(wszJunctionFullName); + if (lTempName < (size_t)(lstrlenW(targetName) + 5)) { + errno = ENAMETOOLONG; + RETURN_INT_COMMENT(-1, ("Intermediate target name too long\n")); + } + lstrcatW(wszTargetTempName, L"\\..\\"); + lstrcatW(wszTargetTempName, targetName); + if (!GetFullPathNameW(wszTargetTempName, PATH_MAX, wszTargetFullName, &pwszFilePart)) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("%s is an invalid target directory name\n", szTarget8)); + } + DEBUG_WSTR2UTF8(wszTargetFullName, szTemp8, sizeof(szTemp8)); + XDEBUG_PRINTF(("wszTargetFullName = \"%s\"; // After absolutization relative to the junction\n", szTemp8)); + } else { /* Already an absolute name. Just make sure it's canonic. (Without . or ..) */ + if (!GetFullPathNameW(targetName, PATH_MAX, wszTargetFullName, &pwszFilePart)) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("%s is an invalid target directory name\n", szTarget8)); + } + DEBUG_WSTR2UTF8(wszTargetFullName, szTemp8, sizeof(szTemp8)); + XDEBUG_PRINTF(("wszTargetFullName = \"%s\"; // After direct reabsolutization\n", szTemp8)); + } + /* Make sure the target drive letter is upper case */ +#pragma warning(disable:4305) /* truncation from 'LPSTR' to 'WCHAR' */ +#pragma warning(disable:4306) /* conversion from 'WCHAR' to 'WCHAR *' of greater size */ + wszTargetFullName[0] = (WCHAR)CharUpperW((WCHAR *)(wszTargetFullName[0])); +#pragma warning(default:4706) +#pragma warning(default:4705) + + /* Make sure that the junction is on a file system that supports reparse points (Ex: NTFS) */ + wszVolumeName[0] = wszJunctionFullName[0]; + GetVolumeInformationW(wszVolumeName, NULL, 0, NULL, NULL, &dwFileSystemFlags, wszFileSystem, sizeof(wszFileSystem)/sizeof(WCHAR)); + if (!(dwFileSystemFlags & FILE_SUPPORTS_REPARSE_POINTS)) { + errno = EDOM; + DEBUG_WSTR2UTF8(wszFileSystem, szTemp8, sizeof(szTemp8)); + RETURN_INT_COMMENT(-1, ("Junctions are not supported on %s volumes\n", szTemp8)); + } + + /* On network drives, make sure the target refers to the local drive on the server */ + /* Note: The local path on the server can be inferred in simple cases, but not in the general case */ + uiDriveType = GetDriveTypeW(wszVolumeName); + DEBUG_WSTR2UTF8(wszVolumeName, szTemp8, sizeof(szTemp8)); + XDEBUG_PRINTF(("GetDriveType(\"%s\") = %d // %s drive\n", szTemp8, uiDriveType, (uiDriveType == DRIVE_REMOTE) ? "Network" : "Local")); + if (uiDriveType == DRIVE_REMOTE) { + WCHAR wszLocalName[] = L"X:"; + WCHAR wszRemoteName[PATH_MAX]; + DWORD dwErr; + DWORD dwLength = PATH_MAX; + wszLocalName[0] = wszJunctionFullName[0]; + dwErr = WNetGetConnectionW(wszLocalName, wszRemoteName, &dwLength); + if (dwErr == NO_ERROR) { + WCHAR *pwsz; + DEBUG_CODE( + char szRemote8[UTF8_PATH_MAX]; + ) + DEBUG_WSTR2UTF8(wszRemoteName, szRemote8, sizeof(szRemote8)); + XDEBUG_PRINTF(("net use %c: %s\n", (char)(wszLocalName[0]), szRemote8)); + if ((wszRemoteName[0] == L'\\') && (wszRemoteName[1] == L'\\')) { + pwsz = wcschr(wszRemoteName+2, L'\\'); + if (pwsz) { + if ((pwsz[2] == L'$') && !pwsz[3]) { /* This is the root of a shared drive. Ex: \\server\D$ -> D: */ + wszTargetFullName[0] = pwsz[1]; /* Local drive name on the server */ + } else { /* Heuristic: Assume the share name is a subdirectory name on the C: drive. Ex: \\server\Public -> C:\Public */ + int lTempName = PATH_MAX; + wszTargetTempName[0] = L'C'; /* Local drive name on the server */ + wszTargetTempName[1] = L':'; + lstrcpyW(wszTargetTempName+2, pwsz); + lTempName -= lstrlenW(wszTargetTempName); + if (lTempName > lstrlenW(wszTargetFullName+2)) { + lstrcatW(wszTargetTempName, wszTargetFullName+2); + lstrcpyW(wszTargetFullName, wszTargetTempName); + } + } + } + } + } else { + XDEBUG_PRINTF(("WNetGetConnection(\"%s\") failed: Error %d\n", szTemp8, dwErr)); + } + } + + /* Make the native target name */ + lNativeName = wsprintfW(wszTargetNativeName, L"\\??\\%s", wszTargetFullName ); + if ( (wszTargetNativeName[lNativeName-1] == L'\\') && + (wszTargetNativeName[lNativeName-2] != L':')) { + wszTargetNativeName[lNativeName-1] = L'\0'; + lNativeName -= 1; + } + + /* Create the link - ignore errors since it might already exist */ + DEBUG_WSTR2UTF8(wszJunctionFullName, szJunction8, sizeof(szJunction8)); + DEBUG_WSTR2UTF8(wszTargetNativeName, szTarget8, sizeof(szTarget8)); + DEBUG_PRINTF(("// Creating junction \"%s\" -> \"%s\"\n", szJunction8, szTarget8)); + CreateDirectoryW(junctionName, NULL); + hFile = CreateFileW(junctionName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL ); + if (hFile == INVALID_HANDLE_VALUE) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("Error creating %s:\n", szJunction8)); + } + + /* Build the reparse info */ + ZeroMemory(reparseInfo, sizeof( *reparseInfo )); + reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + reparseInfo->ReparseTargetLength = (WORD)(lNativeName * sizeof(WCHAR)); + reparseInfo->ReparseTargetMaximumLength = reparseInfo->ReparseTargetLength + sizeof(WCHAR); + reparseInfo->ReparseDataLength = reparseInfo->ReparseTargetLength + MOUNTPOINT_WRITE_BUFFER_HEADER_SIZE - 4; + lstrcpynW(reparseInfo->ReparseTarget, wszTargetNativeName, PATH_MAX); + + /* Set the link */ + if (!DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, reparseInfo, + /* reparseInfo->ReparseDataLength + 4, */ + reparseInfo->ReparseDataLength + 8, + NULL, 0, &dwReturnedLength, NULL )) { + errno = Win32ErrorToErrno(); + CloseHandle(hFile); + RemoveDirectoryW(junctionName); + RETURN_INT_COMMENT(-1, ("Error setting junction for %s:\n", szJunction8)); + } + + CloseHandle(hFile); + RETURN_INT_COMMENT(0, ("Created \"%s\" -> \"%s\"\n", szJunction8, szTarget8)); +} + +/* MsvcLibX-specific routine to create an NTFS junction - MultiByte char version */ +int junctionM(const char *targetName, const char *junctionName, UINT cp) { + WCHAR wszJunction[PATH_MAX]; + WCHAR wszTarget[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + junctionName, /* lpMultiByteStr, */ + wszJunction, /* lpWideCharStr, */ + COUNTOF(wszJunction) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + targetName, /* lpMultiByteStr, */ + wszTarget, /* lpWideCharStr, */ + COUNTOF(wszTarget) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + return junctionW(wszTarget, wszJunction); +} + +/*---------------------------------------------------------------------------*\ +* * +| Function: symlink | +| | +| Description: Create an NTFS symbolic link | +| | +| Parameters: const TCHAR *targetName The symlink target name | +| const TCHAR *linkName The symlink name | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: | +| | +| History: | +| 2014-02-04 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +/* Symbolic links first appeared in Vista WINVER 0x600. + Add support for both old and new versions, by using Windows' CreateSymbolicLink + function if it exists, or else a short stub that fails every time if not. */ +#if WINVER < 0x600 /* This mechanism is only necessary when targeting older versions of Windows */ + +typedef BOOLEAN (WINAPI *LPCREATESYMBOLICLINK)(LPCWSTR lpSymlinkName, LPCWSTR lpTargetName, DWORD dwFlags); + +/* Default routine to use if Windows does not have CreateSymbolicLinkW */ +#pragma warning(disable:4100) /* 'dwFlags' : unreferenced formal parameter */ +BOOLEAN WINAPI DefaultCreateSymbolicLinkW(LPCWSTR lpSymlinkName, LPCWSTR lpTargetName, DWORD dwFlags) { + DWORD dwAttr = GetFileAttributesW(lpTargetName); + if (dwAttr != INVALID_FILE_ATTRIBUTES) { /* If the target exists */ + if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) { /* And if the target is a directory */ + /* Try creating a junction as a workaround */ + int iRet = junctionW(lpTargetName, lpSymlinkName); /* 0=Success, -1=Failure */ + return (BOOLEAN)(iRet + 1); /* 1=Success, 0=Failure */ + } + } + /* Else fail, as symlinks to files aren't supported by this Windows version */ + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; +} +#pragma warning(default:4105) + +/* Initialization routine. Tries using Windows' CreateSymbolicLinkW if present, else uses our default above */ +BOOLEAN WINAPI InitCreateSymbolicLink(LPCWSTR lpSymlinkName, LPCWSTR lpTargetName, DWORD dwFlags) { + extern LPCREATESYMBOLICLINK lpCreateSymbolicLinkW; + lpCreateSymbolicLinkW = (LPCREATESYMBOLICLINK) GetProcAddress( + GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW"); + if (!lpCreateSymbolicLinkW) { /* This is XP or older, not supporting symlinks */ + lpCreateSymbolicLinkW = DefaultCreateSymbolicLinkW; + } + return (*lpCreateSymbolicLinkW)(lpSymlinkName, lpTargetName, dwFlags); +} + +LPCREATESYMBOLICLINK lpCreateSymbolicLinkW = InitCreateSymbolicLink; + +/* Make sure all uses of CreateSymbolicLinkW below go through our static pointer above */ +#undef CreateSymbolicLinkW +#define CreateSymbolicLinkW (*lpCreateSymbolicLinkW) + +#endif /* WINVER < 0x600 */ + +/* Posix routine symlink - Wide char version */ +int symlinkW(const WCHAR *targetName, const WCHAR *linkName) { + DWORD dwAttr; + BOOL done; + DWORD dwFlags; + int err; + DEBUG_CODE( + char szLink8[UTF8_PATH_MAX]; + char szTarget8[UTF8_PATH_MAX]; + ) + + DEBUG_WSTR2UTF8(linkName, szLink8, sizeof(szLink8)); + DEBUG_WSTR2UTF8(targetName, szTarget8, sizeof(szTarget8)); + DEBUG_ENTER(("symlink(\"%s\", \"%s\");\n", szTarget8, szLink8)); + + /* Work around an incompatibility between Unix and Windows: + // Windows needs to know if the target is a file or a directory; + // But Unix allows creating dangling links, in which case we cannot guess what type it'll be. */ + dwAttr = GetFileAttributesW(targetName); + DEBUG_PRINTF(("GetFileAttributes() = 0x%lX\n", dwAttr)); + dwFlags = 0; + if (dwAttr != INVALID_FILE_ATTRIBUTES) { /* File exists */ + if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) dwFlags |= SYMBOLIC_LINK_FLAG_DIRECTORY; + } else { /* Target does not exst. Use a heuristic: Names with trailing / or \ are directories */ + size_t len = lstrlenW(targetName); + if (len) { + WCHAR c = targetName[len-1]; + if ((c == L'/') || (c == L'\\')) dwFlags |= SYMBOLIC_LINK_FLAG_DIRECTORY; + } + } + + done = CreateSymbolicLinkW(linkName, targetName, dwFlags); + + if (done) { + err = 0; + } else { + errno = Win32ErrorToErrno(); + err = -1; + } + RETURN_INT_COMMENT(err, ("%s\n", err?"Failed to create link":"Created link successfully")); +} + +/* Posix routine symlink - MultiByte char version */ +int symlinkM(const char *targetName, const char *linkName, UINT cp) { + WCHAR wszLink[PATH_MAX]; + WCHAR wszTarget[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + linkName, /* lpMultiByteStr, */ + wszLink, /* lpWideCharStr, */ + COUNTOF(wszLink) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + targetName, /* lpMultiByteStr, */ + wszTarget, /* lpWideCharStr, */ + COUNTOF(wszTarget) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + return symlinkW(wszTarget, wszLink); +} + +/*---------------------------------------------------------------------------*\ +* * +| Function: symlinkd | +| | +| Description: Create an NTFS symbolic directory link | +| | +| Parameters: const TCHAR *targetName The symlink target name | +| const TCHAR *linkName The symlink name | +| | +| Returns: 0 = Success, -1 = Failure | +| | +| Notes: | +| | +| History: | +| 2014-03-04 JFL Created this routine | +* * +\*---------------------------------------------------------------------------*/ + +/* MsvcLibX-specific routine to create an NTFS symlinkd - Wide char version */ +int symlinkdW(const WCHAR *targetName, const WCHAR *linkName) { + BOOL done; + int err; + DEBUG_CODE( + char szLink8[UTF8_PATH_MAX]; + char szTarget8[UTF8_PATH_MAX]; + ) + + DEBUG_WSTR2UTF8(linkName, szLink8, sizeof(szLink8)); + DEBUG_WSTR2UTF8(targetName, szTarget8, sizeof(szTarget8)); + DEBUG_ENTER(("symlinkd(\"%s\", \"%s\");\n", szTarget8, szLink8)); + + done = CreateSymbolicLinkW(linkName, targetName, SYMBOLIC_LINK_FLAG_DIRECTORY); + + if (done) { + err = 0; + } else { + errno = Win32ErrorToErrno(); + err = -1; + } + RETURN_INT_COMMENT(err, ("%s\n", err?"Failed to create link":"Created link successfully")); +} + +/* MsvcLibX-specific routine to create an NTFS symlinkd - MultiByte char version */ +int symlinkdM(const char *targetName, const char *linkName, UINT cp) { + WCHAR wszLink[PATH_MAX]; + WCHAR wszTarget[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + linkName, /* lpMultiByteStr, */ + wszLink, /* lpWideCharStr, */ + COUNTOF(wszLink) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(cp, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + targetName, /* lpMultiByteStr, */ + wszTarget, /* lpWideCharStr, */ + COUNTOF(wszTarget) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + return -1; + } + return symlinkdW(wszTarget, wszLink); +} + +#endif + + diff --git a/deps/MsvcLibX/src/uname.c b/deps/MsvcLibX/src/uname.c new file mode 100644 index 0000000000000000000000000000000000000000..10baef0fe62de87498d3c11788ee679dc8ccaf13 --- /dev/null +++ b/deps/MsvcLibX/src/uname.c @@ -0,0 +1,79 @@ +/*****************************************************************************\ +* * +* Filename: uname.c * +* * +* Description: Get the name of the current system. * +* * +* Notes: TO DO: Fix the Win32 windows version for Windows >= 8.1, * +* as explained in MSDN's GetVersion function page. * +* * +* TO DO: Do not rely on PROCESSOR_ARCHITECTURE to get the * +* processor architecture, because the WIN32 version * +* always sees "x86", even on "AMD64" systems. * +* * +* TO DO: Implement sysinfo.c, moving some of the code from * +* here to there, and use it. * +* * +* History: * +* 2014-05-30 JFL Created this file. * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#include "sys/utsname.h" +#include /* For itoa() */ + +static char major[4] = {0}; +static char minor[4] = {0}; + +#ifdef _MSDOS + +#include + +static char name[16] = {0}; + +int uname(struct utsname *pun) { + unsigned int wVersion = _bdos(0x30, 0, 0); /* int 21H ah=30H Get DOS version */ + + _itoa((int)(wVersion & 0x0F), major, 10); + _itoa((int)((wVersion >> 8) & 0x0F), minor, 10); + + /* Use _bdos instead of _intdosx, because even in large memory mode, static variables will be allocated in the default data segment */ + _bdos(0x5E, (unsigned short)(unsigned long)(char far *)name, 0); /* int 21H ax=5E00H ds:dx=&buf Get Machine Name */ + + pun->sysname = "MS-DOS"; /* Name of this operating system */ + pun->nodename = name; /* Name of this node on the network */ /* TO DO: Get it from LAN Manager */ + pun->release = major; /* Current release level of this implementation */ + pun->version = minor; /* Current version level of this release */ + pun->machine = "x86"; /* Name of the hardware type on which the system is running */ + + return 0; +} + +#endif /* defined(_MSDOS) */ + +/*---------------------------------------------------------------------------*/ + +#ifdef _WIN32 + +#include + +#pragma warning(disable:4996) /* Ignore the "This function or variable may be unsafe" warning for itoa() and getenv() */ + +int uname(struct utsname *pun) { + DWORD dwVersion = GetVersion(); + + _itoa((int)(dwVersion & 0x0F), major, 10); + _itoa((int)((dwVersion >> 8) & 0x0F), minor, 10); + + pun->sysname = getenv("OS"); /* Name of this operating system */ + pun->nodename = getenv("COMPUTERNAME"); /* Name of this node on the network */ + pun->release = major; /* Current release level of this implementation */ + pun->version = minor; /* Current version level of this release */ + pun->machine = getenv("PROCESSOR_ARCHITECTURE"); /* Name of the hardware type on which the system is running */ + + return 0; +} + +#endif /* defined(_WIN32) */ diff --git a/deps/MsvcLibX/src/utime.c b/deps/MsvcLibX/src/utime.c new file mode 100644 index 0000000000000000000000000000000000000000..c365ae9f60f1713f455648336958e8c32eedeb42 --- /dev/null +++ b/deps/MsvcLibX/src/utime.c @@ -0,0 +1,216 @@ +/*****************************************************************************\ +* * +* Filename utime.c * +* * +* Description Updated utime() and port of standard C library's lutime() * +* * +* Notes TO DO: Create W, A, U versions of ResolveLinks(), then * +* create W, A, U versions of utime(). * +* * +* History * +* 2014-02-12 JFL Created this module. * +* 2014-06-04 JFL Fixed minors issues in debugging code. * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* 2016-08-25 JFL Added missing routine utimeA(). * +* * +* © Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of Windows print routines */ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include /* Must be included before any direct or indirect inclusion */ +#include + +#include "debugm.h" + +#if defined(_DEBUG) +#include +#endif /* defined(_DEBUG) */ + +#ifdef _WIN32 + +#include +#include /* For MSVC's _get_osfhandle() */ +#include /* For MsvcLibX's ResolveLinks() */ + +/* Convert a Windows FILETIME to a Unix time_t. + A FILETIME is the number of 100-nanosecond intervals since January 1, 1601. + A time_t is the number of 1-second intervals since January 1, 1970. */ + +time_t Filetime2Time_t(FILETIME *pFT) { + ULARGE_INTEGER ull; + ull.LowPart = pFT->dwLowDateTime; + ull.HighPart = pFT->dwHighDateTime; + return (time_t)(ull.QuadPart / 10000000ULL - 11644473600ULL); +} + +void Time_t2Filetime(time_t ft, FILETIME *pFT) { + ULARGE_INTEGER ull; + ull.QuadPart = ft + 11644473600ULL; + ull.QuadPart *= 10000000UL; + pFT->dwLowDateTime = ull.LowPart; + pFT->dwHighDateTime = ull.HighPart; +} + +DEBUG_CODE( + int Utimbuf2String(char *buf, size_t bufsize, const struct utimbuf *times) { + struct tm *pTime; + int n; + if (!times) { + return _snprintf(buf, bufsize, "NULL"); + } + pTime = localtime(&(times->modtime)); /* Time of last data modification */ + n = _snprintf(buf, bufsize, "{%4d-%02d-%02d %02d:%02d:%02d, ...}", + pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday, + pTime->tm_hour, pTime->tm_min, pTime->tm_sec); + return n; + } +); + +/* Low level subroutine used by all the other routines below. */ +int hutime(HANDLE hFile, const struct utimbuf *times) { + FILETIME ftLastAccess; /* last access time */ + FILETIME ftLastWrite; /* last write time */ + int iErr; + struct utimbuf now; + + if (!times) { + now.actime = now.modtime = time(NULL); + times = &now; + } + + Time_t2Filetime(times->actime, &ftLastAccess); + Time_t2Filetime(times->modtime, &ftLastWrite); + iErr = !SetFileTime(hFile, NULL, &ftLastAccess, &ftLastWrite); + if (iErr) { + errno = Win32ErrorToErrno(); + return -1; + } + return 0; +} + +/* Same as 'utime', but does not follow symbolic links. */ +int lutimeW(const WCHAR *path, const struct utimbuf *times) { + DWORD dwAttr; + DWORD dwFlagsAndAttributes; + int iErr; + HANDLE hLink; + + DEBUG_CODE({ + char buf[100]; + char szUtf8[UTF8_PATH_MAX]; + Utimbuf2String(buf, sizeof(buf), times); + DEBUG_WSTR2UTF8(path, szUtf8, sizeof(szUtf8)); + DEBUG_ENTER(("lutime(\"%s\", %s);\n", szUtf8, buf)); + }); + + dwAttr = GetFileAttributesW(path); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + RETURN_INT_COMMENT(-1, ("File does not exist\n")); + } + + dwFlagsAndAttributes = FILE_FLAG_OPEN_REPARSE_POINT; + if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) dwFlagsAndAttributes |= FILE_FLAG_BACKUP_SEMANTICS; + hLink = CreateFileW(path, /* lpFileName, */ + FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess, */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode, */ + NULL, /* lpSecurityAttributes, */ + OPEN_EXISTING, /* dwCreationDisposition, */ + dwFlagsAndAttributes, /* dwFlagsAndAttributes, */ + NULL /* hTemplateFile */ + ); + XDEBUG_PRINTF(("CreateFile() = 0x%p\n", hLink)); + if (hLink == INVALID_HANDLE_VALUE) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("Cannot open the pathname\n")); + } + + iErr = hutime(hLink, times); + CloseHandle(hLink); + RETURN_INT_COMMENT(iErr, ("errno = %d\n", iErr ? errno : 0)); +} + +int lutimeA(const char *path, const struct utimbuf *times) { + WCHAR wszPath[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_ENTER(("lutimeA(\"%s\", %p);\n", path, times)); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + return lutimeW(wszPath, times); +} + +int lutimeU(const char *path, const struct utimbuf *times) { + WCHAR wszPath[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_ENTER(("lutimeU(\"%s\", %p);\n", path, times)); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + return lutimeW(wszPath, times); +} + +/* Same as 'utime', but takes an open file descriptor instead of a name. */ +int futime(int fd, const struct utimbuf *times) { + return hutime((HANDLE)_get_osfhandle(fd), times); +} + +/* Change the file access time to times->actime and its modification time to times->modtime. */ +int utimeA(const char *file, const struct utimbuf *times) { + char buf[PATH_MAX]; + int iErr; + + DEBUG_CODE({ + char buf[100]; + Utimbuf2String(buf, sizeof(buf), times); + DEBUG_ENTER(("utime(\"%s\", %s);\n", file, buf)); + }); + + iErr = ResolveLinksA(file, buf, sizeof(buf)); + if (iErr) RETURN_INT_COMMENT(iErr, ("Cannot resolve the link\n")); + + iErr = lutimeA(buf, times); + RETURN_INT_COMMENT(iErr, ("errno = %d\n", iErr ? errno : 0)); +} + +/* Change the file access time to times->actime and its modification time to times->modtime. */ +int utimeU(const char *file, const struct utimbuf *times) { + char buf[UTF8_PATH_MAX]; + int iErr; + + DEBUG_CODE({ + char buf[100]; + Utimbuf2String(buf, sizeof(buf), times); + DEBUG_ENTER(("utime(\"%s\", %s);\n", file, buf)); + }); + + iErr = ResolveLinksU(file, buf, sizeof(buf)); + if (iErr) RETURN_INT_COMMENT(iErr, ("Cannot resolve the link\n")); + + iErr = lutimeU(buf, times); + RETURN_INT_COMMENT(iErr, ("errno = %d\n", iErr ? errno : 0)); +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/utimes.c b/deps/MsvcLibX/src/utimes.c new file mode 100644 index 0000000000000000000000000000000000000000..482883b87b9fbebab6cad7b0cd1a1391746aaae6 --- /dev/null +++ b/deps/MsvcLibX/src/utimes.c @@ -0,0 +1,219 @@ +/*****************************************************************************\ +* * +* Filename utimes.c * +* * +* Description: WIN32 port of standard C library's *utimes() * +* * +* Notes: TO DO: Create W, A, U versions of ResolveLinks(), then * +* create W, A, U versions of utimes(). * +* * +* History: * +* 2014-02-07 JFL Created this module. * +* 2014-03-24 JFL Renamed "statx.h" as the standard . * +* 2014-06-03 JFL Added support for WIDE, ANSI and UTF8 versions. * +* 2014-06-04 JFL Added handling of UTIME_NOW and UTIME_OMIT. * +* 2014-07-02 JFL Added support for pathnames >= 260 characters. * +* * +* ?Copyright 2016 Hewlett Packard Enterprise Development LP * +* Licensed under the Apache 2.0 license - www.apache.org/licenses/LICENSE-2.0 * +\*****************************************************************************/ + +#define _UTF8_SOURCE /* Generate the UTF-8 version of Windows print routines */ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include /* Must be included before any direct or indirect inclusion */ +#include + +#include "debugm.h" + +#if defined(_DEBUG) +#include +#endif /* defined(_DEBUG) */ + +#ifdef _WIN32 + +#include +#include /* For MSVC's _get_osfhandle() */ +#include /* For MsvcLibX's ResolveLinks() */ + +DEBUG_CODE( + int Timeval2String(char *buf, size_t bufsize, const struct timeval *tvp) { + struct tm *pTime; + int n; + if (tvp->tv_usec == UTIME_NOW) { + return _snprintf(buf, bufsize, "UTIME_NOW"); + } + if (tvp->tv_usec == UTIME_OMIT) { + return _snprintf(buf, bufsize, "UTIME_OMIT"); + } + pTime = localtime(&(tvp->tv_sec)); /* Time of last data modification */ + n = _snprintf(buf, bufsize, "{%4d-%02d-%02d %02d:%02d:%02d.%06d, ...}", + pTime->tm_year + 1900, pTime->tm_mon + 1, pTime->tm_mday, + pTime->tm_hour, pTime->tm_min, pTime->tm_sec, tvp->tv_usec); + return n; + } +); + +/* Convert a Windows FILETIME to a Unix timeval + A FILETIME is the number of 100-nanosecond intervals since January 1, 1601. + A time_t is the number of 1-second intervals since January 1, 1970. */ + +void Filetime2Timeval(const FILETIME *pFT, struct timeval *ptv) { + ULARGE_INTEGER ull; + ull.LowPart = pFT->dwLowDateTime; + ull.HighPart = pFT->dwHighDateTime; + ptv->tv_sec = ull.QuadPart / 10000000ULL - 11644473600ULL; + ptv->tv_usec = (int32_t)((ull.QuadPart % 10000000ULL)/10); +} + +void Timeval2Filetime(const struct timeval *ptv, FILETIME *pFT) { + ULARGE_INTEGER ull; + struct timeval now; + if (ptv->tv_usec == UTIME_NOW) { + gettimeofday(&now, NULL); /* Get the current time into a struct timeval */ + DEBUG_CODE({ + char buf[100]; + Timeval2String(buf, sizeof(buf), &now); + DEBUG_PRINTF(("// UTIME_NOW -> %s\n", buf)); + }); + ptv = &now; + } + ull.QuadPart = ptv->tv_sec + 11644473600ULL; + ull.QuadPart *= 1000000UL; + ull.QuadPart += ptv->tv_usec; + ull.QuadPart *= 10UL; + pFT->dwLowDateTime = ull.LowPart; + pFT->dwHighDateTime = ull.HighPart; +} + +/* Low level subroutine used by all the other routines below. */ +int hutimes(HANDLE hFile, const struct timeval tvp[2]) { + FILETIME ftLastAccess; /* last access time */ + FILETIME ftLastWrite; /* last write time */ + FILETIME *pftLastAccess = &ftLastAccess; + FILETIME *pftLastWrite = &ftLastWrite; + int iErr; + + if (tvp[0].tv_usec != UTIME_OMIT) { + Timeval2Filetime(tvp+0, pftLastAccess); + } else { + pftLastAccess = NULL; /* Do not set this value */ + } + if (tvp[1].tv_usec != UTIME_OMIT) { + Timeval2Filetime(tvp+1, pftLastWrite); + } else { + pftLastWrite = NULL; /* Do not set this value */ + } + iErr = !SetFileTime(hFile, NULL, pftLastAccess, pftLastWrite); + if (iErr) { + errno = Win32ErrorToErrno(); + return -1; + } + return 0; +} + +/* Same as 'utimes', but does not follow symbolic links. */ +int lutimesW(const WCHAR *path, const struct timeval tvp[2]) { + DWORD dwAttr; + DWORD dwFlagsAndAttributes; + int iErr; + HANDLE hLink; + + DEBUG_CODE({ + char buf[100]; + char szUtf8[UTF8_PATH_MAX]; + Timeval2String(buf, sizeof(buf), tvp+1); + DEBUG_WSTR2UTF8(path, szUtf8, sizeof(szUtf8)); + DEBUG_ENTER(("lutimes(\"%s\", %s);\n", szUtf8, buf)); + }); + + dwAttr = GetFileAttributesW(path); + if (dwAttr == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + RETURN_INT_COMMENT(-1, ("File does not exist\n")); + } + + dwFlagsAndAttributes = FILE_FLAG_OPEN_REPARSE_POINT; + if (dwAttr & FILE_ATTRIBUTE_DIRECTORY) dwFlagsAndAttributes |= FILE_FLAG_BACKUP_SEMANTICS; + hLink = CreateFileW(path, /* lpFileName, */ + FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess, */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode, */ + NULL, /* lpSecurityAttributes, */ + OPEN_EXISTING, /* dwCreationDisposition, */ + dwFlagsAndAttributes, /* dwFlagsAndAttributes, */ + NULL /* hTemplateFile */ + ); + XDEBUG_PRINTF(("CreateFile() = 0x%p\n", hLink)); + if (hLink == INVALID_HANDLE_VALUE) { + errno = Win32ErrorToErrno(); + RETURN_INT_COMMENT(-1, ("Cannot open the pathname\n")); + } + + iErr = hutimes(hLink, tvp); + CloseHandle(hLink); + RETURN_INT_COMMENT(iErr, ("errno = %d\n", iErr ? errno : 0)); +} + +int lutimesA(const char *path, const struct timeval tvp[2]) { + WCHAR wszPath[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_ACP, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_ENTER(("lutimesA(\"%s\", %p);\n", path, tvp)); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + return lutimesW(wszPath, tvp); +} + +int lutimesU(const char *path, const struct timeval tvp[2]) { + WCHAR wszPath[PATH_MAX]; + int n; + + /* Convert the pathname to a unicode string, with the proper extension prefixes if it's longer than 260 bytes */ + n = MultiByteToWidePath(CP_UTF8, /* CodePage, (CP_ACP, CP_OEMCP, CP_UTF8, ...) */ + path, /* lpMultiByteStr, */ + wszPath, /* lpWideCharStr, */ + COUNTOF(wszPath) /* cchWideChar, */ + ); + if (!n) { + errno = Win32ErrorToErrno(); + DEBUG_ENTER(("lutimesU(\"%s\", %p);\n", path, tvp)); + RETURN_INT_COMMENT(-1, ("errno=%d - %s\n", errno, strerror(errno))); + } + return lutimesW(wszPath, tvp); +} + +/* Same as 'utimes', but takes an open file descriptor instead of a name. */ +int futimes(int fd, const struct timeval tvp[2]) { + return hutimes((HANDLE)_get_osfhandle(fd), tvp); +} + +/* Change the file access time to tvp[0] and its modification time to tvp[1]. */ +int utimes(const char *file, const struct timeval tvp[2]) { + char buf[UTF8_PATH_MAX]; + int iErr; + + DEBUG_CODE({ + char buf[100]; + Timeval2String(buf, sizeof(buf), tvp+1); + DEBUG_ENTER(("utimes(\"%s\", %s);\n", file, buf)); + }); + + iErr = ResolveLinksU(file, buf, sizeof(buf)); + if (iErr) RETURN_INT_COMMENT(iErr, ("Cannot resolve the link\n")); + + iErr = lutimesU(buf, tvp); + RETURN_INT_COMMENT(iErr, ("errno = %d\n", iErr ? errno : 0)); +} + +#endif /* defined(_WIN32) */ + diff --git a/deps/MsvcLibX/src/xfreopen.c b/deps/MsvcLibX/src/xfreopen.c new file mode 100644 index 0000000000000000000000000000000000000000..724fb8e13b4e09119e23cb37692e8c2ca9eb6d3a --- /dev/null +++ b/deps/MsvcLibX/src/xfreopen.c @@ -0,0 +1,47 @@ +/*****************************************************************************\ +* * +* Filename xfreopen.c * +* * +* Description: WIN32 port of GNU CoreUtils library's xfreopen() * +* * +* Notes: The GNU CoreUtils library extends the freopen function. * +* msvclibx: Use the standard freopen, or _setmode. * +* * +* History: * +* 2014-03-03 JFL Created this module. * +* * +\*****************************************************************************/ + +#define _CRT_SECURE_NO_WARNINGS 1 /* Avoid Visual C++ security warnings */ + +#include +#include +#include +#include +#include "xfreopen.h" + +FILE *xfreopen(const char *filename, const char *mode, FILE *stream) { + int iMode = 0; + if (filename) return freopen(filename, mode, stream); + if (strstr(mode, "r+")) { + iMode = _O_RDWR; + } else if (strstr(mode, "w+")) { + iMode = _O_WRONLY | _O_CREAT | _O_TRUNC; + } else if (strstr(mode, "a+")) { + iMode = _O_RDWR | _O_CREAT | _O_APPEND; + } else if (strchr(mode, 'r')) { + iMode = _O_RDONLY; + } else if (strchr(mode, 'w')) { + iMode = _O_WRONLY | _O_CREAT; + } else if (strchr(mode, 'a')) { + iMode = _O_WRONLY | _O_CREAT | _O_APPEND; + } + if (strchr(mode, 'b')) { + iMode = _O_BINARY; + } else if (strchr(mode, 't')) { + iMode = _O_TEXT; + } + _setmode(_fileno(stream), iMode); + return stream; +} + diff --git a/deps/wepoll/CMakeLists.txt b/deps/wepoll/CMakeLists.txt index cd892cb9f093c8ca952500835a33fd7e0bdc47bd..a81fd782bbc4b05a1158273a7fcc6701bc4d980d 100644 --- a/deps/wepoll/CMakeLists.txt +++ b/deps/wepoll/CMakeLists.txt @@ -3,8 +3,7 @@ PROJECT(TDengine) IF (TD_WINDOWS) INCLUDE_DIRECTORIES(inc) + INCLUDE_DIRECTORIES(inc/sys) AUX_SOURCE_DIRECTORY(src SRC) ADD_LIBRARY(wepoll ${SRC}) ENDIF () - -