浏览代码

NEW: move from tools and config to create CMake

Bill Hoffman 25 年之前
父节点
当前提交
1f42f521ce
共有 57 个文件被更改,包括 5999 次插入14 次删除
  1. 4 4
      CMakeMaster.make.in
  2. 7 7
      CMakeRules.make.in
  3. 3 3
      CMakeVariables.make.in
  4. 18 0
      README
  5. 41 0
      Source/CMakeBuildTargets.cxx
  6. 48 0
      Source/CMakeSetup.cxx
  7. 44 0
      Source/CMakeSetup.dsw
  8. 62 0
      Source/CMakeSetupCMD.cxx
  9. 146 0
      Source/CMakeSetupCMD.dsp
  10. 4 0
      Source/EXEFooter.dsptemplate
  11. 100 0
      Source/EXEHeader.dsptemplate
  12. 327 0
      Source/MFCDialog/CMakeDialog.cpp
  13. 62 0
      Source/MFCDialog/CMakeDialog.h
  14. 74 0
      Source/MFCDialog/CMakeSetup.cpp
  15. 236 0
      Source/MFCDialog/CMakeSetup.dsp
  16. 49 0
      Source/MFCDialog/CMakeSetup.h
  17. 212 0
      Source/MFCDialog/CMakeSetup.rc
  18. 326 0
      Source/MFCDialog/CMakeSetupDialog.cpp
  19. 62 0
      Source/MFCDialog/CMakeSetupDialog.h
  20. 8 0
      Source/MFCDialog/StdAfx.cpp
  21. 27 0
      Source/MFCDialog/StdAfx.h
  22. 二进制
      Source/MFCDialog/res/CMakeSetupDialog.ico
  23. 13 0
      Source/MFCDialog/res/CMakeSetupDialog.rc2
  24. 24 0
      Source/MFCDialog/resource.h
  25. 30 0
      Source/Makefile.in
  26. 77 0
      Source/cmClassFile.cxx
  27. 41 0
      Source/cmClassFile.h
  28. 31 0
      Source/cmDSPBuilder.cxx
  29. 40 0
      Source/cmDSPBuilder.h
  30. 278 0
      Source/cmDSPMakefile.cxx
  31. 69 0
      Source/cmDSPMakefile.h
  32. 278 0
      Source/cmDSPWriter.cxx
  33. 69 0
      Source/cmDSPWriter.h
  34. 22 0
      Source/cmDSWBuilder.cxx
  35. 38 0
      Source/cmDSWBuilder.h
  36. 129 0
      Source/cmDSWMakefile.cxx
  37. 42 0
      Source/cmDSWMakefile.h
  38. 129 0
      Source/cmDSWWriter.cxx
  39. 42 0
      Source/cmDSWWriter.h
  40. 268 0
      Source/cmMakeDepend.cxx
  41. 115 0
      Source/cmMakeDepend.h
  42. 208 0
      Source/cmMakefile.cxx
  43. 104 0
      Source/cmMakefile.h
  44. 46 0
      Source/cmPCBuilder.cxx
  45. 43 0
      Source/cmPCBuilder.h
  46. 1279 0
      Source/cmRegularExpression.cxx
  47. 214 0
      Source/cmRegularExpression.h
  48. 52 0
      Source/cmSystemTools.cxx
  49. 37 0
      Source/cmSystemTools.h
  50. 150 0
      Source/cmUnixMakefile.cxx
  51. 34 0
      Source/cmUnixMakefile.h
  52. 2 0
      Source/cmWindowsConfigure.cxx
  53. 43 0
      Source/cmWindowsConfigure.h
  54. 57 0
      Source/itkVC60Configure.cxx
  55. 37 0
      Source/itkVC60Configure.h
  56. 4 0
      Source/staticLibFooter.dsptemplate
  57. 94 0
      Source/staticLibHeader.dsptemplate

+ 4 - 4
CMakeMaster.make.in

@@ -1,17 +1,17 @@
 #------------------------------------------------------------------------------
 # Include generated rules
-@MAKEINCLUDE@ @MAKEQUOTE@targets.make@MAKEQUOTE@
+@MAKEINCLUDE@ @MAKEQUOTE@CMakeTargets.make@MAKEQUOTE@
 
 #------------------------------------------------------------------------------
 # Include all variable settings
-@MAKEINCLUDE@ @MAKEQUOTE@@ITK_OBJ@/Code/config/MakeVariables.make@MAKEQUOTE@
+@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_OBJ_DIR@/CMake/CMakeVariables.make@MAKEQUOTE@
 
 #------------------------------------------------------------------------------
 # Include user-editable defines.
-@MAKEINCLUDE@ @MAKEQUOTE@@ITK_OBJ@/local.make@MAKEQUOTE@
+@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_OBJ_DIR@/CMakeLocal.make@MAKEQUOTE@
 
 #------------------------------------------------------------------------------
 # Include General Build Rules
-@MAKEINCLUDE@ @MAKEQUOTE@@ITK_OBJ@/Code/config/MakeRules.make@MAKEQUOTE@
+@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_OBJ_DIR@/CMake/CMakeRules.make@MAKEQUOTE@
 
 

+ 7 - 7
CMakeRules.make.in

@@ -15,22 +15,22 @@
 # 
 #------------------------------------------------------------------------------
 #
-all: ${OBJ_SUB_DIRS} ${EXECUTABLES} ${SUBDIR_BUILD} ${ITK_LIB_FILE} ${LOCAL_BUILD_TARGETS}
+all: ${OBJ_SUB_DIRS} ${EXECUTABLES} ${SUBDIR_BUILD} ${ITK_LIB_FILE} ${LOCAL_BUILD_TARGETS} 
 
 #------------------------------------------------------------------------------
 
-${RULESGEN}: @fullSrcDir@/Code/tools/*.cxx @fullSrcDir@/Code/tools/*.h
-	cd @ITK_OBJ@/Code/tools; ${MAKE} rulesgen
+${CMAKE}: @fullSrcDir@/CMake/Source/*.cxx @fullSrcDir@/CMake/Source/*.h
+	cd @CMAKE_OBJ_DIR@/CMake/Source; ${MAKE} CMakeBuildTargets
 
-depend: ${RULESGEN}
-	${RULESGEN} Makefile
+depend: ${CMAKE}
+	${CMAKE} ${srcdir}/CMakeLists.txt -S${srcdir} -I${srcdir} ${INCLUDE_FLAGS}
 
 
 clean: ${SUBDIR_CLEAN}
 	rm -f ${SRC_OBJ} ${ITK_EXECUTABLES} 
 
-targets.make: ${RULESGEN} Makefile
-	${RULESGEN} Makefile -S${srcdir} -I${srcdir} ${INCLUDE_FLAGS}
+CMakeTargets.make: ${CMAKE} ${srcdir}/CMakeLists.txt
+	${CMAKE} ${srcdir}/CMakeLists.txt -S${srcdir} -I${srcdir} ${INCLUDE_FLAGS}
 
 #------------------------------------------------------------------------------
 # rules for the normal library

+ 3 - 3
CMakeVariables.make.in

@@ -1,10 +1,10 @@
 topdir = @fullSrcDir@
 
-CONFIG_DIR = @ITK_OBJ@
+CONFIG_DIR = @CMAKE_OBJ_DIR@
 
 SHELL = /bin/sh
 
-ITK_OBJ       = @ITK_OBJ@
+CMAKE_OBJ_DIR = ${CONFIG_DIR}
 
 RANLIB        = @RANLIB@
 CC            = @CC@
@@ -104,6 +104,6 @@ CXX_FLAGS = ${CPPFLAGS} ${LOCAL_CXXFLAGS} ${CXXFLAGS} \
 CC_FLAGS = ${CPPFLAGS} ${LOCAL_CFLAGS} ${CFLAGS} 
 
 # set up the path to the rulesgen program
-RULESGEN = @ITK_OBJ@/Code/tools/rulesgen
+CMAKE = @CMAKE_OBJ_DIR@/CMake/Source/CMakeBuildTargets
 
 BUILD_LIB_FILE  = lib${ME}${ITK_LIB_EXT}

+ 18 - 0
README

@@ -0,0 +1,18 @@
+CMakeMaster.make     -> main file to be included by makefiles
+CMakeVariables.make  -> all make varibles are set in this file
+CMakeRules.make      -> All build rules are here
+CMakeLocal.make      -> Place for hand configuration
+CMakeLists.txt       -> File in each directory that contains classes, exe, etc
+CMakeTargets.make    -> generated rules for make style build
+
+Windows / Visual Studio 6.0
+CMakeSetup.exe   -> window MFC based GUI for configure on windows
+CMakeSetupCMD.exe            -> windows command line version of CMakeConfigure
+
+Unix 
+configure            -> run on unix to configure for build
+CMakeBuildTargets    -> Unix program to read CMakeLists.txt and generate CMakeTargets.make
+
+TODO:
+Fix cmUnixMakefile.cxx and cmDSPMakefile.cxx 
+to read libraries and -I stuff from a config file

+ 41 - 0
Source/CMakeBuildTargets.cxx

@@ -0,0 +1,41 @@
+#include "cmUnixMakefile.h"
+#include "cmMakeDepend.h"
+#include <iostream>
+
+main(int ac, char** av)
+{
+  if(ac < 2)
+    {
+    std::cerr << "Usage: " << av[0] << " Makefile.in  -Ipath ..." << std::endl;
+    return -1;
+    }
+  cmUnixMakefile* mf = new cmUnixMakefile;
+  cmMakeDepend md;
+  if(ac > 2)
+    {
+    for(int i =2; i < ac; i++)
+      {
+      std::string arg = av[i];
+      if(arg.find("-I",0) != std::string::npos)
+	{
+	std::string path = arg.substr(2);
+	md.AddSearchPath(path.c_str());
+	}
+      if(arg.find("-S",0) != std::string::npos)
+	{
+	std::string path = arg.substr(2);
+	mf->SetCurrentDirectory(path.c_str());
+	}
+      }
+    }
+  if(!mf->ReadMakefile(av[1]))
+    {
+    std::cerr << "Usage: " << av[0] << " Makefile.in  -Ipath ..." << std::endl;
+    return -1;
+    }
+
+  md.SetMakefile(mf);
+  md.DoDepends();
+  mf->OutputMakefile("CMakeTargets.make");
+  delete mf;
+}

+ 48 - 0
Source/CMakeSetup.cxx

@@ -0,0 +1,48 @@
+#include "cmDSWBuilder.h"
+#include "cmDSPBuilder.h"
+#include <iostream>
+
+void SetArgs(cmPCBuilder& builder, int ac, char** av)
+{
+  for(int i =2; i < ac; i++)
+    {
+    std::string arg = av[i];
+    if(arg.find("-H",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      builder.SetHomeDirectory(path.c_str());
+      }
+    if(arg.find("-D",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      builder.SetCurrentDirectory(path.c_str());
+      }
+    }
+}
+
+main(int ac, char** av)
+{
+  if(ac < 3)
+    {
+    std::cerr << "Usage: " << av[0] << 
+      " Makefile.in -[DSP|DSW] -Hinsighthome -Dcurrentdir ..." << std::endl;
+    return -1;
+    }
+  std::string arg = av[2];
+  if(arg.find("-DSP", 0) != std::string::npos)
+    {
+    cmDSPBuilder builder;
+    builder.SetInputMakefilePath(av[1]);
+    SetArgs(builder, ac, av);
+    builder.CreateDSPFile();
+    }
+  else
+    {
+    cmDSWBuilder builder;
+    builder.SetInputMakefilePath(av[1]);
+    SetArgs(builder, ac, av);
+    builder.CreateDSWFile();
+    }
+  return 0;
+}
+

+ 44 - 0
Source/CMakeSetup.dsw

@@ -0,0 +1,44 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "CMakeSetup"=.\MFCDialog\CMakeSetup.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name pcbuilderCMD
+    End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "CMakeSetupCMD"=.\CMakeSetupCMD.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+

+ 62 - 0
Source/CMakeSetupCMD.cxx

@@ -0,0 +1,62 @@
+#include "cmDSWBuilder.h"
+#include "cmDSPBuilder.h"
+#include <iostream>
+
+void SetArgs(cmPCBuilder& builder, int ac, char** av)
+{
+  for(int i =3; i < ac; i++)
+    {
+    std::string arg = av[i];
+    if(arg.find("-H",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      builder.SetHomeDirectory(path.c_str());
+      }
+    if(arg.find("-D",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      std::cerr << "set makefile dir " << path.c_str() << std::endl;
+      builder.SetMakefileDirectory(path.c_str());
+      }
+    if(arg.find("-O",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      builder.SetOutputDirectory(path.c_str());
+      }
+    if(arg.find("-B",0) != std::string::npos)
+      {
+      std::string path = arg.substr(2);
+      builder.SetOutputHomeDirectory(path.c_str());
+      std::cout << "set output home to " << path.c_str() << std::endl;
+      }
+    }
+}
+
+main(int ac, char** av)
+{
+  std::cerr << "pcbuilderCMD\n ";
+  
+  if(ac < 3)
+    {
+    std::cerr << "Usage: " << av[0] << 
+      " Makefile.in -[DSP|DSW] -Hinsighthome -Dcurrentdir -Ooutput directory" << std::endl;
+    return -1;
+    }
+  std::string arg = av[2];
+  if(arg.find("-DSP", 0) != std::string::npos)
+    {
+    cmDSPBuilder builder;
+    SetArgs(builder, ac, av);
+    builder.SetInputMakefilePath(av[1]);
+    builder.CreateDSPFile();
+    }
+  else
+    {
+    cmDSWBuilder builder;
+    SetArgs(builder, ac, av);
+    builder.SetInputMakefilePath(av[1]);
+    builder.CreateDSWFile();
+    }
+  return 0;
+}
+

+ 146 - 0
Source/CMakeSetupCMD.dsp

@@ -0,0 +1,146 @@
+# Microsoft Developer Studio Project File - Name="CMakeSetupCMD" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=CMakeSetupCMD - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "CMakeSetupCMD.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "CMakeSetupCMD.mak" CFG="CMakeSetupCMD - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "CMakeSetupCMD - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "CMakeSetupCMD - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "CMakeSetupCMD - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GR /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GR /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "CMakeSetupCMD - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /W3 /Gm /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "CMakeSetupCMD - Win32 Release"
+# Name "CMakeSetupCMD - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\cmClassFile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmDSPBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmDSPMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmDSWBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmDSWMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmMakeDepend.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmPCBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmRegularExpression.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\cmSystemTools.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetupCMD.cxx
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project

+ 4 - 0
Source/EXEFooter.dsptemplate

@@ -0,0 +1,4 @@
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project

+ 100 - 0
Source/EXEHeader.dsptemplate

@@ -0,0 +1,100 @@
+# Microsoft Developer Studio Project File - Name="pcbuilder" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# CM DSP Header file
+# This file is read by the build system of cm, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit here...
+
+# variables to REPLACE
+# 
+# BUILD_INCLUDES == include path
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_LIBNAME  == name of output library
+# CM_DEBUG_LIBRARIES == libraries linked in 
+# CM_RELEASE_LIBRARIES == libraries linked in 
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GR /GX /Zm1000 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GR /GX /Zm1000 /O2 /D "WIN32" BUILD_INCLUDES EXTRA_DEFINES /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32  CM_RELEASE_LIBRARIES kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP  /W3 /GR /Zm1000 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /MD /GR /Gm /GX /Zm1000 /ZI /Od /D "WIN32" BUILD_INCLUDES EXTRA_DEFINES /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32   kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 CM_DEBUG_LIBRARIES kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"

+ 327 - 0
Source/MFCDialog/CMakeDialog.cpp

@@ -0,0 +1,327 @@
+// CMakeSetupDialogDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "pcbuilder.h"
+#include "CMakeSetupDialog.h"
+#include "../itkDSWBuilder.h"
+#include "../itkVC60Configure.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+  CAboutDlg();
+
+// Dialog Data
+  //{{AFX_DATA(CAboutDlg)
+  enum { IDD = IDD_ABOUTBOX };
+  //}}AFX_DATA
+
+  // ClassWizard generated virtual function overrides
+  //{{AFX_VIRTUAL(CAboutDlg)
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+  //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+  //{{AFX_MSG(CAboutDlg)
+  //}}AFX_MSG
+  DECLARE_MESSAGE_MAP()
+    };
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+  //{{AFX_DATA_INIT(CAboutDlg)
+  //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+  //{{AFX_DATA_MAP(CAboutDlg)
+  //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+  //{{AFX_MSG_MAP(CAboutDlg)
+  // No message handlers
+  //}}AFX_MSG_MAP
+  END_MESSAGE_MAP();
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog dialog
+
+CMakeSetupDialog::CMakeSetupDialog(CWnd* pParent /*=NULL*/)
+  : CDialog(CMakeSetupDialog::IDD, pParent)
+{
+  //{{AFX_DATA_INIT(CMakeSetupDialog)
+  m_WhereITK = _T("");
+  m_WhereBuildITK = _T("");
+  //}}AFX_DATA_INIT
+  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
+  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+  m_WhereITK = _T("");
+  this->LoadFromRegistry();
+}
+
+void CMakeSetupDialog::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+  //{{AFX_DATA_MAP(CMakeSetupDialog)
+  DDX_Text(pDX, IDC_WhereITK, m_WhereITK);
+  DDX_Text(pDX, IDC_WhereITK2, m_WhereBuildITK);
+  //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CMakeSetupDialog, CDialog)
+  //{{AFX_MSG_MAP(CMakeSetupDialog)
+  ON_WM_SYSCOMMAND()
+  ON_WM_PAINT()
+  ON_WM_QUERYDRAGICON()
+  ON_EN_CHANGE(IDC_WhereITK, OnChangeEdit1)
+  ON_BN_CLICKED(IDC_BUTTON2, OnBrowse)
+  ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
+  //}}AFX_MSG_MAP
+  END_MESSAGE_MAP();
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog message handlers
+
+BOOL CMakeSetupDialog::OnInitDialog()
+{
+  CDialog::OnInitDialog();
+
+  // Add "About..." menu item to system menu.
+
+  // IDM_ABOUTBOX must be in the system command range.
+  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+  ASSERT(IDM_ABOUTBOX < 0xF000);
+
+  CMenu* pSysMenu = GetSystemMenu(FALSE);
+  if (pSysMenu != NULL)
+    {
+    CString strAboutMenu;
+    strAboutMenu.LoadString(IDS_ABOUTBOX);
+    if (!strAboutMenu.IsEmpty())
+      {
+      pSysMenu->AppendMenu(MF_SEPARATOR);
+      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+      }
+    }
+
+  // Set the icon for this dialog.  The framework does this automatically
+  //  when the application's main window is not a dialog
+  SetIcon(m_hIcon, TRUE);			// Set big icon
+  SetIcon(m_hIcon, FALSE);		// Set small icon
+	
+  // TODO: Add extra initialization here
+	
+  return TRUE;  // return TRUE  unless you set the focus to a control
+}
+
+void CMakeSetupDialog::OnSysCommand(UINT nID, LPARAM lParam)
+{
+  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+    {
+    CAboutDlg dlgAbout;
+    dlgAbout.DoModal();
+    }
+  else
+    {
+    CDialog::OnSysCommand(nID, lParam);
+    }
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+//  to draw the icon.  For MFC applications using the document/view model,
+//  this is automatically done for you by the framework.
+
+void CMakeSetupDialog::OnPaint() 
+{
+  if (IsIconic())
+    {
+    CPaintDC dc(this); // device context for painting
+
+    SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
+
+    // Center icon in client rectangle
+    int cxIcon = GetSystemMetrics(SM_CXICON);
+    int cyIcon = GetSystemMetrics(SM_CYICON);
+    CRect rect;
+    GetClientRect(&rect);
+    int x = (rect.Width() - cxIcon + 1) / 2;
+    int y = (rect.Height() - cyIcon + 1) / 2;
+
+    // Draw the icon
+    dc.DrawIcon(x, y, m_hIcon);
+    }
+  else
+    {
+    CDialog::OnPaint();
+    }
+}
+
+// The system calls this to obtain the cursor to display while the user drags
+//  the minimized window.
+HCURSOR CMakeSetupDialog::OnQueryDragIcon()
+{
+  return (HCURSOR) m_hIcon;
+}
+
+void CMakeSetupDialog::OnChangeEdit1() 
+{
+  // TODO: If this is a RICHEDIT control, the control will not
+  // send this notification unless you override the CDialog::OnInitDialog()
+  // function and call CRichEditCtrl().SetEventMask()
+  // with the ENM_CHANGE flag ORed into the mask.
+	
+  // TODO: Add your control notification handler code here
+	
+}
+
+void CMakeSetupDialog::OnBrowse() 
+{
+  this->UpdateData();
+  Browse(m_WhereITK, "Enter Path to Insight Source");
+  this->UpdateData(false);
+}
+
+bool CMakeSetupDialog::Browse(CString &result, const char *title)
+{
+// don't know what to do with initial right now...
+  char szPathName[4096];
+  BROWSEINFO bi;
+ 
+  bi.hwndOwner = m_hWnd;
+  bi.pidlRoot = NULL;
+  bi.pszDisplayName = (LPTSTR)szPathName;
+  bi.lpszTitle = title;
+  bi.ulFlags = BIF_BROWSEINCLUDEFILES  ;
+  bi.lpfn = NULL;
+
+  LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
+
+  bool bSuccess = (bool)SHGetPathFromIDList(pidl, szPathName);
+  if(bSuccess)
+    {
+    result = szPathName;
+    }
+  
+  return bSuccess;
+}
+
+void CMakeSetupDialog::OnOK() 
+{ 
+  // get all the info from the screen
+  this->UpdateData();
+  
+  // configure the system for VC60
+  itkVC60Configure config;
+  config.SetWhereITK(m_WhereITK);
+  config.SetWhereBuildITK(m_WhereBuildITK);
+  config.Configure();
+  
+  itkDSWBuilder builder;
+  // Set the ITK home directory
+  builder.SetHomeDirectory(m_WhereITK);
+  // Set the Makefile.in file
+  CString makefileIn = m_WhereITK;
+  makefileIn += "/Makefile.in";
+  builder.SetInputMakefilePath(makefileIn);
+  // Set the output directory
+  builder.SetOutputDirectory(m_WhereBuildITK);
+  // set the directory which contains the Makefile.in
+  builder.SetMakefileDirectory(m_WhereITK);
+  // Create the master DSW file and all children dsp files for ITK
+  builder.CreateDSWFile();
+  CDialog::OnOK();
+  this->SaveToRegistry();
+}
+
+void CMakeSetupDialog::OnButton3() 
+{
+  this->UpdateData();
+  Browse(m_WhereBuildITK, "Enter Path to Insight Build");
+  this->UpdateData(false);
+}
+
+void CMakeSetupDialog::SaveToRegistry()
+{ 
+  HKEY hKey;
+  DWORD dwDummy;
+
+  if(RegCreateKeyEx(HKEY_CURRENT_USER, 
+		    _T("Software\\Kitware\\ITK PCBuilder\\Settings"),
+		    0, "", REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, 
+		    NULL, &hKey, &dwDummy) != ERROR_SUCCESS) 
+    {
+    return;
+    }
+  else
+    {
+    RegSetValueEx(hKey, _T("WhereITK"), 0, REG_SZ, 
+		  (CONST BYTE *)(const char *)m_WhereITK, 
+		  m_WhereITK.GetLength());
+    RegSetValueEx(hKey, _T("WhereBuildITK"), 0, REG_SZ, 
+		  (CONST BYTE *)(const char *)m_WhereBuildITK, 
+		  m_WhereBuildITK.GetLength());
+    
+    }
+  RegCloseKey(hKey);
+}
+
+
+void CMakeSetupDialog::ReadRegistryValue(HKEY hKey,
+					    CString *val,
+					    char *key,
+					    char *adefault)
+{
+  DWORD dwType, dwSize;
+  char *pb;
+
+  dwType = REG_SZ;
+  pb = val->GetBuffer(MAX_PATH);
+  dwSize = MAX_PATH;
+  if(RegQueryValueEx(hKey,_T(key), NULL, &dwType, 
+		     (BYTE *)pb, &dwSize) != ERROR_SUCCESS)
+    {
+    val->ReleaseBuffer();
+    *val = _T(adefault);
+    }
+  else
+    {
+    val->ReleaseBuffer();
+    }
+}
+
+
+void CMakeSetupDialog::LoadFromRegistry()
+{ 
+  HKEY hKey;
+  if(RegOpenKeyEx(HKEY_CURRENT_USER, 
+		  _T("Software\\Kitware\\ITK PCBuilder\\Settings"), 
+		  0, KEY_READ, &hKey) != ERROR_SUCCESS)
+    {
+    return;
+    }
+  else
+    {
+    // save some values
+    this->ReadRegistryValue(hKey, &(m_WhereITK),"WhereITK","C:\\Insight");
+    this->ReadRegistryValue(hKey, &(m_WhereBuildITK),"WhereBuildITK",
+			    "C:\\vtkbin");
+    }
+  RegCloseKey(hKey);
+}

+ 62 - 0
Source/MFCDialog/CMakeDialog.h

@@ -0,0 +1,62 @@
+// CMakeSetupDialogDlg.h : header file
+//
+
+#if !defined(AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)
+#define AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog dialog
+
+class CMakeSetupDialog : public CDialog
+{
+// Construction
+public:
+  CMakeSetupDialog(CWnd* pParent = NULL);	// standard constructor
+protected:
+  bool Browse(CString&, const char* title);
+  void SaveToRegistry();
+  void LoadFromRegistry();
+  void ReadRegistryValue(HKEY hKey,
+			 CString *val,
+			 char *key,
+			 char *adefault);
+// Dialog Data
+  //{{AFX_DATA(CMakeSetupDialog)
+  enum { IDD = IDD_CMakeSetupDialog_DIALOG };
+  CString	m_WhereITK;
+  CString	m_WhereBuildITK;
+  //}}AFX_DATA
+  
+  // ClassWizard generated virtual function overrides
+  //{{AFX_VIRTUAL(CMakeSetupDialog)
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
+  //}}AFX_VIRTUAL
+  
+// Implementation
+protected:
+  HICON m_hIcon;
+  
+  // Generated message map functions
+  //{{AFX_MSG(CMakeSetupDialog)
+  virtual BOOL OnInitDialog();
+  afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+  afx_msg void OnPaint();
+  afx_msg HCURSOR OnQueryDragIcon();
+  afx_msg void OnChangeEdit1();
+  afx_msg void OnBrowse();
+  virtual void OnOK();
+  afx_msg void OnButton3();
+  
+  //}}AFX_MSG
+  DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)

+ 74 - 0
Source/MFCDialog/CMakeSetup.cpp

@@ -0,0 +1,74 @@
+// CMakeSetupdialog.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "CMakeSetup.h"
+#include "CMakeSetupDialog.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetup
+
+BEGIN_MESSAGE_MAP(CMakeSetup, CWinApp)
+  //{{AFX_MSG_MAP(CMakeSetup)
+  // NOTE - the ClassWizard will add and remove mapping macros here.
+  //    DO NOT EDIT what you see in these blocks of generated code!
+  //}}AFX_MSG
+  ON_COMMAND(ID_HELP, CWinApp::OnHelp)
+  END_MESSAGE_MAP();
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetup construction
+CMakeSetup::CMakeSetup()
+{
+  // TODO: add construction code here,
+  // Place all significant initialization in InitInstance
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CMakeSetup object
+
+CMakeSetup theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetup initialization
+
+BOOL CMakeSetup::InitInstance()
+{
+  AfxEnableControlContainer();
+
+  // Standard initialization
+  // If you are not using these features and wish to reduce the size
+  //  of your final executable, you should remove from the following
+  //  the specific initialization routines you do not need.
+
+#ifdef _AFXDLL
+  Enable3dControls();			// Call this when using MFC in a shared DLL
+#else
+  Enable3dControlsStatic();	// Call this when linking to MFC statically
+#endif
+
+  CMakeSetupDialog dlg;
+  m_pMainWnd = &dlg;
+  int nResponse = dlg.DoModal();
+  if (nResponse == IDOK)
+    {
+    // TODO: Place code here to handle when the dialog is
+    //  dismissed with OK
+    }
+  else if (nResponse == IDCANCEL)
+    {
+    // TODO: Place code here to handle when the dialog is
+    //  dismissed with Cancel
+    }
+
+  // Since the dialog has been closed, return FALSE so that we exit the
+  //  application, rather than start the application's message pump.
+  return FALSE;
+}

+ 236 - 0
Source/MFCDialog/CMakeSetup.dsp

@@ -0,0 +1,236 @@
+# Microsoft Developer Studio Project File - Name="CMakeSetup" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=CMakeSetup - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "CMakeSetup.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "CMakeSetup.mak" CFG="CMakeSetup - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "CMakeSetup - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "CMakeSetup - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "CMakeSetup - Win32 Release"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".."
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /machine:I386
+
+!ELSEIF  "$(CFG)" == "CMakeSetup - Win32 Debug"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".."
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FD /GZ /c
+# SUBTRACT CPP /YX /Yc /Yu
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x409 /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "CMakeSetup - Win32 Release"
+# Name "CMakeSetup - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\cmClassFile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSPBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSPMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSWBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSWMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmMakeDepend.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmMakefile.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmPCBuilder.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmRegularExpression.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmSystemTools.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\itkVC60Configure.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmWindowsConfigure.cxx
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetup.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetup.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetupDialog.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\cmClassFile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSPBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSPMakefile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSWBuilder.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmDSWMakefile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmMakeDepend.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmMakefile.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\CMakeSetup.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\cmRegularExpression.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetup.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetupDialog.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\CMakeSetup.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\CMakeSetupDialog.rc2
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\CMakeSetupDialog.ico
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project

+ 49 - 0
Source/MFCDialog/CMakeSetup.h

@@ -0,0 +1,49 @@
+// CMakeSetupdialog.h : main header file for the CMakeSetupDIALOG application
+//
+
+#if !defined(AFX_CMakeSetupDIALOG_H__AC17A6F4_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)
+#define AFX_CMakeSetupDIALOG_H__AC17A6F4_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef __AFXWIN_H__
+#error include 'stdafx.h' before including this file for PCH
+#endif
+
+#include "resource.h"		// main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetup:
+// See CMakeSetupdialog.cpp for the implementation of this class
+//
+
+class CMakeSetup : public CWinApp
+{
+public:
+  CMakeSetup();
+
+// Overrides
+  // ClassWizard generated virtual function overrides
+  //{{AFX_VIRTUAL(CMakeSetup)
+public:
+  virtual BOOL InitInstance();
+  //}}AFX_VIRTUAL
+
+// Implementation
+
+  //{{AFX_MSG(CMakeSetup)
+  // NOTE - the ClassWizard will add and remove member functions here.
+  //    DO NOT EDIT what you see in these blocks of generated code !
+  //}}AFX_MSG
+  DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CMakeSetupDIALOG_H__AC17A6F4_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)

+ 212 - 0
Source/MFCDialog/CMakeSetup.rc

@@ -0,0 +1,212 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+    "#define _AFX_NO_OLE_RESOURCES\r\n"
+    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+    "\r\n"
+    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
+    "#ifdef _WIN32\r\n"
+    "LANGUAGE 9, 1\r\n"
+    "#pragma code_page(1252)\r\n"
+    "#endif //_WIN32\r\n"
+    "#include ""res\\CMakeSetupDialog.rc2""  // non-Microsoft Visual C++ edited resources\r\n"
+    "#include ""afxres.rc""         // Standard components\r\n"
+    "#endif\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME           ICON    DISCARDABLE     "res\\CMakeSetupDialog.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE  0, 0, 235, 55
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About CMakeSetup"
+FONT 8, "MS Sans Serif"
+BEGIN
+    ICON            IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+    LTEXT           "CMakeSetup Version 1.0",IDC_STATIC,40,10,119,8,
+                    SS_NOPREFIX
+    LTEXT           "Copyright (C) 2000",IDC_STATIC,40,25,119,8
+    DEFPUSHBUTTON   "OK",IDOK,178,7,50,14,WS_GROUP
+END
+
+IDD_CMakeSetupDialog_DIALOG DIALOGEX 0, 0, 320, 200
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "CMakeSetupDialog"
+FONT 8, "MS Sans Serif"
+BEGIN
+    DEFPUSHBUTTON   "OK",IDOK,260,7,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,260,23,50,14
+    EDITTEXT        IDC_WhereSource,13,27,135,13,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse...",IDC_BUTTON2,150,28,43,13
+    LTEXT           "Where is the Insight Source",IDC_STATIC,14,15,104,9
+    EDITTEXT        IDC_WhereBuild,16,67,133,13,ES_AUTOHSCROLL
+    PUSHBUTTON      "Browse...",IDC_BUTTON3,151,66,43,13
+    LTEXT           "Where do you want to build the binaries",IDC_STATIC,16,
+                    56,128,9
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904B0"
+        BEGIN
+            VALUE "CompanyName", "\0"
+            VALUE "FileDescription", "CMakeSetup MFC Application\0"
+            VALUE "FileVersion", "1, 0, 0, 1\0"
+            VALUE "InternalName", "CMakeSetup\0"
+            VALUE "LegalCopyright", "Copyright (C) 2000\0"
+            VALUE "LegalTrademarks", "\0"
+            VALUE "OriginalFilename", "CMakeSetup.EXE\0"
+            VALUE "ProductName", "CMakeSetup Application\0"
+            VALUE "ProductVersion", "1, 0, 0, 1\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+
+#endif    // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE 
+BEGIN
+    IDD_ABOUTBOX, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 228
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 48
+    END
+
+    IDD_CMAKESETUPDIALOG_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 313
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 193
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE 
+BEGIN
+    IDS_ABOUTBOX            "&About CMakeSetup..."
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE 9, 1
+#pragma code_page(1252)
+#endif //_WIN32
+#include "res\CMakeSetupDialog.rc2"  // non-Microsoft Visual C++ edited resources
+#include "afxres.rc"         // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 326 - 0
Source/MFCDialog/CMakeSetupDialog.cpp

@@ -0,0 +1,326 @@
+// pcbuilderdialogDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "CMakeSetup.h"
+#include "CMakeSetupDialog.h"
+#include "../cmDSWBuilder.h"
+#include "../itkVC60Configure.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+  CAboutDlg();
+
+// Dialog Data
+  //{{AFX_DATA(CAboutDlg)
+  enum { IDD = IDD_ABOUTBOX };
+  //}}AFX_DATA
+
+  // ClassWizard generated virtual function overrides
+  //{{AFX_VIRTUAL(CAboutDlg)
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
+  //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+  //{{AFX_MSG(CAboutDlg)
+  //}}AFX_MSG
+  DECLARE_MESSAGE_MAP()
+    };
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+  //{{AFX_DATA_INIT(CAboutDlg)
+  //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+  //{{AFX_DATA_MAP(CAboutDlg)
+  //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+  //{{AFX_MSG_MAP(CAboutDlg)
+  // No message handlers
+  //}}AFX_MSG_MAP
+  END_MESSAGE_MAP();
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog dialog
+
+CMakeSetupDialog::CMakeSetupDialog(CWnd* pParent /*=NULL*/)
+  : CDialog(CMakeSetupDialog::IDD, pParent)
+{
+  //{{AFX_DATA_INIT(CMakeSetupDialog)
+  m_WhereSource = _T("");
+  m_WhereBuild = _T("");
+  //}}AFX_DATA_INIT
+  // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
+  m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+  m_WhereSource = _T("");
+  this->LoadFromRegistry();
+}
+
+void CMakeSetupDialog::DoDataExchange(CDataExchange* pDX)
+{
+  CDialog::DoDataExchange(pDX);
+  //{{AFX_DATA_MAP(CMakeSetupDialog)
+  DDX_Text(pDX, IDC_WhereSource, m_WhereSource);
+  DDX_Text(pDX, IDC_WhereBuild, m_WhereBuild);
+  //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CMakeSetupDialog, CDialog)
+  //{{AFX_MSG_MAP(CMakeSetupDialog)
+  ON_WM_SYSCOMMAND()
+  ON_WM_PAINT()
+  ON_WM_QUERYDRAGICON()
+  ON_EN_CHANGE(IDC_WhereSource, OnChangeEdit1)
+  ON_BN_CLICKED(IDC_BUTTON2, OnBrowse)
+  ON_BN_CLICKED(IDC_BUTTON3, OnButton3)
+  //}}AFX_MSG_MAP
+  END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog message handlers
+
+  BOOL CMakeSetupDialog::OnInitDialog()
+{
+  CDialog::OnInitDialog();
+
+  // Add "About..." menu item to system menu.
+
+  // IDM_ABOUTBOX must be in the system command range.
+  ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+  ASSERT(IDM_ABOUTBOX < 0xF000);
+
+  CMenu* pSysMenu = GetSystemMenu(FALSE);
+  if (pSysMenu != NULL)
+    {
+    CString strAboutMenu;
+    strAboutMenu.LoadString(IDS_ABOUTBOX);
+    if (!strAboutMenu.IsEmpty())
+      {
+      pSysMenu->AppendMenu(MF_SEPARATOR);
+      pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+      }
+    }
+
+  // Set the icon for this dialog.  The framework does this automatically
+  //  when the application's main window is not a dialog
+  SetIcon(m_hIcon, TRUE);			// Set big icon
+  SetIcon(m_hIcon, FALSE);		// Set small icon
+	
+  // TODO: Add extra initialization here
+	
+  return TRUE;  // return TRUE  unless you set the focus to a control
+}
+
+void CMakeSetupDialog::OnSysCommand(UINT nID, LPARAM lParam)
+{
+  if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+    {
+    CAboutDlg dlgAbout;
+    dlgAbout.DoModal();
+    }
+  else
+    {
+    CDialog::OnSysCommand(nID, lParam);
+    }
+}
+
+// If you add a minimize button to your dialog, you will need the code below
+//  to draw the icon.  For MFC applications using the document/view model,
+//  this is automatically done for you by the framework.
+
+void CMakeSetupDialog::OnPaint() 
+{
+  if (IsIconic())
+    {
+    CPaintDC dc(this); // device context for painting
+
+    SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
+
+    // Center icon in client rectangle
+    int cxIcon = GetSystemMetrics(SM_CXICON);
+    int cyIcon = GetSystemMetrics(SM_CYICON);
+    CRect rect;
+    GetClientRect(&rect);
+    int x = (rect.Width() - cxIcon + 1) / 2;
+    int y = (rect.Height() - cyIcon + 1) / 2;
+
+    // Draw the icon
+    dc.DrawIcon(x, y, m_hIcon);
+    }
+  else
+    {
+    CDialog::OnPaint();
+    }
+}
+
+// The system calls this to obtain the cursor to display while the user drags
+//  the minimized window.
+HCURSOR CMakeSetupDialog::OnQueryDragIcon()
+{
+  return (HCURSOR) m_hIcon;
+}
+
+void CMakeSetupDialog::OnChangeEdit1() 
+{
+  // TODO: If this is a RICHEDIT control, the control will not
+  // send this notification unless you override the CDialog::OnInitDialog()
+  // function and call CRichEditCtrl().SetEventMask()
+  // with the ENM_CHANGE flag ORed into the mask.
+	
+  // TODO: Add your control notification handler code here
+	
+}
+
+void CMakeSetupDialog::OnBrowse() 
+{
+  this->UpdateData();
+  Browse(m_WhereSource, "Enter Path to Insight Source");
+  this->UpdateData(false);
+}
+
+bool CMakeSetupDialog::Browse(CString &result, const char *title)
+{
+// don't know what to do with initial right now...
+  char szPathName[4096];
+  BROWSEINFO bi;
+ 
+  bi.hwndOwner = m_hWnd;
+  bi.pidlRoot = NULL;
+  bi.pszDisplayName = (LPTSTR)szPathName;
+  bi.lpszTitle = title;
+  bi.ulFlags = BIF_BROWSEINCLUDEFILES  ;
+  bi.lpfn = NULL;
+
+  LPITEMIDLIST pidl = SHBrowseForFolder(&bi);
+
+  bool bSuccess = (bool)SHGetPathFromIDList(pidl, szPathName);
+  if(bSuccess)
+    {
+    result = szPathName;
+    }
+  
+  return bSuccess;
+}
+
+void CMakeSetupDialog::OnOK() 
+{ 
+  // get all the info from the screen
+  this->UpdateData();
+  
+  // configure the system for VC60
+  itkVC60Configure config;
+  config.SetWhereSource(m_WhereSource);
+  config.SetWhereBuild(m_WhereBuild);
+  config.Configure();
+  
+  cmDSWBuilder builder;
+  // Set the ITK home directory
+  builder.SetHomeDirectory(m_WhereSource);
+  // Set the Makefile.in file
+  CString makefileIn = m_WhereSource;
+  makefileIn += "/Makefile.in";
+  builder.SetInputMakefilePath(makefileIn);
+  // Set the output directory
+  builder.SetOutputDirectory(m_WhereBuild);
+  // set the directory which contains the Makefile.in
+  builder.SetMakefileDirectory(m_WhereSource);
+  // Create the master DSW file and all children dsp files for ITK
+  builder.CreateDSWFile();
+  CDialog::OnOK();
+  this->SaveToRegistry();
+}
+
+void CMakeSetupDialog::OnButton3() 
+{
+  this->UpdateData();
+  Browse(m_WhereBuild, "Enter Path to Insight Build");
+  this->UpdateData(false);
+}
+
+void CMakeSetupDialog::SaveToRegistry()
+{ 
+  HKEY hKey;
+  DWORD dwDummy;
+
+  if(RegCreateKeyEx(HKEY_CURRENT_USER, 
+		    _T("Software\\Kitware\\CMakeSetup\\Settings"),
+		    0, "", REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, 
+		    NULL, &hKey, &dwDummy) != ERROR_SUCCESS) 
+    {
+    return;
+    }
+  else
+    {
+    RegSetValueEx(hKey, _T("WhereSource"), 0, REG_SZ, 
+		  (CONST BYTE *)(const char *)m_WhereSource, 
+		  m_WhereSource.GetLength());
+    RegSetValueEx(hKey, _T("WhereBuild"), 0, REG_SZ, 
+		  (CONST BYTE *)(const char *)m_WhereBuild, 
+		  m_WhereBuild.GetLength());
+    
+    }
+  RegCloseKey(hKey);
+}
+
+
+void CMakeSetupDialog::ReadRegistryValue(HKEY hKey,
+					    CString *val,
+					    char *key,
+					    char *adefault)
+{
+  DWORD dwType, dwSize;
+  char *pb;
+
+  dwType = REG_SZ;
+  pb = val->GetBuffer(MAX_PATH);
+  dwSize = MAX_PATH;
+  if(RegQueryValueEx(hKey,_T(key), NULL, &dwType, 
+		     (BYTE *)pb, &dwSize) != ERROR_SUCCESS)
+    {
+    val->ReleaseBuffer();
+    *val = _T(adefault);
+    }
+  else
+    {
+    val->ReleaseBuffer();
+    }
+}
+
+
+void CMakeSetupDialog::LoadFromRegistry()
+{ 
+  HKEY hKey;
+  if(RegOpenKeyEx(HKEY_CURRENT_USER, 
+		  _T("Software\\Kitware\\CMakeSetup\\Settings"), 
+		  0, KEY_READ, &hKey) != ERROR_SUCCESS)
+    {
+    return;
+    }
+  else
+    {
+    // save some values
+    this->ReadRegistryValue(hKey, &(m_WhereSource),"WhereSource","C:\\Insight");
+    this->ReadRegistryValue(hKey, &(m_WhereBuild),"WhereBuild",
+			    "C:\\Insight");
+    }
+  RegCloseKey(hKey);
+}

+ 62 - 0
Source/MFCDialog/CMakeSetupDialog.h

@@ -0,0 +1,62 @@
+// CMakeSetupDialogDlg.h : header file
+//
+
+#if !defined(AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)
+#define AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+/////////////////////////////////////////////////////////////////////////////
+// CMakeSetupDialog dialog
+
+class CMakeSetupDialog : public CDialog
+{
+// Construction
+public:
+  CMakeSetupDialog(CWnd* pParent = NULL);	// standard constructor
+protected:
+  bool Browse(CString&, const char* title);
+  void SaveToRegistry();
+  void LoadFromRegistry();
+  void ReadRegistryValue(HKEY hKey,
+			 CString *val,
+			 char *key,
+			 char *adefault);
+// Dialog Data
+  //{{AFX_DATA(CMakeSetupDialog)
+  enum { IDD = IDD_CMakeSetupDialog_DIALOG };
+  CString	m_WhereSource;
+  CString	m_WhereBuild;
+  //}}AFX_DATA
+  
+  // ClassWizard generated virtual function overrides
+  //{{AFX_VIRTUAL(CMakeSetupDialog)
+protected:
+  virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support
+  //}}AFX_VIRTUAL
+  
+// Implementation
+protected:
+  HICON m_hIcon;
+  
+  // Generated message map functions
+  //{{AFX_MSG(CMakeSetupDialog)
+  virtual BOOL OnInitDialog();
+  afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+  afx_msg void OnPaint();
+  afx_msg HCURSOR OnQueryDragIcon();
+  afx_msg void OnChangeEdit1();
+  afx_msg void OnBrowse();
+  virtual void OnOK();
+  afx_msg void OnButton3();
+  
+  //}}AFX_MSG
+  DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CMakeSetupDialogDLG_H__AC17A6F6_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)

+ 8 - 0
Source/MFCDialog/StdAfx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+//	pcbuilderdialog.pch will be the pre-compiled header
+//	stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+

+ 27 - 0
Source/MFCDialog/StdAfx.h

@@ -0,0 +1,27 @@
+// stdafx.h : include file for standard system include files,
+//  or project specific include files that are used frequently, but
+//      are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__AC17A6F8_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)
+#define AFX_STDAFX_H__AC17A6F8_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN		// Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h>         // MFC core and standard components
+#include <afxext.h>         // MFC extensions
+#include <afxdisp.h>        // MFC Automation classes
+#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>			// MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__AC17A6F8_4634_11D4_8F21_00A0CC33FCD3__INCLUDED_)

二进制
Source/MFCDialog/res/CMakeSetupDialog.ico


+ 13 - 0
Source/MFCDialog/res/CMakeSetupDialog.rc2

@@ -0,0 +1,13 @@
+//
+// PCBUILDERDIALOG.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+	#error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////

+ 24 - 0
Source/MFCDialog/resource.h

@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by pcbuilder.rc
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDD_CMakeSetupDialog_DIALOG      102
+#define IDR_MAINFRAME                   128
+#define IDC_WhereSource                    1001
+#define IDC_BUTTON2                     1002
+#define IDC_WhereBuild                   1003
+#define IDC_BUTTON3                     1004
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        129
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         1003
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 30 - 0
Source/Makefile.in

@@ -0,0 +1,30 @@
+
+srcdir        = @srcdir@
+VPATH         = @srcdir@
+
+# DO NOT INCLUDE CMakeMaster.make here!
+# This will cause an infinite loop as it will add the
+# rule for changing into this directory
+
+@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_OBJ_DIR@/CMake/CMakeRules.make@MAKEQUOTE@
+CMAKE =
+@MAKEINCLUDE@ @MAKEQUOTE@@CMAKE_OBJ_DIR@/CMake/CMakeVariables.make@MAKEQUOTE@
+
+OBJS = \
+cmClassFile.o \
+cmMakefile.o \
+cmUnixMakefile.o \
+cmMakeDepend.o \
+cmRegularExpression.o \
+CMakeBuildTargets.o
+
+cmClassFile.o : cmClassFile.h cmClassFile.cxx
+cmMakefile.o : cmMakefile.h cmMakefile.cxx cmClassFile.h
+cmUnixMakefile.o : cmUnixMakefile.h cmUnixMakefile.cxx cmMakefile.h cmClassFile.h
+cmMakeDepend.o : cmMakeDepend.h cmMakeDepend.cxx  cmMakefile.h cmClassFile.h cmRegularExpression.h
+cmRegularExpression.o : cmRegularExpression.h cmRegularExpression.cxx
+CMakeBuildTargets.o : CMakeBuildTargets.cxx cmMakefile.h cmMakeDepend.h
+
+CMakeBuildTargets: ${OBJS}
+	${CXX}  ${OBJS} ${CXX_FLAGS}  -o CMakeBuildTargets
+

+ 77 - 0
Source/cmClassFile.cxx

@@ -0,0 +1,77 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmClassFile.h"
+#include <sys/stat.h>
+#include <iostream>
+
+
+// Helper function to hide the use of system stat function
+bool cmFileExists(const char* filename)
+{
+  struct stat fs;
+  if (stat(filename, &fs) != 0) 
+  {
+    return false;
+  }
+  else
+  {
+    return true;
+  }
+}
+
+// Set the name of the class and the full path to the file.
+// The class must be found in dir and end in name.cxx, name.txx, 
+// name.c or it will be considered a header file only class
+// and not included in the build process
+void cmClassFile::SetName(const char* name, const char* dir)
+{
+  m_HeaderFileOnly = true;
+  m_ClassName = name;
+  std::string pathname = dir;
+  if(pathname != "")
+    {
+    pathname += "/";
+    }
+  
+  pathname += m_ClassName;
+  std::string hname = pathname;
+  hname += ".cxx";
+  if(cmFileExists(hname.c_str()))
+  {
+    m_HeaderFileOnly = false;
+    m_FullPath = hname;
+    return;
+  }
+  hname = pathname;
+  hname += ".c";
+  if(cmFileExists(hname.c_str()))
+  {
+    m_HeaderFileOnly = false;
+    m_FullPath = hname;
+    return;
+  }
+  hname = pathname;
+  hname += ".txx";
+  if(cmFileExists(hname.c_str()))
+  {
+    m_HeaderFileOnly = false;
+    m_FullPath = hname;
+    return;
+  }
+  std::cerr << "file seems to be a header only " << hname << " " << m_ClassName.c_str() << std::endl;
+}
+
+
+void cmClassFile::Print()
+{
+  if(m_AbstractClass)
+    std::cout <<  "Abstract ";
+  else
+    std::cout << "Concrete ";
+  if(m_HeaderFileOnly)
+    std::cout << "Header file ";
+  else
+    std::cout << "CXX file ";
+  std::cout << m_ClassName << std::endl;
+}

+ 41 - 0
Source/cmClassFile.h

@@ -0,0 +1,41 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmClassFile a structure that represents a class loaded from 
+ * a makefile.
+ */
+#ifndef cmClassFile_h
+#define cmClassFile_h
+#include <string>
+#include <vector>
+
+// helper function returns true if a file exits
+bool cmFileExists(const char* filename);
+
+struct cmClassFile
+{
+  // Set the name of the file
+  void SetName(const char* name, const char* dir);
+  void Print();
+
+  bool m_AbstractClass;
+  bool m_HeaderFileOnly;
+  std::string m_FullPath;
+  std::string m_ClassName;
+  std::vector<std::string> m_Depends;
+};
+
+#endif

+ 31 - 0
Source/cmDSPBuilder.cxx

@@ -0,0 +1,31 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmDSPBuilder.h"
+#include "cmDSPMakefile.h"
+
+cmDSPBuilder::~cmDSPBuilder()
+{
+  delete m_Makefile;
+}
+
+cmDSPBuilder::cmDSPBuilder()
+{
+  m_Makefile = new cmDSPMakefile;
+}
+
+cmMakefile* cmDSPBuilder::GetMakefile()
+{
+  return m_Makefile;
+}
+
+
+void cmDSPBuilder::CreateDSPFile()
+{
+  m_Makefile->OutputDSPFile();
+}
+
+std::vector<std::string> cmDSPBuilder::GetCreatedProjectNames()
+{
+  return m_Makefile->GetCreatedProjectNames();
+}

+ 40 - 0
Source/cmDSPBuilder.h

@@ -0,0 +1,40 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSPBuilder is a Facade class for cmDSWMakefile 
+ */
+
+#ifndef __cmDSPBuilder_h
+#define __cmDSPBuilder_h
+#include "cmPCBuilder.h"
+#include <vector>
+#include <string>
+class cmDSPMakefile;
+
+class cmDSPBuilder : public cmPCBuilder
+{
+public:
+  cmDSPBuilder();
+  ~cmDSPBuilder();
+  void CreateDSPFile();
+  std::vector<std::string> GetCreatedProjectNames();  
+  virtual cmMakefile* GetMakefile();
+protected:
+  cmDSPMakefile* m_Makefile;
+};
+
+#endif
+

+ 278 - 0
Source/cmDSPMakefile.cxx

@@ -0,0 +1,278 @@
+#include "cmDSPMakefile.h"
+#include "cmSystemTools.h"
+#include <iostream>
+#include <fstream>
+#include <windows.h>
+
+void cmDSPMakefile::OutputDSPFile()
+{ 
+  m_IncludeOptions = "/STACK:10000000 ";
+  m_IncludeOptions = "/I \"";
+  m_IncludeOptions += this->GetHomeDirectory();
+  m_IncludeOptions += "/Code/Common\" ";
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetHomeDirectory();
+  m_IncludeOptions += "/Code/Insight3DParty/vxl\" ";
+  // Add the Build directory vcl to the -I path for config.h type stuff
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetOutputHomeDirectory();
+  m_IncludeOptions += "/Code/Insight3DParty/vxl\" ";
+  // Add the Build directory to the -I path for config.h type stuff
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetOutputHomeDirectory();
+  m_IncludeOptions += "\" ";
+  m_DebugLibraryOptions = " ITKCommon.lib ITKNumerics.lib ";
+  m_DebugLibraryOptions += " /LIBPATH:\"";
+  m_DebugLibraryOptions += this->GetOutputHomeDirectory();
+  m_DebugLibraryOptions += "/Code/Common/Debug\" ";
+  m_DebugLibraryOptions += " /LIBPATH:\"";
+  m_DebugLibraryOptions += this->GetOutputHomeDirectory();
+  m_DebugLibraryOptions += "/Code/Insight3DParty/vxl/Debug\" ";
+  m_ReleaseLibraryOptions = m_DebugLibraryOptions;
+  cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
+  // If the output directory is not the m_cmHomeDirectory
+  // then create it.
+  if(m_OutputDirectory != m_cmHomeDirectory)
+    {
+    if(!cmSystemTools::MakeDirectory(m_OutputDirectory.c_str()))
+      {
+      MessageBox(0, "Error creating directory ", 0, MB_OK);
+      MessageBox(0, m_OutputDirectory.c_str(), 0, MB_OK);
+      }
+    }
+  
+  if(!m_Executables)
+    {
+    if(this->m_LibraryName == "")
+      {
+      std::cerr  << "No library name in Makefile.in dsp not created" << std::endl;
+      return;
+      }
+    std::cerr << "building library " << this->m_LibraryName.c_str() << std::endl;
+    this->SetBuildType(STATIC_LIBRARY);
+    this->CreateSingleDSP();
+    }
+  else
+    {
+    std::cerr << "Build Executables " << std::endl;
+    this->CreateExecutableDSPFiles();
+    }
+}
+void cmDSPMakefile::CreateExecutableDSPFiles()
+{
+  std::cerr << "Create executables for ";
+  for(int i = 0; i < m_Classes.size(); ++i)
+    {
+    cmClassFile& classfile = m_Classes[i];
+    std::string fname = m_OutputDirectory;
+    fname += "/";
+    fname += classfile.m_ClassName;
+    fname += ".dsp";
+    std::ofstream fout(fname.c_str());
+    if(!fout)
+      {
+      MessageBox(0, "Error writing ", 0, MB_OK);
+      MessageBox(0, fname.c_str(), 0, MB_OK);
+      std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+      }
+    else
+      {
+      m_LibraryName = classfile.m_ClassName;
+      this->SetBuildType(EXECUTABLE);
+      std::string pname = m_LibraryName;
+      m_CreatedProjectNames.push_back(pname);
+
+      this->WriteDSPHeader(fout);
+      this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+      this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
+      this->WriteDSPEndGroup(fout);
+      this->WriteDSPBuildRule(fout);
+      this->WriteDSPFooter(fout);
+      }
+    
+    }
+}
+
+
+void cmDSPMakefile::CreateSingleDSP()
+{
+  std::string fname;
+  std::cerr << "writting dsp file " << m_cmCurrentDirectory.c_str()
+	    << std::endl;
+  fname = m_OutputDirectory;
+  fname += "/";
+  fname += this->m_LibraryName;
+  fname += ".dsp";
+  m_CreatedProjectNames.clear();
+  std::string pname = m_LibraryName;
+  m_CreatedProjectNames.push_back(pname);
+  std::cerr << "writting dsp file " << fname.c_str() << std::endl;
+  std::ofstream fout(fname.c_str());
+  if(!fout)
+    {
+    MessageBox(0, "Error writing ", 0, MB_OK);
+    MessageBox(0, fname.c_str(), 0, MB_OK);
+    std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+    return;
+  }
+  this->WriteDSPFile(fout);
+}
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
+{
+  std::string dspname = *(m_CreatedProjectNames.end()-1);
+  dspname += ".dsp";
+#undef GetCurrentDirectory
+  std::string makefileIn = this->GetCurrentDirectory();
+  makefileIn += "/";
+  makefileIn += "Makefile.in";
+  std::string dsprule = GetHomeDirectory();
+  dsprule += "/CMake/pcbuilderCMD ";
+  dsprule += makefileIn;
+  dsprule += " -DSP -H";
+  dsprule += this->GetHomeDirectory();
+  dsprule += " -D";
+  dsprule += this->GetCurrentDirectory();
+  dsprule += " -O";
+  dsprule += this->GetOutputDirectory();
+  dsprule += " -B";
+  dsprule += this->GetOutputHomeDirectory();
+  this->WriteCustomRule(fout, makefileIn.c_str(), 
+			dspname.c_str(),
+			dsprule.c_str());
+}
+
+void cmDSPMakefile::WriteDSPFile(std::ostream& fout)
+{
+  this->WriteDSPHeader(fout);
+  this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+  this->WriteDSPBuildRules(fout);
+  this->WriteDSPEndGroup(fout);
+  this->WriteDSPBuildRule(fout);
+  this->WriteDSPFooter(fout);
+}
+
+
+void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
+				     const char* source,
+				     const char* result,
+				     const char* command)
+{
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" << source << "\n\n";
+  fout << "# Begin Custom Build\n\n";
+  fout << '\"' << result << "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n";
+  fout << "  " << command << "\n\n";
+  fout << "# End Custom Build\n\n";
+  fout << "# End Source File\n";
+}
+
+
+void cmDSPMakefile::WriteDSPBeginGroup(std::ostream& fout, 
+					const char* group,
+					const char* filter)
+{
+  fout << "# Begin Group \"" << group << "\"\n"
+    "# PROP Default_Filter \"" << filter << "\"\n";
+}
+
+
+void cmDSPMakefile::WriteDSPEndGroup(std::ostream& fout)
+{
+  fout << "# End Group\n";
+}
+
+
+
+
+void cmDSPMakefile::SetBuildType(BuildType b)
+{
+  switch(b)
+    {
+    case STATIC_LIBRARY:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/staticLibHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/staticLibFooter.dsptemplate";
+      break;
+    case DLL:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/DLLHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/DLLFooter.dsptemplate";
+      break;
+    case EXECUTABLE:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/EXEHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/EXEFooter.dsptemplate";
+      break;
+    }
+}
+
+  
+void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
+{
+  std::ifstream fin(m_DSPHeaderTemplate.c_str());
+  if(!fin)
+    {
+    std::cerr << "failed to open " << m_DSPHeaderTemplate.c_str() 
+	      << " for read" << std::endl;
+    return;
+    }
+  char buffer[2048];
+  while(fin)
+    {
+      fin.getline(buffer, 2048);
+      std::string line = buffer;
+      cmSystemTools::ReplaceString(line, "CM_RELEASE_LIBRARIES",
+                                    m_ReleaseLibraryOptions.c_str());
+      cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
+                                    m_DebugLibraryOptions.c_str());
+      cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
+                                    m_IncludeOptions.c_str());
+      cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", 
+                                    m_LibraryName.c_str());
+      cmSystemTools::ReplaceString(line, 
+                                    "EXTRA_DEFINES", "");
+      fout << line.c_str() << std::endl;
+    }
+}
+
+
+void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
+{  
+  std::ifstream fin(m_DSPFooterTemplate.c_str());
+  if(!fin)
+    {
+    std::cerr << "can not open " << m_DSPFooterTemplate.c_str() <<
+      " for read" << std::endl;
+    return;
+    }
+  char buffer[2048];
+  while(fin)
+    {
+      fin.getline(buffer, 2048);
+      fout << buffer << std::endl;
+    }
+}
+
+					
+void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout)
+{
+  for(int i = 0; i < m_Classes.size(); ++i)
+    {
+    if(!m_Classes[i].m_AbstractClass && !m_Classes[i].m_HeaderFileOnly)
+      {
+      this->WriteDSPBuildRule(fout, m_Classes[i].m_FullPath.c_str());
+      }
+    }
+}
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout, const char* path)
+{
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" 
+       << path << "\n";
+  fout << "# End Source File\n";
+}

+ 69 - 0
Source/cmDSPMakefile.h

@@ -0,0 +1,69 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSPMakefile generate a microsoft DSP project file.
+ * see the *.dsptemplate files for information on the templates
+ * used for making the project files.
+ */
+#ifndef cmDSPMakefile_h
+#define cmDSPMakefile_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmMakefile.h"
+#include <vector>
+
+class cmDSPMakefile : public cmMakefile
+{
+public:
+  void OutputDSPFile();
+  enum BuildType { STATIC_LIBRARY, DLL, EXECUTABLE };
+  void SetBuildType(BuildType );
+  // return array of created DSP names
+  // Each executable must have its own dsp
+  std::vector<std::string> GetCreatedProjectNames() 
+    {
+      return m_CreatedProjectNames;
+    }
+  
+private:
+  std::string m_DSPHeaderTemplate;
+  std::string m_DSPFooterTemplate;
+  std::vector<std::string> m_CreatedProjectNames;
+  
+  void CreateExecutableDSPFiles();
+  void CreateSingleDSP();
+  void WriteDSPFile(std::ostream& fout);
+  void WriteDSPBeginGroup(std::ostream& fout, 
+			  const char* group,
+			  const char* filter);
+  void WriteDSPEndGroup(std::ostream& fout);
+  void WriteDSPHeader(std::ostream& fout);
+  void WriteDSPBuildRules(std::ostream& fout);
+  void WriteDSPBuildRule(std::ostream& fout, const char*);
+  void WriteDSPFooter(std::ostream& fout);
+  void WriteDSPBuildRule(std::ostream& fout);
+  void WriteCustomRule(std::ostream& fout,
+		       const char* source,
+		       const char* result,
+		       const char* command);
+private:
+  std::string m_IncludeOptions;
+  std::string m_DebugLibraryOptions;
+  std::string m_ReleaseLibraryOptions;
+};
+
+#endif

+ 278 - 0
Source/cmDSPWriter.cxx

@@ -0,0 +1,278 @@
+#include "cmDSPMakefile.h"
+#include "cmSystemTools.h"
+#include <iostream>
+#include <fstream>
+#include <windows.h>
+
+void cmDSPMakefile::OutputDSPFile()
+{ 
+  m_IncludeOptions = "/STACK:10000000 ";
+  m_IncludeOptions = "/I \"";
+  m_IncludeOptions += this->GetHomeDirectory();
+  m_IncludeOptions += "/Code/Common\" ";
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetHomeDirectory();
+  m_IncludeOptions += "/Code/Insight3DParty/vxl\" ";
+  // Add the Build directory vcl to the -I path for config.h type stuff
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetOutputHomeDirectory();
+  m_IncludeOptions += "/Code/Insight3DParty/vxl\" ";
+  // Add the Build directory to the -I path for config.h type stuff
+  m_IncludeOptions += "/I \"";
+  m_IncludeOptions += this->GetOutputHomeDirectory();
+  m_IncludeOptions += "\" ";
+  m_DebugLibraryOptions = " ITKCommon.lib ITKNumerics.lib ";
+  m_DebugLibraryOptions += " /LIBPATH:\"";
+  m_DebugLibraryOptions += this->GetOutputHomeDirectory();
+  m_DebugLibraryOptions += "/Code/Common/Debug\" ";
+  m_DebugLibraryOptions += " /LIBPATH:\"";
+  m_DebugLibraryOptions += this->GetOutputHomeDirectory();
+  m_DebugLibraryOptions += "/Code/Insight3DParty/vxl/Debug\" ";
+  m_ReleaseLibraryOptions = m_DebugLibraryOptions;
+  cmSystemTools::ReplaceString(m_ReleaseLibraryOptions, "Debug", "Release");
+  // If the output directory is not the m_cmHomeDirectory
+  // then create it.
+  if(m_OutputDirectory != m_cmHomeDirectory)
+    {
+    if(!cmSystemTools::MakeDirectory(m_OutputDirectory.c_str()))
+      {
+      MessageBox(0, "Error creating directory ", 0, MB_OK);
+      MessageBox(0, m_OutputDirectory.c_str(), 0, MB_OK);
+      }
+    }
+  
+  if(!m_Executables)
+    {
+    if(this->m_LibraryName == "")
+      {
+      std::cerr  << "No library name in Makefile.in dsp not created" << std::endl;
+      return;
+      }
+    std::cerr << "building library " << this->m_LibraryName.c_str() << std::endl;
+    this->SetBuildType(STATIC_LIBRARY);
+    this->CreateSingleDSP();
+    }
+  else
+    {
+    std::cerr << "Build Executables " << std::endl;
+    this->CreateExecutableDSPFiles();
+    }
+}
+void cmDSPMakefile::CreateExecutableDSPFiles()
+{
+  std::cerr << "Create executables for ";
+  for(int i = 0; i < m_Classes.size(); ++i)
+    {
+    cmClassFile& classfile = m_Classes[i];
+    std::string fname = m_OutputDirectory;
+    fname += "/";
+    fname += classfile.m_ClassName;
+    fname += ".dsp";
+    std::ofstream fout(fname.c_str());
+    if(!fout)
+      {
+      MessageBox(0, "Error writing ", 0, MB_OK);
+      MessageBox(0, fname.c_str(), 0, MB_OK);
+      std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+      }
+    else
+      {
+      m_LibraryName = classfile.m_ClassName;
+      this->SetBuildType(EXECUTABLE);
+      std::string pname = m_LibraryName;
+      m_CreatedProjectNames.push_back(pname);
+
+      this->WriteDSPHeader(fout);
+      this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+      this->WriteDSPBuildRule(fout, classfile.m_FullPath.c_str());
+      this->WriteDSPEndGroup(fout);
+      this->WriteDSPBuildRule(fout);
+      this->WriteDSPFooter(fout);
+      }
+    
+    }
+}
+
+
+void cmDSPMakefile::CreateSingleDSP()
+{
+  std::string fname;
+  std::cerr << "writting dsp file " << m_cmCurrentDirectory.c_str()
+	    << std::endl;
+  fname = m_OutputDirectory;
+  fname += "/";
+  fname += this->m_LibraryName;
+  fname += ".dsp";
+  m_CreatedProjectNames.clear();
+  std::string pname = m_LibraryName;
+  m_CreatedProjectNames.push_back(pname);
+  std::cerr << "writting dsp file " << fname.c_str() << std::endl;
+  std::ofstream fout(fname.c_str());
+  if(!fout)
+    {
+    MessageBox(0, "Error writing ", 0, MB_OK);
+    MessageBox(0, fname.c_str(), 0, MB_OK);
+    std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+    return;
+  }
+  this->WriteDSPFile(fout);
+}
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout)
+{
+  std::string dspname = *(m_CreatedProjectNames.end()-1);
+  dspname += ".dsp";
+#undef GetCurrentDirectory
+  std::string makefileIn = this->GetCurrentDirectory();
+  makefileIn += "/";
+  makefileIn += "Makefile.in";
+  std::string dsprule = GetHomeDirectory();
+  dsprule += "/CMake/pcbuilderCMD ";
+  dsprule += makefileIn;
+  dsprule += " -DSP -H";
+  dsprule += this->GetHomeDirectory();
+  dsprule += " -D";
+  dsprule += this->GetCurrentDirectory();
+  dsprule += " -O";
+  dsprule += this->GetOutputDirectory();
+  dsprule += " -B";
+  dsprule += this->GetOutputHomeDirectory();
+  this->WriteCustomRule(fout, makefileIn.c_str(), 
+			dspname.c_str(),
+			dsprule.c_str());
+}
+
+void cmDSPMakefile::WriteDSPFile(std::ostream& fout)
+{
+  this->WriteDSPHeader(fout);
+  this->WriteDSPBeginGroup(fout, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat");
+  this->WriteDSPBuildRules(fout);
+  this->WriteDSPEndGroup(fout);
+  this->WriteDSPBuildRule(fout);
+  this->WriteDSPFooter(fout);
+}
+
+
+void cmDSPMakefile::WriteCustomRule(std::ostream& fout,
+				     const char* source,
+				     const char* result,
+				     const char* command)
+{
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" << source << "\n\n";
+  fout << "# Begin Custom Build\n\n";
+  fout << '\"' << result << "\" : $(SOURCE) \"$(INTDIR)\" \"$(OUTDIR)\"\n";
+  fout << "  " << command << "\n\n";
+  fout << "# End Custom Build\n\n";
+  fout << "# End Source File\n";
+}
+
+
+void cmDSPMakefile::WriteDSPBeginGroup(std::ostream& fout, 
+					const char* group,
+					const char* filter)
+{
+  fout << "# Begin Group \"" << group << "\"\n"
+    "# PROP Default_Filter \"" << filter << "\"\n";
+}
+
+
+void cmDSPMakefile::WriteDSPEndGroup(std::ostream& fout)
+{
+  fout << "# End Group\n";
+}
+
+
+
+
+void cmDSPMakefile::SetBuildType(BuildType b)
+{
+  switch(b)
+    {
+    case STATIC_LIBRARY:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/staticLibHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/staticLibFooter.dsptemplate";
+      break;
+    case DLL:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/DLLHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/DLLFooter.dsptemplate";
+      break;
+    case EXECUTABLE:
+      m_DSPHeaderTemplate = m_cmHomeDirectory;
+      m_DSPHeaderTemplate += "/CMake/EXEHeader.dsptemplate";
+      m_DSPFooterTemplate = m_cmHomeDirectory;
+      m_DSPFooterTemplate += "/CMake/EXEFooter.dsptemplate";
+      break;
+    }
+}
+
+  
+void cmDSPMakefile::WriteDSPHeader(std::ostream& fout)
+{
+  std::ifstream fin(m_DSPHeaderTemplate.c_str());
+  if(!fin)
+    {
+    std::cerr << "failed to open " << m_DSPHeaderTemplate.c_str() 
+	      << " for read" << std::endl;
+    return;
+    }
+  char buffer[2048];
+  while(fin)
+    {
+      fin.getline(buffer, 2048);
+      std::string line = buffer;
+      cmSystemTools::ReplaceString(line, "CM_RELEASE_LIBRARIES",
+                                    m_ReleaseLibraryOptions.c_str());
+      cmSystemTools::ReplaceString(line, "CM_DEBUG_LIBRARIES",
+                                    m_DebugLibraryOptions.c_str());
+      cmSystemTools::ReplaceString(line, "BUILD_INCLUDES",
+                                    m_IncludeOptions.c_str());
+      cmSystemTools::ReplaceString(line, "OUTPUT_LIBNAME", 
+                                    m_LibraryName.c_str());
+      cmSystemTools::ReplaceString(line, 
+                                    "EXTRA_DEFINES", "");
+      fout << line.c_str() << std::endl;
+    }
+}
+
+
+void cmDSPMakefile::WriteDSPFooter(std::ostream& fout)
+{  
+  std::ifstream fin(m_DSPFooterTemplate.c_str());
+  if(!fin)
+    {
+    std::cerr << "can not open " << m_DSPFooterTemplate.c_str() <<
+      " for read" << std::endl;
+    return;
+    }
+  char buffer[2048];
+  while(fin)
+    {
+      fin.getline(buffer, 2048);
+      fout << buffer << std::endl;
+    }
+}
+
+					
+void cmDSPMakefile::WriteDSPBuildRules(std::ostream& fout)
+{
+  for(int i = 0; i < m_Classes.size(); ++i)
+    {
+    if(!m_Classes[i].m_AbstractClass && !m_Classes[i].m_HeaderFileOnly)
+      {
+      this->WriteDSPBuildRule(fout, m_Classes[i].m_FullPath.c_str());
+      }
+    }
+}
+
+void cmDSPMakefile::WriteDSPBuildRule(std::ostream& fout, const char* path)
+{
+  fout << "# Begin Source File\n\n";
+  fout << "SOURCE=" 
+       << path << "\n";
+  fout << "# End Source File\n";
+}

+ 69 - 0
Source/cmDSPWriter.h

@@ -0,0 +1,69 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSPMakefile generate a microsoft DSP project file.
+ * see the *.dsptemplate files for information on the templates
+ * used for making the project files.
+ */
+#ifndef cmDSPMakefile_h
+#define cmDSPMakefile_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmMakefile.h"
+#include <vector>
+
+class cmDSPMakefile : public cmMakefile
+{
+public:
+  void OutputDSPFile();
+  enum BuildType { STATIC_LIBRARY, DLL, EXECUTABLE };
+  void SetBuildType(BuildType );
+  // return array of created DSP names
+  // Each executable must have its own dsp
+  std::vector<std::string> GetCreatedProjectNames() 
+    {
+      return m_CreatedProjectNames;
+    }
+  
+private:
+  std::string m_DSPHeaderTemplate;
+  std::string m_DSPFooterTemplate;
+  std::vector<std::string> m_CreatedProjectNames;
+  
+  void CreateExecutableDSPFiles();
+  void CreateSingleDSP();
+  void WriteDSPFile(std::ostream& fout);
+  void WriteDSPBeginGroup(std::ostream& fout, 
+			  const char* group,
+			  const char* filter);
+  void WriteDSPEndGroup(std::ostream& fout);
+  void WriteDSPHeader(std::ostream& fout);
+  void WriteDSPBuildRules(std::ostream& fout);
+  void WriteDSPBuildRule(std::ostream& fout, const char*);
+  void WriteDSPFooter(std::ostream& fout);
+  void WriteDSPBuildRule(std::ostream& fout);
+  void WriteCustomRule(std::ostream& fout,
+		       const char* source,
+		       const char* result,
+		       const char* command);
+private:
+  std::string m_IncludeOptions;
+  std::string m_DebugLibraryOptions;
+  std::string m_ReleaseLibraryOptions;
+};
+
+#endif

+ 22 - 0
Source/cmDSWBuilder.cxx

@@ -0,0 +1,22 @@
+#include "cmDSWBuilder.h"
+#include "cmDSWMakefile.h"
+
+cmDSWBuilder::~cmDSWBuilder()
+{
+  delete m_Makefile;
+}
+
+cmDSWBuilder::cmDSWBuilder()
+{
+  m_Makefile = new cmDSWMakefile;
+}
+
+cmMakefile* cmDSWBuilder::GetMakefile()
+{
+  return m_Makefile;
+}
+
+void cmDSWBuilder::CreateDSWFile()
+{
+  m_Makefile->OutputDSWFile();
+}

+ 38 - 0
Source/cmDSWBuilder.h

@@ -0,0 +1,38 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSWBuilder 
+ */
+
+#ifndef __cmDSWBuilder_h
+#define __cmDSWBuilder_h
+
+#include "cmPCBuilder.h"
+class cmDSWMakefile;
+
+class cmDSWBuilder : public cmPCBuilder
+{
+public:
+  cmDSWBuilder();
+  ~cmDSWBuilder();
+  void CreateDSWFile();
+  virtual cmMakefile* GetMakefile();
+protected:
+  cmDSWMakefile* m_Makefile;
+};
+
+#endif
+

+ 129 - 0
Source/cmDSWMakefile.cxx

@@ -0,0 +1,129 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmDSWMakefile.h"
+#include "cmDSPBuilder.h"
+#include "cmSystemTools.h"
+#include <iostream>
+#include <fstream>
+#include <windows.h>
+
+
+// virtual override, ouput the makefile 
+void cmDSWMakefile::OutputDSWFile()
+{ 
+  if(m_OutputDirectory == "")
+    {
+    // default to build in place
+    m_OutputDirectory = m_cmHomeDirectory;
+    }
+  // If the output directory is not the m_cmHomeDirectory
+  // then create it.
+  if(m_OutputDirectory != m_cmHomeDirectory)
+    {
+    if(!cmSystemTools::MakeDirectory(m_OutputDirectory.c_str()))
+      {
+      MessageBox(0, "Error creating directory ", 0, MB_OK);
+      MessageBox(0, m_OutputDirectory.c_str(), 0, MB_OK);
+      }
+    }
+  
+  
+  std::string fname;
+  fname = m_OutputDirectory;
+  fname += "/";
+  fname += this->m_LibraryName;
+  fname += ".dsw";
+  std::cerr << "writting dsw file " << fname.c_str() << std::endl;
+
+  std::ofstream fout(fname.c_str());
+  if(!fout)
+    {
+    std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+    return;
+    }
+  this->WriteDSWFile(fout);
+}
+
+
+void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
+{
+  this->WriteDSWHeader(fout);
+  for(std::vector<std::string>::iterator i = m_SubDirectories.begin();
+      i != m_SubDirectories.end(); ++i)
+    {
+    const char* dir = (*i).c_str();
+    std::vector<std::string> dspnames = this->CreateDSPFile(dir);
+    std::cerr << "Create dsp for " << dspnames.size() << " number of dsp files in " << dir << std::endl;
+    for(std::vector<std::string>::iterator si = dspnames.begin();
+	si != dspnames.end(); ++si)
+      {
+      std::string dspname = *si;
+      std::cerr << "Create dsp for " << (*si).c_str() << std::endl;
+      if(dspname == "")
+	{
+	std::cerr << "Project name not found in " << dir << "/Makefile.in" << std::endl;
+	std::cerr << "Skipping Project " << std::endl;
+	}
+      else
+	{
+	std::string subdir = "./";
+	subdir += dir;
+	this->WriteProject(fout, dspname.c_str(), subdir.c_str());
+	}
+      }
+    }
+  this->WriteDSWFooter(fout);
+}
+
+std::vector<std::string> cmDSWMakefile::CreateDSPFile(const char* subdir)
+{
+#undef GetCurrentDirectory
+  std::string currentDir = this->GetCurrentDirectory();
+  currentDir += "/";
+  currentDir += subdir;
+  cmDSPBuilder dsp;
+  dsp.SetOutputHomeDirectory(this->GetOutputDirectory());
+  dsp.SetHomeDirectory(this->GetHomeDirectory());
+  dsp.SetMakefileDirectory(currentDir.c_str());
+  std::string outdir = m_OutputDirectory;
+  outdir += "/";
+  outdir += subdir;
+  dsp.SetOutputDirectory(outdir.c_str());
+  currentDir += "/";
+  currentDir += "Makefile.in";
+  dsp.SetInputMakefilePath(currentDir.c_str());
+  dsp.CreateDSPFile();
+  return dsp.GetCreatedProjectNames();
+}
+
+
+void cmDSWMakefile::WriteProject(std::ostream& fout, 
+				  const char* dspname,
+				  const char* dir)
+{
+  fout << "###############################################################################\n\n";
+  fout << "Project: \"" << dspname << "\"=" 
+       << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
+  fout << "Package=<5>\n{{{\n}}}\n\n";
+  fout << "Package=<4>\n";
+  fout << "{{{\n";
+  // insert Begin Project Dependency  Project_Dep_Name project stuff here
+  fout << "}}}\n\n";
+}
+
+void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
+{
+  fout << "###############################################################################\n\n";
+  fout << "Global:\n\n";
+  fout << "Package=<5>\n{{{\n}}}\n\n";
+  fout << "Package=<3>\n{{{\n}}}\n\n";
+  fout << "###############################################################################\n\n";
+}
+
+  
+void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
+{
+  fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";
+  fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
+}

+ 42 - 0
Source/cmDSWMakefile.h

@@ -0,0 +1,42 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSWMakefile - class to write a microsoft DSW file.
+ */
+#ifndef cmDSWMakefile_h
+#define cmDSWMakefile_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+
+#include "cmMakefile.h"
+#include <vector>
+
+
+class cmDSWMakefile : public cmMakefile
+{
+public:
+  virtual void OutputDSWFile();
+private:
+  void WriteDSWFile(std::ostream& fout);
+  void WriteDSWHeader(std::ostream& fout);
+  std::vector<std::string> CreateDSPFile(const char* dir);
+  void WriteProject(std::ostream& fout, 
+		     const char* name, const char* path);
+  void WriteDSWFooter(std::ostream& fout);
+};
+
+#endif

+ 129 - 0
Source/cmDSWWriter.cxx

@@ -0,0 +1,129 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmDSWMakefile.h"
+#include "cmDSPBuilder.h"
+#include "cmSystemTools.h"
+#include <iostream>
+#include <fstream>
+#include <windows.h>
+
+
+// virtual override, ouput the makefile 
+void cmDSWMakefile::OutputDSWFile()
+{ 
+  if(m_OutputDirectory == "")
+    {
+    // default to build in place
+    m_OutputDirectory = m_cmHomeDirectory;
+    }
+  // If the output directory is not the m_cmHomeDirectory
+  // then create it.
+  if(m_OutputDirectory != m_cmHomeDirectory)
+    {
+    if(!cmSystemTools::MakeDirectory(m_OutputDirectory.c_str()))
+      {
+      MessageBox(0, "Error creating directory ", 0, MB_OK);
+      MessageBox(0, m_OutputDirectory.c_str(), 0, MB_OK);
+      }
+    }
+  
+  
+  std::string fname;
+  fname = m_OutputDirectory;
+  fname += "/";
+  fname += this->m_LibraryName;
+  fname += ".dsw";
+  std::cerr << "writting dsw file " << fname.c_str() << std::endl;
+
+  std::ofstream fout(fname.c_str());
+  if(!fout)
+    {
+    std::cerr  << "Error can not open " << fname.c_str() << " for write" << std::endl;
+    return;
+    }
+  this->WriteDSWFile(fout);
+}
+
+
+void cmDSWMakefile::WriteDSWFile(std::ostream& fout)
+{
+  this->WriteDSWHeader(fout);
+  for(std::vector<std::string>::iterator i = m_SubDirectories.begin();
+      i != m_SubDirectories.end(); ++i)
+    {
+    const char* dir = (*i).c_str();
+    std::vector<std::string> dspnames = this->CreateDSPFile(dir);
+    std::cerr << "Create dsp for " << dspnames.size() << " number of dsp files in " << dir << std::endl;
+    for(std::vector<std::string>::iterator si = dspnames.begin();
+	si != dspnames.end(); ++si)
+      {
+      std::string dspname = *si;
+      std::cerr << "Create dsp for " << (*si).c_str() << std::endl;
+      if(dspname == "")
+	{
+	std::cerr << "Project name not found in " << dir << "/Makefile.in" << std::endl;
+	std::cerr << "Skipping Project " << std::endl;
+	}
+      else
+	{
+	std::string subdir = "./";
+	subdir += dir;
+	this->WriteProject(fout, dspname.c_str(), subdir.c_str());
+	}
+      }
+    }
+  this->WriteDSWFooter(fout);
+}
+
+std::vector<std::string> cmDSWMakefile::CreateDSPFile(const char* subdir)
+{
+#undef GetCurrentDirectory
+  std::string currentDir = this->GetCurrentDirectory();
+  currentDir += "/";
+  currentDir += subdir;
+  cmDSPBuilder dsp;
+  dsp.SetOutputHomeDirectory(this->GetOutputDirectory());
+  dsp.SetHomeDirectory(this->GetHomeDirectory());
+  dsp.SetMakefileDirectory(currentDir.c_str());
+  std::string outdir = m_OutputDirectory;
+  outdir += "/";
+  outdir += subdir;
+  dsp.SetOutputDirectory(outdir.c_str());
+  currentDir += "/";
+  currentDir += "Makefile.in";
+  dsp.SetInputMakefilePath(currentDir.c_str());
+  dsp.CreateDSPFile();
+  return dsp.GetCreatedProjectNames();
+}
+
+
+void cmDSWMakefile::WriteProject(std::ostream& fout, 
+				  const char* dspname,
+				  const char* dir)
+{
+  fout << "###############################################################################\n\n";
+  fout << "Project: \"" << dspname << "\"=" 
+       << dir << "\\" << dspname << ".dsp - Package Owner=<4>\n\n";
+  fout << "Package=<5>\n{{{\n}}}\n\n";
+  fout << "Package=<4>\n";
+  fout << "{{{\n";
+  // insert Begin Project Dependency  Project_Dep_Name project stuff here
+  fout << "}}}\n\n";
+}
+
+void cmDSWMakefile::WriteDSWFooter(std::ostream& fout)
+{
+  fout << "###############################################################################\n\n";
+  fout << "Global:\n\n";
+  fout << "Package=<5>\n{{{\n}}}\n\n";
+  fout << "Package=<3>\n{{{\n}}}\n\n";
+  fout << "###############################################################################\n\n";
+}
+
+  
+void cmDSWMakefile::WriteDSWHeader(std::ostream& fout)
+{
+  fout << "Microsoft Developer Studio Workspace File, Format Version 6.00\n";
+  fout << "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n\n";
+}

+ 42 - 0
Source/cmDSWWriter.h

@@ -0,0 +1,42 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmDSWMakefile - class to write a microsoft DSW file.
+ */
+#ifndef cmDSWMakefile_h
+#define cmDSWMakefile_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+
+#include "cmMakefile.h"
+#include <vector>
+
+
+class cmDSWMakefile : public cmMakefile
+{
+public:
+  virtual void OutputDSWFile();
+private:
+  void WriteDSWFile(std::ostream& fout);
+  void WriteDSWHeader(std::ostream& fout);
+  std::vector<std::string> CreateDSPFile(const char* dir);
+  void WriteProject(std::ostream& fout, 
+		     const char* name, const char* path);
+  void WriteDSWFooter(std::ostream& fout);
+};
+
+#endif

+ 268 - 0
Source/cmMakeDepend.cxx

@@ -0,0 +1,268 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmMakeDepend.h"
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+#include <functional>
+
+
+void cmMakeDepend::SetIncludeRegularExpression(const char* prefix)
+{
+  m_IncludeFileRegularExpression.compile(prefix);
+}
+
+cmMakeDepend::cmMakeDepend()
+{
+  m_Verbose = false;
+  m_IncludeFileRegularExpression.compile("^itk|^vtk|^vnl|^vcl|^f2c");
+}
+
+cmMakeDepend::~cmMakeDepend()
+{ 
+  for(DependArray::iterator i = m_DependInformation.begin();
+      i != m_DependInformation.end(); ++i)
+    {
+    delete *i;
+    }
+  m_DependInformation.clear();
+}
+
+
+// Set the makefile that depends will be made from.
+// The pointer is kept so the cmClassFile array can
+// be updated with the depend information. 
+
+void cmMakeDepend::SetMakefile(cmMakefile* makefile)
+{
+  m_Makefile = makefile;
+  int index = 0;
+  std::vector<cmClassFile>::iterator i = makefile->m_Classes.begin();
+  while(i != makefile->m_Classes.end())
+    {
+    if(!(*i).m_HeaderFileOnly)
+      {
+      cmDependInformation* info = new cmDependInformation;
+      info->m_FullPath = this->FullPath((*i).m_FullPath.c_str());
+      this->AddFileToSearchPath(info->m_FullPath.c_str());
+      info->m_IncludeName = (*i).m_FullPath;
+      m_DependInformation.push_back(info);
+      info->m_ClassFileIndex = index;
+      
+      }
+    ++i;
+    index++;
+    }
+}
+
+
+// Compute the depends.
+void cmMakeDepend::DoDepends()
+{
+  // The size of the m_DependInformation will change as
+  // Depend is called so do not use an iterater but rather
+  // depend on the size of the array.
+  int j = 0;
+  while(j != m_DependInformation.size())
+    {
+    cmDependInformation* info = m_DependInformation[j];
+    // compute the depend information for the info object
+    // this may add more objects to the m_DependInformation
+    // array
+    this->Depend(info);
+    ++j;
+    }
+  // Now update the depend information for each cmClassFile
+  // in the cmMakefile m_Makefile
+  for(DependArray::iterator i = m_DependInformation.begin();
+      i != m_DependInformation.end(); ++i)
+    {
+    cmDependInformation* info = *i;
+    // Remove duplicate depends
+    info->RemoveDuplicateIndices();
+    std::vector<cmClassFile>::iterator j = m_Makefile->m_Classes.begin();
+    // find the class 
+    if(info->m_ClassFileIndex != -1)
+      {
+      cmClassFile& cfile = m_Makefile->m_Classes[info->m_ClassFileIndex];
+      for( std::vector<int>::iterator indx = info->m_Indices.begin();
+	   indx != info->m_Indices.end(); ++indx)
+	{
+	cfile.m_Depends.push_back(m_DependInformation[*indx]->m_FullPath);
+	}
+      }
+    }
+}
+
+// This function actually reads the file
+// and scans it for #include directives
+void cmMakeDepend::Depend(cmDependInformation* info)
+{
+  const char* path = info->m_FullPath.c_str();
+  if(!path)
+    {
+    std::cerr << "no full path for object"  << std::endl;
+    return;
+    }
+  
+  std::ifstream fin(path);
+  if(!fin)
+    {
+    std::cerr << "error can not open " << info->m_FullPath << std::endl;
+    return;
+    }
+  char line[255];
+  while(!fin.eof() && !fin.fail())
+    {
+    fin.getline(line, 255);
+    if(!strncmp(line, "#include", 8))
+      {
+      // if it is an include line then create a string class
+      std::string currentline = line;
+      size_t qstart = currentline.find('\"', 8);
+      size_t qend;
+      // if a quote is not found look for a <
+      if(qstart == std::string::npos)
+	{
+	qstart = currentline.find('<', 8);
+	// if a < is not found then move on
+	if(qstart == std::string::npos)
+	  {
+	  std::cerr << "unknown include directive " << currentline 
+		    << std::endl;
+	  continue;
+	  }
+	else
+	  {
+	  qend = currentline.find('>', qstart+1);
+	  }
+	}
+      else
+	{
+	qend = currentline.find('\"', qstart+1);
+	}
+      // extract the file being included
+      std::string includeFile = currentline.substr(qstart+1, qend - qstart-1);
+      // see if the include matches the regular expression
+      if(!m_IncludeFileRegularExpression.find(includeFile))
+	{
+	if(m_Verbose)
+	  {
+	  std::cerr  << "skipping " << includeFile << " for file " << path << std::endl;
+	  }
+	continue;
+	}
+      // find the index of the include file in the
+      // m_DependInformation array, if it is not
+      // there then FindInformation will create it
+      int index = this->FindInformation(includeFile.c_str());
+      // add the index to the depends of the current 
+      // depend info object
+      info->m_Indices.push_back(index);
+      // Get the depend information object for the include file
+      cmDependInformation* dependInfo = m_DependInformation[index];
+      // if the depends are not known for an include file, then compute them
+      // recursively 
+      if(!dependInfo->m_DependDone)
+	{
+	// stop the recursion here
+	dependInfo->m_DependDone = true;
+	this->Depend(dependInfo);
+	}
+      // add the depends of the included file to the includer
+      info->MergeInfo(dependInfo);
+      }
+    }
+  info->m_DependDone = true;
+}
+
+
+// Find the cmDependInformation array index of the 
+// given include file.   Create a new cmDependInformation
+// object if one is not found
+int cmMakeDepend::FindInformation(const char* fname)
+{
+  int i = 0;
+  
+  while(i < m_DependInformation.size())
+    {
+    if(m_DependInformation[i]->m_IncludeName == fname)
+      {
+      return i;
+      }    
+    ++i;
+    }
+  cmDependInformation* newinfo = new cmDependInformation;
+  newinfo->m_FullPath = this->FullPath(fname);
+  this->AddFileToSearchPath(newinfo->m_FullPath.c_str());
+  newinfo->m_IncludeName = fname;
+  m_DependInformation.push_back(newinfo);
+  return m_DependInformation.size()-1;
+}
+
+// remove duplicate indices from the depend information 
+void cmDependInformation::RemoveDuplicateIndices()
+{
+  std::sort(m_Indices.begin(), m_Indices.end(), std::less<int>());
+  std::vector<int>::iterator new_end = 
+    std::unique(m_Indices.begin(), m_Indices.end());
+  m_Indices.erase(new_end, m_Indices.end());
+}
+
+// add the depend information from info to this
+void cmDependInformation::MergeInfo(cmDependInformation* info)
+{
+  std::vector<int>::iterator i = info->m_Indices.begin();
+  for(; i!= info->m_Indices.end(); ++i)
+    {
+    m_Indices.push_back(*i);
+    }
+}
+
+// find the full path to fname by searching the m_IncludeDirectories array
+std::string cmMakeDepend::FullPath(const char* fname)
+{
+  for(std::vector<std::string>::iterator i = m_IncludeDirectories.begin();
+      i != m_IncludeDirectories.end(); ++i)
+    {
+    if(cmFileExists(fname))
+      {
+      return std::string(fname);
+      }
+    std::string path = *i;
+    path = path + "/";
+    path = path + fname;
+    if(cmFileExists(path.c_str()))
+      {
+      return path;
+      }
+    }
+  std::cerr << "File not found " << fname  << std::endl;
+  return std::string(fname);
+}
+
+// Add a directory to the search path
+void cmMakeDepend::AddSearchPath(const char* path)
+{
+  m_IncludeDirectories.push_back(path);
+}
+
+// Add a directory to the search path
+void cmMakeDepend::AddFileToSearchPath(const char* file)
+{
+  std::string filepath = file;
+  std::string::size_type pos = filepath.rfind('/');
+  if(pos != std::string::npos)
+    {
+    std::string path = filepath.substr(0, pos);
+    if(std::find(m_IncludeDirectories.begin(), m_IncludeDirectories.end(), path)
+       == m_IncludeDirectories.end())
+      {
+      m_IncludeDirectories.push_back(path);
+      return;
+      }
+    }
+}
+
+  

+ 115 - 0
Source/cmMakeDepend.h

@@ -0,0 +1,115 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmMakeDepend 
+ */
+#ifndef cmMakeDepend_h
+#define cmMakeDepend_h
+
+#include "cmMakefile.h"
+#include "cmClassFile.h"
+#include "cmRegularExpression.h"
+#include <vector>
+#include <string>
+
+
+// This structure stores the depend information 
+// for a single source file
+struct cmDependInformation
+{
+  cmDependInformation() 
+    {
+      m_DependDone = false;
+      m_ClassFileIndex = -1;
+    }
+// index into m_DependInformation array of cmMakeDepend 
+// class, represents the files that this file depends on
+  std::vector<int> m_Indices;	
+
+// full path to file
+  std::string m_FullPath;	
+
+// name as include directive uses
+  std::string m_IncludeName;
+
+// refers back to the index of the  cmMakefile's array
+// of cmClassFile objects which this class class describes,
+// -1 for files not in the array
+  int m_ClassFileIndex;	
+  
+// flag to determine if depends have
+// been done for this file
+  bool m_DependDone;
+  
+// function to add the depends of another file to this one
+  void MergeInfo(cmDependInformation*);
+  
+// remove duplicate depends from the index list
+  void RemoveDuplicateIndices();
+};
+
+
+// cmMakeDepend is used to generate dependancy information for
+// the classes in a makefile
+class cmMakeDepend
+{
+public:
+  cmMakeDepend();
+  ~cmMakeDepend();
+  
+  /** 
+   * Set the makefile that is used as a source of classes.
+   */
+  void SetMakefile(cmMakefile* makefile); 
+  /** 
+   * Generate the depend information
+   */
+  void DoDepends();
+  /** 
+   * Set a regular expression that include files must match
+   * in order to be considered as part of the depend information
+   */
+  void SetIncludeRegularExpression(const char* regex);
+  /**
+   * Add a directory to the search path for include files
+   */
+  void AddSearchPath(const char*);
+private: 
+  void AddFileToSearchPath(const char* filepath);
+  /**
+   * Find the index into the m_DependInformation array
+   * that matches the given m_IncludeName
+   */
+  int FindInformation(const char* includeName);
+  /**
+   * Compute the depend information for this class
+   */
+  void Depend(cmDependInformation* info);
+  /** 
+   * Find the full path name for the given file name.
+   * This uses the include directories
+   */
+  std::string FullPath(const char*);
+private:
+  cmMakefile* m_Makefile;
+  bool m_Verbose;
+  cmRegularExpression m_IncludeFileRegularExpression;
+  typedef std::vector<cmDependInformation*> DependArray;
+  DependArray m_DependInformation;
+  std::vector<std::string> m_IncludeDirectories;
+};
+
+#endif

+ 208 - 0
Source/cmMakefile.cxx

@@ -0,0 +1,208 @@
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+#include "cmMakefile.h"
+#include "cmClassFile.h"
+
+#include <fstream>
+#include <iostream>
+
+
+// remove extra spaces and the "\" character from the name
+// of the class as it is in the Makefile.in
+inline std::string CleanUpName(const char* name)
+{
+  std::string className = name;
+  size_t i =0;
+  while(className[i] == ' ')
+    {
+    i++;
+    }
+  if(i)
+    {
+    className = className.substr(i, className.size());
+    } 
+  size_t pos = className.find('\\');
+  if(pos != std::string::npos)
+    {
+    className = className.substr(0, pos);
+    }
+  
+  pos = className.find(' ');
+  if(pos != std::string::npos)
+    {
+    className = className.substr(0, pos);
+    }
+  return className;
+}
+
+// default is not to be building executables
+cmMakefile::cmMakefile()
+{
+  m_Executables = false;
+}
+
+
+// call print on all the classes in the makefile
+void cmMakefile::Print()
+{
+  for(int i = 0; i < m_Classes.size(); i++)
+    m_Classes[i].Print();
+}
+
+// Parse the given Makefile.in file into a list of classes.
+
+bool cmMakefile::ReadMakefile(const char* filename)
+{
+  std::cerr << "reading makefile " << filename << std::endl;
+  std::ifstream fin(filename);
+  if(!fin)
+    {
+    std::cerr << "error can not open file " << filename << std::endl;
+    return false;
+    }
+  char inbuffer[2048];
+  while ( fin.getline(inbuffer, 2047 ) )
+    {
+    std::string line = inbuffer;
+    cmClassFile file;
+    if(line.find("COMPILE_CLASSES") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadClasses(fin, false);
+	}
+      }
+#ifdef _WIN32
+    else if(line.find("WIN32_CLASSES") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadClasses(fin, false);
+	}
+      }
+#else
+    else if(line.find("UNIX_CLASSES") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadClasses(fin, false);
+	}
+      }
+#endif
+    else if(line.find("ABSTRACT_CLASSES") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadClasses(fin, true);
+	}
+      }
+    else if(line.find("SUBDIRS") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadSubdirs(fin);
+	}
+      }
+    else if(line.find("EXECUTABLES") != std::string::npos)
+      {
+      if(line.find("\\") != std::string::npos)
+	{
+	this->ReadClasses(fin, false);
+	m_Executables = true;
+	}
+      }
+    else if(line.find("ME") != std::string::npos)
+      {
+      size_t mestart = line.find("ME");
+      size_t start = line.find("=");
+      if(start != std::string::npos && start > mestart )
+	{
+	start++;
+	while(line[start] == ' ' && start < line.size())
+	  {
+	  start++;
+	  }
+	size_t end = line.size()-1;
+	while(line[end] == ' ' && end > start)
+	  {
+	  end--;
+	  }
+	this->SetLibraryName(line.substr(start, end).c_str());
+	}
+      }
+    }
+  return true;
+}
+  
+
+// Read a list from the Makefile stream
+void cmMakefile::ReadClasses(std::ifstream& fin,
+			      bool abstract)
+{
+  char inbuffer[2048];
+  bool done = false;
+  while (!done)
+    {  
+    // read a line from the makefile
+    fin.getline(inbuffer, 2047); 
+    // convert to a string class
+    std::string classname = inbuffer;
+    // if the line does not end in \ then we are at the
+    // end of the list
+    if(classname.find('\\') == std::string::npos)
+      {
+      done = true;
+      }
+    // remove extra spaces and \ from the class name
+    classname = CleanUpName(classname.c_str());
+    
+    // if this is not an abstract list then add new class
+    // to the list of classes in this makefile
+    if(!abstract)
+      {
+      cmClassFile file;
+      file.SetName(classname.c_str(), this->GetCurrentDirectory());
+      file.m_AbstractClass = false;
+      m_Classes.push_back(file);
+      }
+    else
+      {
+      // if this is an abstract list, then look
+      // for an existing class and set it to abstract
+      for(int i = 0; i < m_Classes.size(); i++)
+	{
+	if(m_Classes[i].m_ClassName == classname)
+	  {
+	  m_Classes[i].m_AbstractClass = true;
+	  break;
+	  }
+	}
+      }
+    }
+}
+
+
+// Read a list of subdirectories from the stream
+void cmMakefile::ReadSubdirs(std::ifstream& fin)
+{
+  char inbuffer[2048];
+  bool done = false;
+
+  while (!done)
+    {  
+    // read a line from the makefile
+    fin.getline(inbuffer, 2047); 
+    // convert to a string class
+    std::string dir = inbuffer;
+    // if the line does not end in \ then we are at the
+    // end of the list
+    if(dir.find('\\') == std::string::npos)
+      {
+      done = true;
+      }
+    // remove extra spaces and \ from the class name
+    dir = CleanUpName(dir.c_str());
+    m_SubDirectories.push_back(dir);
+    }
+}

+ 104 - 0
Source/cmMakefile.h

@@ -0,0 +1,104 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmMakefile
+ */
+#ifndef cmMakefile_h
+#define cmMakefile_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+
+#include "cmClassFile.h"
+#include <vector>
+#include <fstream>
+#include <iostream>
+
+class cmMakefile
+{
+public:
+  cmMakefile();
+  // Parse a Makfile.in file
+  bool ReadMakefile(const char* makefile); 
+  // Print useful stuff to stdout
+  void Print();
+  // Set the home directory for the project
+  void SetHomeDirectory(const char* dir) 
+    {
+      m_cmHomeDirectory = dir;
+    }
+  const char* GetHomeDirectory() 
+    {
+      return m_cmHomeDirectory.c_str();
+    }
+  // Set the current directory in the project
+  void SetCurrentDirectory(const char* dir) 
+    {
+      m_cmCurrentDirectory = dir;
+    }
+  const char* GetCurrentDirectory() 
+    {
+      return m_cmCurrentDirectory.c_str();
+    }
+  // Set the name of the library that is built by this makefile
+  void SetLibraryName(const char* lib)
+    {
+      m_LibraryName = lib;
+    }
+  const char* GetLibraryName()
+    {
+      return m_LibraryName.c_str();
+    }
+  
+  // Set the name of the library that is built by this makefile
+  void SetOutputDirectory(const char* lib)
+    {
+      m_OutputDirectory = lib;
+    }
+  const char* GetOutputDirectory()
+    {
+      return m_OutputDirectory.c_str();
+    }
+  
+  // Set the name of the library that is built by this makefile
+  void SetOutputHomeDirectory(const char* lib)
+    {
+      m_OutputHomeDirectory = lib;
+    }
+  const char* GetOutputHomeDirectory()
+    {
+      return m_OutputHomeDirectory.c_str();
+    }
+  
+private:
+  void ReadSubdirs(std::ifstream& fin);
+  void ReadClasses(std::ifstream& fin, bool t);
+  friend class cmMakeDepend;	// make depend needs direct access 
+				// to the m_Classes array
+protected:
+  bool m_Executables;
+  std::string m_Prefix;
+  std::string m_OutputDirectory; // Current output directory for makefile
+  std::string m_OutputHomeDirectory; // Top level output directory
+  std::string m_cmHomeDirectory; // Home directory for source
+  std::string m_cmCurrentDirectory; // current directory in source
+  std::string m_LibraryName;	// library name
+  std::vector<cmClassFile> m_Classes; // list of classes in makefile
+  std::vector<std::string> m_SubDirectories; // list of sub directories
+};
+
+
+#endif

+ 46 - 0
Source/cmPCBuilder.cxx

@@ -0,0 +1,46 @@
+#include "cmPCBuilder.h"
+#include "cmMakefile.h"
+
+
+cmPCBuilder::cmPCBuilder()
+{
+}
+ 
+// Delete the m_Makefile
+cmPCBuilder::~cmPCBuilder()
+{
+}
+
+// Read in the given makefile
+void cmPCBuilder::SetInputMakefilePath(const char* mfile)
+{
+  if(!GetMakefile()->ReadMakefile(mfile))
+    {
+    std::cerr << "Error can not open " << mfile << " for input " << std::endl;
+    abort();
+    }
+}
+
+
+void cmPCBuilder::SetHomeDirectory(const char* dir)
+{
+  GetMakefile()->SetHomeDirectory(dir);
+} 
+
+void cmPCBuilder::SetMakefileDirectory(const char* dir)
+{
+  GetMakefile()->SetCurrentDirectory(dir);
+}
+
+
+
+void cmPCBuilder::SetOutputDirectory(const char* dir)
+{
+  GetMakefile()->SetOutputDirectory(dir);
+}
+
+void cmPCBuilder::SetOutputHomeDirectory(const char* dir)
+{
+  GetMakefile()->SetOutputHomeDirectory(dir);
+}
+

+ 43 - 0
Source/cmPCBuilder.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmPCBuilder 
+ */
+
+#ifndef __cmPCBuilder_h
+#define __cmPCBuilder_h
+class cmMakefile;
+/**
+ * cmPCBuilder is a supper class used for creating a build
+ * file for PC's.  This class can parse an cm Makefile.in and
+ * extract the classes that need to be compiled.
+ */
+
+class cmPCBuilder 
+{
+public:
+  cmPCBuilder();
+  ~cmPCBuilder();
+  virtual cmMakefile* GetMakefile() = 0;
+  void SetInputMakefilePath(const char*);
+  void SetHomeDirectory(const char*);
+  void SetMakefileDirectory(const char*);
+  void SetOutputDirectory(const char*);
+  void SetOutputHomeDirectory(const char*);
+};
+
+#endif
+

+ 1279 - 0
Source/cmRegularExpression.cxx

@@ -0,0 +1,1279 @@
+//
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify,
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+//
+// Created: MNF 06/13/89  Initial Design and Implementation
+// Updated: LGO 08/09/89  Inherit from Generic
+// Updated: MBN 09/07/89  Added conditional exception handling
+// Updated: MBN 12/15/89  Sprinkled "const" qualifiers all over the place!
+// Updated: DLS 03/22/91  New lite version
+//
+// This  is the header file  for the regular  expression class.   An object of
+// this class contains a regular expression,  in  a special "compiled" format.
+// This  compiled format consists  of  several slots   all kept as the objects
+// private data.  The cmRegularExpression class  provides a convenient  way  to  represent
+// regular  expressions.  It makes it easy   to search  for  the  same regular
+// expression in many different strings without having to  compile a string to
+// regular expression format more than necessary.
+//
+// A regular  expression allows a programmer to  specify complex patterns that
+// can be searched for  and  matched against the  character string of a String
+// object.  In  its  simplest case, a   regular expression  is a  sequence  of
+// characters with which you can search for exact character matches.  However,
+// many times you may not know the exact sequence you want to find, or you may
+// only want to find a match at the beginning or end of  a String.  The cmRegularExpression
+// object  allows specification of  such patterns by  utilizing the  following
+// regular  expression  meta-characters   (note   that  more  one  of    these
+// meta-characters  can  be used in a single  regular  expression in  order to
+// create complex search patterns):
+//
+//         ^    Match at beginning of line
+//         $    Match at end of line
+//         .    Match any single character
+//         [ ]  Match any one character inside the brackets
+//         [^ ] Match any character NOT inside the brackets
+//         -    Match any character in range on either side of dash
+//         *    Match preceding pattern zero or more times
+//         +    Match preceding pattern one or more times
+//         ?    Match preceding pattern zero or once only
+//         ()   Save a matched expression and use it in a further match.
+//
+// There are three constructors for cmRegularExpression.  One  just creates an empty cmRegularExpression
+// object.  Another creates a cmRegularExpression object  and initializes it with a regular
+// expression  that is given  in  the form of a   char*.   The  third  takes a
+// reference  to  a cmRegularExpression  object    as an  argument    and creates an object
+// initialized with the information from the given cmRegularExpression object.
+//
+// The  find  member function  finds   the  first  occurence   of  the regualr
+// expression of that object in the string given to find as an argument.  Find
+// returns a boolean, and  if true,  mutates  the private  data appropriately.
+// Find sets pointers to the beginning and end of  the thing last  found, they
+// are pointers into the actual string  that was searched.   The start and end
+// member functions return indicies  into the searched string that  correspond
+// to the beginning   and  end pointers  respectively.   The    compile member
+// function takes a char* and puts the  compiled version of the char* argument
+// into the object's private data fields.  The == and  != operators only check
+// the  to see  if   the compiled  regular  expression   is the same, and  the
+// deep_equal functions also checks  to see if the  start and end pointers are
+// the same.  The is_valid  function returns false if  program is set to NULL,
+// (i.e. there is no valid compiled exression).  The set_invalid function sets
+// the  program to NULL  (Warning: this deletes the compiled  expression). The
+// following examples may help clarify regular expression usage:
+//
+//   *  The regular expression  "^hello" matches  a "hello"  only at  the
+//      beginning of a  line.  It would match "hello  there" but not "hi,
+//      hello there".
+//
+//   *  The regular expression "long$" matches a  "long"  only at the end
+//      of a line. It would match "so long\0", but not "long ago".
+//
+//   *  The regular expression "t..t..g"  will match anything that  has a
+//      "t" then any two characters, another "t", any  two characters and
+//      then a "g".   It will match  "testing", or "test again" but would
+//      not match "toasting"
+//
+//   *  The regular  expression "[1-9ab]" matches any  number one through
+//      nine, and the characters  "a" and  "b".  It would match "hello 1"
+//      or "begin", but would not match "no-match".
+//
+//   *  The  regular expression "[^1-9ab]"  matches any character that is
+//      not a number one  through nine, or  an "a" or "b".   It would NOT
+//      match "hello 1" or "begin", but would match "no-match".
+//
+//   *  The regular expression "br* " matches  something that begins with
+//      a "b", is followed by zero or more "r"s, and ends in a space.  It
+//      would match "brrrrr ", and "b ", but would not match "brrh ".
+//
+//   *  The regular expression "br+ " matches something  that begins with
+//      a "b", is followed by one or more "r"s, and ends in  a space.  It
+//      would match "brrrrr ",  and  "br ", but would not  match "b  " or
+//      "brrh ".
+//
+//   *  The regular expression "br? " matches  something that begins with
+//      a "b", is followed by zero or one "r"s, and ends in  a space.  It
+//      would  match  "br ", and "b  ", but would not match  "brrrr "  or
+//      "brrh ".
+//
+//   *  The regular expression "(..p)b" matches  something ending with pb
+//      and beginning with whatever the two characters before the first p
+//      encounterd in the line were.  It would find  "repb" in "rep drepa
+//      qrepb".  The regular expression "(..p)a"  would find "repa qrepb"
+//      in "rep drepa qrepb"
+//
+//   *  The regular expression "d(..p)" matches something ending  with p,
+//      beginning with d, and having  two characters  in between that are
+//      the same as the two characters before  the first p  encounterd in
+//      the line.  It would match "drepa qrepb" in "rep drepa qrepb".
+//
+
+#include "cmRegularExpression.h"	// Include class specification 
+#include <stdio.h>
+#include <string>
+
+// cmRegularExpression -- Copies the given regular expression.
+
+cmRegularExpression::cmRegularExpression (const cmRegularExpression& rxp) {
+  int ind; 
+  this->progsize = rxp.progsize;		// Copy regular expression size
+  this->program = new char[this->progsize];	// Allocate storage
+  for(ind=this->progsize; ind-- != 0;)		// Copy regular expresion
+    this->program[ind] = rxp.program[ind];
+  this->startp[0] = rxp.startp[0];		// Copy pointers into last
+  this->endp[0] = rxp.endp[0];			// Successful "find" operation
+  this->regmust = rxp.regmust;			// Copy field
+  if (rxp.regmust != NULL) {
+    char* dum = rxp.program;
+    ind = 0;
+    while (dum != rxp.regmust) {
+      ++dum;
+      ++ind;
+    }
+    this->regmust = this->program + ind;
+  }
+  this->regstart = rxp.regstart;		// Copy starting index
+  this->reganch = rxp.reganch;			// Copy remaining private data
+  this->regmlen = rxp.regmlen;			// Copy remaining private data
+}
+
+
+// operator== -- Returns true if two regular expressions have the same
+// compiled program for pattern matching.
+
+bool cmRegularExpression::operator== (const cmRegularExpression& rxp) const {
+  if (this != &rxp) {				// Same address?
+    int ind = this->progsize;			// Get regular expression size
+    if (ind != rxp.progsize)			// If different size regexp
+      return false;				// Return failure
+    while(ind-- != 0)				// Else while still characters
+      if(this->program[ind] != rxp.program[ind]) // If regexp are different    
+	return false;				 // Return failure             
+  }
+  return true;					// Else same, return success  
+}
+
+
+// deep_equal -- Returns true if have the same compiled regular expressions
+// and the same start and end pointers.
+
+bool cmRegularExpression::deep_equal (const cmRegularExpression& rxp) const {
+  int ind = this->progsize;			// Get regular expression size
+  if (ind != rxp.progsize)			// If different size regexp
+    return false;				// Return failure
+  while(ind-- != 0)				// Else while still characters
+    if(this->program[ind] != rxp.program[ind])	// If regexp are different    
+      return false;				// Return failure             
+  return (this->startp[0] == rxp.startp[0] && 	// Else if same start/end ptrs,
+	  this->endp[0] == rxp.endp[0]);	// Return true
+}   
+
+// The remaining code in this file is derived from the  regular expression code
+// whose  copyright statement appears  below.  It has been  changed to work
+// with the class concepts of C++ and COOL.
+
+/*
+ * compile and find 
+ *
+ *	Copyright (c) 1986 by University of Toronto.
+ *	Written by Henry Spencer.  Not derived from licensed software.
+ *
+ *	Permission is granted to anyone to use this software for any
+ *	purpose on any computer system, and to redistribute it freely,
+ *	subject to the following restrictions:
+ *
+ *	1. The author is not responsible for the consequences of use of
+ *		this software, no matter how awful, even if they arise
+ *		from defects in it.
+ *
+ *	2. The origin of this software must not be misrepresented, either
+ *		by explicit claim or by omission.
+ *
+ *	3. Altered versions must be plainly marked as such, and must not
+ *		be misrepresented as being the original software.
+ *
+ * Beware that some of this code is subtly aware of the way operator
+ * precedence is structured in regular expressions.  Serious changes in
+ * regular-expression syntax might require a total rethink.
+ */
+
+/*
+ * The "internal use only" fields in regexp.h are present to pass info from
+ * compile to execute that permits the execute phase to run lots faster on
+ * simple cases.  They are:
+ *
+ * regstart	char that must begin a match; '\0' if none obvious
+ * reganch	is the match anchored (at beginning-of-line only)?
+ * regmust	string (pointer into program) that match must include, or NULL
+ * regmlen	length of regmust string
+ *
+ * Regstart and reganch permit very fast decisions on suitable starting points
+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
+ * of lines that cannot possibly match.  The regmust tests are costly enough
+ * that compile() supplies a regmust only if the r.e. contains something
+ * potentially expensive (at present, the only such thing detected is * or +
+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
+ * supplied because the test in find() needs it and compile() is computing
+ * it anyway.
+ */
+
+/*
+ * Structure for regexp "program".  This is essentially a linear encoding
+ * of a nondeterministic finite-state machine (aka syntax charts or
+ * "railroad normal form" in parsing technology).  Each node is an opcode
+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
+ * all nodes except BRANCH implement concatenation; a "next" pointer with
+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we
+ * have one of the subtle syntax dependencies:  an individual BRANCH (as
+ * opposed to a collection of them) is never concatenated with anything
+ * because of operator precedence.)  The operand of some types of node is
+ * a literal string; for others, it is a node leading into a sub-FSM.  In
+ * particular, the operand of a BRANCH node is the first node of the branch.
+ * (NB this is *not* a tree structure:  the tail of the branch connects
+ * to the thing following the set of BRANCHes.)  The opcodes are:
+ */
+
+// definition	number	opnd?	meaning
+#define	END	0		// no	End of program.
+#define	BOL	1		// no	Match "" at beginning of line.
+#define	EOL	2		// no	Match "" at end of line.
+#define	ANY	3		// no	Match any one character.
+#define	ANYOF	4		// str	Match any character in this string.
+#define	ANYBUT	5		// str	Match any character not in this
+				// string.
+#define	BRANCH	6		// node	Match this alternative, or the
+				// next...
+#define	BACK	7		// no	Match "", "next" ptr points backward.
+#define	EXACTLY	8		// str	Match this string.
+#define	NOTHING	9		// no	Match empty string.
+#define	STAR	10		// node	Match this (simple) thing 0 or more
+				// times.
+#define	PLUS	11		// node	Match this (simple) thing 1 or more
+				// times.
+#define	OPEN	20		// no	Mark this point in input as start of
+				// #n.
+// OPEN+1 is number 1, etc.
+#define	CLOSE	30		// no	Analogous to OPEN.
+
+/*
+ * Opcode notes:
+ *
+ * BRANCH	The set of branches constituting a single choice are hooked
+ *		together with their "next" pointers, since precedence prevents
+ *		anything being concatenated to any individual branch.  The
+ *		"next" pointer of the last BRANCH in a choice points to the
+ *		thing following the whole choice.  This is also where the
+ *		final "next" pointer of each individual branch points; each
+ *		branch starts with the operand node of a BRANCH node.
+ *
+ * BACK		Normal "next" pointers all implicitly point forward; BACK
+ *		exists to make loop structures possible.
+ *
+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
+ *		BRANCH structures using BACK.  Simple cases (one character
+ *		per match) are implemented with STAR and PLUS for speed
+ *		and to minimize recursive plunges.
+ *
+ * OPEN,CLOSE	...are numbered at compile time.
+ */
+
+/*
+ * A node is one char of opcode followed by two chars of "next" pointer.
+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The
+ * value is a positive offset from the opcode of the node containing it.
+ * An operand, if any, simply follows the node.  (Note that much of the
+ * code generation knows about this implicit relationship.)
+ *
+ * Using two bytes for the "next" pointer is vast overkill for most things,
+ * but allows patterns to get big without disasters.
+ */
+
+#define	OP(p)		(*(p))
+#define	NEXT(p)		(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
+#define	OPERAND(p)	((p) + 3)
+
+const unsigned char MAGIC = 0234;
+/*
+ * Utility definitions.
+ */
+
+#define	UCHARAT(p)	((const unsigned char*)(p))[0]
+
+
+#define	FAIL(m)	{ regerror(m); return(NULL); }
+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
+#define	META	"^$.[()|?+*\\"
+
+
+/*
+ * Flags to be passed up and down.
+ */
+#define	HASWIDTH	01	// Known never to match null string.
+#define	SIMPLE		02	// Simple enough to be STAR/PLUS operand.
+#define	SPSTART		04	// Starts with * or +.
+#define	WORST		0	// Worst case.
+
+
+
+/////////////////////////////////////////////////////////////////////////
+//
+//  COMPILE AND ASSOCIATED FUNCTIONS
+//
+/////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for compile().
+ */
+static const char* regparse;	// Input-scan pointer.
+static       int   regnpar;	// () count.
+static       char  regdummy;
+static       char* regcode;	// Code-emit pointer; &regdummy = don't.
+static       long  regsize;	// Code size.
+
+/*
+ * Forward declarations for compile()'s friends.
+ */
+// #ifndef static
+// #define	static	static
+// #endif
+static       char* reg (int, int*);
+static       char* regbranch (int*);
+static       char* regpiece (int*);
+static       char* regatom (int*);
+static       char* regnode (char);
+static const char* regnext (register const char*);
+static       char* regnext (register char*);
+static void        regc (unsigned char);
+static void        reginsert (char, char*);
+static void        regtail (char*, const char*);
+static void        regoptail (char*, const char*);
+
+#ifdef STRCSPN
+static int strcspn ();
+#endif
+
+
+
+/*
+ * We can't allocate space until we know how big the compiled form will be,
+ * but we can't compile it (and thus know how big it is) until we've got a
+ * place to put the code.  So we cheat:  we compile it twice, once with code
+ * generation turned off and size counting turned on, and once "for real".
+ * This also means that we don't allocate space until we are sure that the
+ * thing really will compile successfully, and we never have to move the
+ * code and thus invalidate pointers into it.  (Note that it has to be in
+ * one piece because free() must be able to free it all.)
+ *
+ * Beware that the optimization-preparation code in here knows about some
+ * of the structure of the compiled regexp.
+ */
+
+
+// compile -- compile a regular expression into internal code
+// for later pattern matching.
+
+void cmRegularExpression::compile (const char* exp) {
+    register const char* scan;
+    register const char* longest;
+    register unsigned long len;
+             int         flags;
+
+    if (exp == NULL) {
+      //RAISE Error, SYM(cmRegularExpression), SYM(No_Expr),
+      printf ("cmRegularExpression::compile(): No expression supplied.\n");
+      return;
+    }
+
+    // First pass: determine size, legality.
+    regparse = exp;
+    regnpar = 1;
+    regsize = 0L;
+    regcode = &regdummy;
+    regc(MAGIC);
+    if(!reg(0, &flags))
+      {
+	printf ("cmRegularExpression::compile(): Error in compile.\n");
+	return;
+      }
+    this->startp[0] = this->endp[0] = this->searchstring = NULL;
+
+    // Small enough for pointer-storage convention? 
+    if (regsize >= 32767L) {	// Probably could be 65535L. 
+      //RAISE Error, SYM(cmRegularExpression), SYM(Expr_Too_Big),
+      printf ("cmRegularExpression::compile(): Expression too big.\n");
+      return;
+    }
+
+    // Allocate space. 
+//#ifndef WIN32
+    if (this->program != NULL) delete [] this->program;  
+//#endif
+    this->program = new char[regsize];
+    this->progsize = (int) regsize;
+
+    if (this->program == NULL) {
+      //RAISE Error, SYM(cmRegularExpression), SYM(Out_Of_Memory),
+      printf ("cmRegularExpression::compile(): Out of memory.\n"); 
+      return;
+    }
+
+    // Second pass: emit code.
+    regparse = exp;
+    regnpar = 1;
+    regcode = this->program;
+    regc(MAGIC);
+    reg(0, &flags);
+
+    // Dig out information for optimizations.
+    this->regstart = '\0';		// Worst-case defaults.
+    this->reganch = 0;
+    this->regmust = NULL;
+    this->regmlen = 0;
+    scan = this->program + 1;	// First BRANCH.
+    if (OP(regnext(scan)) == END) {	// Only one top-level choice.
+	scan = OPERAND(scan);
+
+	// Starting-point info.
+	if (OP(scan) == EXACTLY)
+	    this->regstart = *OPERAND(scan);
+	else if (OP(scan) == BOL)
+	    this->reganch++;
+
+	 //
+	 // If there's something expensive in the r.e., find the longest
+	 // literal string that must appear and make it the regmust.  Resolve
+	 // ties in favor of later strings, since the regstart check works
+	 // with the beginning of the r.e. and avoiding duplication
+	 // strengthens checking.  Not a strong reason, but sufficient in the
+	 // absence of others. 
+	 //
+	if (flags & SPSTART) {
+	    longest = NULL;
+	    len = 0;
+	    for (; scan != NULL; scan = regnext(scan))
+		if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
+		    longest = OPERAND(scan);
+		    len = strlen(OPERAND(scan));
+		}
+	    this->regmust = longest;
+	    this->regmlen = len;
+	}
+    }
+}
+
+
+/*
+ - reg - regular expression, i.e. main body or parenthesized thing
+ *
+ * Caller must absorb opening parenthesis.
+ *
+ * Combining parenthesis handling with the base level of regular expression
+ * is a trifle forced, but the need to tie the tails of the branches to what
+ * follows makes it hard to avoid.
+ */
+static char* reg (int paren, int *flagp) {
+    register char* ret;
+    register char* br;
+    register char* ender;
+    register int   parno =0;
+             int   flags;
+
+    *flagp = HASWIDTH;		// Tentatively.
+
+    // Make an OPEN node, if parenthesized.
+    if (paren) {
+	if (regnpar >= NSUBEXP) {
+	  //RAISE Error, SYM(cmRegularExpression), SYM(Too_Many_Parens),
+	  printf ("cmRegularExpression::compile(): Too many parentheses.\n");
+	  return 0;
+        }
+	parno = regnpar;
+	regnpar++;
+	ret = regnode(OPEN + parno);
+    }
+    else
+	ret = NULL;
+
+    // Pick up the branches, linking them together.
+    br = regbranch(&flags);
+    if (br == NULL)
+	return (NULL);
+    if (ret != NULL)
+	regtail(ret, br);	// OPEN -> first.
+    else
+	ret = br;
+    if (!(flags & HASWIDTH))
+	*flagp &= ~HASWIDTH;
+    *flagp |= flags & SPSTART;
+    while (*regparse == '|') {
+	regparse++;
+	br = regbranch(&flags);
+	if (br == NULL)
+	    return (NULL);
+	regtail(ret, br);	// BRANCH -> BRANCH.
+	if (!(flags & HASWIDTH))
+	    *flagp &= ~HASWIDTH;
+	*flagp |= flags & SPSTART;
+      }
+
+    // Make a closing node, and hook it on the end.
+    ender = regnode((paren) ? CLOSE + parno : END);
+    regtail(ret, ender);
+
+    // Hook the tails of the branches to the closing node.
+    for (br = ret; br != NULL; br = regnext(br))
+	regoptail(br, ender);
+
+    // Check for proper termination.
+    if (paren && *regparse++ != ')') {
+        //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Parens),
+        printf ("cmRegularExpression::compile(): Unmatched parentheses.\n");
+	return 0;
+    }
+    else if (!paren && *regparse != '\0') {
+        if (*regparse == ')') {
+            //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Parens),
+            printf ("cmRegularExpression::compile(): Unmatched parentheses.\n");
+	    return 0;
+	}
+	else {
+	    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+	    printf ("cmRegularExpression::compile(): Internal error.\n");
+	    return 0;
+        }
+	// NOTREACHED
+    }
+    return (ret);
+}
+
+
+/*
+ - regbranch - one alternative of an | operator
+ *
+ * Implements the concatenation operator.
+ */
+static char* regbranch (int *flagp) {
+    register char* ret;
+    register char* chain;
+    register char* latest;
+    int                  flags;
+
+    *flagp = WORST;		// Tentatively.
+
+    ret = regnode(BRANCH);
+    chain = NULL;
+    while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
+	latest = regpiece(&flags);
+	if (latest == NULL)
+	    return (NULL);
+	*flagp |= flags & HASWIDTH;
+	if (chain == NULL)	// First piece.
+	    *flagp |= flags & SPSTART;
+	else
+	    regtail(chain, latest);
+	chain = latest;
+    }
+    if (chain == NULL)		// Loop ran zero times.
+	regnode(NOTHING);
+
+    return (ret);
+}
+
+
+/*
+ - regpiece - something followed by possible [*+?]
+ *
+ * Note that the branching code sequences used for ? and the general cases
+ * of * and + are somewhat optimized:  they use the same NOTHING node as
+ * both the endmarker for their branch list and the body of the last branch.
+ * It might seem that this node could be dispensed with entirely, but the
+ * endmarker role is not redundant.
+ */
+static char* regpiece (int *flagp) {
+    register char* ret;
+    register char  op;
+    register char* next;
+    int            flags;
+
+    ret = regatom(&flags);
+    if (ret == NULL)
+	return (NULL);
+
+    op = *regparse;
+    if (!ISMULT(op)) {
+	*flagp = flags;
+	return (ret);
+    }
+
+    if (!(flags & HASWIDTH) && op != '?') {
+        //RAISE Error, SYM(cmRegularExpression), SYM(Empty_Operand),
+        printf ("cmRegularExpression::compile() : *+ operand could be empty.\n");
+	return 0;
+    }
+    *flagp = (op != '+') ? (WORST | SPSTART) : (WORST | HASWIDTH);
+
+    if (op == '*' && (flags & SIMPLE))
+	reginsert(STAR, ret);
+    else if (op == '*') {
+	// Emit x* as (x&|), where & means "self".
+	reginsert(BRANCH, ret);	// Either x
+	regoptail(ret, regnode(BACK));	// and loop
+	regoptail(ret, ret);	// back
+	regtail(ret, regnode(BRANCH));	// or
+	regtail(ret, regnode(NOTHING));	// null.
+    }
+    else if (op == '+' && (flags & SIMPLE))
+	reginsert(PLUS, ret);
+    else if (op == '+') {
+	// Emit x+ as x(&|), where & means "self".
+	next = regnode(BRANCH);	// Either
+	regtail(ret, next);
+	regtail(regnode(BACK), ret);	// loop back
+	regtail(next, regnode(BRANCH));	// or
+	regtail(ret, regnode(NOTHING));	// null.
+    }
+    else if (op == '?') {
+	// Emit x? as (x|)
+	reginsert(BRANCH, ret);	// Either x
+	regtail(ret, regnode(BRANCH));	// or
+	next = regnode(NOTHING);// null.
+	regtail(ret, next);
+	regoptail(ret, next);
+    }
+    regparse++;
+    if (ISMULT(*regparse)) {
+        //RAISE Error, SYM(cmRegularExpression), SYM(Nested_Operand),
+        printf ("cmRegularExpression::compile(): Nested *?+.\n");
+	return 0;
+    }
+    return (ret);
+}
+
+
+/*
+ - regatom - the lowest level
+ *
+ * Optimization:  gobbles an entire sequence of ordinary characters so that
+ * it can turn them into a single node, which is smaller to store and
+ * faster to run.  Backslashed characters are exceptions, each becoming a
+ * separate node; the code is simpler that way and it's not worth fixing.
+ */
+static char* regatom (int *flagp) {
+    register char* ret;
+             int   flags;
+
+    *flagp = WORST;		// Tentatively.
+
+    switch (*regparse++) {
+	case '^':
+	    ret = regnode(BOL);
+	    break;
+	case '$':
+	    ret = regnode(EOL);
+	    break;
+	case '.':
+	    ret = regnode(ANY);
+	    *flagp |= HASWIDTH | SIMPLE;
+	    break;
+	case '[':{
+		register int    rxpclass;
+		register int    rxpclassend;
+
+		if (*regparse == '^') {	// Complement of range.
+		    ret = regnode(ANYBUT);
+		    regparse++;
+		}
+		else
+		    ret = regnode(ANYOF);
+		if (*regparse == ']' || *regparse == '-')
+		    regc(*regparse++);
+		while (*regparse != '\0' && *regparse != ']') {
+		    if (*regparse == '-') {
+			regparse++;
+			if (*regparse == ']' || *regparse == '\0')
+			    regc('-');
+			else {
+			    rxpclass = UCHARAT(regparse - 2) + 1;
+			    rxpclassend = UCHARAT(regparse);
+			    if (rxpclass > rxpclassend + 1) {
+			       //RAISE Error, SYM(cmRegularExpression), SYM(Invalid_Range),
+			       printf ("cmRegularExpression::compile(): Invalid range in [].\n");
+			       return 0;
+                            }
+			    for (; rxpclass <= rxpclassend; rxpclass++)
+				regc(rxpclass);
+			    regparse++;
+			}
+		    }
+		    else
+			regc(*regparse++);
+		}
+		regc('\0');
+		if (*regparse != ']') {
+                    //RAISE Error, SYM(cmRegularExpression), SYM(Unmatched_Bracket),
+                    printf ("cmRegularExpression::compile(): Unmatched [].\n");
+		    return 0;
+	        }
+		regparse++;
+		*flagp |= HASWIDTH | SIMPLE;
+	    }
+	    break;
+	case '(':
+	    ret = reg(1, &flags);
+	    if (ret == NULL)
+		return (NULL);
+	    *flagp |= flags & (HASWIDTH | SPSTART);
+	    break;
+	case '\0':
+	case '|':
+	case ')':
+	    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+            printf ("cmRegularExpression::compile(): Internal error.\n"); // Never here
+	    return 0;
+	case '?':
+	case '+':
+	case '*':
+	    //RAISE Error, SYM(cmRegularExpression), SYM(No_Operand),
+            printf ("cmRegularExpression::compile(): ?+* follows nothing.\n");
+	    return 0;
+	case '\\':
+	    if (*regparse == '\0') {
+	        //RAISE Error, SYM(cmRegularExpression), SYM(Trailing_Backslash),
+                printf ("cmRegularExpression::compile(): Trailing backslash.\n");
+		return 0;
+            }
+	    ret = regnode(EXACTLY);
+	    regc(*regparse++);
+	    regc('\0');
+	    *flagp |= HASWIDTH | SIMPLE;
+	    break;
+	default:{
+		register int    len;
+		register char   ender;
+
+		regparse--;
+		len = strcspn(regparse, META);
+		if (len <= 0) {
+		    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+                    printf ("cmRegularExpression::compile(): Internal error.\n");
+		    return 0;
+                }
+		ender = *(regparse + len);
+		if (len > 1 && ISMULT(ender))
+		    len--;	// Back off clear of ?+* operand.
+		*flagp |= HASWIDTH;
+		if (len == 1)
+		    *flagp |= SIMPLE;
+		ret = regnode(EXACTLY);
+		while (len > 0) {
+		    regc(*regparse++);
+		    len--;
+		}
+		regc('\0');
+	    }
+	    break;
+    }
+    return (ret);
+}
+
+
+/*
+ - regnode - emit a node
+   Location.
+ */
+static char* regnode (char op) {
+    register char* ret;
+    register char* ptr;
+
+    ret = regcode;
+    if (ret == &regdummy) {
+	regsize += 3;
+	return (ret);
+    }
+
+    ptr = ret;
+    *ptr++ = op;
+    *ptr++ = '\0';		// Null "next" pointer.
+    *ptr++ = '\0';
+    regcode = ptr;
+
+    return (ret);
+}
+
+
+/*
+ - regc - emit (if appropriate) a byte of code
+ */
+static void regc (unsigned char b) {
+    if (regcode != &regdummy)
+	*regcode++ = b;
+    else
+	regsize++;
+}
+
+
+/*
+ - reginsert - insert an operator in front of already-emitted operand
+ *
+ * Means relocating the operand.
+ */
+static void reginsert (char op, char* opnd) {
+    register char* src;
+    register char* dst;
+    register char* place;
+
+    if (regcode == &regdummy) {
+	regsize += 3;
+	return;
+    }
+
+    src = regcode;
+    regcode += 3;
+    dst = regcode;
+    while (src > opnd)
+	*--dst = *--src;
+
+    place = opnd;		// Op node, where operand used to be.
+    *place++ = op;
+    *place++ = '\0';
+    *place++ = '\0';
+}
+
+
+/*
+ - regtail - set the next-pointer at the end of a node chain
+ */
+static void regtail (char* p, const char* val) {
+    register char* scan;
+    register char* temp;
+    register int   offset;
+
+    if (p == &regdummy)
+	return;
+
+    // Find last node.
+    scan = p;
+    for (;;) {
+	temp = regnext(scan);
+	if (temp == NULL)
+	    break;
+	scan = temp;
+    }
+
+    if (OP(scan) == BACK)
+	offset = (const char*)scan - val;
+    else
+	offset = val - scan;
+    *(scan + 1) = (offset >> 8) & 0377;
+    *(scan + 2) = offset & 0377;
+}
+
+
+/*
+ - regoptail - regtail on operand of first argument; nop if operandless
+ */
+static void regoptail (char* p, const char* val) {
+    // "Operandless" and "op != BRANCH" are synonymous in practice.
+    if (p == NULL || p == &regdummy || OP(p) != BRANCH)
+	return;
+    regtail(OPERAND(p), val);
+}
+
+
+
+////////////////////////////////////////////////////////////////////////
+// 
+//  find and friends
+// 
+////////////////////////////////////////////////////////////////////////
+
+
+/*
+ * Global work variables for find().
+ */
+static const char*  reginput;	// String-input pointer.
+static const char*  regbol;	// Beginning of input, for ^ check.
+static const char* *regstartp;	// Pointer to startp array.
+static const char* *regendp;	// Ditto for endp.
+
+/*
+ * Forwards.
+ */
+static int regtry (const char*, const char* *,
+		   const char* *, const char*);
+static int regmatch (const char*);
+static int regrepeat (const char*);
+
+#ifdef DEBUG
+int          regnarrate = 0;
+void         regdump ();
+static char* regprop ();
+#endif
+
+bool cmRegularExpression::find (std::string const& s) {
+return find(s.c_str());
+}
+
+
+
+// find -- Matches the regular expression to the given string.
+// Returns true if found, and sets start and end indexes accordingly.
+
+bool cmRegularExpression::find (const char* string) {
+    register const char* s;
+
+    this->searchstring = string;
+
+     // Check validity of program.
+    if (!this->program || UCHARAT(this->program) != MAGIC) {
+        //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+        printf ("cmRegularExpression::find(): Compiled regular expression corrupted.\n");
+        return 0;
+    }
+    
+    // If there is a "must appear" string, look for it.
+    if (this->regmust != NULL) {
+	s = string;
+	while ((s = strchr(s, this->regmust[0])) != NULL) {
+	    if (strncmp(s, this->regmust, this->regmlen) == 0)
+		break;		// Found it.
+	    s++;
+	}
+	if (s == NULL)		// Not present.
+	    return (0);
+    }
+     
+    // Mark beginning of line for ^ .
+    regbol = string;
+
+    // Simplest case:  anchored match need be tried only once.
+    if (this->reganch)
+	return (regtry(string, this->startp, this->endp, this->program) != 0);
+    
+    // Messy cases:  unanchored match.
+    s = string;
+    if (this->regstart != '\0')
+	// We know what char it must start with.
+	while ((s = strchr(s, this->regstart)) != NULL) {
+	    if (regtry(s, this->startp, this->endp, this->program))
+		return (1);
+	    s++;
+	  
+	}
+    else
+	// We don't -- general case.
+	do {
+	    if (regtry(s, this->startp, this->endp, this->program))
+		return (1);
+	} while (*s++ != '\0');
+    
+    // Failure.
+    return (0);
+}
+
+
+/*
+ - regtry - try match at specific point
+   0 failure, 1 success
+ */
+static int regtry (const char* string, const char* *start,
+		   const char* *end, const char* prog) {
+    register       int    i;
+    register const char* *sp1;
+    register const char* *ep;
+
+    reginput = string;
+    regstartp = start;
+    regendp = end;
+
+    sp1 = start;
+    ep = end;
+    for (i = NSUBEXP; i > 0; i--) {
+	*sp1++ = NULL;
+	*ep++ = NULL;
+    }
+    if (regmatch(prog + 1)) {
+	start[0] = string;
+	end[0] = reginput;
+	return (1);
+    }
+    else
+	return (0);
+}
+
+
+/*
+ - regmatch - main matching routine
+ *
+ * Conceptually the strategy is simple:  check to see whether the current
+ * node matches, call self recursively to see whether the rest matches,
+ * and then act accordingly.  In practice we make some effort to avoid
+ * recursion, in particular by going through "ordinary" nodes (that don't
+ * need to know whether the rest of the match failed) by a loop instead of
+ * by recursion.
+ * 0 failure, 1 success
+ */
+static int regmatch (const char* prog) {
+    register const char* scan;	// Current node.
+             const char* next;	// Next node.
+
+    scan = prog;
+
+    while (scan != NULL) {
+
+	next = regnext(scan);
+
+	switch (OP(scan)) {
+	    case BOL:
+		if (reginput != regbol)
+		    return (0);
+		break;
+	    case EOL:
+		if (*reginput != '\0')
+		    return (0);
+		break;
+	    case ANY:
+		if (*reginput == '\0')
+		    return (0);
+		reginput++;
+		break;
+	    case EXACTLY:{
+		    register int         len;
+		    register const char* opnd;
+
+		    opnd = OPERAND(scan);
+		    // Inline the first character, for speed.
+		    if (*opnd != *reginput)
+			return (0);
+		    len = strlen(opnd);
+		    if (len > 1 && strncmp(opnd, reginput, len) != 0)
+			return (0);
+		    reginput += len;
+		}
+		break;
+	    case ANYOF:
+		if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
+		    return (0);
+		reginput++;
+		break;
+	    case ANYBUT:
+		if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
+		    return (0);
+		reginput++;
+		break;
+	    case NOTHING:
+		break;
+	    case BACK:
+		break;
+	    case OPEN + 1:
+	    case OPEN + 2:
+	    case OPEN + 3:
+	    case OPEN + 4:
+	    case OPEN + 5:
+	    case OPEN + 6:
+	    case OPEN + 7:
+	    case OPEN + 8:
+	    case OPEN + 9:{
+		    register       int    no;
+		    register const char* save;
+
+		    no = OP(scan) - OPEN;
+		    save = reginput;
+
+		    if (regmatch(next)) {
+
+			//
+			// Don't set startp if some later invocation of the
+			// same parentheses already has. 
+			//
+			if (regstartp[no] == NULL)
+			    regstartp[no] = save;
+			return (1);
+		    }
+		    else
+			return (0);
+		}
+//		break;
+	    case CLOSE + 1:
+	    case CLOSE + 2:
+	    case CLOSE + 3:
+	    case CLOSE + 4:
+	    case CLOSE + 5:
+	    case CLOSE + 6:
+	    case CLOSE + 7:
+	    case CLOSE + 8:
+	    case CLOSE + 9:{
+		    register       int    no;
+		    register const char* save;
+
+		    no = OP(scan) - CLOSE;
+		    save = reginput;
+
+		    if (regmatch(next)) {
+
+			//
+			// Don't set endp if some later invocation of the
+			// same parentheses already has. 
+			//
+			if (regendp[no] == NULL)
+			    regendp[no] = save;
+			return (1);
+		    }
+		    else
+			return (0);
+		}
+//		break;
+	    case BRANCH:{
+	      
+	      register const char* save;
+
+		    if (OP(next) != BRANCH)	// No choice.
+			next = OPERAND(scan);	// Avoid recursion.
+		    else {
+			do {
+			    save = reginput;
+			    if (regmatch(OPERAND(scan)))
+				return (1);
+			    reginput = save;
+			    scan = regnext(scan);
+			} while (scan != NULL && OP(scan) == BRANCH);
+			return (0);
+			// NOTREACHED
+		    }
+		}
+		break;
+	    case STAR:
+	    case PLUS:{
+	      register char   nextch;
+		    register int        no;
+		    register const char* save;
+		    register int        min_no;
+
+		    //
+		    // Lookahead to avoid useless match attempts when we know
+		    // what character comes next. 
+		    //
+		    nextch = '\0';
+		    if (OP(next) == EXACTLY)
+			nextch = *OPERAND(next);
+		    min_no = (OP(scan) == STAR) ? 0 : 1;
+		    save = reginput;
+		    no = regrepeat(OPERAND(scan));
+		    while (no >= min_no) {
+			// If it could work, try it.
+			if (nextch == '\0' || *reginput == nextch)
+			    if (regmatch(next))
+				return (1);
+			// Couldn't or didn't -- back up.
+			no--;
+			reginput = save + no;
+		    }
+		    return (0);
+		}
+//		break;
+	    case END:
+ 		return (1);	// Success!
+
+	    default:
+	        //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+                printf ("cmRegularExpression::find(): Internal error -- memory corrupted.\n");
+		return 0;
+	}
+	scan = next;
+    }
+
+    // 
+    //  We get here only if there's trouble -- normally "case END" is the
+    //  terminating point. 
+    // 
+    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+    printf ("cmRegularExpression::find(): Internal error -- corrupted pointers.\n");
+    return (0);
+}
+
+
+/*
+ - regrepeat - repeatedly match something simple, report how many
+ */
+static int regrepeat (const char* p) {
+    register       int   count = 0;
+    register const char* scan;
+    register const char* opnd;
+
+    scan = reginput;
+    opnd = OPERAND(p);
+    switch (OP(p)) {
+	case ANY:
+	    count = strlen(scan);
+	    scan += count;
+	    break;
+	case EXACTLY:
+	    while (*opnd == *scan) {
+		count++;
+		scan++;
+	    }
+	    break;
+	case ANYOF:
+	    while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
+		count++;
+		scan++;
+	    }
+	    break;
+	case ANYBUT:
+	    while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
+		count++;
+		scan++;
+	    }
+	    break;
+	default:		// Oh dear.  Called inappropriately.
+	    //RAISE Error, SYM(cmRegularExpression), SYM(Internal_Error),
+	    printf ("cm RegularExpression::find(): Internal error.\n");
+	    return 0;
+    }
+    reginput = scan;
+    return (count);
+}
+
+
+/*
+ - regnext - dig the "next" pointer out of a node
+ */
+static const char* regnext (register const char* p) {
+    register int offset;
+
+    if (p == &regdummy)
+	return (NULL);
+
+    offset = NEXT(p);
+    if (offset == 0)
+	return (NULL);
+
+    if (OP(p) == BACK)
+	return (p - offset);
+    else
+	return (p + offset);
+}
+
+
+static char* regnext (register char* p) {
+    register int offset;
+
+    if (p == &regdummy)
+	return (NULL);
+
+    offset = NEXT(p);
+    if (offset == 0)
+	return (NULL);
+
+    if (OP(p) == BACK)
+	return (p - offset);
+    else
+	return (p + offset);
+}

+ 214 - 0
Source/cmRegularExpression.h

@@ -0,0 +1,214 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/// Original Copyright notice:
+// Copyright (C) 1991 Texas Instruments Incorporated.
+//
+// Permission is granted to any individual or institution to use, copy, modify,
+// and distribute this software, provided that this complete copyright and
+// permission notice is maintained, intact, in all copies and supporting
+// documentation.
+//
+// Texas Instruments Incorporated provides this software "as is" without
+// express or implied warranty.
+//
+// .LIBRARY vbl
+// .HEADER Basics Package
+// .INCLUDE cmRegularExpression.h
+// .FILE cmRegularExpression.cxx
+//
+#ifndef cmRegularExpression_h
+#define cmRegularExpression_h
+
+#include <string>
+
+const int NSUBEXP = 10;
+
+//: Pattern matching with regular expressions
+//  A regular expression allows a programmer to specify  complex
+//  patterns  that  can  be searched for and matched against the
+//  character string of a string object. In its simplest form, a
+//  regular  expression  is  a  sequence  of  characters used to
+//  search for exact character matches. However, many times  the
+//  exact  sequence to be found is not known, or only a match at
+//  the beginning or end of a string is desired. The vbl  regu-
+//  lar  expression  class implements regular expression pattern
+//  matching as is found and implemented in many  UNIX  commands
+//  and utilities.
+//
+//  Example: The perl code
+//  
+//     $filename =~ m"([a-z]+)\.cc";
+//     print $1;
+//     
+//  Is written as follows in C++
+//
+//     vbl_reg_exp re("([a-z]+)\\.cc");
+//     re.find(filename);
+//     cerr << re.match(1);
+//
+//
+//  The regular expression class provides a convenient mechanism
+//  for  specifying  and  manipulating  regular expressions. The
+//  regular expression object allows specification of such  pat-
+//  terns  by using the following regular expression metacharac-
+//  ters:
+// 
+//   ^        Matches at beginning of a line
+//
+//   $        Matches at end of a line
+//
+//  .         Matches any single character
+//
+//  [ ]       Matches any character(s) inside the brackets
+//
+//  [^ ]      Matches any character(s) not inside the brackets
+//
+//   -        Matches any character in range on either side of a dash
+//
+//   *        Matches preceding pattern zero or more times
+//
+//   +        Matches preceding pattern one or more times
+//
+//   ?        Matches preceding pattern zero or once only
+//
+//  ()        Saves a matched expression and uses it in a  later match
+// 
+//  Note that more than one of these metacharacters can be  used
+//  in  a  single  regular expression in order to create complex
+//  search patterns. For example, the pattern [^ab1-9]  says  to
+//  match  any  character  sequence that does not begin with the
+//  characters "ab"  followed  by  numbers  in  the  series  one
+//  through nine.
+//
+class cmRegularExpression {
+public:
+  inline cmRegularExpression ();			// cmRegularExpression with program=NULL
+  inline cmRegularExpression (char const*);	// cmRegularExpression with compiled char*
+  cmRegularExpression (cmRegularExpression const&);	// Copy constructor
+  inline ~cmRegularExpression();			// Destructor 
+
+  void compile (char const*);		// Compiles char* --> regexp
+  bool find (char const*);		// true if regexp in char* arg
+  bool find (std::string const&);		// true if regexp in char* arg
+  inline long start() const;		// Index to start of first find
+  inline long end() const;		// Index to end of first find
+
+  bool operator== (cmRegularExpression const&) const;	// Equality operator
+  inline bool operator!= (cmRegularExpression const&) const; // Inequality operator
+  bool deep_equal (cmRegularExpression const&) const;	// Same regexp and state?
+  
+  inline bool is_valid() const;		// true if compiled regexp
+  inline void set_invalid();		// Invalidates regexp
+
+  // awf added
+  int start(int n) const;
+  int end(int n) const;
+  std::string match(int n) const;
+  
+private: 
+  const char* startp[NSUBEXP];
+  const char* endp[NSUBEXP];
+  char  regstart;			// Internal use only
+  char  reganch;			// Internal use only
+  const char* regmust;			// Internal use only
+  int   regmlen;			// Internal use only
+  char* program;   
+  int   progsize;
+  const char* searchstring;
+}; 
+
+// cmRegularExpression -- Creates an empty regular expression.
+
+inline cmRegularExpression::cmRegularExpression () { 
+  this->program = NULL;
+}
+
+
+// cmRegularExpression -- Creates a regular expression from string s, and
+// compiles s.
+
+
+inline cmRegularExpression::cmRegularExpression (const char* s) {  
+  this->program = NULL;
+  compile(s);
+}
+
+// ~cmRegularExpression -- Frees space allocated for regular expression.
+
+inline cmRegularExpression::~cmRegularExpression () {
+//#ifndef WIN32
+  delete [] this->program;
+//#endif
+}
+
+// Start -- 
+
+inline long cmRegularExpression::start () const {
+  return(this->startp[0] - searchstring);
+}
+
+
+// End -- Returns the start/end index of the last item found.
+
+
+inline long cmRegularExpression::end () const {
+  return(this->endp[0] - searchstring);
+}
+
+
+// operator!= //
+
+inline bool cmRegularExpression::operator!= (const cmRegularExpression& r) const {
+  return(!(*this == r));
+}
+
+
+// is_valid -- Returns true if a valid regular expression is compiled
+// and ready for pattern matching.
+
+inline bool cmRegularExpression::is_valid () const {
+  return (this->program != NULL);
+}
+
+
+// set_invalid -- Invalidates regular expression.
+
+inline void cmRegularExpression::set_invalid () {
+//#ifndef WIN32
+  delete [] this->program;
+//#endif
+  this->program = NULL;
+}
+
+// -- Return start index of nth submatch. start(0) is the start of the full match.
+inline int cmRegularExpression::start(int n) const
+{
+  return this->startp[n] - searchstring;
+}
+
+// -- Return end index of nth submatch. end(0) is the end of the full match.
+inline int cmRegularExpression::end(int n) const
+{
+  return this->endp[n] - searchstring;
+}
+
+// -- Return nth submatch as a string.
+inline std::string cmRegularExpression::match(int n) const
+{
+  return std::string(this->startp[n], this->endp[n] - this->startp[n]);
+}
+
+#endif // cmRegularExpressionh

+ 52 - 0
Source/cmSystemTools.cxx

@@ -0,0 +1,52 @@
+#include "cmSystemTools.h"
+#include <direct.h>
+#include "errno.h"
+#include <windows.h>
+
+bool cmSystemTools::MakeDirectory(const char* path)
+{
+  std::string dir = path;
+  // replace all of the \ with /
+  size_t pos = 0;
+  while((pos = dir.find('\\', pos)) != std::string::npos)
+    {
+    dir[pos] = '/';
+    pos++;
+    }
+  pos =  dir.find(':');
+  if(pos == std::string::npos)
+    {
+    pos = 0;
+    }
+  while((pos = dir.find('/', pos)) != std::string::npos)
+    {
+    std::string topdir = dir.substr(0, pos);
+    _mkdir(topdir.c_str());
+    pos++;
+    }
+  if(_mkdir(path) != 0)
+    {
+    // if it is some other error besides directory exists
+    // then return false
+    if(errno != EEXIST)
+      {
+      return false;
+      }
+    }
+  return true;
+}
+
+void cmSystemTools::ReplaceString(std::string& source,
+                                   const char* replace,
+                                   const char* with)
+{
+  std::string line = source;
+  size_t start = line.find(replace);
+  while(start != std::string::npos)
+    {
+    source = line.substr(0, start);
+    source += with;
+    source += line.substr(start + strlen(replace));
+    start = line.find(replace, start + strlen(replace) );
+    }
+}

+ 37 - 0
Source/cmSystemTools.h

@@ -0,0 +1,37 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmWindowsTools
+ */
+#ifndef cmWindowsTools_h
+#define cmWindowsTools_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4786 )
+#endif
+
+#include <string>
+
+class cmSystemTools
+{
+public:
+  static bool MakeDirectory(const char* path);
+  static void ReplaceString(std::string& source,
+                            const char* replace,
+                            const char* with);
+};
+
+
+#endif

+ 150 - 0
Source/cmUnixMakefile.cxx

@@ -0,0 +1,150 @@
+#include "cmUnixMakefile.h"
+#include <fstream>
+#include <iostream>
+
+// Output the depend information for all the classes 
+// in the makefile.
+void cmUnixMakefile::OutputDepends(std::ostream& fout)
+{
+  for(int i = 0; i < m_Classes.size(); i++)
+    {
+    if(!m_Classes[i].m_AbstractClass && !m_Classes[i].m_HeaderFileOnly)
+      {
+      if( m_Classes[i].m_Depends.size())
+	{
+	fout << m_Classes[i].m_ClassName << ".o : \\\n";
+	for(std::vector<std::string>::iterator j =  
+	      m_Classes[i].m_Depends.begin();
+	    j != m_Classes[i].m_Depends.end(); ++j)
+	  {
+	  if(j+1 == m_Classes[i].m_Depends.end())
+	    {
+	    fout << *j << " \n";
+	    }
+	  else
+	    {
+	    fout << *j << " \\\n";
+	    }
+	  }
+	fout << "\n\n";
+	}
+      }
+    }
+}
+
+// fix up names of directories so they can be used
+// as targets in makefiles.
+inline std::string FixDirectoryName(const char* dir)
+{
+  std::string s = dir;
+  // replace ../ with 3 under bars
+  size_t pos = s.find("../");
+  if(pos != std::string::npos)
+    {
+    s.replace(pos, 3, "___");
+    }
+  // replace / directory separators with a single under bar 
+  pos = s.find("/");
+  while(pos != std::string::npos)
+    {
+    s.replace(pos, 1, "_");
+    pos = s.find("/");
+    }
+  return s;
+}
+
+// output the makefile to the named file
+void cmUnixMakefile::OutputMakefile(const char* file)
+{
+  std::ofstream fout(file);
+  if(!fout)
+    {
+    std::cerr  << "Error can not open " << file << " for write" << std::endl;
+    return;
+    }
+  if(m_Classes.size() )
+    {
+    fout << "SRC_OBJ = \\\n";
+    for(int i = 0; i < m_Classes.size(); i++)
+      {
+      if(!m_Classes[i].m_AbstractClass && !m_Classes[i].m_HeaderFileOnly)
+	{
+	fout << m_Classes[i].m_ClassName << ".o ";
+	if(i ==  m_Classes.size() -1)
+	  {
+	  fout << "\n\n";
+	  }
+	else
+	  {
+	  fout << "\\\n";
+	  }
+	}
+      }
+    fout << "\n";
+    }
+  if( m_Executables )
+    {
+    for(int i = 0; i < m_Classes.size(); i++)
+      {
+      if(!m_Classes[i].m_AbstractClass && !m_Classes[i].m_HeaderFileOnly)
+	{ 
+        std::string DotO = m_Classes[i].m_ClassName;
+        DotO += ".o";
+        fout << m_Classes[i].m_ClassName << ": " << DotO << "\n";
+	fout << "\t ${CXX}  ${CXX_FLAGS}  " << DotO.c_str() << " -o $@ -L${ITK_OBJ}/Code/Common -lITKCommon \\\n"
+	     << "\t-L${ITK_OBJ}/Code/Insight3DParty/vxl -lITKNumerics -lm ${DL_LIBS}\n\n";
+	}
+      }
+    }
+  
+  if( m_SubDirectories.size() )
+    {
+    fout << "SUBDIR_BUILD = \\\n";
+    int i;
+    for(i =0; i < m_SubDirectories.size(); i++)
+      { 
+      std::string subdir = FixDirectoryName(m_SubDirectories[i].c_str());
+      fout << "build_" << subdir.c_str();
+      if(i == m_SubDirectories.size()-1)
+	{
+	fout << " \n\n";
+	}
+      else
+	{
+	fout << " \\\n";
+	}
+      }
+    fout << std::endl;
+    fout << "SUBDIR_CLEAN = \\\n";
+    for(i =0; i < m_SubDirectories.size(); i++)
+      { 
+      std::string subdir = FixDirectoryName(m_SubDirectories[i].c_str());
+      fout << "clean_" << subdir.c_str();
+      if(i == m_SubDirectories.size()-1)
+	{
+	fout << " \n\n";
+	}
+      else
+	{
+	fout << " \\\n";
+	}
+      }
+    fout << std::endl;
+    fout << "alldirs : ${SUBDIR_BUILD}\n\n";
+
+    for(i =0; i < m_SubDirectories.size(); i++)
+      {
+      std::string subdir = FixDirectoryName(m_SubDirectories[i].c_str());
+      fout << "build_" << subdir.c_str() << ": targets.make\n";
+      fout << "\tcd " << m_SubDirectories[i].c_str() 
+	   << "; ${MAKE} -${MAKEFLAGS} targets.make\n";
+      fout << "\tcd " << m_SubDirectories[i].c_str()
+	   << "; ${MAKE} -${MAKEFLAGS} all\n\n";
+
+      fout << "clean_" << subdir.c_str() << ": \n";
+      fout << "\tcd " << m_SubDirectories[i].c_str() 
+	   << "; ${MAKE} -${MAKEFLAGS} clean\n\n";
+      }
+    }
+  this->OutputDepends(fout);
+}

+ 34 - 0
Source/cmUnixMakefile.h

@@ -0,0 +1,34 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * itkUnixMakefile is used generate unix makefiles.
+ */
+
+#ifndef cmUnixMakefile_h
+#define cmUnixMakefile_h
+#include "cmMakefile.h"
+
+
+class cmUnixMakefile : public cmMakefile
+{
+public:
+  // Write the makefile to the named file
+  void OutputMakefile(const char* file);
+protected:
+  void OutputDepends(std::ostream&);
+};
+
+#endif

+ 2 - 0
Source/cmWindowsConfigure.cxx

@@ -0,0 +1,2 @@
+#include "cmWindowsConfigure.h"
+

+ 43 - 0
Source/cmWindowsConfigure.h

@@ -0,0 +1,43 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * cmWindowsConfigure : a class that configures the build
+ * on windows where autoconf configure can not be used.
+ * The system specific .h files normal generated by autoconf
+ * should be generated by sub-classes of this class.
+ */
+#ifndef cmWindowsConfigure_h
+#define cmWindowsConfigure_h
+#include <string>
+
+class cmWindowsConfigure
+{
+public:
+  void SetWhereSource(const char* dir) 
+    {
+      m_WhereSource = dir;
+    }
+  void SetWhereBuild(const char* dir)
+    {
+      m_WhereBuild = dir;
+    }
+  virtual void Configure() = 0;
+protected:
+  std::string m_WhereSource;
+  std::string m_WhereBuild;
+};
+
+#endif

+ 57 - 0
Source/itkVC60Configure.cxx

@@ -0,0 +1,57 @@
+#include "itkVC60Configure.h"
+#include "cmSystemTools.h"
+#include "stdlib.h"
+#include <windows.h>
+
+void itkVC60Configure::Configure()
+{
+  this->GenerateITKConfigHeader();
+  this->GenerateVNLConfigHeader();
+}
+
+void itkVC60Configure::GenerateITKConfigHeader()
+{
+  // for now just copy the itkConfigure.h.in file into place
+  std::string source = m_WhereSource;
+  source += "/itkConfigure.h.in";
+  std::string destdir = m_WhereBuild;
+  std::string dest = destdir;
+  dest += "/itkConfigure.h";
+  this->CopyFileTo(source.c_str(),
+                   destdir.c_str(),
+                   dest.c_str());
+}
+
+void itkVC60Configure::CopyFileTo(const char* source,
+                                  const char* destdir,
+                                  const char* dest)
+{
+  if(!cmSystemTools::MakeDirectory(destdir) )
+    {
+    std::string error = "Error: can not create directory: ";
+    error += destdir;
+    MessageBox(0, error.c_str(), "config ERROR", MB_OK);
+    }
+  if(!CopyFile(source, dest, FALSE))
+    {
+     std::string error = "Error: can not create : ";
+     error += dest;
+     MessageBox(0, error.c_str(), "config ERROR", MB_OK);
+    }
+}
+
+
+void itkVC60Configure::GenerateVNLConfigHeader()
+{
+  // Copy the vcl config stuff for vc50 into place
+  std::string source = m_WhereSource;
+  source += "/Code/Insight3DParty/vxl/vcl/vcl_config-vc60.h ";
+  std::string destdir = m_WhereBuild;
+  destdir += "/Code/Insight3DParty/vxl/vcl";
+  std::string dest = destdir;
+  dest += "/vcl_config.h";
+  this->CopyFileTo(source.c_str(),
+                   destdir.c_str(),
+                   dest.c_str());
+  
+}

+ 37 - 0
Source/itkVC60Configure.h

@@ -0,0 +1,37 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+
+  Copyright (c) 2000 National Library of Medicine
+  All rights reserved.
+
+  See COPYRIGHT.txt for copyright details.
+
+=========================================================================*/
+/**
+ * itkVC60Configure : a class that configures itk for build
+ * on windows with VC60
+ */
+#ifndef itkVC60Configure_h
+#define itkVC60Configure_h
+
+#include "cmWindowsConfigure.h"
+
+class itkVC60Configure : public cmWindowsConfigure
+{
+public:
+  virtual void Configure();
+  virtual void GenerateITKConfigHeader();
+  virtual void GenerateVNLConfigHeader();
+protected:
+  void CopyFileTo(const char* source,
+                  const char* destdir,
+                  const char* dest);
+};
+
+#endif

+ 4 - 0
Source/staticLibFooter.dsptemplate

@@ -0,0 +1,4 @@
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project

+ 94 - 0
Source/staticLibHeader.dsptemplate

@@ -0,0 +1,94 @@
+# Microsoft Developer Studio Project File - Name="OUTPUT_LIBNAME" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# ITK DSP Header file
+# This file is read by the build system of itk, and is used as the top part of
+# a microsoft project dsp header file
+# IF this is in a dsp file, then it is not the header, but has
+# already been used, so do not edit here...
+
+# variables to REPLACE
+# 
+# BUILD_INCLUDES == include path
+# EXTRA_DEFINES == compiler defines
+# OUTPUT_LIBNAME  == name of output library
+
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=OUTPUT_LIBNAME - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "OUTPUT_LIBNAME.mak" CFG="OUTPUT_LIBNAME - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "OUTPUT_LIBNAME - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "OUTPUT_LIBNAME - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "OUTPUT_LIBNAME - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD CPP /nologo /GR /MD /W3 /GX /O2 BUILD_INCLUDES EXTRA_DEFINES /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF  "$(CFG)" == "OUTPUT_LIBNAME - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od BUILD_INCLUDES EXTRA_DEFINES /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+
+!ENDIF 
+
+# Begin Target
+
+# Name "OUTPUT_LIBNAME - Win32 Release"
+# Name "OUTPUT_LIBNAME - Win32 Debug"
+