Makefile.in: Rebuilt.

* Makefile.in: Rebuilt.
	* Makefile.am (AM_CXXFLAGS): Define TOOLEXECLIBDIR.
	(libgcj0_convenience_la_SOURCES): Don't include
	gnu_xml_source_files.
	(libgcj0_convenience_la_LIBADD): New variable.
	(libgcj_la_LIBADD): Don't include sax or w3c_dom.
	(all_java_source_files): javax_imageio_source_files,
	javax_xml_source_files, and gnu_java_beans_source_files.
	($(gnu_xml_source_files:.java=.lo)): Removed target.
	(gnu-xml.lo): New target.
	(javax-imageio.lo): Likewise.
	(javax-xml.lo): Likewise.
	(gnu-java-beans.lo): Likewise.
	(gnu_java_beans_source_files): New variable.
	(javax_imageio_source_files): Likewise.
	(javax_xml_source_files): Likewise.
	(javax_source_files): Moved files to other variable.
	(awt_java_source_files): Likewise.
	(ordinary_java_source_files): Added BootClassLoader.java.
	* java/lang/natVMClassLoader.cc (defineClass): Use boot loader,
	not system class loader.
	(initBootLoader): New method.
	(loadClass): Search bootLoader.
	* java/lang/natClassLoader.cc (_Jv_RegisterInitiatingLoader): Use
	boot loader, not system class loader.
	(_Jv_UnregisterInitiatingLoader): Likewise.
	(_Jv_FindClass): Likewise.  Ensure entries in
	bootstrap_class_list are unique.
	* java/lang/natClass.cc (getClassLoader): Don't special case
	system class loader.
	* java/lang/VMClassLoader.java (bootLoader): New field.
	(getResource): Use bootLoader.
	(getResources): Likewise.
	(initBootLoader): Declare.
	* gnu/gcj/runtime/BootClassLoader.java: New file.
	* external/sax/org/xml/sax/helpers/NamespaceSupport.java
	(EMPTY_ENUMERATION): Now package-private.
	* external/w3c_com/Makefile.in: Rebuilt.
	* external/w3c_com/Makefile.am (MULTIBUILDTOP): New variable.
	(w3c.jar): New target.
	(classes.stamp): Updated.
	(toolexeclib_LTLIBRARIES): Renamed from noinst_LTLIBRARIES.
	Changed name of library.
	(libw3c_gcj_la_SOURCES): New variable.
	(libw3c_gcj_la_GCJFLAGS): Likewise.
	(source_files): Renamed from lib3c_convenience_la_SOURCES.
	* external/sax/Makefile.in: Rebuilt.
	* external/sax/Makefile.am (MULTIBUILDTOP): New variable.
	(sax.jar): New target.
	(classes.stamp): Updated.
	(toolexeclib_LTLIBRARIES): Renamed from noinst_LTLIBRARIES.
	Changed name of library.
	(libsax_gcj_la_SOURCES): New variable.
	(libsax_gcj_la_GCJFLAGS): Likewise.
	(source_files): Renamed from libsax_convenience_la_SOURCES.
	* stacktrace.cc (non_system_trace_fn): Don't look at system class
	loader.
	* prims.cc (_Jv_CreateJavaVM): Initialize the bootstrap class
	loader.
	(_Jv_RunMain): Handle case where 'runtime' is NULL at exit.

From-SVN: r96960
This commit is contained in:
Tom Tromey
2005-03-24 00:04:22 +00:00
committed by Tom Tromey
parent 85624ffd34
commit aa893047e8
24 changed files with 8517 additions and 10715 deletions
@@ -0,0 +1,102 @@
/* Copyright (C) 2005 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
package gnu.gcj.runtime;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.StringTokenizer;
/**
* This is a helper for the bootstrap class loader. It is a
* URLClassLoader so that we can read a class path and re-use all the
* existing code for finding classes, extracting them from jars, etc.
* However, it is never called the way that an ordinary ClassLoader is
* called. For instance, loadClass() is never used.
*/
public final class BootClassLoader extends URLClassLoader
{
BootClassLoader(String libdir)
{
super(new URL[0]);
// Add the contents of the endorsed directories.
StringTokenizer st
= new StringTokenizer (System.getProperty ("java.endorsed.dirs", ""),
File.pathSeparator);
try
{
while (st.hasMoreElements ())
{
String dirname = st.nextToken ();
File dir = new File (dirname);
if (dir.exists ())
{
if (! dirname.endsWith (File.separator))
dirname = dirname + File.separator;
String files[] = dir.list (new FilenameFilter ()
{
public boolean accept (File dir, String name)
{
return name.endsWith (".jar") || name.endsWith (".zip");
}
});
for (int i = files.length - 1; i >= 0; i--)
addURL(new URL("file", "", -1, dirname + files[i]));
}
}
String w3clib = (libdir + File.separator
+ System.mapLibraryName ("w3c-gcj"));
addURL(new URL("gcjlib", "", -1, w3clib));
String saxlib = (libdir + File.separator
+ System.mapLibraryName ("sax-gcj"));
addURL(new URL("gcjlib", "", -1, saxlib));
}
catch (java.net.MalformedURLException x)
{
// This should never happen.
throw new RuntimeException(x);
}
}
public Class bootLoadClass(String name)
throws ClassNotFoundException
{
Class c = findLoadedClass(name);
if (c == null)
{
try
{
// We could hack URLClassLoader to make this more
// efficient, if it mattered.
c = findClass(name);
}
catch (ClassNotFoundException _)
{
c = null;
}
}
return c;
}
public URL bootGetResource(String name)
{
return findResource(name);
}
public Enumeration bootGetResources(String name) throws IOException
{
return findResources(name);
}
}
+159 -124
View File
@@ -60,137 +60,172 @@ import javax.xml.parsers.SAXParserFactory;
*
* @author David Brownell
*/
public final class JAXPFactory extends SAXParserFactory
public final class JAXPFactory
extends SAXParserFactory
{
private Hashtable flags = new Hashtable ();
private Hashtable flags = new Hashtable();
/**
* Constructs a factory which normally returns a non-validating
* parser.
*/
public JAXPFactory () { }
/**
* Constructs a factory which normally returns a non-validating
* parser.
*/
public JAXPFactory()
{
}
public SAXParser newSAXParser ()
public SAXParser newSAXParser()
throws ParserConfigurationException, SAXException
{
JaxpParser jaxp = new JaxpParser ();
Enumeration e = flags.keys ();
XMLReader parser = jaxp.getXMLReader ();
{
JaxpParser jaxp = new JaxpParser();
Enumeration e = flags.keys();
XMLReader parser = jaxp.getXMLReader();
parser.setFeature (
SAXDriver.FEATURE + "namespaces",
isNamespaceAware ());
parser.setFeature (
SAXDriver.FEATURE + "validation",
isValidating ());
// that makes SAX2 feature flags trump JAXP
parser.setFeature(SAXDriver.FEATURE + "namespaces",
isNamespaceAware());
parser.setFeature(SAXDriver.FEATURE + "validation",
isValidating());
// that makes SAX2 feature flags trump JAXP
while (e.hasMoreElements())
{
String uri = (String) e.nextElement();
Boolean value = (Boolean) flags.get(uri);
parser.setFeature(uri, value.booleanValue());
}
while (e.hasMoreElements ()) {
String uri = (String) e.nextElement ();
Boolean value = (Boolean) flags.get (uri);
parser.setFeature (uri, value.booleanValue ());
}
return jaxp;
}
return jaxp;
}
// yes, this "feature transfer" mechanism doesn't play well
public void setFeature (String name, boolean value)
throws
ParserConfigurationException,
SAXNotRecognizedException,
SAXNotSupportedException
{
try {
// force "early" detection of errors where possible
// (flags can't necessarily be set before parsing)
new JaxpParser ().getXMLReader ().setFeature (name, value);
flags.put (name, new Boolean (value));
} catch (SAXNotRecognizedException e) {
throw new SAXNotRecognizedException (name);
} catch (SAXNotSupportedException e) {
throw new SAXNotSupportedException (name);
} catch (Exception e) {
throw new ParserConfigurationException (
e.getClass ().getName ()
+ ": "
+ e.getMessage ());
}
}
public boolean getFeature (String name)
throws
ParserConfigurationException,
SAXNotRecognizedException,
SAXNotSupportedException
{
Boolean value = (Boolean) flags.get (name);
if (value != null)
return value.booleanValue ();
else
try {
return new JaxpParser ().getXMLReader ().getFeature (name);
} catch (SAXNotRecognizedException e) {
throw new SAXNotRecognizedException (name);
} catch (SAXNotSupportedException e) {
throw new SAXNotSupportedException (name);
} catch (SAXException e) {
throw new ParserConfigurationException (
e.getClass ().getName ()
+ ": "
+ e.getMessage ());
}
}
private static class JaxpParser extends SAXParser
{
private XmlReader ae2 = new XmlReader ();
private XMLReaderAdapter parser = null;
JaxpParser () { }
public void setProperty (String id, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException
{ ae2.setProperty (id, value); }
public Object getProperty (String id)
throws SAXNotRecognizedException, SAXNotSupportedException
{ return ae2.getProperty (id); }
public Parser getParser ()
throws SAXException
{
if (parser == null)
parser = new XMLReaderAdapter (ae2);
return parser;
}
public XMLReader getXMLReader ()
throws SAXException
{ return ae2; }
public boolean isNamespaceAware ()
{
try {
return ae2.getFeature (SAXDriver.FEATURE + "namespaces");
} catch (Exception e) {
throw new Error ();
}
}
public boolean isValidating ()
{
try {
return ae2.getFeature (SAXDriver.FEATURE + "validation");
} catch (Exception e) {
throw new Error ();
}
}
// TODO isXIncludeAware()
// yes, this "feature transfer" mechanism doesn't play well
public void setFeature(String name, boolean value)
throws ParserConfigurationException, SAXNotRecognizedException,
SAXNotSupportedException
{
try
{
// force "early" detection of errors where possible
// (flags can't necessarily be set before parsing)
new JaxpParser().getXMLReader().setFeature(name, value);
flags.put(name, new Boolean(value));
}
catch (SAXNotRecognizedException e)
{
throw new SAXNotRecognizedException(name);
}
catch (SAXNotSupportedException e)
{
throw new SAXNotSupportedException(name);
}
catch (Exception e)
{
throw new ParserConfigurationException(e.getClass().getName()
+ ": "
+ e.getMessage());
}
}
public boolean getFeature(String name)
throws ParserConfigurationException, SAXNotRecognizedException,
SAXNotSupportedException
{
Boolean value = (Boolean) flags.get(name);
if (value != null)
{
return value.booleanValue();
}
else
{
try
{
return new JaxpParser().getXMLReader().getFeature(name);
}
catch (SAXNotRecognizedException e)
{
throw new SAXNotRecognizedException(name);
}
catch (SAXNotSupportedException e)
{
throw new SAXNotSupportedException(name);
}
catch (SAXException e)
{
throw new ParserConfigurationException(e.getClass().getName()
+ ": "
+ e.getMessage());
}
}
}
private static class JaxpParser
extends SAXParser
{
private XmlReader ae2 = new XmlReader();
private XMLReaderAdapter parser = null;
JaxpParser()
{
}
public void setProperty(String id, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException
{
ae2.setProperty(id, value);
}
public Object getProperty(String id)
throws SAXNotRecognizedException, SAXNotSupportedException
{
return ae2.getProperty(id);
}
public Parser getParser()
throws SAXException
{
if (parser == null)
{
parser = new XMLReaderAdapter(ae2);
}
return parser;
}
public XMLReader getXMLReader ()
throws SAXException
{
return ae2;
}
public boolean isNamespaceAware()
{
try
{
return ae2.getFeature(SAXDriver.FEATURE + "namespaces");
}
catch (Exception e)
{
throw new Error();
}
}
public boolean isValidating()
{
try
{
return ae2.getFeature(SAXDriver.FEATURE + "validation");
}
catch (Exception e)
{
throw new Error();
}
}
// TODO isXIncludeAware()
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+266 -207
View File
@@ -70,246 +70,305 @@ import gnu.xml.pipeline.ValidationConsumer;
*
* @author David Brownell
*/
public final class XmlReader implements XMLReader
public final class XmlReader
implements XMLReader
{
private SAXDriver aelfred2 = new SAXDriver ();
private EventFilter filter = new EventFilter ();
private boolean isValidating;
private boolean active;
/** Constructs a SAX Parser. */
public XmlReader ()
{ }
/**
* Constructs a SAX Parser, optionally treating validity errors
* as if they were fatal errors.
*/
public XmlReader (boolean invalidIsFatal)
static class FatalErrorHandler
extends DefaultHandler2
{
public void error(SAXParseException e)
throws SAXException
{
if (invalidIsFatal)
setErrorHandler (new DefaultHandler2 () {
public void error (SAXParseException e)
throws SAXException
{ throw e; }
});
throw e;
}
}
private SAXDriver aelfred2 = new SAXDriver();
private EventFilter filter = new EventFilter();
private boolean isValidating;
private boolean active;
/**
* <b>SAX2</b>: Returns the object used to report the logical
* content of an XML document.
*/
public ContentHandler getContentHandler ()
{ return filter.getContentHandler (); }
/**
* Constructs a SAX Parser.
*/
public XmlReader()
{
}
/**
* <b>SAX2</b>: Assigns the object used to report the logical
* content of an XML document.
* @exception IllegalStateException if called mid-parse
*/
public void setContentHandler (ContentHandler handler)
{
if (active)
throw new IllegalStateException ("already parsing");
filter.setContentHandler (handler);
}
/**
* Constructs a SAX Parser, optionally treating validity errors
* as if they were fatal errors.
*/
public XmlReader(boolean invalidIsFatal)
{
if (invalidIsFatal)
{
setErrorHandler(new FatalErrorHandler());
}
}
/**
* <b>SAX2</b>: Returns the object used to report the logical
* content of an XML document.
*/
public ContentHandler getContentHandler()
{
return filter.getContentHandler();
}
/**
* <b>SAX2</b>: Returns the object used to process declarations related
* to notations and unparsed entities.
*/
public DTDHandler getDTDHandler ()
{ return filter.getDTDHandler (); }
/**
* <b>SAX2</b>: Assigns the object used to report the logical
* content of an XML document.
* @exception IllegalStateException if called mid-parse
*/
public void setContentHandler(ContentHandler handler)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
filter.setContentHandler(handler);
}
/**
* <b>SAX1</b> Assigns DTD handler
* @exception IllegalStateException if called mid-parse
*/
public void setDTDHandler (DTDHandler handler)
{
if (active)
throw new IllegalStateException ("already parsing");
filter.setDTDHandler (handler);
}
/**
* <b>SAX2</b>: Returns the object used to process declarations related
* to notations and unparsed entities.
*/
public DTDHandler getDTDHandler()
{
return filter.getDTDHandler();
}
/**
* <b>SAX2</b>: Returns the object used when resolving external
* entities during parsing (both general and parameter entities).
*/
public EntityResolver getEntityResolver ()
{ return aelfred2.getEntityResolver (); }
/**
* <b>SAX1</b> Assigns DTD handler
* @exception IllegalStateException if called mid-parse
*/
public void setDTDHandler(DTDHandler handler)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
filter.setDTDHandler(handler);
}
/**
* <b>SAX2</b>: Returns the object used when resolving external
* entities during parsing (both general and parameter entities).
*/
public EntityResolver getEntityResolver()
{
return aelfred2.getEntityResolver();
}
/** <b>SAX1</b> Assigns parser's entity resolver */
public void setEntityResolver (EntityResolver handler)
{ aelfred2.setEntityResolver (handler); }
/**
* <b>SAX1</b> Assigns parser's entity resolver
*/
public void setEntityResolver(EntityResolver handler)
{
aelfred2.setEntityResolver(handler);
}
/**
* <b>SAX2</b>: Returns the object used to receive callbacks for XML
* errors of all levels (fatal, nonfatal, warning); this is never null;
*/
public ErrorHandler getErrorHandler ()
{ return aelfred2.getErrorHandler (); }
/**
* <b>SAX2</b>: Returns the object used to receive callbacks for XML
* errors of all levels (fatal, nonfatal, warning); this is never null;
*/
public ErrorHandler getErrorHandler()
{
return aelfred2.getErrorHandler();
}
/**
* <b>SAX1</b> Assigns error handler
* @exception IllegalStateException if called mid-parse
*/
public void setErrorHandler (ErrorHandler handler)
{
if (active)
throw new IllegalStateException ("already parsing");
aelfred2.setErrorHandler (handler);
}
/**
* <b>SAX1</b> Assigns error handler
* @exception IllegalStateException if called mid-parse
*/
public void setErrorHandler(ErrorHandler handler)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
aelfred2.setErrorHandler(handler);
}
/**
* <b>SAX2</b>: Assigns the specified property.
* @exception IllegalStateException if called mid-parse
*/
public void setProperty (String propertyId, Object value)
/**
* <b>SAX2</b>: Assigns the specified property.
* @exception IllegalStateException if called mid-parse
*/
public void setProperty(String propertyId, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException
{
if (active)
throw new IllegalStateException ("already parsing");
if (getProperty (propertyId) != value)
filter.setProperty (propertyId, value);
}
{
if (active)
{
throw new IllegalStateException("already parsing");
}
if (getProperty(propertyId) != value)
{
filter.setProperty(propertyId, value);
}
}
/**
* <b>SAX2</b>: Returns the specified property.
*/
public Object getProperty (String propertyId)
/**
* <b>SAX2</b>: Returns the specified property.
*/
public Object getProperty(String propertyId)
throws SAXNotRecognizedException
{
if ((SAXDriver.PROPERTY + "declaration-handler")
.equals (propertyId)
|| (SAXDriver.PROPERTY + "lexical-handler")
.equals (propertyId))
return filter.getProperty (propertyId);
throw new SAXNotRecognizedException (propertyId);
}
private void forceValidating ()
{
if ((SAXDriver.PROPERTY + "declaration-handler").equals(propertyId)
|| (SAXDriver.PROPERTY + "lexical-handler").equals(propertyId))
{
return filter.getProperty(propertyId);
}
throw new SAXNotRecognizedException(propertyId);
}
private void forceValidating()
throws SAXNotRecognizedException, SAXNotSupportedException
{
aelfred2.setFeature (
SAXDriver.FEATURE + "namespace-prefixes",
true);
aelfred2.setFeature (
SAXDriver.FEATURE + "external-general-entities",
true);
aelfred2.setFeature (
SAXDriver.FEATURE + "external-parameter-entities",
true);
}
{
aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
true);
aelfred2.setFeature(SAXDriver.FEATURE + "external-general-entities",
true);
aelfred2.setFeature(SAXDriver.FEATURE + "external-parameter-entities",
true);
}
/**
* <b>SAX2</b>: Sets the state of features supported in this parser.
* Note that this parser requires reporting of namespace prefixes when
* validating.
*/
public void setFeature (String featureId, boolean state)
/**
* <b>SAX2</b>: Sets the state of features supported in this parser.
* Note that this parser requires reporting of namespace prefixes when
* validating.
*/
public void setFeature(String featureId, boolean state)
throws SAXNotRecognizedException, SAXNotSupportedException
{
boolean value = getFeature (featureId);
{
boolean value = getFeature(featureId);
if (state == value)
return;
if (state == value)
{
return;
}
if ((SAXDriver.FEATURE + "validation").equals (featureId)) {
if (active)
throw new SAXNotSupportedException ("already parsing");
if (state)
forceValidating ();
isValidating = state;
} else
aelfred2.setFeature (featureId, state);
}
if ((SAXDriver.FEATURE + "validation").equals(featureId))
{
if (active)
{
throw new SAXNotSupportedException("already parsing");
}
if (state)
{
forceValidating();
}
isValidating = state;
}
else
{
aelfred2.setFeature(featureId, state);
}
}
/**
* <b>SAX2</b>: Tells whether this parser supports the specified feature.
* At this time, this directly parallels the underlying SAXDriver,
* except that validation is optionally supported.
*
* @see SAXDriver
*/
public boolean getFeature (String featureId)
/**
* <b>SAX2</b>: Tells whether this parser supports the specified feature.
* At this time, this directly parallels the underlying SAXDriver,
* except that validation is optionally supported.
*
* @see SAXDriver
*/
public boolean getFeature(String featureId)
throws SAXNotRecognizedException, SAXNotSupportedException
{
if ((SAXDriver.FEATURE + "validation").equals (featureId))
return isValidating;
{
if ((SAXDriver.FEATURE + "validation").equals(featureId))
{
return isValidating;
}
return aelfred2.getFeature (featureId);
}
return aelfred2.getFeature(featureId);
}
/**
* <b>SAX1</b>: Sets the locale used for diagnostics; currently,
* only locales using the English language are supported.
* @param locale The locale for which diagnostics will be generated
*/
public void setLocale (Locale locale)
/**
* <b>SAX1</b>: Sets the locale used for diagnostics; currently,
* only locales using the English language are supported.
* @param locale The locale for which diagnostics will be generated
*/
public void setLocale(Locale locale)
throws SAXException
{ aelfred2.setLocale (locale); }
{
aelfred2.setLocale(locale);
}
/**
* <b>SAX1</b>: Preferred API to parse an XML document, using a
* system identifier (URI).
/**
* <b>SAX1</b>: Preferred API to parse an XML document, using a
* system identifier (URI).
*/
public void parse (String systemId)
public void parse(String systemId)
throws SAXException, IOException
{
parse (new InputSource (systemId));
}
{
parse(new InputSource(systemId));
}
/**
* <b>SAX1</b>: Underlying API to parse an XML document, used
* directly when no URI is available. When this is invoked,
* and the parser is set to validate, some features will be
* automatically reset to appropriate values: for reporting
* namespace prefixes, and incorporating external entities.
*
* @param source The XML input source.
*
* @exception IllegalStateException if called mid-parse
* @exception SAXException The handlers may throw any SAXException,
* and the parser normally throws SAXParseException objects.
* @exception IOException IOExceptions are normally through through
* the parser if there are problems reading the source document.
*/
public void parse (InputSource source)
/**
* <b>SAX1</b>: Underlying API to parse an XML document, used
* directly when no URI is available. When this is invoked,
* and the parser is set to validate, some features will be
* automatically reset to appropriate values: for reporting
* namespace prefixes, and incorporating external entities.
*
* @param source The XML input source.
*
* @exception IllegalStateException if called mid-parse
* @exception SAXException The handlers may throw any SAXException,
* and the parser normally throws SAXParseException objects.
* @exception IOException IOExceptions are normally through through
* the parser if there are problems reading the source document.
*/
public void parse(InputSource source)
throws SAXException, IOException
{
EventFilter next;
boolean nsdecls;
{
EventFilter next;
boolean nsdecls;
synchronized (aelfred2) {
if (active)
throw new IllegalStateException ("already parsing");
active = true;
}
synchronized (aelfred2)
{
if (active)
{
throw new IllegalStateException("already parsing");
}
active = true;
}
// set up the output pipeline
if (isValidating) {
forceValidating ();
next = new ValidationConsumer (filter);
} else
next = filter;
// set up the output pipeline
if (isValidating)
{
forceValidating();
next = new ValidationConsumer(filter);
}
else
{
next = filter;
}
// connect pipeline and error handler
// don't let _this_ call to bind() affect xmlns* attributes
nsdecls = aelfred2.getFeature (
SAXDriver.FEATURE + "namespace-prefixes");
EventFilter.bind (aelfred2, next);
if (!nsdecls)
aelfred2.setFeature (
SAXDriver.FEATURE + "namespace-prefixes",
false);
// connect pipeline and error handler
// don't let _this_ call to bind() affect xmlns* attributes
nsdecls = aelfred2.getFeature(SAXDriver.FEATURE + "namespace-prefixes");
EventFilter.bind(aelfred2, next);
if (!nsdecls)
{
aelfred2.setFeature(SAXDriver.FEATURE + "namespace-prefixes",
false);
}
// parse, clean up
try
{
aelfred2.parse(source);
}
finally
{
active = false;
}
}
// parse, clean up
try {
aelfred2.parse (source);
} finally {
active = false;
}
}
}