You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@etch.apache.org by di...@apache.org on 2008/11/16 23:35:38 UTC

svn commit: r718128 [4/6] - in /incubator/etch/branches/etch-python: ./ binding-csharp/compiler/src/main/java/etch/bindings/csharp/compiler/ binding-csharp/compiler/src/main/resources/etch/bindings/csharp/compiler/ binding-csharp/runtime/ binding-cshar...

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchCompiler.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchCompiler.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchCompiler.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchCompiler.java Sun Nov 16 14:35:35 2008
@@ -17,644 +17,389 @@
 
 package etch.compiler;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
-import java.util.Scanner;
+import java.util.Map;
 import java.util.Set;
 import java.util.StringTokenizer;
-import java.util.regex.Pattern;
 
 import etch.compiler.ast.Module;
-
+import etch.compiler.ast.Name;
+import etch.compiler.ast.Opt;
+import etch.compiler.ast.Service;
+
+/**
+ * The main driver of the compiler.
+ */
 public class EtchCompiler
 {
-
-    private static String ETCH_INCLUDE_PATH = "ETCH_INCLUDE_PATH";
-    private static Integer ETCH_OUTPUT_COUNTER = 1;
-
     /**
      * Instantiate a new compiler
+     * @param cl the class loader to use to load the binding
      */
     public EtchCompiler( ClassLoader cl )
     {
     	this.cl = cl;
-    	
-        // Default options
-        ignoreGlobal = false;
-        ignoreLocal = false;
-        ignoreEnvIncludePath = false;
-        
-        initLogHandler();
-        initIncludePath();
     }
     
     private final ClassLoader cl;
-
-    private File getTempOutputDirectory() throws Exception
-    {
-        // TODO check
-        String suffix = String.format("%d", ETCH_OUTPUT_COUNTER++);
-        File tmpOutputDir = File.createTempFile("etch-outputdir", suffix);
-        if (!tmpOutputDir.delete())
-        {
-            String msg = String.format("Could not initialize temporary output directory (delete): %s \n", tmpOutputDir);
-            throw new Exception(msg);
-        }
-        if (!tmpOutputDir.mkdirs())
-        {
-            String msg = String.format("Could not initialize temporary output directory (create): %s \n", tmpOutputDir);
-            throw new Exception(msg);
-        }
-        tmpOutputDir.deleteOnExit();
-        String msg = String.format("Created temporary output directory: %s\n", tmpOutputDir);
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, msg);
-        return tmpOutputDir;
-    }
-
-    // logHandler
-
-    private LogHandler logHandler;
     
-    private void initLogHandler()
-    {
-        logHandler = new CompilerLogHandler( "Command" );
-    }
-
-    public void setQuiet(boolean value)
+    /**
+     * Runs the compiler using the specified input options.
+     * @param clo
+     * @throws Exception 
+     */
+    public void run( CmdLineOptions clo ) throws Exception
     {
-        logHandler.setQuiet(value);
+    	clo.cl = cl;
+    	
+    	if (clo.lh == null)
+    	{
+	    	clo.lh = new ConsoleLogHandler( "Command" );
+	    	clo.lh.setLevel(
+	    		clo.quiet ? LogHandler.LEVEL_WARNING : LogHandler.LEVEL_INFO );
+    	}
+    	
+    	if (!initBindingClass( clo ))
+    		return;
+    	
+    	if (!checkSourceFile( clo ))
+    		return;
+    	
+    	initOutput( clo );
+        clo.lh.push( clo.sourceFile.getName(), null );
+        
+        try
+        {
+			compile( clo );
+	    	
+			if (!clo.lh.hasError())
+			{
+		        clo.lh.report( LogHandler.LEVEL_INFO, "Saving Resources..." );
+		        
+		        saveOutput( clo );
+		        
+		        if (!clo.lh.hasError())
+		        	clo.lh.report( LogHandler.LEVEL_INFO, "Saving Resources Done." );
+		        else
+		        	clo.lh.report( LogHandler.LEVEL_INFO, "Saving Resources Failed." );
+			}
+			else
+				clo.lh.report( LogHandler.LEVEL_INFO, "Compile Failed." );
+	    }
+        catch ( Exception e )
+        {
+        	clo.lh.report( LogHandler.LEVEL_ERROR, "caught exception: %s", e );
+        	e.printStackTrace();
+        }
+        finally
+        {
+        	clo.lh.pop( clo.sourceFile.getName() );
+        }
     }
-    
-    // includePath
-    
-    private List<File> includePath;
-    private List<File> envIncludePath;
 
-    private void initIncludePath()
-    {
-        includePath    = new LinkedList<File>();
-        envIncludePath = new LinkedList<File>();
+	private static boolean initBindingClass( CmdLineOptions clo )
+	{
+		if (clo.bindingClass != null)
+			return true;
+
+		String n = clo.binding;
+		
+		if (n == null || n.length() == 0)
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Binding not specified." );
+			return false;
+		}
+		
+		if (n.equalsIgnoreCase( "help" ))
+		{
+			// TODO find some way to list the bindings?
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Binding help not yet implemented." );
+			return false;
+		}
+		
+		if (n.equalsIgnoreCase( "null" ))
+		{
+			clo.bindingClass = NullCompiler.class;
+			return true;
+		}
+		
+		String cn = String.format( BINDING_FORMAT, n );
+		
+		try
+		{
+			clo.bindingClass = clo.cl.loadClass( cn );
+			return true;
+		}
+		catch ( ClassNotFoundException e )
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Binding '%s' could not be loaded; class '%s' not in classpath.",
+				n, cn );
+			return false;
+		}
+		catch ( RuntimeException e )
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Binding '%s' could not be loaded; class '%s' threw exception %s",
+				n, cn, e );
+			e.printStackTrace();
+			return false;
+		}
+	}
+	
+	private static boolean initBackend( CmdLineOptions clo )
+	{
+		try
+		{
+			clo.backend = (Backend) clo.bindingClass.newInstance();
+			return true;
+		}
+		catch ( Exception e )
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Binding '%s' could not be initialized; caught exception %s.",
+				clo.binding, e );
+			e.printStackTrace();
+			return false;
+		}
+	}
+    
+    private final static String BINDING_FORMAT = "etch.bindings.%s.compiler.Compiler";
+
+	private static boolean checkSourceFile( CmdLineOptions clo )
+	{
+		File f = clo.sourceFile;
+		
+		if (!f.isFile())
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Source file '%s' does not exist or is not a file.", f );
+			return false;
+		}
+		
+		if (!f.getName().endsWith( ".etch" ))
+		{
+			clo.lh.report( LogHandler.LEVEL_ERROR,
+				"Source file '%s' must have .etch extension.", f );
+			return false;
+		}
+		
+		return true;
+	}
+
+	/**
+     * @param etchHome command line specified location for the etch.
+     * @return sets up the class loader based on information from
+     * our environment.
+     * @throws Exception
+     */
+    public static ClassLoader setupClassLoader( File etchHome )
+        throws Exception
+    {
+        // get the current class path...
+        
+        Set<String> mainClassPath = new HashSet<String>();
         
-        // Harvest include path from envvar 'ETCH_INCLUDE_PATH'
-        
-        String tempIncludePathString = System.getenv(ETCH_INCLUDE_PATH);
-        if (tempIncludePathString != null)
+        ClassLoader cl = EtchMain.class.getClassLoader();
+        if (cl instanceof URLClassLoader)
         {
-            envIncludePath = new LinkedList<File>();
-            StringTokenizer tempPath = new StringTokenizer(tempIncludePathString, File.pathSeparator);
-            while (tempPath.hasMoreTokens())
+            for (URL u: ((URLClassLoader) cl).getURLs())
             {
-                File temp = new File(tempPath.nextToken());
-                if (temp.exists() && temp.isDirectory())
+                String s = u.toString();
+                if (s.startsWith( "file:" ) && s.endsWith( ".jar" ))
                 {
-                    try
-                    {
-                        envIncludePath.add(temp.getCanonicalFile());                        
-                    }
-                    catch ( IOException e )
+                    File f = new File( u.toURI() );
+                    if (f.isFile() && f.canRead())
                     {
-                        // ignore
+                        s = f.getCanonicalPath();
+                        mainClassPath.add( s );
+//                      System.out.println( "mainClassPath.add: "+s );
                     }
                 }
             }
         }
-    }
-
-    /**
-     * add a directory to the ETCH_INCLUDE_PATH
-     *
-     * @param value path to add
-     */
-    public void addIncludePath(File value)
-    {
-        if (value.exists() && value.isDirectory())
-        {
-            try
-            {
-                includePath.add(value.getCanonicalFile());                
-            }
-            catch ( IOException e )
-            {
-                // ignore
-            }
-        }
-    }
-
-    /**
-     * return a list of the directories in the Etch include path
-     *
-     */
-    public List<File> getIncludePath()
-    {
-        return getIncludePath(null);
-    }
-    
-    /**
-     * return a list of the directories in the Etch include path, inserting 'workingDirectory' at the beginning
-     *
-     * @param workingDirectory use this value as the workingDirectory path
-     */
-    public List<File> getIncludePath(File workingDirectory)
-    {
-        // Setup Etch include path from the environment variable, commandline options
-        // and the working directory of the etch file itself.
-        List<File> effectiveIncludePath = new LinkedList<File>();
         
-        if (!ignoreEnvIncludePath)
-            effectiveIncludePath.addAll(envIncludePath);
+        // search etch.home (if specified) for more jar files to add
+        // to a secondary class loader. exclude jar files on the main
+        // class path.
         
-        effectiveIncludePath.addAll(includePath);
-        if (workingDirectory != null)
-        {
-            try
-            {
-                effectiveIncludePath.add(0, workingDirectory.getCanonicalFile());                
-            }
-            catch ( IOException e )
-            {
-                String msg = String.format("Could not add working directory %s to the includePath \n", workingDirectory);
-                logHandler.logMessage ( LogHandler.LEVEL_WARNING, null, msg );
-            }
-        }
+        String s = etchHome != null ? etchHome.getCanonicalPath() : null;
         
-        return effectiveIncludePath;
-    }
-
-    // outputDirectory
-    
-    private File outputDir;
-
-    /**
-     * set the output directory for generated source
-     *
-     * @param value directory to output source
-     */
-    public void setOutputDirectory(File value) throws Exception
-    {
-        if (value == null)
-        {
-            outputDir = null;
-            return;
-        }
-            
-        if (value.exists() && (!value.isDirectory() || !value.canWrite()))
-        {
-            // Not a directory, not writable
-            // TODO better exception name
-            throw new Exception("Specified output directory: '" + value.toString() + "' is not a directory or not writable \n");
-        }
-        outputDir = value.getCanonicalFile();
-    }
-
-    /**
-     * return the name of the output directory
-     *
-     */
-    public File getOutputDirectory()
-    {
-        return outputDir;
-    }
-
-    // templateOutputDirectory
-    
-    private File templateOutputDir;
-    
-    /**
-     * set an alternative output directory for generated template source, i.e. IMPL and MAIN files
-     *
-     * @param value directory to output template source
-     */
-    public void setTemplateOutputDirectory(File value) throws Exception
-    {
-        if (value == null)
+        if (s == null || s.length() == 0)
         {
-            templateOutputDir = null;
-            return;
+        	// from java -Detch.home=...
+            s = System.getProperty( "etch.home" );
         }
-            
-        if (!value.isDirectory() || !value.canWrite())
-        {
-            // Not a directory, not writable
-            // TODO better exception name
-            throw new Exception("Specified output directory: '" + value.toString() + "' is not a directory or not writable \n");
-        }
-        templateOutputDir = value.getCanonicalFile();
-    }
-    
-    /**
-     * return the name of the template output directory
-     *
-     */
-    public File getTemplateOutputDirectory()
-    {
-        return templateOutputDir;
-    }
-    
-    private boolean overwriteTemplate;
-
-    /**
-     * set the value of the OverwriteTemplate flag
-     *
-     * @param value
-     */
-    public void setOverwriteTemplate(boolean value)
-    {
-        overwriteTemplate = value;
-    }
 
-    /**
-     * return the value of the OverwriteTemplate flag
-     */
-    public boolean getOverwriteTemplate()
-    {
-        return overwriteTemplate;
-    }    
-
-    // binding
-
-    private String   bindingName;
-	private Class<?> bindingClass;
-    
-    /**
-     * set the name of the binding
-     * The compiler will assume the binding class is 'etch.bindings.<name>.compiler.Compiler'
-     *
-     * @param value name of the binding (e.g., java, csharp, xml, ...)
-     */
-    public void setBindingName(String value)
-    {
-        bindingName = value;
-    }
-    
-    /**
-     * get the name of the binding
-     *
-     */
-    public String getBindingName()
-    {
-        return bindingName;
-    }
-    
-    /**
-     * get the fully-qualified class name of the binding
-     *
-     */
-    public String getBindingClassName()
-    {
-        if (bindingName == null)
-            return null;
-                        
-        // TODO perhaps allow user to specifiy a fully qualified classname for the binding as an option?
-        return String.format("etch.bindings.%s.compiler.Compiler", bindingName);
-    }
-    
-    
-    private boolean initBindingClass() throws Exception
-    {
-
-        if (bindingClass != null)
-            return true;
-
-        try
-        {   
-            bindingClass = cl.loadClass(getBindingClassName());
-            // bindingClass = Class.forName(getBindingClassName());
-            return true;
-        }
-        catch ( ClassNotFoundException e )
+        if (s == null || s.length() == 0)
         {
-            String msg = String.format("Binding '" + getBindingName() + "' could not be loaded; class '" + getBindingClassName() + "' not in classpath.\n");
-            // TODO better exception
-            e.printStackTrace();
-            throw new Exception(msg);
+            s = System.getenv( "ETCH_HOME" );
         }
-    }
-    
-    private Class<?> getBindingClass() throws Exception
-    {
-        initBindingClass();
-        return bindingClass;
-    }
-    
-    private Backend getBindingClassInstance() throws Exception
-    {
-        initBindingClass();
-        return (Backend) bindingClass.newInstance();    
-    }
-
-    // what
-
-    private Set<String> what = new HashSet<String>();
-
-    /**
-     * add to the list of what the compiler should produce, (e.g. 'client','server','helper')
-     *
-     * @param what a valid compiler product
-     */
-    public void addWhat(String value) throws Exception
-    {
-        what.add(value);
-        if (value == "FORCE")
-            overwriteTemplate = true;
-    }
-
-    /**
-     * return the set of compiler products to be produced
-     *
-     */
-    public Set<String> getWhat()
-    {
-        return what;
-    }
-
-    // ignoreGlobal
-
-    private boolean ignoreGlobal;
-
-    /**
-     * set the value of the IgnoreGlobal flag
-     *
-     * @param value
-     */
-    public void setIgnoreGlobal(boolean value)
-    {
-        ignoreGlobal = value;
-    }
-
-    /**
-     * return the value of the IgnoreGlobal flag
-     */
-    public boolean getIgnoreGlobal()
-    {
-        return ignoreGlobal;
-    }
-
-    // ignoreLocal
-
-    private boolean ignoreLocal;
-
-    /**
-     * set the value of the IgnoreLocal flag
-     *
-     * @param value
-     */
-    public void setIgnoreLocal(boolean value)
-    {
-        ignoreLocal = value;
-    }
-
-    /**
-     * return the value of the IgnoreLocal flag
-     */
-    public boolean getIgnoreLocal()
-    {
-        return ignoreLocal;
-    }
-
-    // ignoreEnvironmentIncludePath
-
-    private boolean ignoreEnvIncludePath;
-
-    /**
-     * set the value of the IgnoreEnvironmentIncludePath flag
-     *
-     * @param value
-     */
-    public void setIgnoreEnvironmentIncludePath(boolean value)
-    {
-        ignoreEnvIncludePath = value;
-    }
-
-    /**
-     * return value of the IgnoreEnvironmentIncludePath flag
-     */
-    public boolean getIgnoreEnvironmentIncludePath()
-    {
-        return ignoreEnvIncludePath;
-    }
-
-    // userWordsList
-
-    private String userWordsList;
+        
+        if (s != null && s.length() > 0)
+            s = s + File.separator + "lib";
 
-    /**
-     * specify a Users Words list
-     *
-     * @param value path to Users Words list file
-     */
-    public void setUserWordsList(File value) throws Exception
-    {
-        if (!value.isFile() || !value.canRead())
+        //      System.out.println( "etch.home.lib = "+s );
+        if (s != null && s.length() > 0)
         {
-            // Not a file or not readable
-            // TODO better Exception
-            throw new Exception("The user words list specified: '" + value.toString() + "' is not a file or is not readable");
-        }
-        userWordsList = value.getCanonicalFile().getPath();
-    }
-
-    /**
-     * return the path to the User Words list file
-     */
-    public String getUserWordsList()
-    {
-        return userWordsList;
-    }
-
-    // isMixinSuppressed
-    
-    private boolean isMixinSuppressed = false;
-
-    /**
-     * set the value of the MixinSuppressed flag
-     *
-     * @param value
-     */
-    public void setMixinSuppressed(boolean value)
-    {
-        isMixinSuppressed = value;
-    }
-
-    /**
-     * return the value of the MixinSuppressed flag
-     */
-    public boolean getNoMixinArtifacts()
-    {
-        return isMixinSuppressed;
-    }
-
-    // mixinOutputDir
-
-    private File mixinOutputDir;
+            File d = new File( s );
+            
+            if (!d.isDirectory() || !d.canRead())
+            	throw new IOException( String.format(
+            		"Specified $ETCH_HOME/lib is not a directory: %s\n", s ) );
 
-    /**
-     * set the path for mixin outputs
-     *
-     * @param value path
-     */
-    public void setMixinOutputDirectory(File value) throws Exception
-    {
-        if (!value.isDirectory() || !value.canWrite())
-        {
-            // Not a directory or cannot write
-            throw new Exception(String.format("Mixin output directory %s is not found or is not writable", value));
+            d = d.getCanonicalFile();
+            
+            MyURLClassLoader ncl = new MyURLClassLoader( new URL[] {}, cl );
+            for (File f: d.listFiles())
+            {
+                if (!f.isFile())
+                    continue;
+                String x = f.getCanonicalPath();
+                if (!x.endsWith( ".jar" ))
+                    continue;
+                if (!mainClassPath.contains( x ))
+                    ncl.addURL( f.toURI().toURL() );
+            }
+            cl = ncl;
         }
-        mixinOutputDir = value.getCanonicalFile();
-    }
-
-    /**
-     * get the value of the mixin output directory
-     *
-     */
-    public File getMixinOutputDirectory()
-    {
-        return mixinOutputDir;
+        return cl;
     }
-
-    // flattenPackages
-
-    private boolean flattenPackages = true;
-
-    /**
-     * set the value of the FlattenPackages flag
-     *
-     * @param value
-     */
-    public void setFlattenPackages(boolean value)
-    {
-        flattenPackages = value;
-    }
-
-    /**
-     * get the value of the FlattenPackages attribute
-     */
-    public boolean getFlattenPackages()
-    {
-        return flattenPackages;
-    }
-    
-    // sourceFiles
     
-    /**
-     * validate that the path specified is a .etch file
-     *
-     * @param value filename
-     */
-    public void validateEtchFile(File value) throws Exception
+    private static class MyURLClassLoader extends URLClassLoader
     {
-        
-        if (!value.isFile() || !value.canRead())
+        /**
+         * This is just a class loader where we can hang more urls to
+         * search.
+         * @param urls
+         * @param parent
+         */
+        public MyURLClassLoader( URL[] urls, ClassLoader parent )
         {
-            String msg = String.format("File '%s' does not exist or cannot be read.", value);
-            // TODO better exception
-            throw new Exception(msg);
+            super( urls, parent );
         }
         
-        String s = value.getName();
-        if (!s.endsWith(".etch"))
+        @Override
+        public void addURL( URL url )
         {
-            String msg = String.format("File '%s' must have .etch extension", value);
-            // TODO better exception
-            throw new Exception(msg);
+            super.addURL( url );
         }
     }
     
-    /****************************/
-    
-    /**
-     * Compile an .etch file, assume workingDirectory is the same as the file's parent directory
-     *
-     * @param name filename
-     */
-    public void compile(File name) throws Exception
-    {
-        name = name.getCanonicalFile();
-        validateEtchFile(name);
-        
-        FileInputStream is = new java.io.FileInputStream(name);
-        
-        String msg = String.format("Compiling %s ...\n", name);
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, msg);
-        if (name.getParentFile() != null)
-            compile((InputStream)is, name.getParentFile());
-        else
-            compile((InputStream)is, name.getAbsoluteFile().getParentFile());
-    }
+    // includePath
 
     /**
-     * Compile an .etch input stream
-     *
-     * @param is stream
+     * Initialize {@link CmdLineOptions#effectiveIncludePath} given the
+     * compilation we are about to perform.
+     * @param clo
      */
-    public void compile(InputStream is) throws Exception
+    private static void initIncludePath( CmdLineOptions clo ) throws IOException
     {
-        // TODO null is not valid, pass a legitimate dir or change the other method
-        compile(is, null);
-    }
-
-    /**
-     * Compile an .etch input stream, specify the workingDirectory
-     *
-     * @param is stream
-     * @param workingDirectory working directory
-     */
-    public void compile(InputStream is, File workingDirectory) throws Exception
-    {   
-             
-        CmdLineOptions options = new CmdLineOptions();
-        workingDirectory = workingDirectory.getCanonicalFile();
-        
-        // Configure EtchHelper
-        // TODO really need to re-factor how compiler-directive stuff in CmdLineOptions is passed around
-//        EtchHelper.cl = options;
-        options.lh = logHandler;
-
-        // Setup options
-        //  if there are any problems, inconsistencies in the option set, Exceptions will be thrown
-        options.includePath = getIncludePath(workingDirectory);
-        options.bindingClass = getBindingClass();
-        options.what = getWhat();
-        options.outputDir = getTempOutputDirectory();
-        // options.outputDir = getOutputDirectory();
-        options.mixinOutputDir = getMixinOutputDirectory();
-        options.ignoreGlobal = getIgnoreGlobal();
-        options.ignoreLocal = getIgnoreLocal();
-        options.userWordsList = getUserWordsList();
-        options.noMixinArtifacts = getNoMixinArtifacts();
-        options.noFlattenPackages = !getFlattenPackages();
-
-        // Instantiate a new backend and parser
-        final Backend b = getBindingClassInstance();
-            
-        final EtchGrammar parser = new EtchGrammar(b, is);
+//    	System.out.println( "initIncludePath: sourceFile = "+clo.sourceFile );
+//    	System.out.println( "initIncludePath: includePath = "+clo.includePath );
+    	
+    	// includePath is composed of the source file's directory, then
+    	// the paths specifies by -I command line directives, then the
+    	// paths specified by the ETCH_INCLUDE_PATH environment variable.
+    	
+    	clo.effectiveIncludePath = new ArrayList<File>( );
+    	
+    	// add directory of source file.
+    	if (clo.sourceFile != null)
+    		clo.effectiveIncludePath.add(
+    			clo.sourceFile.getCanonicalFile().getParentFile() );
+    	
+    	for (File f: clo.includePath)
+    	{
+    		if (f.isDirectory())
+    			clo.effectiveIncludePath.add( f );
+    		else
+    			clo.lh.report( LogHandler.LEVEL_WARNING,
+            		"Include path element doesn't exist: %s", f );
+    	}
+    	
+    	if (!clo.ignoreIncludePath)
+    	{
+	        String s = System.getenv( CmdLineOptions.ETCH_INCLUDE_PATH );
+	        if (s != null)
+	        {
+	            StringTokenizer st = new StringTokenizer( s, File.pathSeparator );
+	            while (st.hasMoreTokens())
+	            {
+	                File f = new File( st.nextToken() );
+	                if (f.isDirectory())
+	                	clo.effectiveIncludePath.add( f );
+	                else
+	                	clo.lh.report( LogHandler.LEVEL_WARNING,
+	                		"Environment include path element doesn't exist: %s", f );
+	            }
+	        }
+    	}
+//    	System.out.println( "initIncludePath: effectiveIncludePath = "+clo.effectiveIncludePath );
+    }
+
+	private static Module compile( CmdLineOptions clo ) throws Exception
+	{
+		InputStream is = new BufferedInputStream( new FileInputStream( clo.sourceFile ) );
+    	try
+		{
+			return compile( clo, is );
+		}
+		finally
+		{
+			is.close();
+		}
+	}
+    
+    private static Module compile( CmdLineOptions clo, InputStream is ) throws Exception
+	{
+    	initIncludePath( clo );
+    	
+    	if (!initBackend( clo ))
+    		return null;
+    	
+    	if (clo.sourceFile != null)
+    		clo.lh.report( LogHandler.LEVEL_INFO, "Compiling %s...", clo.sourceFile );
+    	else
+    		clo.lh.report( LogHandler.LEVEL_INFO, "Compiling..." );
+    	
+    	final EtchGrammar parser = new EtchGrammar( clo.backend, is );
         
         final Module m;
         
         // Parse .etch source
         try
         {
-            m = parser.module( options );
-            logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Parsed Ok.\n");
+            m = parser.module( clo );
+            clo.lh.report( LogHandler.LEVEL_INFO, "Parsed Ok." );
+            
             m.check();
-            logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Checked Ok.\n");
+            clo.lh.report( LogHandler.LEVEL_INFO, "Checked Ok." );
         }
         catch ( ParseException e )
         {
             String fmt = e.getMessage();
-            logHandler.logMessage( LogHandler.LEVEL_ERROR, e.currentToken, fmt);
-            // TODO better exception
+            clo.lh.report( LogHandler.LEVEL_ERROR,
+            	e.currentToken != null ? e.currentToken.beginLine : null,
+            		e.getMessage() );
+            // TODO better report of a ParseException
             throw new Exception(e.currentToken + " " + fmt);
         }
-        catch ( Exception e)
+        catch ( Exception e )
         {
-            String fmt = e.getMessage();
-            logHandler.logMessage( LogHandler.LEVEL_ERROR, null, fmt);
-            // TODO better exception
+            clo.lh.report( LogHandler.LEVEL_ERROR, "caught exception: %s", e );
+            // TODO better report of an Exception
             throw e;
         }
         
@@ -663,158 +408,211 @@
         try
         {
             // TODO report work lists?
-            logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Generating Resources... \n");
+        	clo.lh.report( LogHandler.LEVEL_INFO, "Generating Resources..." );
             
             // TODO integrate includePath with code generation.
-            b.generate(m, options, logHandler);
+            clo.backend.generate( m, clo );
+
+            // Move generated code to target location
+            //   the parser will set 'isMixinPresent' if a "mixin" directive is in the .etch file
+            // TODO would be nice if the backend just put things in the right place from the start .. sigh re-factor later        
+            // moveGeneratedCode(options.outputDir, options.isMixinPresent, workingDirectory);
         }
         catch ( Exception e )
         {
             String fmt = e.getMessage();
-            // TODO better exception
+            // TODO better report of an Exception
             e.printStackTrace();
             throw new Exception(fmt);
         }
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Generating Complete. \n");
-        
-        // Move generated code to target location
-        //   the parser will set 'isMixinPresent' if a "mixin" directive is in the .etch file
-        // TODO would be nice if the backend just put things in the right place from the start .. sigh re-factor later        
-        moveGeneratedCode(options.outputDir, options.isMixinPresent, workingDirectory);
 
         // Complete
 
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Compile Done.\n");
-        
-        // return m;
-    }
-
-    private static class GeneratedFiles
-    {
-        private Pattern rest         = Pattern.compile(".*");
-        private String IMPL_PATTERN  = ".*Impl.+(Server|Client)..+$";
-        private String MAIN_PATTERN  = ".*Main.+(Client|Listener)..+$";
-
-        private File basedir;
-
-        public GeneratedFiles(File basedir)
-        {
-            this.basedir = basedir;
-        }
-            
-        public List<String> relativeFiles()
-        {
-            return strip(find(null));
-        }
-        
-        public List<String> templateFiles()
-        {
-            List<String> r = new LinkedList<String>();
-            
-            for (String f: relativeFiles())
-            {
-                if (f.matches(IMPL_PATTERN) || f.matches(MAIN_PATTERN))
-                    r.add(f);
-            }
-            return r;
-        }
-        
-        public List<String> nonTemplateFiles()
-        {
-            List<String> r = new LinkedList<String>();
-            
-            for (String f: relativeFiles())
-            {
-                if (!f.matches(IMPL_PATTERN) && !f.matches(MAIN_PATTERN))
-                    r.add(f);
-            }
-            return r;
-        }
-        
-        private List<String> strip(List<File> files)
-        {
-            List<String> s = new LinkedList<String>();
-
-            for (File n: files)
-            {
-                Scanner t = new Scanner(n.getPath());
-                t.skip(Pattern.quote(basedir.getPath()));
-                s.add(t.next(rest));
-            }
-            return s;
-        }
-
-        private List<File> find(File root)
-        {
-            List<File> lst = new LinkedList<File>();
-
-            if (root == null)
-                root = basedir;
-
-            for (File n: root.listFiles())
-            {
-                if (n.isDirectory())
-                {
-                    lst.addAll(find(n));
-                }
-                else
-                {
-                    lst.add(n);
-                }
-            }
-            return lst;
-        }
-    }
-
-    private void moveFiles(File srcDir, File destDir, List<String> files, boolean overwrite) throws Exception
-    {
-        //
-        for (String f: files)
-        {
-            File srcFile  = new File(srcDir, f);
-            File destFile = new File(destDir, f);
-            if (destFile.exists() && overwrite)
-                destFile.delete();
-                
-            if (!destFile.exists())
-            {
-                File parent = new File(destFile.getParent());
-                parent.mkdirs();
-                srcFile.renameTo(destFile);
-                logHandler.logMessage( LogHandler.LEVEL_INFO, null, "  Writing " + f + "\n");
-            }
-            else
-            {
-                logHandler.logMessage( LogHandler.LEVEL_INFO, null, "  No overwrite, skipping " + f + "\n");
-                srcFile.delete();
-            }
-        }
+        clo.lh.report( LogHandler.LEVEL_INFO, "Compile Done." );
+        return m;
     }
 
-    private void moveGeneratedCode(File srcDir, boolean mixinPresent, File workingDirectory) throws Exception
-    {
-
-        File target = outputDir;
-        File templateTarget = templateOutputDir;
-        
-        //  override output directory if mixin detected
-        if (mixinPresent && mixinOutputDir != null)
-            target = mixinOutputDir;
-                
-        if (target == null)
-            target = workingDirectory;
-        
-        if (templateOutputDir == null)
-            templateTarget = target;
-        
-        // move files
-        GeneratedFiles gf = new GeneratedFiles(srcDir);
-        
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Moving generated code to " + target.toString() + "\n");
-        moveFiles(srcDir, target, gf.nonTemplateFiles(), true);
-        
-        logHandler.logMessage( LogHandler.LEVEL_INFO, null, " Moving starter template code to " + templateTarget.toString() + "\n");
-        moveFiles(srcDir, templateTarget, gf.templateFiles(), overwriteTemplate);
-        
-    }
+	private static void initOutput( CmdLineOptions clo )
+	{
+		clo.output = new FileOutput();
+		clo.templateOutput = new FileOutput();
+		clo.mixinOutput = clo.noMixinArtifacts ? new NullOutput() : new FileOutput();
+	}
+
+	private static void saveOutput( CmdLineOptions clo ) throws IOException
+	{
+		// TODO implement saveOutput
+//		clo.output.report( "output" );
+//		clo.templateOutput.report( "templateOutput" );
+//		clo.mixinOutput.report( "mixinOutput" );
+		
+		if (clo.testing)
+			return;
+		
+		// Destination directory of generated artifacts. Use source file's
+		// parent directory if not specified.
+		
+		File outputDir = clo.outputDir;
+		boolean noQualOutputDir = false;
+		if (outputDir == null)
+		{
+			outputDir = clo.sourceFile.getCanonicalFile().getParentFile();
+			noQualOutputDir = true;
+		}
+
+		// Destination directory of generated user-editable artifacts. Use
+		// outputDir if not specified.
+		
+		File templateOutputDir = clo.templateOutputDir;
+		boolean noQualTemplateOutputDir = false;
+		if (templateOutputDir == null)
+		{
+			templateOutputDir = outputDir;
+			noQualTemplateOutputDir = noQualOutputDir;
+		}
+		
+		// Destination directory of mixin generated artifacts. Use outputDir
+		// if not specified.
+		
+		File mixinOutputDir = clo.mixinOutputDir;
+		boolean noQualMixinOutputDir = false;
+		if (mixinOutputDir == null)
+		{
+			mixinOutputDir = outputDir;
+			noQualMixinOutputDir = noQualOutputDir;
+		}
+		
+		boolean force = clo.what.contains( Backend.WHAT_FORCE );
+
+		saveFiles( clo.output, outputDir, noQualOutputDir, clo.noFlattenPackages, true );
+		saveFiles( clo.templateOutput, templateOutputDir, noQualTemplateOutputDir, clo.noFlattenPackages, force );
+		saveFiles( clo.mixinOutput, mixinOutputDir, noQualMixinOutputDir, clo.noFlattenPackages, true );
+	}
+
+	private static void saveFiles( Output output, File outputDir,
+		boolean noQualOutputDir, boolean noFlattenPackages, boolean force )
+		throws IOException
+	{
+		output.saveFiles( outputDir, noQualOutputDir, noFlattenPackages, force );
+	}
+
+	/**
+	 * Parses a mixin which is within the specified service.
+	 * @param intf
+	 * @param n
+	 * @param opts
+	 * @return the constructed Mixin object, or null.
+	 * @throws Exception 
+	 */
+	public static Module parseModule( Service intf, Name n, Map<String,
+		Opt> opts ) throws Exception
+	{
+		CmdLineOptions clo = new CmdLineOptions( intf.getCmdLineOptions() );
+		
+		// find the mixin file
+		
+		String fn = n.name;
+		
+		// fn is something like a.b.c.d or perhaps just plain d.
+		//
+		// we will look for d.etch, a/b/c/d.etch, and a.b.c/d.etch.
+		//
+		// we can look in the same directory as the original source we are
+		// compiling (the working dir), or any of the include path directories.
+		
+		String module;
+		String file;
+		int i = fn.lastIndexOf( '.' );
+		if (i >= 0)
+		{
+			module = fn.substring( 0, i );
+			file = fn.substring( i+1 );
+		}
+		else
+		{
+			module = null;
+			file = fn;
+		}
+		
+		file = file + ".etch";
+		
+//		System.out.printf( "searching for mixin '%s' module '%s'\n", file, module );
+//		System.out.println( "includePath = "+clo.includePath );
+//		System.out.println( "effectiveIncludePath = "+clo.effectiveIncludePath );
+		
+		List<File> list = new ArrayList<File>();
+		
+		// look for the unqualified name
+		find( list, clo, null, file );
+		
+		if (module != null)
+		{
+			// look for the qualified name
+			find( list, clo, module, file );
+			find( list, clo, module.replace( '.', '/' ), file );
+		}
+		
+		if (list.isEmpty())
+			return null;
+		
+		File f = list.get( 0 );
+//		System.out.println( "mixing in = "+f );
+		
+		return parseModule0( clo, n, f );
+	}
+	
+	private static void find( List<File> list, CmdLineOptions clo, String path,
+		String file ) throws IOException
+	{
+		for (File d: clo.effectiveIncludePath)
+		{
+			File f = d;
+			
+			if (path != null)
+				f = new File( f, path );
+			
+			f = new File( f, file ).getCanonicalFile();
+			
+			if (f.isFile() && !list.contains( f ))
+				list.add( f );
+		}
+	}
+
+	/**
+	 * @param clo
+	 * @param n
+	 * @param f
+	 * @return the parsed module of the mixin.
+	 * @throws Exception
+	 */
+	public static Module parseModule0( CmdLineOptions clo, Name n, File f )
+		throws Exception
+	{
+		clo.sourceFile = f;
+		clo.output = clo.mixinOutput;
+		
+		clo.templateOutput = new NullOutput();
+		clo.what.remove( Backend.WHAT_MAIN );
+		clo.what.remove( Backend.WHAT_IMPL );
+		
+		if (clo.noMixinArtifacts)
+		{
+			clo.what.clear();
+			clo.what.add( Backend.WHAT_NONE );
+		}
+		
+		clo.lh.report( LogHandler.LEVEL_INFO, n.token.beginLine,
+			"Compiling mixin file: %s", n.name );
+		clo.lh.push( f.getName(), n.token.beginLine );
+		try
+		{
+			return compile( clo );
+		}
+		finally
+		{
+			clo.lh.pop( f.getName() );
+			clo.lh.report( LogHandler.LEVEL_INFO, n.token.beginLine,
+				"Done compiling mixin file: %s", n.name );
+		}
+	}
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchHelper.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchHelper.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchHelper.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchHelper.java Sun Nov 16 14:35:35 2008
@@ -614,7 +614,7 @@
 		//Get the Gramar Obj
 		EtchGrammar oGramar = (EtchGrammar) this;
 
-		servobj.getCmdLineOptions().lh.push( fileName.toString(), new Integer(fileName.beginLine) );
+		servobj.getCmdLineOptions().lh.push( fileName.toString(), fileName.beginLine );
 
 		//System.out.println("------Start Do Include-------");
 
@@ -622,13 +622,13 @@
 	  	String oStr = fileName.toString().replaceAll("\"", "");
 
 	 // 	System.out.println("Including " + oStr);
-	  	servobj.getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_INFO, null,"Including " + oStr + "\n");
+	  	servobj.getCmdLineOptions().lh.report( LogHandler.LEVEL_INFO, "Including %s", oStr );
 
 	    //Create the input string and read it in
 		InputStream oStream = null;
 
 		// Search the etch path for the file
-		for (File f : servobj.getCmdLineOptions().includePath)
+		for (File f : servobj.getCmdLineOptions().effectiveIncludePath)
 		{
 			try
 			{
@@ -676,7 +676,7 @@
 		//Put the old data back
 		oGramar.ReInit( oOldTM );
 		oGramar.token = token;
-		servobj.getCmdLineOptions().lh.pop();
+		servobj.getCmdLineOptions().lh.pop( fileName.toString() );
 		//System.out.println("------End Do Include---------");
 	}
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchMain.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchMain.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchMain.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/EtchMain.java Sun Nov 16 14:35:35 2008
@@ -18,12 +18,6 @@
 package etch.compiler;
 
 import java.io.File;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
 import java.util.StringTokenizer;
 
 import etch.util.cmd.CommandParser;
@@ -36,131 +30,32 @@
  */
 public class EtchMain extends Program
 {
-    private static String WHO_DELIMETER = ",";
-    
-    /**
+	/**
      * @param args
      * @throws Exception 
      */
     public static void main( String[] args ) throws Exception
     {
-        try
-        {
-            main( new EtchMain(), args );
-        }
-        catch ( Throwable e )
-        {
-            System.out.println(e.getMessage());
-            e.printStackTrace();
-            System.exit( 3 );
-            return;
-        }
+    	new EtchMain().doMain( args );
     }
     
     /**
-     * @param etchHome command line specified location for the etch.
-     * @return sets up the class loader based on information from
-     * our environment.
+     * Runs the main program, parsing command line arguments and performing
+     * the action.
+     * @param args
      * @throws Exception
      */
-    public static ClassLoader setupClassLoader( String etchHome )
-        throws Exception
+    public void doMain( String[] args ) throws Exception
     {
-        // get the current class path...
-        
-        Set<String> mainClassPath = new HashSet<String>();
-        
-        ClassLoader cl = EtchMain.class.getClassLoader();
-        if (cl instanceof URLClassLoader)
-        {
-            for (URL u: ((URLClassLoader) cl).getURLs())
-            {
-                String s = u.toString();
-                if (s.startsWith( "file:/" ) && s.endsWith( ".jar" ))
-                {
-                    s = s.substring( 6 );
-                    File f = new File( s );
-                    if (f.isFile() && f.canRead())
-                    {
-                        s = f.getCanonicalPath();
-                        mainClassPath.add( s );
-//                      System.out.println( "mainClassPath.add: "+s );
-                    }
-                }
-            }
-        }
-        
-        // search etch.home.lib (if specified) for more jar files to add
-        // to a secondary class loader. exclude jar files on the main
-        // class path.
-        
-        String s = etchHome;
-        
-        if (s == null || s.length() == 0)
-            s = System.getProperty( "etch.home.lib" );
-        
-        if (s == null || s.length() == 0)
-        {
-            s = System.getProperty( "etch.home" );
-            if (s != null && s.length() > 0)
-                s = s + File.separator + "lib";
-        }
-
-        if (s == null || s.length() == 0)
-        {
-            s = System.getenv( "ETCH_HOME" );
-            if (s != null && s.length() > 0)
-                s = s + File.separator + "lib";
-        }
-        
-//      System.out.println( "etch.home.lib = "+s );
-        if (s != null && s.length() > 0)
-        {
-            File d = new File( s );
-            if (d.isDirectory() && d.canRead())
-            {
-                MyURLClassLoader ncl = new MyURLClassLoader( new URL[] {}, cl );
-                for (File f: d.listFiles())
-                {
-                    if (!f.isFile())
-                        continue;
-                    if (!f.getName().endsWith( ".jar" ))
-                        continue;
-                    // s = f.getCanonicalPath();
-                    if (!mainClassPath.contains( f.getCanonicalPath() ))
-                    {
-                        ncl.addURL(f.toURL());
-//                      System.out.println( "+++ "+s.getName() );
-
-                    }
-                    else
-                    {
-//                      System.out.println( "--- "+s.getName() );
-                    }
-                }
-                cl = ncl;
-            }
-        }
-        return cl;
-    }
-    
-    private static class MyURLClassLoader extends URLClassLoader
-    {
-        /**
-         * This is just a class loader where we can hang more urls to
-         * search.
-         * @param urls
-         * @param parent
-         */
-        public MyURLClassLoader( URL[] urls, ClassLoader parent )
-        {
-            super( urls, parent );
-        }
-        
-        @Override
-        public void addURL( URL url )
+    	try
+    	{
+    		main( this, args );
+    	}
+        catch ( Throwable e )
         {
-            super.addURL( url );
+        	e.printStackTrace();
+            exit( 3, toString(), e.toString(), true );
+            return;
         }
     }
 
@@ -169,9 +64,7 @@
      */
     public EtchMain()
     {
-        sourceFiles = new LinkedList<File>();   
-        what        = new LinkedList<String>();
-        includePath = new LinkedList<File>();
+        // nothing to do.
     }
 
     @Override
@@ -184,57 +77,51 @@
     protected void defineOptionsAndParameters( CommandParser cp )
         throws Exception
     {
-        cp.defineFileOption( "-t|--template-out", "templateDir", "setTemplateDir",
-            "specifies the output directory for Impl* and Main* files",
-            Option.SINGLETON, null, null );
-            
         cp.defineFileOption( "-d|--output-dir", "outputDir", "setOutputDir",
-            "specifies the output directory",
+            "output directory for compiler generated files",
+            Option.SINGLETON, null, null );
+
+        cp.defineFileOption( "-m|--mixin-output-dir", "outputDir", "setMixinOutputDir",
+            "output directory for compiler generated files for mixins",
             Option.SINGLETON, null, null );
 
+        cp.defineFileOption( "-t|--template-output-dir", "outputDir", "setTemplateOutputDir",
+            "output directory for compiler generated user editable template files",
+            Option.SINGLETON, null, null );
+            
         cp.defineStringOption( "-b|--binding", "binding", "setBinding",
             "specifies a target language binding to generate",
             Option.REQUIRED|Option.SINGLETON, null, null );
 
-        cp.defineStringOption( "-w|--what|--who", "what", "setWhat",
-            "specifies what files to generate: all,server,client,impl,main,helper (--who is deprecated)",
-            Option.SINGLETON, "BOTH", null );
+        cp.defineStringOption( "-w|--what", "what", "addWhat",
+            "specifies what files to generate (depends upon binding, try -w help for more info; separate with '"+CmdLineOptions.WHAT_DELIMETER+"')",
+            Option.NONE, null, null );
 
-        cp.defineNullOption( "-g|--ignore-global", "ignoreGlobalWordsList",
+        cp.defineNullOption( "-g|--ignore-global-words-list", "ignoreGlobalWordsList",
             "ignore the global reserved words list",
             Option.SINGLETON );
 
-        cp.defineNullOption( "-l|--ignore-local", "ignoreLocalWordsList",
-            "ignore the local reserved words list",
+        cp.defineNullOption( "-l|--ignore-local-words-list", "ignoreLocalWordsList",
+            "ignore the local (binding-specific) reserved words list",
             Option.SINGLETON );
 
-        cp.defineFileOption( "-W|--word-list", "wordList", "setUserWordsList",
-            "specifies a reserved words list",
+        cp.defineFileOption( "-W|--user-words-list", "wordList", "setUserWordsList",
+            "file name of a user-specified reserved words list",
             Option.SINGLETON, null, null );
 
-        cp.defineStringOption( "-I|--include-path", "includePath", "setIncludePath",
-            "a search directory for included etch files",
+        cp.defineStringOption( "-I|--include-path", "includePath", "addIncludePath",
+            "adds search directories for included or mixed in etch files (separate elements with system path separator '"+File.pathSeparator+"')",
             Option.NONE, null, null );
 
-        /*
-        cp.defineStringOption( "-L|--etch-lib", "etchLib", "setEtchLib",
-            "the fully qualified path of ETCH_HOME/lib",
-            Option.SINGLETON, null, null );
-        */
-
-        cp.defineNullOption( "-i|--ignore-include-path", "ignoreEnvIncludePath",
-            "ignore the include path environment variable",
+        cp.defineNullOption( "-i|--ignore-include-path", "ignoreIncludePath",
+            "ignore the "+CmdLineOptions.ETCH_INCLUDE_PATH+" environment variable",
             Option.SINGLETON );
 
-        cp.defineFileOption( "-m|--dir-mixin", "mixinOutputDir", "setMixinOutputDir",
-            "the output dir for mixin artifacts",
-            Option.SINGLETON, null, null );
-
-        cp.defineNullOption( "-n|--no-mixin-artifacts", "setNoMixinArtifacts",
+        cp.defineNullOption( "-n|--no-mixin-artifacts", "noMixinArtifacts",
             "mixin artifacts should not be generated",
             Option.SINGLETON );
 
-        cp.defineNullOption( "-q|--quiet", "setQuiet",
+        cp.defineNullOption( "-q|--quiet", "quiet",
             "only report problems",
             Option.SINGLETON );
 
@@ -242,130 +129,117 @@
             "show the version and exit",
             Option.SINGLETON );
 
-        cp.defineNullOption( "-f|--no-flatten", "setNoFlattenPackages",
-            "the namespace directory tree should not be flattened",
+        cp.defineNullOption( "-f|--no-flatten-packages", "noFlattenPackages",
+            "namespace directory tree should not be flattened",
             Option.SINGLETON );
+        
+        cp.defineNullOption( "--testing", "setTesting",
+        	"",
+        	Option.HIDDEN );
 
-        cp.defineFileParameter( "file", "setFile",
-            "Etch source to compile", true, true, null );
+        cp.defineFileParameter( "sourceFile", "setSourceFile",
+            "etch source file to compile", true, false, null );
     }
+    
+    private final CmdLineOptions clo = new CmdLineOptions();
 
     /**
-     * Command parser method to set the output directory.
+     * Sets the output directory of compiler generated files.
      * @param cp
      * @param option
      * @param token
      * @param value the output directory
-     * @return true if it worked, false otherwise.
      */
-    public boolean setOutputDir( CommandParser cp, Option option, String token,
+    public void setOutputDir( CommandParser cp, Option option, String token,
         File value )
     {
-        outputDirectory = value;
-        return true;
+        clo.outputDir = value;
     }
-    private File outputDirectory = null;
     
     /**
-     * Command parser method to set the output directory for template files Impl* and Main*.
+     * Sets the output directory for user editable template files.
      * @param cp
      * @param option
      * @param token
      * @param value the template output directory
-     * @return true if it worked, false otherwise.
      */
-    public boolean setTemplateDir( CommandParser cp, Option option, String token,
+    public void setTemplateOutputDir( CommandParser cp, Option option, String token,
         File value )
     {
-        templateOutputDirectory = value;
-        return true;
+    	clo.templateOutputDir = value;
     }
-    private File templateOutputDirectory = null;    
 
     /**
-     * Command parser method to set the binding.
+     * Sets the binding.
      * @param cp
      * @param option
      * @param token
      * @param value the binding
-     * @return true if it worked, false otherwise.
      */
-    public boolean setBinding( CommandParser cp, Option option, String token,
+    public void setBinding( CommandParser cp, Option option, String token,
         String value )
     {
-        bindingName = value;
-        return true;
+    	clo.binding = value;
     }
-    private String bindingName = null;
 
     /**
-     * Command parser method to set for whom/what we are generating code.
+     * Adds to the set of what needs to be generated.
      * @param cp
      * @param option
      * @param token
      * @param value the list of what needs to be generated.
-     * @return true if it worked, false otherwise.
      */
-    public boolean setWhat( CommandParser cp, Option option, String token,
+    public void addWhat( CommandParser cp, Option option, String token,
         String value )
     {
-        StringTokenizer st = new StringTokenizer(value,WHO_DELIMETER);
-
+        StringTokenizer st = new StringTokenizer( value, CmdLineOptions.WHAT_DELIMETER );
         while (st.hasMoreElements()) 
-            what.add(st.nextToken().toUpperCase());
-
-        return true;
+        	clo.what.add(st.nextToken().toUpperCase());
     }
-    private List<String> what;
 
     /**
-     * Command parser method to ignore the globally reserved words list.
+     * Sets the ignore the globally reserved words list flag.
      * @param cp
      * @param option
      * @param token
      */
     public void ignoreGlobalWordsList(CommandParser cp, Option option, String token)
     {
-        ignoreGlobal = true;
+    	clo.ignoreGlobalWordsList = true;
     }
-    private boolean ignoreGlobal = true;
 
     /**
-     * Command parser method to ignore the locally reserved words list.
+     * Sets the ignore the locally reserved words list flag.
      * @param cp
      * @param option
      * @param token
      */
     public void ignoreLocalWordsList(CommandParser cp, Option option, String token)
     {
-        ignoreLocal = true;
+    	clo.ignoreLocalWordsList = true;
     }
-    private boolean ignoreLocal = false;
 
     /**
-     * Command parser method to set the user-defined reserved words list.
+     * Sets the file name of the user-defined reserved words list.
      * @param cp
      * @param option
      * @param token
-     * @param value the reserved words list
-     * @return true if it worked, false otherwise.
+     * @param value the file name of the user-defined reserved words list
      */
-    public boolean setUserWordsList(CommandParser cp, Option option, String token,
+    public void setUserWordsList(CommandParser cp, Option option, String token,
         File value)
     {
-        userWordList = value;
-        return true;
+    	clo.userWordsList = value;
     }
-    private File userWordList = null;
 
     /**
-     * Command parser method to set the include path.
+     * Adds to the include path.
      * @param cp
      * @param option
      * @param token
-     * @param value path to append to the current include path
+     * @param value path list to append to the current include path.
      */
-    public void setIncludePath( CommandParser cp, Option option, String token,
+    public void addIncludePath( CommandParser cp, Option option, String token,
         String value )
     {
         StringTokenizer includeTokens = new StringTokenizer(value,
@@ -374,38 +248,35 @@
         while(includeTokens.hasMoreTokens())
         {
             File temp = new File(includeTokens.nextToken());
-            includePath.add(temp);
+            clo.includePath.add(temp);
         }
     }
-    private List<File> includePath;
 
     /**
-     * Command parser method to ignore the include path from the environment.
+     * Sets the ignore the include path from the environment flag.
      * @param cp
      * @param option
      * @param token
      */
-    public void ignoreEnvIncludePath(CommandParser cp, Option option,
+    public void ignoreIncludePath(CommandParser cp, Option option,
         String token)
     {
-        ignoreEnvironmentIncludePath = true;
+    	clo.ignoreIncludePath = true;
     }
-    private boolean ignoreEnvironmentIncludePath = false;
 
     /**
-     * Command parser method to set the quiet flag.
+     * Sets the quiet flag.
      * @param cp
      * @param option
      * @param token
      */
-    public void setQuiet( CommandParser cp, Option option, String token )
+    public void quiet( CommandParser cp, Option option, String token )
     {
-        quiet = true;
+    	clo.quiet = true;
     }
-    private boolean quiet = false;
 
     /**
-     * Command parser method to show the version and exit.
+     * Shows the version and exits.
      * @param cp
      * @param option
      * @param token
@@ -418,125 +289,80 @@
     }
 
     /**
-     * Command parser method to suppress mixin artifacts.
+     * Sets the suppress mixin artifacts flag.
      * @param cp
      * @param option
      * @param token
      */
-    public void setNoMixinArtifacts( CommandParser cp, Option option, String token )
+    public void noMixinArtifacts( CommandParser cp, Option option, String token )
     {
-        mixinSuppressed = true;
+    	clo.noMixinArtifacts = true;
     }
-    private boolean mixinSuppressed = false;
 
     /**
-     * Command parser method to set the output directory for mixins.
+     * Sets the output directory for mixins.
      * @param cp
      * @param option
      * @param token
      * @param value the output directory for mixin
-     * @return true if it worked, false otherwise.
      */
-    public boolean setMixinOutputDir( CommandParser cp, Option option, String token,
+    public void setMixinOutputDir( CommandParser cp, Option option, String token,
         File value )
     {
-        mixinOutputDirectory = value;
-        return true;
+    	clo.mixinOutputDir = value;
     }
-    
-    private File mixinOutputDirectory = null;
 
     /**
+     * Sets the no flatten packages flag.
      * @param cp
      * @param option
      * @param token
      */
-    public void setNoFlattenPackages( CommandParser cp, Option option, String token)
+    public void noFlattenPackages( CommandParser cp, Option option, String token )
     {
-        noFlattenPackages = true;
+    	clo.noFlattenPackages = true;
     }
     
-    private boolean noFlattenPackages;
-
     /**
-     * Command parser method to set the etch file to compile.
+     * Sets the hidden testing flag.
      * @param cp
+     * @param option
+     * @param token
+     */
+    public void setTesting( CommandParser cp, Option option, String token )
+    {
+    	clo.testing = true;
+    	clo.lh = new ListLogHandler();
+    	testingClo = clo;
+    }
+    
+    /**
+     * If --testing is on the command line, the CmdLineOptions is saved
+     * here for reference by unit testing programs.
+     */
+    public CmdLineOptions testingClo;
+
+    /**
+     * Sets the etch source file to compile.
+     * @param cp the command parser
      * @param param
      * @param value path of etch file to compile
-     * @return true if file added to list, false otherwise.
      */
-    public boolean setFile( CommandParser cp, Parameter param, File value )
+    public void setSourceFile( CommandParser cp, Parameter param, File value )
     {
-        sourceFiles.add(value);
-        return true;
+    	clo.sourceFile = value;
     }
-    private List<File> sourceFiles;
 
     @Override
     protected void run() throws Exception
     {
-        if (bindingName == null)
-            throw new Exception ("No binding specified.");
-        
-        // Instantiate a new compiler instance
-        EtchCompiler etchCompiler = new EtchCompiler( setupClassLoader( null ) );
-        etchCompiler.setQuiet( quiet );
-
-        // VALIDATE
-
-        try
-        {
-            etchCompiler.setBindingName(bindingName);
-            etchCompiler.setIgnoreEnvironmentIncludePath(ignoreEnvironmentIncludePath);        
-            etchCompiler.setMixinSuppressed(mixinSuppressed);
-            etchCompiler.setFlattenPackages(!noFlattenPackages);        
-            etchCompiler.setOverwriteTemplate(false);
-            etchCompiler.setIgnoreLocal(ignoreLocal);
-            etchCompiler.setIgnoreGlobal(ignoreGlobal);
-        
-            for (File f: includePath)
-                etchCompiler.addIncludePath(f);
-            
-            for (String w: what)
-                etchCompiler.addWhat(w);
-
-            if (outputDirectory != null)
-                etchCompiler.setOutputDirectory(outputDirectory);
-        
-            if (userWordList != null)
-                etchCompiler.setUserWordsList(userWordList);
+        // Instantiate a new compiler instance and run it.
+    	ClassLoader cl = EtchCompiler.setupClassLoader( null );
+        EtchCompiler etchCompiler = new EtchCompiler( cl );
         
-            if (mixinOutputDirectory != null)
-                etchCompiler.setMixinOutputDirectory(mixinOutputDirectory);
+        etchCompiler.run( clo );
         
-            if (templateOutputDirectory != null)
-                etchCompiler.setTemplateOutputDirectory(templateOutputDirectory);
-        }
-        catch (Exception e)
-        {
-            throw new Exception("Invalid parameter passed to the compiler:\n" + e.getMessage());
-        }
-        
-        // EXECUTE 
-        
-        boolean status = true;
-        for (File name: sourceFiles)
-        {
-            try
-            {
-                etchCompiler.validateEtchFile(name);
-                etchCompiler.compile(name);
-            }
-            catch ( Exception e )
-            {
-                System.out.println(String.format("Error Compiling %s: %s", name.getName(), e.getMessage()));
-                e.printStackTrace();
-                status = false;
-            }
-        }
-        if (!status)
-        {
-            throw new Exception("One or more .etch files failed to compile.");
-        }
+        if (clo.lh.hasError())
+        	exit( 3, "EtchMain", "errors during compile", false );
     }
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/LogHandler.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/LogHandler.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/LogHandler.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/LogHandler.java Sun Nov 16 14:35:35 2008
@@ -26,73 +26,197 @@
 public interface LogHandler
 {
 	/**
-	 * Constant to specify an Error Message
+	 * A message which is always printed, but doesn't affect compilation.
+	 * Also usually formatted without level, phase, source, line number, or
+	 * history information.
+	 */
+	public static final int LEVEL_IMPORTANT = 0;
+	
+	/**
+	 * An error level message. Also causes compiler to exit with an error code.
 	 */
 	public static final int LEVEL_ERROR = 1;
+	
 	/**
-	 * Constant to specify an Warning Message
+	 * A warning level message.
 	 */
 	public static final int LEVEL_WARNING = 2;
+	
 	/**
-	 * Constant to specify an Info Message
+	 * An information level message.
 	 */
 	public static final int LEVEL_INFO = 3;
+	
 	/**
-	 * Constant to specify an unformatted message to be printed always.
+	 * Formats and reports a message without a line number.
+	 * @param level
+	 * @param fmt
+	 * @param params
+	 */
+	public void report( int level, String fmt, Object ... params );
+	
+	/**
+	 * Formats and reports a message with perhaps a line number.
+	 * @param level
+	 * @param lineNumber
+	 * @param fmt
+	 * @param params
 	 */
-	public static final int LEVEL_MESSAGE = 4;
+	public void report( int level, Integer lineNumber, String fmt,
+		Object ... params );
 	
 	/**
 	 * This method is used to either store or print messages
 	 * @param level indicates ERROR, WARNING or INFO
-	 * @param token indicates the token at which the error occured
+	 * @param token indicates the token at which the error occurred
 	 * @param msg String message
+	 * @deprecated use {@link #report(int, Integer, String)} instead.
+	 */
+	@Deprecated
+	public void logMessage( int level, Token token, String msg );
+	
+	/**
+	 * Reports a pre-formatted message perhaps with a line number.
+	 * @param level
+	 * @param lineNumber
+	 * @param msg
 	 */
-	public void logMessage(int level, Token token, String msg );
+	public void report( int level, Integer lineNumber, String msg );
 	
 	/**
-	 * This method is used to specify the source of the Message
-	 * @param str  File name where the Message occured
-	 * @param num  Line Number where the Message occured
+	 * Determines if a message is interesting given its level.
+	 * @param level
+	 * @return true if a message is interesting given its level.
 	 */
+	public boolean isInteresting( int level );
 	
-	public void push(String str, Integer num);
+	/**
+	 * Pushes a new source on the stack.
+	 * @param newSource new source name being read.
+	 * @param lineNumberInOldSource line number in old source which caused the new
+	 * source to be read. This should be null for the top level source.
+	 */
+	public void push( String newSource, Integer lineNumberInOldSource );
 	
 	/**
-	 * This method removes the source that was added by the push method.
+	 * Removes the source that was added by the last push method.
 	 * It behaves exactly like the pop method in Stacks
-	 *
+	 * @param oldSource the source name we just finished reading. This was
+	 * previously passed as the argument to the last push.
 	 */
+	public void pop( String oldSource );
 	
-	public void pop();
+	/**
+	 * @return true if an error has been reported.
+	 */
+	public boolean hasError();
 	
 	/**
-	 * Indicates whether an error was encountered
-	 * @return flag to indicate whether an error occured
+	 * @return count of errors that have been reported.
 	 */
+	public int errorCount();
 	
-	public boolean hasError();
+	/**
+	 * @return true if a warning has been reported.
+	 */
+	public boolean hasWarning();
 	
 	/**
-	 * Sets the quiet flag.
-	 * @param quiet
+	 * @return count of warnings that have been reported.
 	 */
-	public void setQuiet( boolean quiet );
+	public int warningCount();
 
 	/**
-	 * This method gets the isQuiet Variable
-	 * @return whether Compiler is printing info and warning messages
+	 * Gets the level of logging.
+	 * @return the current level of logging. Only messages with level less than
+	 * or equal to this value will be logged.
+	 */
+	public int getLevel();
+	
+	/**
+	 * Sets the level of logging. Only messages with level less than
+	 * or equal to this value will be logged.
+	 * @param level the level of logging
+	 */
+	public void setLevel( int level );
+	
+	/**
+	 * @return the current phase of processing. The initial value is null.
 	 */
-	public boolean getQuiet();
+	public String getPhase();
 	
 	/**
 	 * Sets the current phase of processing.
-	 * @param phase
+	 * @param phase may be null.
 	 */
 	public void setPhase( String phase );
 	
 	/**
-	 * @return the current phase of processing.
+	 * Final condensation of the information of a report.
 	 */
-	public String getPhase();
+	public static class Message
+	{
+		/**
+		 * @param level
+		 * @param phase
+		 * @param source
+		 * @param lineNumber
+		 * @param msg
+		 * @param history
+		 */
+		public Message( int level, String phase, String source,
+			Integer lineNumber, String msg, History[] history )
+		{
+			this.level = level;
+			this.phase = phase;
+			this.source = source;
+			this.lineNumber = lineNumber;
+			this.msg = msg;
+			this.history = history;
+		}
+		
+		/** the level of the report */
+		public final int level;
+		
+		/** the phase of processing when the report was made */
+		public final String phase;
+		
+		/** the current input source */
+		public final String source;
+		
+		/** the line number of the source which caused the report (if any) */
+		public final Integer lineNumber;
+		
+		/** the text of the report */
+		public final String msg;
+		
+		/** the history of sources previous to source / lineNumber above */
+		public final History[] history;
+	}
+
+	/**
+	 * Record of the input streams previous to the last one pushed.
+	 */
+	public static class History
+	{
+		/**
+		 * @param source
+		 * @param lineNumber
+		 */
+		public History( String source, int lineNumber )
+		{
+			this.source = source;
+			this.lineNum = lineNumber;
+		}
+		
+		/**
+		 * The source of the input stream (file, stdin, etc.)
+		 */
+		public final String source;
+		
+		/**
+		 * The line number of the source which caused a new source to be pushed.
+		 */
+		public final int lineNum;
+	}
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/ReservedWordChecker.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/ReservedWordChecker.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/ReservedWordChecker.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/ReservedWordChecker.java Sun Nov 16 14:35:35 2008
@@ -154,9 +154,9 @@
 	{
 		String msg = String.format( "Etch: %s '%s' is a reserved word at line %d\n", what, token.image, token.beginLine);
 		if (rewrite)
-			lh.logMessage( LogHandler.LEVEL_WARNING, token,msg  );
+			lh.report( LogHandler.LEVEL_WARNING, token.beginLine, msg );
 		else
-			lh.logMessage( LogHandler.LEVEL_ERROR, token,msg  );
+			lh.report( LogHandler.LEVEL_ERROR, token.beginLine, msg );
 		ok = rewrite;
 	}
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/Service.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/Service.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/Service.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/java/etch/compiler/ast/Service.java Sun Nov 16 14:35:35 2008
@@ -17,22 +17,15 @@
 
 package etch.compiler.ast;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import etch.compiler.Backend;
-import etch.compiler.CmdLineOptions;
-import etch.compiler.Etch2;
+import etch.compiler.EtchCompiler;
 import etch.compiler.EtchGrammarConstants;
-import etch.compiler.LogHandler;
 import etch.compiler.ParseException;
 import etch.compiler.Token;
 
@@ -85,125 +78,30 @@
 	{
 		optsCheck( Mixin.class, nOpts );
 		
-		try {
-		
-
-			getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_INFO, n.token,
-			" Checking Mixin file: " + n.name + " at line : "
-				+ n.token.beginLine + "\n" );
-		String filename = n.name;
-		filename = filename.replace( '.', '/' );
-		filename = filename + ".etch";
-		List<File> list = getCmdLineOptions().includePath;
-		String searchPath = null;
-		File etchFile = null;
-		boolean mixinFileExist = false;
-		
-		
-		if (list != null)
+		try
 		{
-			for (int i = 0; i < list.size(); i++)
-			{
-				File f = list.get( i );
-				if (f != null)
-				{
-					searchPath = f.getAbsolutePath() + "/" + filename;
-					etchFile = new File( searchPath );
-					if (etchFile.exists())
-					{
-						mixinFileExist = true;
-						break;
-					}
-				}
-			}
-			if (mixinFileExist)
-			{
-
-				getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_INFO, n.token,
-					" Found mixin file " + etchFile.getAbsolutePath()
-						+ " in Include Path \n" );
-				// System.out.println(" We found the file " + etchFile.getName()
-				// + "
-				// Now lets try to generate the parsed tree");
-				
-				// Does -d or -dm option exist. If not return
-				if (!getCmdLineOptions().noMixinArtifacts)
-				{
-					if (getCmdLineOptions().outputDir == null
-						&& getCmdLineOptions().mixinOutputDir == null)
-					{
-						getCmdLineOptions().lh
-						.logMessage(
-							LogHandler.LEVEL_ERROR,
-							n.token,
-							"-d or -m option is not specified. Please specify one of these"
-							+ " options. Mixin artifacts will only be generated when atleast one of these options"
-							+ " is present \n" );
-
-						return null;
-					}
-				}
-				
-				InputStream is = null;
-				try
-				{
-					is = new java.io.FileInputStream( etchFile );
-				}
-				catch ( FileNotFoundException e1 )
-				{
-					e1.printStackTrace();
-
-				}
-
-				getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_INFO, null,
-					"Parsing file " + etchFile.getAbsolutePath() + "\n" );
-				getCmdLineOptions().lh.push( etchFile.getName(), new Integer(
-					n.token.beginLine ) );
-				
-				CmdLineOptions cmdLineObject = new CmdLineOptions(getCmdLineOptions());
-				HashSet<String> set = new HashSet<String>();
-				if (getCmdLineOptions().noMixinArtifacts)
-				{
-					cmdLineObject.isMixinPresent = false;
-					set.add(Backend.WHAT_NONE);
-				}
-				else
-				{
-					cmdLineObject.isMixinPresent = true;
-					set = populateWhat(getCmdLineOptions().what);
-				}
-				cmdLineObject.what = set;
-				
-				
-				Module retMod = Etch2.doCompile( cmdLineObject, is,
-					getCmdLineOptions().lh );
-				getCmdLineOptions().lh.pop();
-				Mixin mixin = new Mixin( this, n, nOpts, retMod );
-				nameList.add( n, mixin );
-				return mixin;
-			}
-			getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_ERROR, n.token,
-				" Mixin file does not exist in Include Path. \n" );
-		}
-		else
-		{
-			getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_ERROR, n.token,
-				" No Include Path defined for Mixin File \n" );
+			Module module = EtchCompiler.parseModule( this, n, nOpts );
+			if (module == null)
+				throw new ParseException( String.format(
+					"could not find mixin '%s' at line %d",
+					n.name, n.token.beginLine ) );
 			
+			Mixin mixin = new Mixin( this, n, nOpts, module );
+			nameList.add( n, mixin );
+			return mixin;
 		}
+		catch ( ParseException e )
+		{
+			throw e;
 		}
-		catch (Exception e) {
-			getCmdLineOptions().lh.logMessage( LogHandler.LEVEL_ERROR, n.token,
-			" Unexpected Error occured during parsing mixin \n" );
-			e.printStackTrace();
-			
+		catch ( Exception e )
+		{
+			throw new ParseException( String.format(
+				"could not find mixin '%s' at line %d: %s",
+				n.name, n.token.beginLine, e ) );
 		}
-
-		return null;
 	}
 	
-	
-	
 	/**
 	 * Adds a constant declaration.
 	 * @param n
@@ -661,35 +559,4 @@
 		
 		walker.postService( this );
 	}
-	
-	private HashSet<String> populateWhat(Set<String> set) {
-		HashSet<String> retSet = new HashSet<String>();
-		if (set.contains( Backend.WHAT_ALL ) || set.contains( Backend.WHAT_BOTH )) {
-			retSet.add( Backend.WHAT_BOTH );
-		}
-		if (set.contains( Backend.WHAT_CLIENT)) {
-			retSet.add( Backend.WHAT_CLIENT );
-		}
-		if (set.contains( Backend.WHAT_SERVER)) {
-			retSet.add( Backend.WHAT_SERVER );
-		}
-		if (set.contains( Backend.WHAT_MAIN ) || set.contains( Backend.WHAT_IMPL ) ||
-			set.contains( Backend.WHAT_HELPER )) {
-			if (retSet.isEmpty()) {
-				retSet.add( Backend.WHAT_BOTH );
-			}
-		}
-		if (set.contains( Backend.WHAT_FORCE ) ) {
-			
-				retSet.add( Backend.WHAT_FORCE );
-			
-		}
-		if (set.contains( Backend.WHAT_NONE)) {
-			retSet.clear();
-			retSet.add( Backend.WHAT_NONE );
-		}
-
-		return retSet;
-		
-	}
 }

Modified: incubator/etch/branches/etch-python/compiler/src/main/scripts/etch.bat
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/main/scripts/etch.bat?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/main/scripts/etch.bat (original)
+++ incubator/etch/branches/etch-python/compiler/src/main/scripts/etch.bat Sun Nov 16 14:35:35 2008
@@ -12,7 +12,6 @@
 
 set ETCH_CP=
 for %%i in ("%ETCH_HOME%\lib\etch-compiler-*.jar") do set ETCH_CP=%ETCH_CP%;%%i
-rem for %%i in ("%ETCH_HOME%\lib\etch-util-*.jar") do set ETCH_CP=%ETCH_CP%;%%i
 
 rem add clover to classpath if defined and exists
 
@@ -21,4 +20,4 @@
 set ETCH_CP=%ETCH_CP%;%CLOVER_HOME%\lib\clover.jar
 :skip_clover
 
-java -cp "%ETCH_CP%" -Detch.home="%ETCH_HOME%" etch.compiler.EtchMain %*
+java -cp "%ETCH_CP%" etch.compiler.EtchMain %*

Modified: incubator/etch/branches/etch-python/compiler/src/test/java/etch/compiler/TestMapWords.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/compiler/src/test/java/etch/compiler/TestMapWords.java?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/compiler/src/test/java/etch/compiler/TestMapWords.java (original)
+++ incubator/etch/branches/etch-python/compiler/src/test/java/etch/compiler/TestMapWords.java Sun Nov 16 14:35:35 2008
@@ -91,11 +91,10 @@
 		}
 
 		@Override
-		public void generate( Module module, CmdLineOptions options, LogHandler lh )
+		public void generate( Module module, CmdLineOptions options )
 			throws Exception
 		{
 			// Not needed for testing
-
 		}
 
 		@Override

Modified: incubator/etch/branches/etch-python/examples/build.xml
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/examples/build.xml?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/examples/build.xml (original)
+++ incubator/etch/branches/etch-python/examples/build.xml Sun Nov 16 14:35:35 2008
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <project name="etch-examples" basedir="." default="help">
     <description>Etch Examples</description>
+	<target name="help"><echo>Please select a target...</echo></target>
     <property name="Etch.basedir" location="${basedir}/.." />
     <import file="${Etch.basedir}/build-support/etch.common.xml" />
 
@@ -55,10 +56,10 @@
 
     <target name="component-all" >
         <mkdir dir="${basedir}/target" />
-        <build_example dir="perf" logdir="${basedir}/target/logs" />
-        <build_example dir="distmap" logdir="${basedir}/target/logs" />
         <build_example dir="chat" logdir="${basedir}/target/logs" />
+        <build_example dir="distmap" logdir="${basedir}/target/logs" />
         <build_example dir="example" logdir="${basedir}/target/logs" />
+        <build_example dir="perf" logdir="${basedir}/target/logs" />
     </target>
 
 </project>

Modified: incubator/etch/branches/etch-python/examples/chat/README.txt
URL: http://svn.apache.org/viewvc/incubator/etch/branches/etch-python/examples/chat/README.txt?rev=718128&r1=718127&r2=718128&view=diff
==============================================================================
--- incubator/etch/branches/etch-python/examples/chat/README.txt (original)
+++ incubator/etch/branches/etch-python/examples/chat/README.txt Sun Nov 16 14:35:35 2008
@@ -1,10 +1,26 @@
-
 To build:
 
 > ant debug
 
-To Run:
+The debug ant target will build both the java and csharp
+programs.
+
+To run java chat, open a cmd window and run these commands:
+
+> cd target\bin
+> start java -cp chat.jar etch.examples.chat.MainChatListener
+> start java -cp chat.jar etch.examples.chat.MainChatClient
+> start java -cp chat.jar etch.examples.chat.MainChatClient
+
+Two chat clients will be started; there is a help command;
+login as a different user in each with any password; they
+can chat with each other!
+
+To run csharp chat:
+
+> cd target\bin
+> start ChatListener.exe
+> start ChatClient.exe
+> start ChatClient.exe
 
-> cd target/bin
-> java -cp chat.jar etch.examples.chat.MainChatListener
-> java -cp chat.jar etch.examples.chat.MainChatClient
+You can mix and match the various clients and listeners.