From 2dea19e6a8e37168f240a8ceee5da382be506222 Mon Sep 17 00:00:00 2001
From: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 8 Jan 2012 17:16:43 +0400
Subject: [PATCH] COMP: Fixed MS Visual Studio build errors

---
 Utilities/hdf5/H5public.h         |    8 ++
 Utilities/metis/CMakeLists.txt    |    4 +
 Utilities/metis/metis.h           |    6 +-
 Utilities/metis/metisexport.h     |   18 +++
 Utilities/metis/proto.h           |    6 +-
 Utilities/metis/vrand48.c         |   21 ++++
 Utilities/metis/vrand48.h         |    7 +
 libsrc/CMakeLists.txt             |    5 +-
 libsrc/XdmfHex125Generator.cxx    |    5 +-
 libsrc/XdmfHex125Generator.h      |    2 +-
 libsrc/XdmfHex64Generator.cxx     |    5 +-
 libsrc/XdmfHex64Generator.h       |    2 +-
 libsrc/utils/CMakeLists.txt       |   12 ++-
 libsrc/utils/XdmfExodusReader.cxx |    8 +-
 libsrc/utils/XdmfExodusReader.h   |    2 +-
 libsrc/utils/XdmfExodusWriter.cxx |    6 +
 libsrc/utils/XdmfExodusWriter.h   |    2 +-
 libsrc/utils/XdmfPartitioner.cxx  |    4 +
 libsrc/utils/XdmfPartitioner.h    |    2 +-
 libsrc/utils/xgetopt.cpp          |  219 +++++++++++++++++++++++++++++++++++++
 libsrc/utils/xgetopt.h            |   25 ++++
 21 files changed, 350 insertions(+), 19 deletions(-)
 create mode 100644 Utilities/metis/metisexport.h
 create mode 100644 Utilities/metis/vrand48.c
 create mode 100644 Utilities/metis/vrand48.h
 create mode 100644 libsrc/utils/xgetopt.cpp
 create mode 100644 libsrc/utils/xgetopt.h

diff --git a/Utilities/hdf5/H5public.h b/Utilities/hdf5/H5public.h
index 2ac1ce9..1579e37 100644
--- a/Utilities/hdf5/H5public.h
+++ b/Utilities/hdf5/H5public.h
@@ -43,6 +43,14 @@
 #   include <stdint.h>    /*for C9x types             */
 #endif
 #endif
+
+// For uint64_t on >= VS2010
+#ifdef _MSC_VER
+#   if _MSC_VER >= 1600
+#      include <stdint.h>
+#   endif
+#endif
+
 #ifdef H5_HAVE_INTTYPES_H
 #   include <inttypes.h>        /* For uint64_t on some platforms            */
 #endif
diff --git a/Utilities/metis/CMakeLists.txt b/Utilities/metis/CMakeLists.txt
index 6474087..6e5cef7 100644
--- a/Utilities/metis/CMakeLists.txt
+++ b/Utilities/metis/CMakeLists.txt
@@ -53,6 +53,10 @@ timing.c
 util.c
 )
 
+IF(MSVC)
+  SET(srcs ${srcs} vrand48.c) # because MSVC does not have srand48 and drand48
+ENDIF(MSVC)
+
 ADD_LIBRARY(metis SHARED ${srcs})
 
 IF(NOT VTK_INSTALL_BIN_DIR_CM24)
diff --git a/Utilities/metis/metis.h b/Utilities/metis/metis.h
index d1206d6..b0bd380 100644
--- a/Utilities/metis/metis.h
+++ b/Utilities/metis/metis.h
@@ -18,7 +18,11 @@
 #else
 #include <malloc.h>
 #endif
-#include <strings.h>
+
+#ifndef _MSC_VER
+#   include <strings.h>
+#endif
+
 #include <string.h>
 #include <ctype.h>
 #include <math.h>
diff --git a/Utilities/metis/metisexport.h b/Utilities/metis/metisexport.h
new file mode 100644
index 0000000..253417f
--- /dev/null
+++ b/Utilities/metis/metisexport.h
@@ -0,0 +1,18 @@
+#ifndef __metis_export_h
+#define __metis_export_h
+
+#if defined(_WIN32) && !defined(WIN32)
+# define WIN32
+#endif
+
+#if defined(WIN32)
+#  if defined(metis_EXPORTS)
+#    define METIS_EXPORT __declspec( dllexport ) 
+#  else
+#    define METIS_EXPORT __declspec( dllimport ) 
+#  endif
+#else
+#  define METIS_EXPORT
+#endif
+
+#endif
diff --git a/Utilities/metis/proto.h b/Utilities/metis/proto.h
index 9ceb6c0..8d2940b 100644
--- a/Utilities/metis/proto.h
+++ b/Utilities/metis/proto.h
@@ -12,6 +12,8 @@
  *
  */
 
+#include "metisexport.h"
+
 /* balance.c */
 void Balance2Way(CtrlType *, GraphType *, int *, float);
 void Bnd2WayBalance(CtrlType *, GraphType *, int *);
@@ -230,8 +232,8 @@ void HEXNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
 void QUADNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy);
 
 /* meshpart.c */
-void METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
-void METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void METIS_EXPORT METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
+void METIS_EXPORT METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *);
 
 /* mfm.c */
 void MocFM_2WayEdgeRefine(CtrlType *, GraphType *, float *, int);
diff --git a/Utilities/metis/vrand48.c b/Utilities/metis/vrand48.c
new file mode 100644
index 0000000..62bb071
--- /dev/null
+++ b/Utilities/metis/vrand48.c
@@ -0,0 +1,21 @@
+#include "vrand48.h"
+#include <stdlib.h>
+#define PRECISION 2.82e14
+
+double drand48(void)
+{
+	double x = 0;
+	double denom = RAND_MAX + 1.0;
+	double need;
+	for(need = PRECISION; need>1; need /= (RAND_MAX + 1.))
+	{
+		x += rand()/denom;
+		denom *= RAND_MAX + 1. ;
+	}
+	return x;
+}
+void srand48(long int seedval)
+{
+	srand(seedval);
+}
+
diff --git a/Utilities/metis/vrand48.h b/Utilities/metis/vrand48.h
new file mode 100644
index 0000000..e56e80d
--- /dev/null
+++ b/Utilities/metis/vrand48.h
@@ -0,0 +1,7 @@
+#ifndef VRAND48_H
+#define VRAND48_H
+
+double drand48(void);
+void srand48(long int seedval);
+
+#endif
diff --git a/libsrc/CMakeLists.txt b/libsrc/CMakeLists.txt
index adfdc29..0c00944 100644
--- a/libsrc/CMakeLists.txt
+++ b/libsrc/CMakeLists.txt
@@ -494,7 +494,10 @@ IF(XDMF_WRAP_PYTHON)
   ENDIF(XDMF_BUILD_VTK)
 
   CONFIGURE_FILE(__init__.py ${Xdmf_BINARY_DIR}/libsrc/__init__.py @ONLY)
-  CONFIGURE_FILE(${XDMF_PYTHON_FILE} ${CMAKE_BINARY_DIR}/libsrc/Xdmf.py COPYONLY)
+
+  IF(NOT XDMF_REGENERATE_WRAPPERS)
+    CONFIGURE_FILE(${XDMF_PYTHON_FILE} ${CMAKE_BINARY_DIR}/libsrc/Xdmf.py COPYONLY)
+  ENDIF(NOT XDMF_REGENERATE_WRAPPERS)
 
   INSTALL(FILES ${Xdmf_BINARY_DIR}/libsrc/__init__.py 
     DESTINATION ${XDMF_WRAP_PYTHON_INSTALL_DIR}
diff --git a/libsrc/XdmfHex125Generator.cxx b/libsrc/XdmfHex125Generator.cxx
index 8b18b20..ef4f446 100644
--- a/libsrc/XdmfHex125Generator.cxx
+++ b/libsrc/XdmfHex125Generator.cxx
@@ -81,12 +81,13 @@ public:
 class XdmfHex125Generator::SpectralOperations : public XdmfHex125Generator::Operations
 {
 public:
-  static const double C = 0.65465367070797709; // sqrt(3/7)
+  static const double C; // sqrt(3/7)
   void ComputeInteriorPoints(std::vector<XdmfFloat64> & quarterPoint, std::vector<XdmfFloat64> & midPoint, std::vector<XdmfFloat64> & threeQuarterPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
   void ComputeQuarterPoint (std::vector<XdmfFloat64> & quarterPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
   void ComputeMidPoint(std::vector<XdmfFloat64> & midPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
   void ComputeThreeQuarterPoint(std::vector<XdmfFloat64> & threeQuarterPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
 };
+const double XdmfHex125Generator::SpectralOperations::C = 0.65465367070797709; // sqrt(3/7)
 
 inline void XdmfHex125Generator::NormalOperations::ComputeInteriorPoints(std::vector<XdmfFloat64> & quarterPoint, std::vector<XdmfFloat64> & midPoint, std::vector<XdmfFloat64> & threeQuarterPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2)
 {
@@ -171,7 +172,7 @@ inline void InsertPointWithoutCheck(const std::vector<XdmfFloat64> & newPoint, s
 
 inline void InsertPointWithCheck(const std::vector<XdmfFloat64> & newPoint, std::map<std::vector<XdmfFloat64>, XdmfInt32, PointComparison> & coordToIdMap, std::vector<XdmfInt32> & newConnectivity, std::vector<XdmfFloat64> & newPoints)
 {
-  std::map<std::vector<XdmfFloat64>, XdmfInt32>::const_iterator iter = coordToIdMap.find(newPoint);
+  std::map<std::vector<XdmfFloat64>, XdmfInt32, PointComparison>::const_iterator iter = coordToIdMap.find(newPoint);
   if(iter == coordToIdMap.end())
   {
     // Not inserted before
diff --git a/libsrc/XdmfHex125Generator.h b/libsrc/XdmfHex125Generator.h
index 650da79..b4bb3e5 100644
--- a/libsrc/XdmfHex125Generator.h
+++ b/libsrc/XdmfHex125Generator.h
@@ -32,7 +32,7 @@ class XdmfGrid;
  *        mesh from an XdmfGrid containing linear hexahedron elements.
  */
 
-class XdmfHex125Generator
+class XDMF_EXPORT XdmfHex125Generator
 {
 public:
 
diff --git a/libsrc/XdmfHex64Generator.cxx b/libsrc/XdmfHex64Generator.cxx
index 3a1717f..b840ab2 100644
--- a/libsrc/XdmfHex64Generator.cxx
+++ b/libsrc/XdmfHex64Generator.cxx
@@ -71,11 +71,12 @@ public:
 class XdmfHex64Generator::SpectralOperations : public XdmfHex64Generator::Operations
 {
 public:
-  static const double C = 0.44721359549995793; // 1 / sqrt(5)
+  static const double C; // 1 / sqrt(5)
   virtual void ComputeInteriorPoints(std::vector<XdmfFloat64> & leftPoint, std::vector<XdmfFloat64> & rightPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
   virtual void ComputeLeftPoint(std::vector<XdmfFloat64> & leftPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
   virtual void ComputeRightPoint(std::vector<XdmfFloat64> & rightPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2);
 };
+const double XdmfHex64Generator::SpectralOperations::C=0.44721359549995793; // 1 / sqrt(5)
 
 inline void XdmfHex64Generator::NormalOperations::ComputeInteriorPoints(std::vector<XdmfFloat64> & leftPoint, std::vector<XdmfFloat64> & rightPoint, const std::vector<XdmfFloat64> & point1, const std::vector<XdmfFloat64> & point2)
 {
@@ -145,7 +146,7 @@ inline void InsertPointWithoutCheck(const std::vector<XdmfFloat64> & newPoint, s
 
 inline void InsertPointWithCheck(const std::vector<XdmfFloat64> & newPoint, std::map<std::vector<XdmfFloat64>, XdmfInt32, PointComparison> & coordToIdMap, std::vector<XdmfInt32> & newConnectivity, std::vector<XdmfFloat64> & newPoints)
 {
-  std::map<std::vector<XdmfFloat64>, XdmfInt32>::const_iterator iter = coordToIdMap.find(newPoint);
+  std::map<std::vector<XdmfFloat64>, XdmfInt32, PointComparison>::const_iterator iter = coordToIdMap.find(newPoint);
   if(iter == coordToIdMap.end())
   {
     // Not inserted before
diff --git a/libsrc/XdmfHex64Generator.h b/libsrc/XdmfHex64Generator.h
index 51e2521..66f5b16 100644
--- a/libsrc/XdmfHex64Generator.h
+++ b/libsrc/XdmfHex64Generator.h
@@ -32,7 +32,7 @@ class XdmfGrid;
  *        mesh from an XdmfGrid containing linear hexahedron elements.
  */
 
-class XdmfHex64Generator
+class XDMF_EXPORT XdmfHex64Generator
 {
 public:
 
diff --git a/libsrc/utils/CMakeLists.txt b/libsrc/utils/CMakeLists.txt
index 9b60ebe..1ca6a8c 100644
--- a/libsrc/utils/CMakeLists.txt
+++ b/libsrc/utils/CMakeLists.txt
@@ -56,7 +56,9 @@ IF(XDMF_WRAP_PYTHON)
   SET_TARGET_PROPERTIES(_XdmfUtils PROPERTIES PREFIX "")
   ADD_DEPENDENCIES(_XdmfUtils XdmfUtils)
 
-  CONFIGURE_FILE(${XDMF_UTILS_PYTHON_FILE} XdmfUtils.py COPYONLY)
+  IF(NOT XDMF_REGENERATE_WRAPPERS)
+    CONFIGURE_FILE(${XDMF_UTILS_PYTHON_FILE} XdmfUtils.py COPYONLY)
+  ENDIF(NOT XDMF_REGENERATE_WRAPPERS)
 
   INSTALL(FILES ${XDMF_UTILS_PYTHON_FILE}
       DESTINATION ${XDMF_WRAP_PYTHON_INSTALL_DIR}
@@ -71,7 +73,13 @@ ${XDMF_NETCDF_LIBRARIES} metis)
 
 ADD_EXECUTABLE(XdmfDiff XdmfDiff)
 ADD_EXECUTABLE(XdmfExodusConverter XdmfExodusConverter)
-ADD_EXECUTABLE(XdmfPartitioner XdmfPartitioner)
+
+IF(MSVC)
+  ADD_EXECUTABLE(XdmfPartitioner XdmfPartitioner xgetopt) # because MSVC does not have getopt
+ELSE(MSVC)
+  ADD_EXECUTABLE(XdmfPartitioner XdmfPartitioner)
+ENDIF(MSVC)
+
 SET_TARGET_PROPERTIES(XdmfDiff XdmfPartitioner PROPERTIES COMPILE_FLAGS -DBUILD_EXE)
 TARGET_LINK_LIBRARIES(XdmfDiff XdmfUtils)
 TARGET_LINK_LIBRARIES(XdmfExodusConverter XdmfUtils)
diff --git a/libsrc/utils/XdmfExodusReader.cxx b/libsrc/utils/XdmfExodusReader.cxx
index 0b24e6f..653ba24 100644
--- a/libsrc/utils/XdmfExodusReader.cxx
+++ b/libsrc/utils/XdmfExodusReader.cxx
@@ -430,7 +430,7 @@ XdmfGrid * XdmfExodusReader::read(const char * fileName, XdmfElement * parentEle
   int * nodeSetIds = new int[num_node_sets];
   ex_get_node_set_ids(exodusHandle, nodeSetIds);
 
-  char * node_set_names[num_node_sets];
+  char **node_set_names=new char *[num_node_sets];
   for (int j=0; j<num_node_sets; j++)
   {
     node_set_names[j] = new char[MAX_STR_LENGTH+1];
@@ -507,9 +507,9 @@ XdmfGrid * XdmfExodusReader::read(const char * fileName, XdmfElement * parentEle
     "\nNum Elem Vars: " << num_elem_vars << endl;
   */
 
-  char * global_var_names[num_global_vars];
-  char * nodal_var_names[num_nodal_vars];
-  char * elem_var_names[num_elem_vars];
+  char ** global_var_names=new char *[num_global_vars];
+  char ** nodal_var_names=new char *[num_nodal_vars];
+  char ** elem_var_names=new char *[num_elem_vars];
   for (int j=0; j<num_global_vars; j++)
   {
     global_var_names[j] = new char[MAX_STR_LENGTH+1];
diff --git a/libsrc/utils/XdmfExodusReader.h b/libsrc/utils/XdmfExodusReader.h
index bfbf2e3..2b705ff 100644
--- a/libsrc/utils/XdmfExodusReader.h
+++ b/libsrc/utils/XdmfExodusReader.h
@@ -31,7 +31,7 @@
  *        Data is read and stored directly into Xdmf format.
  */
 
-class XdmfExodusReader
+class XDMF_EXPORT XdmfExodusReader
 {
   public:
     /*!
diff --git a/libsrc/utils/XdmfExodusWriter.cxx b/libsrc/utils/XdmfExodusWriter.cxx
index 1a67d47..0f5c3db 100644
--- a/libsrc/utils/XdmfExodusWriter.cxx
+++ b/libsrc/utils/XdmfExodusWriter.cxx
@@ -25,6 +25,12 @@
 
 #include "XdmfExodusWriter.h"
 
+#ifdef _MSC_VER
+#   if (_MSC_VER == 1500) || (_MSC_VER == 1400)
+#   include <ctime>
+#   endif
+#endif
+
 #include <cassert>
 #include <exodusII.h>
 #include <map>
diff --git a/libsrc/utils/XdmfExodusWriter.h b/libsrc/utils/XdmfExodusWriter.h
index a409baa..53a95a5 100644
--- a/libsrc/utils/XdmfExodusWriter.h
+++ b/libsrc/utils/XdmfExodusWriter.h
@@ -32,7 +32,7 @@ class XdmfExodusWriterNameHandler;
  *        ExodusII file from an Xdmf file.
  */
 
-class XdmfExodusWriter
+class XDMF_EXPORT XdmfExodusWriter
 {
   public:
     /*!
diff --git a/libsrc/utils/XdmfPartitioner.cxx b/libsrc/utils/XdmfPartitioner.cxx
index 3019cbd..0d1af97 100644
--- a/libsrc/utils/XdmfPartitioner.cxx
+++ b/libsrc/utils/XdmfPartitioner.cxx
@@ -27,6 +27,10 @@
 
 #include <sstream>
 
+#ifdef _MSC_VER
+#   include "xgetopt.h"
+#endif
+
 #ifndef BUILD_EXE
 
 extern "C"
diff --git a/libsrc/utils/XdmfPartitioner.h b/libsrc/utils/XdmfPartitioner.h
index 60bf6a2..53a9964 100644
--- a/libsrc/utils/XdmfPartitioner.h
+++ b/libsrc/utils/XdmfPartitioner.h
@@ -33,7 +33,7 @@ class XdmfGrid;
  * is returned containing the partitioned grids.
  */
 
-class XdmfPartitioner
+class XDMF_EXPORT XdmfPartitioner
 {
   public:
 
diff --git a/libsrc/utils/xgetopt.cpp b/libsrc/utils/xgetopt.cpp
new file mode 100644
index 0000000..f2cc8dd
--- /dev/null
+++ b/libsrc/utils/xgetopt.cpp
@@ -0,0 +1,219 @@
+// XGetopt.cpp  Version 1.2
+//
+// Author:  Hans Dietrich
+//          hdietrich2@hotmail.com
+//
+// Description:
+//     XGetopt.cpp implements getopt(), a function to parse command lines.
+//
+// History
+//     Version 1.2 - 2003 May 17
+//     - Added Unicode support
+//
+//     Version 1.1 - 2002 March 10
+//     - Added example to XGetopt.cpp module header 
+//
+// This software is released into the public domain.
+// You are free to use it in any way you like.
+//
+// This software is provided "as is" with no expressed
+// or implied warranty.  I accept no liability for any
+// damage or loss of business that this software may cause.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+// if you are using precompiled headers then include this line:
+//#include "stdafx.h"
+///////////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+// if you are not using precompiled headers then include these lines:
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+///////////////////////////////////////////////////////////////////////////////
+
+
+#include "XGetopt.h"
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+//  X G e t o p t . c p p
+//
+//
+//  NAME
+//       getopt -- parse command line options
+//
+//  SYNOPSIS
+//       int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
+//
+//       extern TCHAR *optarg;
+//       extern int optind;
+//
+//  DESCRIPTION
+//       The getopt() function parses the command line arguments. Its
+//       arguments argc and argv are the argument count and array as
+//       passed into the application on program invocation.  In the case
+//       of Visual C++ programs, argc and argv are available via the
+//       variables __argc and __argv (double underscores), respectively.
+//       getopt returns the next option letter in argv that matches a
+//       letter in optstring.  (Note:  Unicode programs should use
+//       __targv instead of __argv.  Also, all character and string
+//       literals should be enclosed in _T( ) ).
+//
+//       optstring is a string of recognized option letters;  if a letter
+//       is followed by a colon, the option is expected to have an argument
+//       that may or may not be separated from it by white space.  optarg
+//       is set to point to the start of the option argument on return from
+//       getopt.
+//
+//       Option letters may be combined, e.g., "-ab" is equivalent to
+//       "-a -b".  Option letters are case sensitive.
+//
+//       getopt places in the external variable optind the argv index
+//       of the next argument to be processed.  optind is initialized
+//       to 0 before the first call to getopt.
+//
+//       When all options have been processed (i.e., up to the first
+//       non-option argument), getopt returns EOF, optarg will point
+//       to the argument, and optind will be set to the argv index of
+//       the argument.  If there are no non-option arguments, optarg
+//       will be set to NULL.
+//
+//       The special option "--" may be used to delimit the end of the
+//       options;  EOF will be returned, and "--" (and everything after it)
+//       will be skipped.
+//
+//  RETURN VALUE
+//       For option letters contained in the string optstring, getopt
+//       will return the option letter.  getopt returns a question mark (?)
+//       when it encounters an option letter not included in optstring.
+//       EOF is returned when processing is finished.
+//
+//  BUGS
+//       1)  Long options are not supported.
+//       2)  The GNU double-colon extension is not supported.
+//       3)  The environment variable POSIXLY_CORRECT is not supported.
+//       4)  The + syntax is not supported.
+//       5)  The automatic permutation of arguments is not supported.
+//       6)  This implementation of getopt() returns EOF if an error is
+//           encountered, instead of -1 as the latest standard requires.
+//
+//  EXAMPLE
+//       BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
+//       {
+//           int c;
+//
+//           while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
+//           {
+//               switch (c)
+//               {
+//                   case _T('a'):
+//                       TRACE(_T("option a\n"));
+//                       //
+//                       // set some flag here
+//                       //
+//                       break;
+//
+//                   case _T('B'):
+//                       TRACE( _T("option B\n"));
+//                       //
+//                       // set some other flag here
+//                       //
+//                       break;
+//
+//                   case _T('n'):
+//                       TRACE(_T("option n: value=%d\n"), atoi(optarg));
+//                       //
+//                       // do something with value here
+//                       //
+//                       break;
+//
+//                   case _T('?'):
+//                       TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
+//                       return FALSE;
+//                       break;
+//
+//                   default:
+//                       TRACE(_T("WARNING: no handler for option %c\n"), c);
+//                       return FALSE;
+//                       break;
+//               }
+//           }
+//           //
+//           // check for non-option args here
+//           //
+//           return TRUE;
+//       }
+//
+///////////////////////////////////////////////////////////////////////////////
+
+TCHAR   *optarg;        // global argument pointer
+int     optind = 0;     // global argv index
+
+int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
+{
+    static TCHAR *next = NULL;
+    if (optind == 0)
+        next = NULL;
+
+    optarg = NULL;
+
+    if (next == NULL || *next == _T('\0'))
+    {
+        if (optind == 0)
+            optind++;
+
+        if (optind >= argc || argv[optind][0] != _T('-') || argv[optind][1] == _T('\0'))
+        {
+            optarg = NULL;
+            if (optind < argc)
+                optarg = argv[optind];
+            return EOF;
+        }
+
+        if (_tcscmp(argv[optind], _T("--")) == 0)
+        {
+            optind++;
+            optarg = NULL;
+            if (optind < argc)
+                optarg = argv[optind];
+            return EOF;
+        }
+
+        next = argv[optind];
+        next++;     // skip past -
+        optind++;
+    }
+
+    TCHAR c = *next++;
+    TCHAR *cp = _tcschr(optstring, c);
+
+    if (cp == NULL || c == _T(':'))
+        return _T('?');
+
+    cp++;
+    if (*cp == _T(':'))
+    {
+        if (*next != _T('\0'))
+        {
+            optarg = next;
+            next = NULL;
+        }
+        else if (optind < argc)
+        {
+            optarg = argv[optind];
+            optind++;
+        }
+        else
+        {
+            return _T('?');
+        }
+    }
+
+    return c;
+}
diff --git a/libsrc/utils/xgetopt.h b/libsrc/utils/xgetopt.h
new file mode 100644
index 0000000..80686cc
--- /dev/null
+++ b/libsrc/utils/xgetopt.h
@@ -0,0 +1,25 @@
+// XGetopt.h  Version 1.2
+//
+// Author:  Hans Dietrich
+//          hdietrich2@hotmail.com
+//
+// This software is released into the public domain.
+// You are free to use it in any way you like.
+//
+// This software is provided "as is" with no expressed
+// or implied warranty.  I accept no liability for any
+// damage or loss of business that this software may cause.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef XGETOPT_H
+#define XGETOPT_H
+
+#include <tchar.h>
+
+extern int optind, opterr;
+extern TCHAR *optarg;
+
+int getopt(int argc, TCHAR *argv[], TCHAR *optstring);
+
+#endif //XGETOPT_H
-- 
1.7.4.msysgit.0

