mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	MSVC compatibility
1. MSVC compatibility 2. CONFIG_VERSION (too common/generic) replaced by QUICKJS_VERSION due to clashes with other libraries that use CONFIG_VERSION too
This commit is contained in:
		
							parent
							
								
									7c312df422
								
							
						
					
					
						commit
						4298c1a726
					
				
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| # OS generated files  | ||||
| ## Mac OS X | ||||
| .DS_Store | ||||
| .Trashes | ||||
| .Spotlight-V100 | ||||
| # # Windows | ||||
| Thumbs.db | ||||
| .bin | ||||
| .build | ||||
							
								
								
									
										26
									
								
								cutils.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								cutils.c
									
									
									
									
									
								
							| @ -29,6 +29,30 @@ | ||||
| 
 | ||||
| #include "cutils.h" | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| 
 | ||||
|  // From: https://stackoverflow.com/a/26085827
 | ||||
| int gettimeofday(struct timeval * tp, struct timezone * tzp) | ||||
| { | ||||
|   static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); | ||||
| 
 | ||||
|   SYSTEMTIME  system_time; | ||||
|   FILETIME    file_time; | ||||
|   uint64_t    time; | ||||
| 
 | ||||
|   GetSystemTime(&system_time); | ||||
|   SystemTimeToFileTime(&system_time, &file_time); | ||||
|   time = ((uint64_t)file_time.dwLowDateTime); | ||||
|   time += ((uint64_t)file_time.dwHighDateTime) << 32; | ||||
| 
 | ||||
|   tp->tv_sec = (long)((time - EPOCH) / 10000000L); | ||||
|   tp->tv_usec = (long)(system_time.wMilliseconds * 1000); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| void pstrcpy(char *buf, int buf_size, const char *str) | ||||
| { | ||||
|     int c; | ||||
| @ -297,7 +321,7 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp) | ||||
|             return -1; | ||||
|         c = (c << 6) | (b & 0x3f); | ||||
|     } | ||||
|     if (c < utf8_min_code[l - 1]) | ||||
|     if (c < (int)utf8_min_code[l - 1]) | ||||
|         return -1; | ||||
|     *pp = p; | ||||
|     return c; | ||||
|  | ||||
							
								
								
									
										97
									
								
								cutils.h
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								cutils.h
									
									
									
									
									
								
							| @ -28,14 +28,32 @@ | ||||
| #include <stdlib.h> | ||||
| #include <inttypes.h> | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
|   #include <windows.h> | ||||
|   #include <intrin.h> | ||||
| #else  | ||||
|   #include <sys/time.h> | ||||
| #endif | ||||
| 
 | ||||
| /* set if CPU is big endian */ | ||||
| #undef WORDS_BIGENDIAN | ||||
| 
 | ||||
| #define likely(x)       __builtin_expect(!!(x), 1) | ||||
| #define unlikely(x)     __builtin_expect(!!(x), 0) | ||||
| #define force_inline inline __attribute__((always_inline)) | ||||
| #define no_inline __attribute__((noinline)) | ||||
| #define __maybe_unused __attribute__((unused)) | ||||
| #ifndef __has_attribute | ||||
|   #define likely(x)    (x) | ||||
|   #define unlikely(x)  (x) | ||||
|   #define force_inline __forceinline | ||||
|   #define no_inline __declspec(noinline) | ||||
|   #define __maybe_unused | ||||
|   #define __attribute__(x) | ||||
|   #define __attribute(x) | ||||
|   typedef size_t ssize_t; | ||||
| #else | ||||
|   #define likely(x)       __builtin_expect(!!(x), 1) | ||||
|   #define unlikely(x)     __builtin_expect(!!(x), 0) | ||||
|   #define force_inline inline __attribute__((always_inline)) | ||||
|   #define no_inline __attribute__((noinline)) | ||||
|   #define __maybe_unused __attribute__((unused)) | ||||
| #endif | ||||
| 
 | ||||
| #define xglue(x, y) x ## y | ||||
| #define glue(x, y) xglue(x, y) | ||||
| @ -114,27 +132,91 @@ static inline int64_t min_int64(int64_t a, int64_t b) | ||||
| /* WARNING: undefined if a = 0 */ | ||||
| static inline int clz32(unsigned int a) | ||||
| { | ||||
| #ifdef _MSC_VER | ||||
|     unsigned long idx; | ||||
|     _BitScanReverse(&idx, a); | ||||
|     return 31 ^ idx; | ||||
| #else | ||||
|     return __builtin_clz(a); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* WARNING: undefined if a = 0 */ | ||||
| static inline int clz64(uint64_t a) | ||||
| { | ||||
|     return __builtin_clzll(a); | ||||
| #ifdef _MSC_VER | ||||
|   unsigned long where; | ||||
|   // BitScanReverse scans from MSB to LSB for first set bit.
 | ||||
|   // Returns 0 if no set bit is found.
 | ||||
| #if INTPTR_MAX >= INT64_MAX // 64-bit
 | ||||
|   if (_BitScanReverse64(&where, a)) | ||||
|     return (int)(63 - where); | ||||
| #else | ||||
|   // Scan the high 32 bits.
 | ||||
|   if (_BitScanReverse(&where, (uint32_t)(a >> 32))) | ||||
|     return (int)(63 - (where + 32)); // Create a bit offset from the MSB.
 | ||||
|   // Scan the low 32 bits.
 | ||||
|   if (_BitScanReverse(&where, (uint32_t)(a))) | ||||
|     return (int)(63 - where); | ||||
| #endif | ||||
|   return 64; // Undefined Behavior.
 | ||||
| #else | ||||
|   return __builtin_clzll(a); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* WARNING: undefined if a = 0 */ | ||||
| static inline int ctz32(unsigned int a) | ||||
| { | ||||
| #ifdef _MSC_VER | ||||
|     unsigned long idx; | ||||
|     _BitScanForward(&idx, a); | ||||
|     return 31 ^ idx; | ||||
| #else | ||||
|     return __builtin_ctz(a); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /* WARNING: undefined if a = 0 */ | ||||
| static inline int ctz64(uint64_t a) | ||||
| { | ||||
|     return __builtin_ctzll(a); | ||||
| #ifdef _MSC_VER | ||||
|   unsigned long where; | ||||
|   // Search from LSB to MSB for first set bit.
 | ||||
|   // Returns zero if no set bit is found.
 | ||||
| #if INTPTR_MAX >= INT64_MAX // 64-bit
 | ||||
|   if (_BitScanForward64(&where, a)) | ||||
|     return (int)(where); | ||||
| #else | ||||
|   // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
 | ||||
|   // Scan the Low Word.
 | ||||
|   if (_BitScanForward(&where, (uint32_t)(a))) | ||||
|     return (int)(where); | ||||
|   // Scan the High Word.
 | ||||
|   if (_BitScanForward(&where, (uint32_t)(a >> 32))) | ||||
|     return (int)(where + 32); // Create a bit offset from the LSB.
 | ||||
| #endif | ||||
|   return 64; | ||||
| #else | ||||
|   return __builtin_ctzll(a); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef _MSC_VER | ||||
| #pragma pack(push, 1) | ||||
| struct packed_u64 { | ||||
|     uint64_t v; | ||||
| }; | ||||
| 
 | ||||
| struct packed_u32 { | ||||
|     uint32_t v; | ||||
| }; | ||||
| 
 | ||||
| struct packed_u16 { | ||||
|     uint16_t v; | ||||
| }; | ||||
| #pragma pack(pop) | ||||
| #else | ||||
| struct __attribute__((packed)) packed_u64 { | ||||
|     uint64_t v; | ||||
| }; | ||||
| @ -146,6 +228,7 @@ struct __attribute__((packed)) packed_u32 { | ||||
| struct __attribute__((packed)) packed_u16 { | ||||
|     uint16_t v; | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| static inline uint64_t get_u64(const uint8_t *tab) | ||||
| { | ||||
|  | ||||
| @ -465,7 +465,7 @@ static int parse_digits(const uint8_t **pp, BOOL allow_overflow) | ||||
|         p++; | ||||
|     } | ||||
|     *pp = p; | ||||
|     return v; | ||||
|     return (int)v; | ||||
| } | ||||
| 
 | ||||
| static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) | ||||
|  | ||||
							
								
								
									
										107
									
								
								premake5.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								premake5.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | ||||
| 
 | ||||
| ----------------------------------------------------------------------------------------------------------------------- | ||||
| 
 | ||||
| (function() | ||||
|   -- generate "quickjs-version.h" using VERSION file | ||||
|   local file = io.open("VERSION", "r") | ||||
|   local vers = file:read() | ||||
|   file:close() | ||||
|   vars = vers:gsub("%s+", "") | ||||
|   file = io.open("quickjs-version.h", "w+") | ||||
|   file:write("#define QUICKJS_VERSION \"" .. vers .. "\"\r\n") | ||||
|   file:close() | ||||
| end)()   | ||||
| 
 | ||||
| 
 | ||||
| workspace "quickjs-msvc" | ||||
| 	-- Premake output folder | ||||
| 	location(path.join(".build", _ACTION)) | ||||
| 
 | ||||
| 	platforms { "x86", "x64", "arm32", "arm64"  }  | ||||
| 
 | ||||
| 	-- Configuration settings | ||||
| 	configurations { "Debug", "Release" } | ||||
| 
 | ||||
| 	filter "platforms:x86" | ||||
|   	architecture "x86" | ||||
| 	filter "platforms:x64" | ||||
|   	architecture "x86_64"   | ||||
| 	filter "platforms:arm32" | ||||
|   	architecture "ARM"   | ||||
| 	filter "platforms:arm64" | ||||
|   	architecture "ARM64"   | ||||
| 
 | ||||
| 	filter "system:windows" | ||||
|   	removeplatforms { "arm32" }   | ||||
| 
 | ||||
| 	-- Debug configuration | ||||
| 	filter { "configurations:Debug" } | ||||
| 		defines { "DEBUG" } | ||||
| 		symbols "On" | ||||
| 		optimize "Off" | ||||
| 
 | ||||
| 	-- Release configuration | ||||
| 	filter { "configurations:Release" } | ||||
| 		defines { "NDEBUG" } | ||||
| 		optimize "Speed" | ||||
| 		inlining "Auto" | ||||
| 
 | ||||
| 	filter { "language:not C#" } | ||||
| 		defines { "_CRT_SECURE_NO_WARNINGS" } | ||||
| 		buildoptions { "/std:c++latest" } | ||||
| 		systemversion "latest" | ||||
| 
 | ||||
| 	filter { } | ||||
| 		targetdir ".bin/%{cfg.longname}/" | ||||
| 		exceptionhandling "Off" | ||||
| 		rtti "Off" | ||||
| 		--vectorextensions "AVX2" | ||||
| 
 | ||||
| ----------------------------------------------------------------------------------------------------------------------- | ||||
| 
 | ||||
| project "quickjs" | ||||
| 	language "C" | ||||
| 	kind "StaticLib" | ||||
| 	files { | ||||
|     "cutils.h", | ||||
| 		"cutils.c", | ||||
| 		"libregexp.c", | ||||
| 		"libunicode.c", | ||||
| 		"quickjs.c", | ||||
| 		"quickjs-libc.c", | ||||
| 		"libregexp.h", | ||||
| 		"libregexp-opcode.h", | ||||
| 		"libunicode.h", | ||||
| 		"libunicode-table.h", | ||||
| 		"list.h", | ||||
| 		"quickjs.h", | ||||
| 		"quickjs-atom.h", | ||||
| 		"quickjs-libc.h", | ||||
| 		"quickjs-opcode.h" | ||||
| 	} | ||||
| 
 | ||||
| ----------------------------------------------------------------------------------------------------------------------- | ||||
| 
 | ||||
| project "qjsc" | ||||
| 	language "C" | ||||
| 	kind "ConsoleApp" | ||||
| 	links { "quickjs" } | ||||
| 	files { | ||||
| 		"qjsc.c" | ||||
| 	} | ||||
| 
 | ||||
| ----------------------------------------------------------------------------------------------------------------------- | ||||
| 
 | ||||
| project "qjs" | ||||
| 	language "C" | ||||
| 	kind "ConsoleApp" | ||||
| 	links { "quickjs" } | ||||
| 	dependson { "qjsc" } | ||||
| 	files { | ||||
| 		"qjs.c", | ||||
| 		"repl.js", | ||||
| 		"repl.c" | ||||
| 	} | ||||
| 
 | ||||
| -- Compile repl.js and save bytecode into repl.c | ||||
| prebuildcommands { "\"%{cfg.buildtarget.directory}/qjsc.exe\" -c -o \"../../repl.c\" -m \"../../repl.js\"" } | ||||
							
								
								
									
										8
									
								
								qjs.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								qjs.c
									
									
									
									
									
								
							| @ -28,18 +28,20 @@ | ||||
| #include <inttypes.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <time.h> | ||||
| #if defined(__APPLE__) | ||||
| #include <malloc/malloc.h> | ||||
| #include <unistd.h> | ||||
| #elif defined(__linux__) | ||||
| #include <malloc.h> | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| #include "cutils.h" | ||||
| #include "quickjs-libc.h" | ||||
| #include "quickjs-version.h" | ||||
| 
 | ||||
| extern const uint8_t qjsc_repl[]; | ||||
| extern const uint32_t qjsc_repl_size; | ||||
| @ -276,7 +278,7 @@ static const JSMallocFunctions trace_mf = { | ||||
| 
 | ||||
| void help(void) | ||||
| { | ||||
|     printf("QuickJS version " CONFIG_VERSION "\n" | ||||
|     printf("QuickJS version " QUICKJS_VERSION "\n" | ||||
|            "usage: " PROG_NAME " [options] [file [args]]\n" | ||||
|            "-h  --help         list options\n" | ||||
|            "-e  --eval EXPR    evaluate EXPR\n" | ||||
| @ -448,8 +450,10 @@ int main(int argc, char **argv) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| #ifdef CONFIG_BIGNUM | ||||
|     if (load_jscalc) | ||||
|         bignum_ext = 1; | ||||
| #endif | ||||
| 
 | ||||
|     if (trace_memory) { | ||||
|         js_trace_malloc_init(&trace_data); | ||||
|  | ||||
							
								
								
									
										7
									
								
								qjsc.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								qjsc.c
									
									
									
									
									
								
							| @ -27,14 +27,17 @@ | ||||
| #include <inttypes.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #if !defined(_WIN32) | ||||
| #include <sys/wait.h> | ||||
|   #include <unistd.h> | ||||
| #else | ||||
|   #include "win/getopt.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "cutils.h" | ||||
| #include "quickjs-libc.h" | ||||
| #include "quickjs-version.h" | ||||
| 
 | ||||
| typedef struct { | ||||
|     char *name; | ||||
| @ -341,7 +344,7 @@ static const char main_c_template2[] = | ||||
| 
 | ||||
| void help(void) | ||||
| { | ||||
|     printf("QuickJS Compiler version " CONFIG_VERSION "\n" | ||||
|     printf("QuickJS Compiler version " QUICKJS_VERSION "\n" | ||||
|            "usage: " PROG_NAME " [options] [files]\n" | ||||
|            "\n" | ||||
|            "options are:\n" | ||||
|  | ||||
| @ -28,20 +28,30 @@ | ||||
| #include <inttypes.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
| #include <signal.h> | ||||
| #include <limits.h> | ||||
| #include <sys/stat.h> | ||||
| #include <dirent.h> | ||||
| #if defined(_WIN32) | ||||
| #include <windows.h> | ||||
| #include <conio.h> | ||||
| #include <utime.h> | ||||
|   #include <windows.h> | ||||
|   #include <conio.h> | ||||
|   #include <io.h> | ||||
|   #include <fcntl.h> | ||||
|   #include <sys/types.h> | ||||
|   #include <sys/stat.h> | ||||
|   #include <sys/utime.h> | ||||
|   #include "win/dirent.h" | ||||
|   #ifndef PATH_MAX | ||||
|     #define PATH_MAX MAX_PATH | ||||
|   #endif | ||||
|   #define popen _popen | ||||
|   #define pclose _pclose | ||||
| #else | ||||
|   #include <dirent.h> | ||||
|   #include <unistd.h> | ||||
|   #include <sys/time.h> | ||||
| #include <dlfcn.h> | ||||
| #include <termios.h> | ||||
| #include <sys/ioctl.h> | ||||
|  | ||||
							
								
								
									
										1
									
								
								quickjs-version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								quickjs-version.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| #define QUICKJS_VERSION "2020-09-06" | ||||
							
								
								
									
										17
									
								
								quickjs.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								quickjs.c
									
									
									
									
									
								
							| @ -28,14 +28,15 @@ | ||||
| #include <inttypes.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
| #include <fenv.h> | ||||
| #include <math.h> | ||||
| #if defined(__APPLE__) | ||||
| #include <malloc/malloc.h> | ||||
| #include <sys/time.h> | ||||
| #elif defined(__linux__) | ||||
| #include <malloc.h> | ||||
| #include <sys/time.h> | ||||
| #endif | ||||
| 
 | ||||
| #include "cutils.h" | ||||
| @ -48,7 +49,7 @@ | ||||
| 
 | ||||
| #define OPTIMIZE         1 | ||||
| #define SHORT_OPCODES    1 | ||||
| #if defined(EMSCRIPTEN) | ||||
| #if defined(EMSCRIPTEN) || defined(_MSC_VER) | ||||
| #define DIRECT_DISPATCH  0 | ||||
| #else | ||||
| #define DIRECT_DISPATCH  1 | ||||
| @ -67,11 +68,11 @@ | ||||
| 
 | ||||
| /* define to include Atomics.* operations which depend on the OS
 | ||||
|    threads */ | ||||
| #if !defined(EMSCRIPTEN) | ||||
| #if !defined(EMSCRIPTEN) && !defined(_MSC_VER) | ||||
| #define CONFIG_ATOMICS | ||||
| #endif | ||||
| 
 | ||||
| #if !defined(EMSCRIPTEN) | ||||
| #if !defined(EMSCRIPTEN) && !defined(_MSC_VER) | ||||
| /* enable stack limitation */ | ||||
| #define CONFIG_STACK_CHECK | ||||
| #endif | ||||
| @ -6157,7 +6158,7 @@ void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) | ||||
| #ifdef CONFIG_BIGNUM | ||||
|             "BigNum " | ||||
| #endif | ||||
|             CONFIG_VERSION " version, %d-bit, malloc limit: %"PRId64"\n\n", | ||||
|             QUICKJS_VERSION " version, %d-bit, malloc limit: %"PRId64"\n\n", | ||||
|             (int)sizeof(void *) * 8, (int64_t)(ssize_t)s->malloc_limit); | ||||
| #if 1 | ||||
|     if (rt) { | ||||
| @ -10164,7 +10165,11 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, | ||||
|             } else | ||||
| #endif | ||||
|             { | ||||
| #ifdef _MSC_VER | ||||
|                 double d = INFINITY; | ||||
| #else | ||||
|                 double d = 1.0 / 0.0; | ||||
| #endif  | ||||
|                 if (is_neg) | ||||
|                     d = -d; | ||||
|                 val = JS_NewFloat64(ctx, d); | ||||
| @ -41345,7 +41350,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, | ||||
|     uint32_t tag; | ||||
| 
 | ||||
|     if (unlikely(argc == 0)) { | ||||
|         return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0); | ||||
|         return __JS_NewFloat64(ctx, is_max ? -INFINITY : INFINITY); | ||||
|     } | ||||
| 
 | ||||
|     tag = JS_VALUE_GET_TAG(argv[0]); | ||||
|  | ||||
| @ -27,6 +27,7 @@ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include "quickjs-version.h" | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| @ -517,9 +518,9 @@ static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val) | ||||
| { | ||||
|     JSValue v; | ||||
|     if (val == (int32_t)val) { | ||||
|         v = JS_NewInt32(ctx, val); | ||||
|         v = JS_NewInt32(ctx, (int32_t)val); | ||||
|     } else { | ||||
|         v = __JS_NewFloat64(ctx, val); | ||||
|         v = __JS_NewFloat64(ctx, (double)val); | ||||
|     } | ||||
|     return v; | ||||
| } | ||||
|  | ||||
							
								
								
									
										1166
									
								
								win/dirent.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1166
									
								
								win/dirent.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										653
									
								
								win/getopt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										653
									
								
								win/getopt.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,653 @@ | ||||
| #ifndef __GETOPT_H__ | ||||
| /**
 | ||||
|  * DISCLAIMER | ||||
|  * This file is part of the mingw-w64 runtime package. | ||||
|  * | ||||
|  * The mingw-w64 runtime package and its code is distributed in the hope that it  | ||||
|  * will be useful but WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESSED OR  | ||||
|  * IMPLIED ARE HEREBY DISCLAIMED.  This includes but is not limited to  | ||||
|  * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||
|  */ | ||||
|  /*
 | ||||
|  * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
|  * copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  * Sponsored in part by the Defense Advanced Research Projects | ||||
|  * Agency (DARPA) and Air Force Research Laboratory, Air Force | ||||
|  * Materiel Command, USAF, under agreement number F39502-99-1-0512. | ||||
|  */ | ||||
| /*-
 | ||||
|  * 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. | ||||
|  */ | ||||
| 
 | ||||
| #pragma warning(disable:4996) | ||||
| 
 | ||||
| #define __GETOPT_H__ | ||||
| 
 | ||||
| /* All the headers include this file. */ | ||||
| #include <crtdefs.h> | ||||
| #include <errno.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdio.h> | ||||
| #include <windows.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #define REPLACE_GETOPT    /* use this getopt as the system getopt(3) */ | ||||
| 
 | ||||
| #ifdef REPLACE_GETOPT | ||||
| int opterr = 1;   /* if error message should be printed */ | ||||
| int optind = 1;   /* index into parent argv vector */ | ||||
| int optopt = '?';   /* character checked for validity */ | ||||
| #undef  optreset    /* see getopt.h */ | ||||
| #define optreset    __mingw_optreset | ||||
| int optreset;   /* reset getopt */ | ||||
| char    *optarg;    /* argument associated with option */ | ||||
| #endif | ||||
| 
 | ||||
| //extern int optind;    /* index of first non-option in argv      */
 | ||||
| //extern int optopt;    /* single option character, as parsed     */
 | ||||
| //extern int opterr;    /* flag to enable built-in diagnostics... */
 | ||||
| //        /* (user may set to zero, to suppress)    */
 | ||||
| //
 | ||||
| //extern char *optarg;    /* pointer to argument of current option  */
 | ||||
| 
 | ||||
| #define PRINT_ERROR ((opterr) && (*options != ':')) | ||||
| 
 | ||||
| #define FLAG_PERMUTE  0x01  /* permute non-options to the end of argv */ | ||||
| #define FLAG_ALLARGS  0x02  /* treat non-options as args to option "-1" */ | ||||
| #define FLAG_LONGONLY 0x04  /* operate as getopt_long_only */ | ||||
| 
 | ||||
| /* return values */ | ||||
| #define BADCH   (int)'?' | ||||
| #define BADARG    ((*options == ':') ? (int)':' : (int)'?') | ||||
| #define INORDER   (int)1 | ||||
| 
 | ||||
| #ifndef __CYGWIN__ | ||||
| #define __progname __argv[0] | ||||
| #else | ||||
| extern char __declspec(dllimport) *__progname; | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __CYGWIN__ | ||||
| static char EMSG[] = ""; | ||||
| #else | ||||
| #define EMSG    "" | ||||
| #endif | ||||
| 
 | ||||
| static int getopt_internal(int, char * const *, const char *, | ||||
|          const struct option *, int *, int); | ||||
| static int parse_long_options(char * const *, const char *, | ||||
|             const struct option *, int *, int); | ||||
| static int gcd(int, int); | ||||
| static void permute_args(int, int, int, char * const *); | ||||
| 
 | ||||
| static 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"; | ||||
| 
 | ||||
| static void | ||||
| _vwarnx(const char *fmt,va_list ap) | ||||
| { | ||||
|   (void)fprintf(stderr,"%s: ",__progname); | ||||
|   if (fmt != NULL) | ||||
|     (void)vfprintf(stderr,fmt,ap); | ||||
|   (void)fprintf(stderr,"\n"); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| warnx(const char *fmt,...) | ||||
| { | ||||
|   va_list ap; | ||||
|   va_start(ap,fmt); | ||||
|   _vwarnx(fmt,ap); | ||||
|   va_end(ap); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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 * const *nargv) | ||||
| { | ||||
|   int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; | ||||
|   char *swap; | ||||
| 
 | ||||
|   /*
 | ||||
|    * 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]; | ||||
|       /* LINTED const cast */ | ||||
|       ((char **) nargv)[pos] = nargv[cstart]; | ||||
|       /* LINTED const cast */ | ||||
|       ((char **)nargv)[cstart] = swap; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #ifdef REPLACE_GETOPT | ||||
| /*
 | ||||
|  * getopt -- | ||||
|  *  Parse argc/argv argument vector. | ||||
|  * | ||||
|  * [eventually this will replace the BSD getopt] | ||||
|  */ | ||||
| int | ||||
| getopt(int nargc, char * const *nargv, const char *options) | ||||
| { | ||||
| 
 | ||||
|   /*
 | ||||
|    * We don't pass FLAG_PERMUTE to getopt_internal() since | ||||
|    * the BSD getopt(3) (unlike GNU) has never done this. | ||||
|    * | ||||
|    * Furthermore, since many privileged programs call getopt() | ||||
|    * before dropping privileges it makes sense to keep things | ||||
|    * as simple (and bug-free) as possible. | ||||
|    */ | ||||
|   return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); | ||||
| } | ||||
| #endif /* REPLACE_GETOPT */ | ||||
| 
 | ||||
| //extern int getopt(int nargc, char * const *nargv, const char *options);
 | ||||
| 
 | ||||
| #ifdef _BSD_SOURCE | ||||
| /*
 | ||||
|  * BSD adds the non-standard `optreset' feature, for reinitialisation | ||||
|  * of `getopt' parsing.  We support this feature, for applications which | ||||
|  * proclaim their BSD heritage, before including this header; however, | ||||
|  * to maintain portability, developers are advised to avoid it. | ||||
|  */ | ||||
| # define optreset  __mingw_optreset | ||||
| extern int optreset; | ||||
| #endif | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| /*
 | ||||
|  * POSIX requires the `getopt' API to be specified in `unistd.h'; | ||||
|  * thus, `unistd.h' includes this header.  However, we do not want | ||||
|  * to expose the `getopt_long' or `getopt_long_only' APIs, when | ||||
|  * included in this manner.  Thus, close the standard __GETOPT_H__ | ||||
|  * declarations block, and open an additional __GETOPT_LONG_H__ | ||||
|  * specific block, only when *not* __UNISTD_H_SOURCED__, in which | ||||
|  * to declare the extended API. | ||||
|  */ | ||||
| #endif /* !defined(__GETOPT_H__) */ | ||||
| 
 | ||||
| #if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) | ||||
| #define __GETOPT_LONG_H__ | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| struct option   /* specification for a long form option...  */ | ||||
| { | ||||
|   const char *name;   /* option name, without leading hyphens */ | ||||
|   int         has_arg;    /* does it take an argument?    */ | ||||
|   int        *flag;   /* where to save its status, or NULL  */ | ||||
|   int         val;    /* its associated status value    */ | ||||
| }; | ||||
| 
 | ||||
| enum        /* permitted values for its `has_arg' field...  */ | ||||
| { | ||||
|   no_argument = 0,        /* option never takes an argument */ | ||||
|   required_argument,    /* option always requires an argument */ | ||||
|   optional_argument   /* option may take an argument    */ | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * parse_long_options -- | ||||
|  *  Parse long options in argc/argv argument vector. | ||||
|  * Returns -1 if short_too is set and the option does not match long_options. | ||||
|  */ | ||||
| static int | ||||
| parse_long_options(char * const *nargv, const char *options, | ||||
|   const struct option *long_options, int *idx, int short_too) | ||||
| { | ||||
|   char *current_argv, *has_equal; | ||||
|   size_t current_argv_len; | ||||
|   int i, ambiguous, match; | ||||
| 
 | ||||
| #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) | ||||
| 
 | ||||
|   current_argv = place; | ||||
|   match = -1; | ||||
|   ambiguous = 0; | ||||
| 
 | ||||
|   optind++; | ||||
| 
 | ||||
|   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) == current_argv_len) { | ||||
|       /* exact match */ | ||||
|       match = i; | ||||
|       ambiguous = 0; | ||||
|       break; | ||||
|     } | ||||
|     /*
 | ||||
|      * If this is a known short option, don't allow | ||||
|      * a partial match of a single character. | ||||
|      */ | ||||
|     if (short_too && current_argv_len == 1) | ||||
|       continue; | ||||
| 
 | ||||
|     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 (short_too) { | ||||
|       --optind; | ||||
|       return (-1); | ||||
|     } | ||||
|     if (PRINT_ERROR) | ||||
|       warnx(illoptstring, current_argv); | ||||
|     optopt = 0; | ||||
|     return (BADCH); | ||||
|   } | ||||
|   if (idx) | ||||
|     *idx = match; | ||||
|   if (long_options[match].flag) { | ||||
|     *long_options[match].flag = long_options[match].val; | ||||
|     return (0); | ||||
|   } else | ||||
|     return (long_options[match].val); | ||||
| #undef IDENTICAL_INTERPRETATION | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * getopt_internal -- | ||||
|  *  Parse argc/argv argument vector.  Called by user level routines. | ||||
|  */ | ||||
| static int | ||||
| getopt_internal(int nargc, char * const *nargv, const char *options, | ||||
|   const struct option *long_options, int *idx, int flags) | ||||
| { | ||||
|   char *oli;        /* option letter list index */ | ||||
|   int optchar, short_too; | ||||
|   static int posixly_correct = -1; | ||||
| 
 | ||||
|   if (options == NULL) | ||||
|     return (-1); | ||||
| 
 | ||||
|   /*
 | ||||
|    * XXX Some GNU programs (like cvs) set optind to 0 instead of | ||||
|    * XXX using optreset.  Work around this braindamage. | ||||
|    */ | ||||
|   if (optind == 0) | ||||
|     optind = optreset = 1; | ||||
| 
 | ||||
|   /*
 | ||||
|    * Disable GNU extensions if POSIXLY_CORRECT is set or options | ||||
|    * string begins with a '+'. | ||||
|    * | ||||
|    * CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or | ||||
|    *                 optreset != 0 for GNU compatibility. | ||||
|    */ | ||||
|   if (posixly_correct == -1 || optreset != 0) | ||||
|     posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); | ||||
|   if (*options == '-') | ||||
|     flags |= FLAG_ALLARGS; | ||||
|   else if (posixly_correct || *options == '+') | ||||
|     flags &= ~FLAG_PERMUTE; | ||||
|   if (*options == '+' || *options == '-') | ||||
|     options++; | ||||
| 
 | ||||
|   optarg = NULL; | ||||
|   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' && strchr(options, '-') == NULL)) { | ||||
|       place = EMSG;   /* found non-option */ | ||||
|       if (flags & FLAG_ALLARGS) { | ||||
|         /*
 | ||||
|          * GNU extension: | ||||
|          * return non-option as argument to option 1 | ||||
|          */ | ||||
|         optarg = nargv[optind++]; | ||||
|         return (INORDER); | ||||
|       } | ||||
|       if (!(flags & FLAG_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 we have "-" do nothing, if "--" we are done. | ||||
|      */ | ||||
|     if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { | ||||
|       optind++; | ||||
|       place = EMSG; | ||||
|       /*
 | ||||
|        * 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, nargv); | ||||
|         optind -= nonopt_end - nonopt_start; | ||||
|       } | ||||
|       nonopt_start = nonopt_end = -1; | ||||
|       return (-1); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   /*
 | ||||
|    * Check long options if: | ||||
|    *  1) we were passed some | ||||
|    *  2) the arg is not just "-" | ||||
|    *  3) either the arg starts with -- we are getopt_long_only() | ||||
|    */ | ||||
|   if (long_options != NULL && place != nargv[optind] && | ||||
|       (*place == '-' || (flags & FLAG_LONGONLY))) { | ||||
|     short_too = 0; | ||||
|     if (*place == '-') | ||||
|       place++;    /* --foo long option */ | ||||
|     else if (*place != ':' && strchr(options, *place) != NULL) | ||||
|       short_too = 1;    /* could be short option too */ | ||||
| 
 | ||||
|     optchar = parse_long_options(nargv, options, long_options, | ||||
|         idx, short_too); | ||||
|     if (optchar != -1) { | ||||
|       place = EMSG; | ||||
|       return (optchar); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if ((optchar = (int)*place++) == (int)':' || | ||||
|       (optchar == (int)'-' && *place != '\0') || | ||||
|       (oli = (char*)strchr(options, optchar)) == NULL) { | ||||
|     /*
 | ||||
|      * If the user specified "-" and  '-' isn't listed in | ||||
|      * options, return -1 (non-option) as per POSIX. | ||||
|      * Otherwise, it is an unknown option character (or ':'). | ||||
|      */ | ||||
|     if (optchar == (int)'-' && *place == '\0') | ||||
|       return (-1); | ||||
|     if (!*place) | ||||
|       ++optind; | ||||
|     if (PRINT_ERROR) | ||||
|       warnx(illoptchar, optchar); | ||||
|     optopt = optchar; | ||||
|     return (BADCH); | ||||
|   } | ||||
|   if (long_options != NULL && optchar == 'W' && oli[1] == ';') { | ||||
|     /* -W long-option */ | ||||
|     if (*place)     /* no space */ | ||||
|       /* NOTHING */; | ||||
|     else if (++optind >= nargc) { /* no arg */ | ||||
|       place = EMSG; | ||||
|       if (PRINT_ERROR) | ||||
|         warnx(recargchar, optchar); | ||||
|       optopt = optchar; | ||||
|       return (BADARG); | ||||
|     } else        /* white space */ | ||||
|       place = nargv[optind]; | ||||
|     optchar = parse_long_options(nargv, options, long_options, | ||||
|         idx, 0); | ||||
|     place = EMSG; | ||||
|     return (optchar); | ||||
|   } | ||||
|   if (*++oli != ':') {      /* doesn't take argument */ | ||||
|     if (!*place) | ||||
|       ++optind; | ||||
|   } else {        /* takes (optional) argument */ | ||||
|     optarg = NULL; | ||||
|     if (*place)     /* no white space */ | ||||
|       optarg = place; | ||||
|     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); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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) | ||||
| { | ||||
| 
 | ||||
|   return (getopt_internal(nargc, nargv, options, long_options, idx, | ||||
|       FLAG_PERMUTE)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * getopt_long_only -- | ||||
|  *  Parse argc/argv argument vector. | ||||
|  */ | ||||
| int | ||||
| getopt_long_only(int nargc, char * const *nargv, const char *options, | ||||
|     const struct option *long_options, int *idx) | ||||
| { | ||||
| 
 | ||||
|   return (getopt_internal(nargc, nargv, options, long_options, idx, | ||||
|       FLAG_PERMUTE|FLAG_LONGONLY)); | ||||
| } | ||||
| 
 | ||||
| //extern int getopt_long(int nargc, char * const *nargv, const char *options,
 | ||||
| //    const struct option *long_options, int *idx);
 | ||||
| //extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
 | ||||
| //    const struct option *long_options, int *idx);
 | ||||
| /*
 | ||||
|  * Previous MinGW implementation had... | ||||
|  */ | ||||
| #ifndef HAVE_DECL_GETOPT | ||||
| /*
 | ||||
|  * ...for the long form API only; keep this for compatibility. | ||||
|  */ | ||||
| # define HAVE_DECL_GETOPT 1 | ||||
| #endif | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */ | ||||
							
								
								
									
										4
									
								
								win/premake-vs2017.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								win/premake-vs2017.bat
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| cd .. | ||||
| premake5 vs2017 | ||||
| cd .build | ||||
| start vs2017\quickjs-msvc.sln | ||||
							
								
								
									
										4
									
								
								win/premake-vs2019.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								win/premake-vs2019.bat
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| cd .. | ||||
| premake5 vs2019 | ||||
| cd .build | ||||
| start vs2019\quickjs-msvc.sln | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user