2007-09-26  Stefan Seefeld  <stefan@codesourcery.com>

	* NEWS: Document new features in version 2.4.
	* doc/qmtest.ent: Set version number to 2.4.
	* qm/config.py: Don't hard-code version number.
	* qmdist/command/build_py.py: ...but compute it at build time.
	* qmdist/command/install_lib.py: Likewise.
	* setup.py: Cleanup.
	* share/qmtest/examples: Move to...
	* share/doc/qmtest/examples: ...here.

2007-09-25  Stefan Seefeld  <stefan@codesourcery.com>

	* MANIFEST.in: Remove obsolete entries.
	* qm/test/classes/xml_expectation_database.py: Refine.
	* share/qmtest/examples/tdb: Rename to...
	* share/qmtest/examples/xml_tdb: ...this.
	* share/qmtest/examples/compilation_tdb: Add new example test database.
	* qm/test/classes/previous_testrun.py: Add file_name parameter.
	* doc/concepts.xml: Document expectation databases.
	* doc/customizing.xml: Likewise.

	* qm/test/classes/compiler.py: Add 'ldflags' parameters.
	* qm/test/classes/compiler_test.py: Add 'compiler' and 'ldflags'
	  parameters to CompilationStep.
	* qm/test/classes/compilation_test.py: Adjust.
	* qm/test/classes/compilation_test_database.py: Adjust.
	* doc/customizing.xml: Adjust.
	
2007-09-24  Stefan Seefeld  <stefan@codesourcery.com>

	* share/qmtest/tutorial: Rename to...
	* share/qmtest/examples: ...this.

2007-09-20  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/mount_database.py: Add 'mounts' parameter,
	  fix GetIds() method.
	* tests/QMTest/configuration: Update MountDatabase configuration.
	* qm/test/expectation_database.py: Define new extension type.
	* qm/test/classes/previous_testrun.py: New extension.
	* qm/test/classes/xml_expectation_database.py: New extension.
	* qm/test/classes/classes.qmc: Register them.
	* qm/test/cmdline.py: Support ExpectationDatabase
	* qm/test/base.py: Likewise.
	* qm/test/execution_engine.py: Adjust.
	* qm/test/web/web.py: Adjust.
	* share/qmtest/dtml/test/dir.dtml: Only make expectations editable 
	  if they really are
	* share/qmtest/dtml/test/results.dtml: Likewise.
	* qm/fields.py: Various fixes to DictionaryField and SetField.
	* qm/web.py: Insert correct module search path for local
	  DocumentTemplate package.

2007-09-19  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/mount_database.py: Add support for 'mounts' parameter,
	  fix GetIds() method.
	* tests/QMTest/configuration: Adjust.
	* qm/fields.py: Fix various issues with DictionaryField and SetField.

2007-08-17  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/python.py: Expect new-style exceptions (python 2.5).

2007-07-03  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compilation_test_database.py: New test database class.
	* qm/test/classes/classes.qmc: Register it.

2007-02-09  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/external/DocumentTemplate/*: partially merge in bits from Zope 2.10.1
	to replace all uses of the obsolete 'regex' module by 're'.
	* qm/web.py: Adjust module search path to make 'import DocumentTemplate' work.

2007-01-25  Stefan Seefeld  <stefan@codesourcery.com>

	* qmdist/command/__init__.py: Explicitely close the modified file.
	* qmdist/command/install_lib.py: Force recompilation.

2006-12-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_stream.py
	(DejaGNUReader.__UpdateResult): Treat DejaGNU UNTESTED results as
	QMTEST UNTESTED results when generating outcomes from a DejaGNU log
	file.

2006-11-29  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/target.py: Only delete the 'qmtest.id' context variable if it
	really exists.

2006-11-23  Stefan Seefeld  <stefan@codesourcery.com>

	* qmdist/command/install_lib.py: Force recompilation of generated 
	config.py file.

2006-11-08  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/host.py: Adjust constructor to expect keyword arguments.

2006-11-03  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/config.py: Provide initial values for config parameters.
	* qm/__init__.py: Use it.
	* qm/__version.py: Removed (since now obsolete).
	* qmdist/command/__init__.py: Add reset_config_variables.
	* scripts/qmtest-postinstall.py: Use it.
	* qmdist/command/install_lib.py: Use it.
	* qmdist/command/install_data.py: Removed (since now obsolete).
	* qmdist/command/build_py.py: New command; adjusts qm.prefix so it
	is usable in the build tree.
	* qmdist/command/build_doc.py: Modularize.
	* qmdist/command/check.py: Set PYTHONPATH so the right code gets tested.
	* qmdist/command/__init__.py: Adjust to always use qm.config.
	* setup.py: Adjust.
	* qm/test/result_reader.py: Fix fallout from last patch.
	* tests/xmldb/api.qms/test.qms/fields.qmt: Likewise.
	
2006-11-02  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/extension.py: Enhance handling of parameters and constructor arguments.
	* qm/test/database.py: Likewise.
	* qm/test/file_database.py: Likewise.
	* qm/test/file_result_reader.py: Likewise.
	* qm/test/file_result_stream.py: Likewise.
	* qm/test/result_stream.py: Likewise.
	* qm/test/runnable.py: Likewise.
	* qm/test/suite.py: Likewise.
	* qm/test/target.py: Likewise.
	* qm/test/classes/dejagnu_stream.py: Likewise.
	* qm/test/classes/pickle_result_stream.py: Likewise.
	* qm/test/classes/rsh_target.py: Likewise.
	* qm/test/classes/sql_result_stream.py: Likewise.
	* qm/test/classes/tet_stream.py: Likewise.
	* qm/test/classes/text_result_stream.py: Likewise.
	* qm/test/classes/xml_result_stream.py: Likewise.

2006-10-31  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/share/*: Merged into...
	* share/qmtest: ...here.
	* share/*: Likewise.
	* setup.py: Simplify.
	* qmdist/command/install_data.py: Adjust data_path ('qm' -> 'qmtest').
	* qm/__init__.py: Simplify.
	* qm/common.py: Remove obsolete 'is_installed' variable.
	* qm/diagnostic.py: Likewise.
	* qm/test/web/web.py: Adjust menu to contain 'Tutorial' in new location.

2006-10-31  Stefan Seefeld  <stefan@codesourcery.com>

	* qmdist/command/install_data.py: Set 'prefix' variable.
	* scripts/qmtest-postinstall.py: Adjust it to actual installation.
	* qmdist/command/bdist_wininst.py: Use postinstall script.
	* qmdist/command/install_script.py: Removed (obsoleted).
	* share/logo.bmp: Some eye-candy for windows installer.
	* qm/test/qmtest: Move to...
	* scripts/qmtest: ...here; removed obsolete logic to determine paths.
	* setup.py: Incorporate all the above changes.
	* MANIFEST.in: Reflect new script location.
	* qm/__init__.py: Use correct variables unconditionally.

	* qmdist/command/build_doc.py: Fix to at least build html even if no
	fo processor is found.

2006-10-25  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/command_host.py: New host extension.
	* qm/test/classes/classes.qmc: Register it.

2006-09-29  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compiler_test.py: Fix quoting of command annotation.
	* qm/fields.py: Add DictionaryField.
	* qm/test/context.py: Add GetDerivedValue and as_string_list functions.
	* qm/test/database.py: Prevent redundant instantiation of extension 
	classes.
	
2006-09-05  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable.Spawn): Search PATH on Windows if
	appropriate.

2006-09-03  Mark Mitchell  <mark@codesourcery.com>

	* qm/host.py (Host.UploadAndRun): Correct logic for deleting files.

2006-08-18  Stefan Seefeld  <stefan@codesourcery.com>

	Reorganize and enhance Tutorial:
	* qm/doc/tutorial.xml: New file.
	* qm/doc/qmtest.ent: Likewise.
	* qm/doc/introduction.xml: Likewise.
	* qm/doc/cli_reference.xml: Likewise.
	* qm/doc/concepts.xml: Likewise.
	* qm/doc/cs.css: Likewise.
	* qm/doc/html.xsl: Likewise.
	* qm/doc/qm-opl.xml: XML-ified.
	* qm/doc/manual/common-manual.xml: Removed.
	* qmdist/command/build_doc.py: Adjust build procedure for html generation.
	
2006-08-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/host.py (Host.Run): Add 'relative' parameter.
	(Host.UploadAndRun): Use it.
	* qm/test/classes/ssh_host.py (SSHHost.Run): Add 'relative'
	parameter.

	* qm/test/cmdline.py (QMTest.__ExecuteSummarize): Display resource
	results too.
	* qm/test/doc/reference.xml: Document.

2006-07-17  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/cmdline.py: Allow 'qmtest create' to create explicit suites,
	and make their content visible through 'qmtest ls'.

2006-06-21  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/report.py: Add support for '-' special output file.

2006-06-09  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/host.py: Fix signature of Host.Run(), and implement it
	(using local_host.LocalHost.Run() code).
	* qm/test/classes/local_host.py: Remove now obsolete Run() method.
	* qm/test/classes/ssh_host.py: Derive from Host, not LocalHost.

2006-06-02  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/extension.py: Raise AttributeError instead of AssertionError when
	wrong attributes are passed.
	* qm/common.py: Add parse_string_list function.
	* qm/test/context.py: Add Context.GetStringList method.
	* qm/test/classes/compiler.py: Add optional ldflags argument to
	Compiler constructor.
	* qm/test/classes/compiler_test.py: Fix _RemoveDirectory()
	* qm/test/classes/compilation_test.py: Add ExecutableTest.
	* qm/test/classes/classes.qmc: Adjust compilation_test name changes.

2006-03-07  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compiler_table.py: Fix search for host
	extension to include database-specific path.

2005-12-02  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/__init__.py: Define new extension_path variable.
	* qm/test/base.py: Use it to lookup QMTest extensions.
	* qm/dist/__init__.py: Provide build infrastructure to install 
	qmtest extensions.
	* qm/dist/distribution.py: Likewise.
	* qm/dist/command/__init__.py: Likewise.
	* qm/dist/command/build_extensions.py: Likewise.
	* qm/dist/command/install_extensions.py: Likewise.
	* setup.py: Install it.
	* qmdist/command/install_data.py: Likewise.

2005-12-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (QMTest.__ExecuteSummarize): Print resource
	results for UNTESTED tests.
	
	* qm/test/classes/compiler_table.py: Provide standard names for
	the C and C++ programming languages.

2005-11-30  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (get_extension_class_name): Use only the final
	component of the module in forming the extension class name.  
	* qm/test/database.py (Database.GetIds): Handle generic
	databases. 

	* qm/test/classes/compiler_test.py (CompilationStep): Provide
	default values.
	(CompilerBase._MakeDirectory): Do not create the temporary build
	directory if it already exists.
	(CompilerTest.Run): Create the temporary build directory.  Record
	the output from the compiler here.
	(CompilerTest._GetExecutableArguments): New function.
	(CompilerTest._MustExecutableExitSuccessfully): New function.
	(CompilerTest._RunExecutable): Use new functions.
	(CompilerTest._CheckOutput): Do not record the output here.
	Adjust use of _DiagnosticsToString.
	(CompilerTest._CheckExecutableOutput): New function.
	(CompilerTest._DiagnosticsToString): Add annotation parameter.

	* qm/test/classes/compiler.py (Compiler.ParseOutput): Do not try
	to match an error message against multiple severities.

	* qm/test/result.py (Result.CheckExitStatus): Fix typos.

	* qm/host.py (Host.UploadAndRun): Delete the file after running
	it.
	* qm/test/classes/local_host.py (LocalHost.UploadAndRun): New
	method.
	* qm/test/classes/compiler_test.py (CompilerTest._RunExecutable):
	Do not delete executables after running them.

2005-11-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_stream.py
	(DejaGNUStream.__summary_outcomes): Add KFAIL, KPASS.
	(DejaGNUStream.__outcome_descs): Likewise.
	(DejaGNUStream.__expected_outcomes): Likewise.
	(DejaGNUReader.__UpdateResult): Likewise.
	* qm/test/classes/dejagnu_test.py (DejaGNUTest.KFAIL): New
	variable.
	(DejaGNUTest.KPASS): Likewise.
	(DejaGNUTest.outcome_map): Add KFAIL, KPASS.

2005-11-16  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compiler_table.py: Tolerate whitespace in
	context file. 
	* qm/test/classes/dejagnu_test.py: Use CompilerTable.target as host.

2005-11-04  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/test_run.py: Add GetAnnotations() method.
	* qm/test/reader_test_run.py: Implement it.
	* qm/test/report.py: Rewrite report generation now supporting two formats.
	* qm/test/cmdline.py: Add '--flat' option to the 'report' command.
	* qm/test/doc/reference.xml: Document it.
	* share/xml/report.xslt: Adjust html-report generation to new format.
	
2005-11-04  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_stream.py (DejaGNUReader.__NextOutcome):
	Ignore ERROR results.
	(DejaGNUReader.__UpdateResult): Don't repeat causes.  Don't use
	causes at all for non-combined results.

2005-10-25  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/result.py: Add refactored CheckExitStatus method.
	* qm/test/classes/command.py: Use it.
	* qm/test/classes/compiler_test.py: Prepare CompilerTest for reuse;
	general cleanup.
	* qm/test/classes/compilation_test.py: Add new SimpleCompilationTest
	and SimpleCompiledResource extensions.
	* qm/test/classes/classes.qmc: Register them.

2005-10-25  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_stream.py (sets.Set): Don't import it.
	(DejaGNUReader.__init__): Don't set test_ids.

2005-10-25  Stefan Seefeld  <stefan@codesourcery.com>

	* share/xml/report.xslt: Fix handling of multiple test runs.

2005-10-24  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_stream.py
	(DejaGNUStream.__UpdateResult): Fix typo.

	* qm/test/classes/dejagnu_stream.py (cgi): Import it.
	(re): Likewise.
	(sets.Set): Likewise.
	(DejaGNUReader): Add combined mode.  Add expectations-generation
	mode.

2005-10-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (load_outcomes): Adjust documentation.
	(load_results): Permit file parameter to be an extension
	descriptor.
	* qm/test/cmdline.py (QMTest.commands_spec): Add --output
	option to "qmtest summarize".
	(QMTest.__ExecuteSummarize): Use self.results_file_name.  Adjust
	call to load_results.  Pass result of --output option to
	__GetResultStreams.
	(QMTest.__ExecuteRun): Use self.results_file_name.  Pass results
	file name to __GetResultStreams.
	(QMTest.__GetExpectedOutcomes): Adjust call to load_outcomes.
	(QMTest.__FilterTestsToRun): Likewise.
	(QMTest.__GetResultStreams): Add output_file parameter.  Create a
	file result stream appropriate.
	* qm/test/report.py (ReportGenerator._CreateResultStreams): Adjust
	call to load_results.
	* qm/test/classes/dir_run_database.py (DirRunDatabase.__init__):
	Likewise.
	* qm/test/doc/manual.xml: Use DocBook 4.2.  Provide a URL for the
	DocBook DTD.
	* qm/test/doc/reference.xml: Document -o option to summarize and
	extended descriptor syntax for input file.
	
	* qm/test/result_stream.py (qm.test.result.Result): Import it.
	(ResultStream._GetExpectedOutcome): New method.
	* qm/test/classes/text_result_stream.py
	(TextResultStream.WriteResult): Use it.
	(TextResultStream.DisplayResult): Treat Result.CAUSE annotation as
	HTML.

	* qm/test/result.py (Result.SetOutcome): Use SetCause.
	(Result.SetCause): New method.
	(Result.NoteException): Use SetCause.

2005-10-18  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/cmdline.py: Fix handling of '.' pseudo-id.
	* qm/test/web/web.py: Likewise.

2005-10-14  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/cmdline.py: Add 'annotate' option to 'run' command, refine
	'describe' option.

2005-09-14  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/cmdline.py: Add 'describe' and enhance 'ls' commands.
	* qm/test/doc/reference.xml: Document the above.

	* qm/label.py: Fix documentation.
	* qm/test/database.py: Fix typo.
	* qm/test/classes/thread_target.py: Clarify trace messages.
	* qm/test/share/dtml/dir.dtml: Fix typo.
	* qm/test/share/dtml/navigation-bar.dtml: Enhance menu display.
	* qm/test/share/dtml/show.dtml: Add missing logo.
	* share/web/stylesheets/qm.css: Enhance menu display.
	
	Add support for inspecting 'run databases':
	* qm/test/run_database.py: New RunDatabase extension.
	* qm/test/base.py: Register it.
	* qm/test/dir_run_database.py: Implement it.
	* qm/test/classes/classes.qmc: Register implementation.
	* qm/test/test_run.py: Define TestRun base class.
	* qm/test/reader_test_run.py: Implement it.
	* qm/web.py: Allow WebRequest to inherit all fields from its base.
	* qm/test/cmdline.py: Add -R option to the 'gui' command.
	* qm/test/web/web.py: Add support for new report pages.
	* qm/test/share/dtml/report/dir.dtml: New page template.
	* qm/test/share/dtml/report/show.dtml: New page template.
	* setup.py: Add new share/dtml/report directory.

2005-09-06  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/dejagnu_test.py: Fix typo.
	* qm/test/classes/dg_test.py: Add new 'keep_output' field.

2005-09-02  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/resource_adapter.py: New file.
	* qm/test/resource.py (resource_adapter): Remove.

2005-09-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/resource.py (resource_adapter): New function.

2005-08-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (FileResultReader): Import it.
	(get_extension_classes): New function.
	(load_results): Let FileResultReaders decided if they understand
	the file format, rather than hard-coding the decision here.
	* qm/test/cmdline.py (QMTest.GetDatabaseIfAvailable): New method.
	Use it throughout, where appropriate.
	(QMTest.__ExecuteSummarize): Permit execution without a database.
	(QMTest.__GetResultStreams): Likewise.
	* qm/test/file_result_reader.py (FileResultReader.InvalidFile):
	New class.
	* qm/test/result_stream.py (ResultStream.arguments): Remove unused
	"database" argument.
	* qm/test/classes/classes.qmc: Add dejagnu_stream.DejaGNUReader.
	* qm/test/classes/dejagnu_test.py (DejaGNUTest.ERROR): Fix typo.
	(DejaGNUTest.__outcome_map): Rename to ...
	(DejaGNUTest.outcome_map): ... this.  Fill in all entries.
	(DejaGNUTest._RecordDejaGNUOutcome): Adjust.
	* qm/test/classes/pickle_result_stream.py
	(PickleResultReader.__init__): Raise InvalidFile if appropriate.
	* qm/test/classes/xml_result_stream.py (XMLResultReader.__init__):
	Likewise.
	* qm/test/classes/dejagnu_stream.py (DejaGNUReader): New class.

2005-08-19  Stefan Seefeld  <stefan@codesourcery.com>

	* MANIFEST.in: Add missing files.

2005-07-22  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (QMTest.list_long_option_spec): New variable.
	(QMTest.list_recursive_option_spec): Likewise.
	(QMTest.commands_spec): Add "ls".
	(QMTest.Execute): Support "ls".
	(QMTest.__ExecuteList): New method.
	* qm/test/datbase.py (Database.GetExtensions): New method.
	* qm/test/doc/reference.xml: Describe "qmtest ls".

2005-07-21  Stefan Seefeld  <stefan@codesourcery.com>

	* setup.py: Adjust contact info.
	* qm/test/doc/manual.xml: Update copyright notice.

2005-07-21  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dg_test.py (DGTest._RunDGToolPortion): Fix
	typo.

	* qm/extension.py (Extension.GetClassName): New method.
	(Extension.GetExplicitArguments): Likewise.
	(Extension.MakeDomEelement): Use GetExplicitArguments.
	(parse_descriptor): Add extension_loader.
	* qm/test/cmdline.py (qm.test.runnable.Runnable): Import it.
	(QMTest.extension_id_option_spec): New variable.
	(QMTest.conflicting_option_specs): Update.
	(QMTest.__ExecuteCreate): Support writing extensions to the
	database.
	* qm/test/database.py (Database.GetExtension): Fix typo.
	* qm/test/doc/reference.xml: Document --id option to "qmtest
	create".
	* qm/test/share/messages/diagnostics.txt (db not modifiable): New
	message.
	(no db specified): Update message.

2005-07-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (qm.test.resource.Resource): Import it.
	(qm.test.suite.Suite): Likewise.
	(Database._is_generic_database): New
	variable.
	(Database.GetExtension): New function.
	(Database.GetTest): Use it.
	(Database.GetResource): Likewise.
	(Database.GetSuite): Likewise.
	* qm/test/doc/reference.xml: Update information about writing
	database classes.

	* qm/executable.py (Executable.Spawn): Initialize self.__child.
	(Executable._GetChildPID): Adjust documentation to reflect that
	this function may return None.
	(TimeoutExecutable.Run): If the child is None, do not try to kill
	it.

	* qm/test/doc/reference.xml: Add documentation about
	prerequisites.

2005-07-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py (ExecutionEngine.__AddTestToStack):
	If a test prerequisite does not exist, give the test an error
	outcome.
	* qm/test/share/messages/diagnostics.txt (prerequisite not in
	database): New message.
	* tests/regress/bad_prereq: New test.

	* qm/test/classes/python.py (ExecTest.Run): Handle empty input.

	* qm/test/doc/reference.xml: Provide example of SetUp and CleanUp
	methods for resources.

	Revert:
	2005-07-19  Mark Mitchell  <mark@codesourcery.com>
	* qm/test/doc/manual.xml: Use DocBook 4.2.

	* qm/test/doc/manual.xml: Use DocBook 4.2.
	* qmdist/command/build_doc.py (find_file): Remove.
	(build_doc.user_options): New variable.
	(build_doc.xml_dcl_paths): Likewise.
	(build_doc.dtd_dirs): Likewise.
	(build_doc.stylesheet_dirs): Likewise.
	(build_doc.initialize_options): New function.
	(build_doc.finalize_options): Likewise.
	(build_doc.call_jade): Remove dcl parameter.  Use Jade options
	provided by the user.
	(build_doc.run): Honor user direction regarding what
	documentation to build.
	(build_doc.find_file): New function.
	
	* qm/test/classes/command.py (ShellScriptTest._GetShell): New
	function.
	(ShellScriptTest.Run): Use it.

	* qm/test/file_database.py: Fix typo in documentation.

2005-07-06  Stefan Seefeld  <stefan@codesourcery.com>

	* NEWS: Report improvements in version 2.3. 

2005-07-05  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Fix typo.

2005-06-23  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/share/xml/report.xslt: New stylesheet to generate html reports.
	* setup.py: Fix installation paths.

	* qm/__version.py: Increment version_info to (2,3,0).

	* qm/test/cmdline.py: Enhance documentation for 'report' command.
	* qm/test/file_database.py: Fix typos.
	* qm/test/result_stream.py: Remove obsolete comment.
	* qm/test/doc/reference.xml: Document 'report' command.
	* qm/test/web/web.py: Fix incorrect documentation strings.

2005-06-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/remote_host.py: Rename to ...
	* qm/host.py: ... this.  Replace "RemoteHost" with "Host"
	throughout.
	* qm/test/base.py: Adjust accordingly.
	* qm/test/classes/classes.qmc: Likewise.
	* qm/test/classes/compiler_table.py: Likewise.
	* qm/test/classes/local_host.py: Likewise.

2005-06-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/remote_host.py: New file.
	* qm/test/base.py (__extension_bases): Add "remote_host".
	(extension_kinds): Derive automatically from __extension_base.
	* qm/test/classes/classes.qmc: Add local_host.LocalHost,
	ssh_host.SSHHost, ssh_host.RSHHost, and simulator.Simulator.
	* qm/test/classes/compiler.py (Compiler.GetExecutableExtension):
	New method.
	(Compiler.GetObjectExtension): Likewise.
	* qm/test/classes/compiler_table.py (CompilerTable.Setup): Fix
	typos and thinkos.  Set up CompilerTable.target.
	* qm/test/classes/compiler_test.py (CompiledExecutable): Remove.
	(CompilerTest._GetObjectFileName): Fix typo in comment.
	(CompilerTest.Run): Save the compiler.
	(CompilerTest._RunExecutable): Use the RemoteHost provided by the
	compiler table.
	* qm/test/classes/local_host.py: New file.
	* qm/test/classes/simulator.py: Likewise.
	* qm/test/classes/ssh_host.py: Likewise.

	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Use
	__CheckExtensionKind. 

	* qm/test/result.py (Result.NoteException): Quote exception
	string. 

	* qm/extension.py (Extension.Type.__init__): Fix overlong lines.
	(make_dom_element): Fix typo in comment.

2005-06-06  Stefan Seefeld  <stefan@codesourcery.com>

	* setup.py: Move data into <prefix>/share/qm.
	* qm/__init__.py: Likewise.
	* qmdist/command/install_data.py: Likewise.
	* MANIFEST.in: Cleanup.
	* Makefile: Removed.
	* configure: Removed.
	* configure.in: Removed.
	* qm/test/classes/compiler.py: Bugfix and cleanup.

2005-06-01  Mark Mitchell  <mark@codesourcery.com>

        Test documentation generation again.

2005-05-31  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/report.py: Support expectation files.
	* qm/test/cmdline.py: Factor out global database
	and targets objects to...
	* qm/test/test.py: ...here.
	* qm/test/database.py: ...and here.
	* qm/test/context.py: Add TARGET_CONTEXT_PROPERTY.
	* qm/test/target.py: Define it.
	* qm/test/classes/command.py: Use unicode context variables
	when setting up environment, but only when convertible to str.

2005-05-18  Zack Weinberg  <zack@codesourcery.com>

	* qm/test/database.py (ItemDescriptor._Execute): Use getattr
	and a bound method object instead of eval.

2005-05-03  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/report.py: Add ReportGenerator module.
	* qm/test/cmdline.py: Add 'report' command.

2005-04-15  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compiler.py: Add support for new 'ldflags' parameter.
	* qm/test/classes/compiler_table.py: Likewise.

2005-04-14  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/compiler.py: Moved over extension from qmtc.
	* qm/test/classes/compiler_table.py: Likewise.
	* qm/test/classes/compiler_test.py: Likewise.
	* qm/test/classes/classes.qmc: Registered 'CompilerTable' resource.

2005-03-31  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/extension.py: Fix omission (see entry from 2005-03-24).

2005-03-29  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/parameter_database.py: New file.

2005-03-24  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/extension.py: Enhance the detection of argument name collision.
	* Makefile: Removed.
	* configure.in: Removed.
	* configure: Removed.

2005-03-21  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/extension.py: Use metaclass to manipulate 'Field' members.
	* qm/fields.py: Make fields more convenient to use in the context of
	Extensions.
	* tests/xmldb/api.xms/test.qms/fields.qmt: New unit test for this feature.
	* tests/xmldb/QMTest/test_inheritance.py: Adjust test to new
	feature.
	* qm/test/classes/python.py: Work around a python bug.

	* qm/test/classes/command.py: Generalize ExecTestBase's output
	validation.

2005-03-20  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/test/classes/xml_database.py: Fix ExplicitSuite constructor call.
	* tests/regress/QMTest/selftest.py: Allow an 'ids' file to specify test
	and suite ids to be specified to be used in the 'qmtest run' command.
	* tests/regress/xml2: New regression test for XMLDatabase's ability to
	use explicit suites.
	* qm/test/share/tutorial/tdb/suite.qms: New demo suite.

2005-02-14  Stefan Seefeld  <stefan@codesourcery.com>

	* README: Update documentation to reflect current build procedure.
	* GNUmakefile.in: Removed.

2005-02-14  Stefan Seefeld  <stefan@codesourcery.com>

	* qm/web.py: Replace deprecated use of whrandom by random.
	* qm/external/DocumentTemplate/DT_Util.py: Likewise.

2005-01-05  Stefan Seefeld  <stefan@codesourcery.com>

	* qmdist/command/build_scripts.py: Create new command to extend
	the default build_scripts command.
	* setup.py: Use the extended build_scripts command.
	* GNUmakefile.in: Remove obsolete command.

2004-12-16  Stefan Seefeld <seefeld@sympatico.ca>

	* qm/test/web/web.py: Replace operator 'is' by '=='
	in string comparison

2004-10-28  Matthias Klose <doko@cs.tu-berlin.de>

	* qmdist/command/build_doc.py (build_doc.run): Use "openjade" if
	"jade" is not available.

2004-08-20  Nathaniel Smith  <njs@codesourcery.com>

	* qm/__init__.py: Don't import or define 'lib_dir'.
	* qmdist/command/install_data.py (install_data.run): Don't define
	'lib_dir'.
	* qm/common.py (get_lib_directory): Don't use 'lib_dir' and
	'qm.prefix', but rather '__file__'.
	* qm/test/base.py (get_extension_directories): Remove
	now-redundant logic around call to 'get_lib_directory'.

2004-05-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/qmtest (check_python_version): Clarify error message.

2004-05-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/qmtest (check_python_version): Rework to avoid using
	newer Python features.

2004-05-26  Mark Mitchell  <mark@codesourcery.com>

	* MANIFEST.in (qm/test/doc/html/qm.css): Include it.

2004-05-25  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py
	(ExecutionEngine._WriteInitialAnnotations): Check that uname is
	not None before trying to write it out.
	* qm/test/qmtest (qm.sigmask): Import it in the global scope, not
	...
	(main): ... here.

2004-05-24  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention improvements in 2.2.

	* GNUmakefile.in (distclean): Remove MANIFEST.
	* setup.py: Install documentation stylesheet.
	* doc/qm-sgml.dsl: Use documentation stylesheet.
	* doc/qm.css: Incorporate bits of CodeSourcery web site
	look-and-feel.
	* qmdist/command/build_doc.py (build_doc.run): Copy documentation
	stylesheet to HTML directory.

	* qm/test/doc/manual.xml: Update copyright date and version
	number.

2004-05-24  Nathaniel Smith  <njs@codesourcery.com>

	* qmdist/command/build_doc.py (build_doc.run): Create
	'doc/qm-version' file.
	* doc/qm.mod: Define entity 'qm_version' to its contents.
	* qm/test/doc/manual.xml (internal_doc_url): Use
	'qm_version_entity' in definition.

2004-05-21  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/target.py (Target.Start): Add instance variable
	'__order_of_resources'.
	(Target._FinishResourceSetUp): Record resource setup order in
	it.
	(Target.Stop): Use it to determine resource cleanup order.
	* tests/regress/resource_ordering: New test.

2004-05-21  Nathaniel Smith  <njs@codesourcery.com>

	* Makefile: Switch default copyright date to 2004.
	* docbook: Likewise.
	* docbook-chapter: Likewise.
	* dtml: Likewise.
	* html: Likewise.
	* py: Likewise.
	* xml: Likewise.

2004-05-05  Nathaniel Smith  <njs@codesourcery.com>

	* GNUmakefile.in (build): Force executable bit on scripts in
	build directory.

2004-05-04  Nathaniel Smith  <njs@codesourcery.com>

	* setup.py: Import 'Extension'.
	Use it to build qm.sigmask.
	* qm/sigmask.c: New file.
	* qm/test/qmtest (main): Import 'qm.sigmask'; call
	'qm.sigmask.save_mask'.
	* qm/executable.py: Import 'qm.sigmask'.
	(Executable._InitializeChild): Call 'qm.sigmask.restore_mask'.

	* tests/xmldb/signals_unblocked.qmt: New test.
	* tests/xmldb/signals_unblocked_tmpdir.qma: New resource.

	* qmdist/command/check.py (check): Overhaul to respect
	QMTESTFLAGS and use the correct path to the QMTest executable.
	* GNUmakefile.in: Use "setup.py check" to run tests.
	* qm/test/qmtest (rel_libdir): When running out of source tree,
	use built library.

2004-03-30  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (htmllib): Import it.
	(StringIO): Likewise.
	(formatter): Likewise.
	(html_to_text): New function.
	* qm/test/classes/text_result_stream.py
	(TextResultStream._DisplayAnnotations): Use it.
	(formatter): Don't import it.
	(htmllib): Likewise.
	(StringIO): Likewise.
	(qm.common): Import it.
	(qm.fields): Likewise.

	* qm/test/result.py (cgi): Import it.
	(Result.Quote): New function.
	(Result.NoteException): Use it.
	* qm/test/classes/dg_test.py (DGTest._RunDGTest): Likewise.
	* qm/test/classes/command.py (ExecTestBase.RunProgram):
	Likewise.
	* qm/test/classes/dejagnu_base.py
	(DejaGNUBase._RecordCommandOutput): Likewise.
	(DejaGNUBase._RecordCommand): Likewise.
	* tests/regress/QMTest/selftest.py (RegTest.Run): Likewise.
	* tests/results_files/QMTest/results_file_test.py
	(ResultsFileTest.Run): Likewise.

	* qm/test/classes/tet_stream.py (TETStream): Many output
	enhancements.

	* qm/test/classes/dg_test.py (DGTest._RunDGTest): Refactor,
	(DGTest._RunDGToolPortion): ...creating this.
	(DGTest._RunDGExecutePortion): ...and this.

	* qm/test/classes/pickle_result_stream.py (types): Import it.
	(PickleResultStream.WriteAnnotation): Check that annotations are
	strings.

	* qm/common.py (get_username): Expand docstring.
	(get_userid): New function.
	* qm/test/execution_engine.py
	(ExecutionEngine._WriteInitialAnnotations): Use it.
	Disambiguate old "qmtest.run.user" annotation by renaming to
	"qmtest.run.username".
	Add "qmtest.run.command_line" annotation.

2004-03-15  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/target.py (Target._SetUpResource): Fix typo from
	previous commit.

2004-03-15  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/base.py (CouldNotLoadExtensionError.__init__): Save
	'exc_info' value for later use.
	* qm/test/target.py (qm.test.base): Import it.
	(Target._SetUpResource): Check for
	'CouldNotLoadExtensionError'.

	* qm/test/classes/dg_test.py (DGTest._RunDGTest): Clarify
	comment.
	Convert to pass tool arguments as a list, not a string.
	Support 'dg-excess-errors'.
	(DGTest._RunTool): Convert docstring to describe new argument
	passing conventions.
	(DGTest._DGoptions): Convert options immediately from string to
	list.
	(DGTest._DGexcess_errors): New method.

	* qm/test/classes/tet_stream.py (TETStream): Add detailed
	description of TET/LSB and DejaGNU result codes.  Fix mapping
	between them.

	* qm/test/classes/dejagnu_test.py
	(DejaGNUTest.TargetExecutable._StdinPipe): Don't override.
	(DejaGNUTest.BuildExecutable._StdinPipe): Don't override.

2004-03-02  Mark Mitchell  <mark@codesourcery.com>

	* qmdist/command/install_scripts.py (install_scripts.run): Handle
	pathnames that contain backslashes correctly.

2004-03-02  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/dg_test.py (DGTest._RunDGTest): Fix formatting
	of paths to match DejaGNU.
	(DGTest._DGBogus): Fix copy/paste error in docstring.
	(DGTest.__ExpectDiagnostic): Use "" rather than 'None' to denote
	empty comment, to match DejaGNU.

2004-03-02  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/explicit_suite.py (arguments): Fix formatting
	of description for 'is_implicit'.

2004-03-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable.Spawn): Under Windows, convert all
	environment variables to Unicode if any of them are Unicode.
	* NEWS: Mention this improvement.

2004-02-27  Mark Mitchell  <mark@codesourcery.com>

	* setup.py: Install both "qmtest" and "qmtest.py" on all systems.

2004-02-20  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (format_time_iso): Make argument default to
	current time.
	* qm/test/execution_engine.py (ExecutionEngine.Run): Don't pass
	explicit argument to 'format_time_iso'.
	(ExecutionEngine._WriteInitialAnnotations): Likewise.

	* qm/test/target.py (qm.common): Import.
	(Target.RunTest): Record start and end times.

	* qm/test/classes/tet_stream.py (TETStream._ExtractTime): New
	function.
	(TETStream._WriteTCStart): Use it.
	(TETStream._WriteDejaGNUResult): Likewise.
	(TETStream._WriteTestResult): Likewise.

2004-02-19  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (parse_time_iso): New function.
	* qm/test/classes/tet_stream.py: New file.
	* qm/test/classes/classes.qmc (tet_stream.TETStream): Add.

2004-02-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/__version.py: Advance to 2.2.0.

	* qm/executable.py (TimeoutExecutable.Run): Handle failure to
	locate the executable file robustly under Windows.

2004-02-15  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (open_temporary_file_fd): Change default suffix to
	empty string.
	(open_temporary_file): Likewise.
	* qm/test/classes/command.py (ShellScriptTest.Run): Likewise.

2004-02-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (encode_data_as_text): Remove.
	(decode_data_from_text): Likewise.
	(format_byte_count): Likewise.

	(base64): Don't import.
	(cPickle): Likewise.
	(cStringIO): Likewise.
	(dircache): Likewise.
	(gzip): Likewise.
	(operator): Likewise.
	(quopri): Likewise.
	(socket): Likewise.

2004-02-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (open_temporary_file_fd): Add suffix parameter.
	(open_temporary_file): Add mode and suffix parameters.
	* qm/platform.py (get_shell_for_script): Use /c on Windows.
	* qm/test/classes/command.py (ShellScriptTest): Make the
	script have a ".bat" extension on Windows.
	* NEWS: Mention this fix.

2004-02-11  Nathaniel Smith  <njs@codesourcery.com>

	* qm/fields.py: Use types.StringTypes instead of
	qm.common.string_types.  Also remove tabs.
	* qm/test/result.py: Likewise.
	* qm/common.py (string_types): Remove.
	(Empty): Remove.
	(MutexError): Remove.
	(MutexLockError): Remove.
	(ConfigurationError): Remove.
	(indent_lines): Remove.

2004-02-11  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py: Import getpass.
	(get_username): New function.
	* qm/test/execution_engine.py
	(ExecutionEngine._WriteInitialAnnotations): New method.
	(ExecutionEngine.Run): Call it.
	(TerminationRequested): New exception.
	(ExecutionEngine._RunTests): Raise it when terminating.
	(ExecutionEngine.Run): Check for exceptions in _RunTests.

	(ExecutionEngine.RequestTermination): More tracing.
	(ExecutionEngine.Run): Likewise.
	(ExecutionEngine._RunTests): Likewise.

2004-02-08  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Remove "Not yet released" markers from news for 2.1.

	* qm/test/web/web.py (ShowSuitePage.MakeDeleteScript): Return the
	result of MakeConfirmationDialog.

2004-02-04  Anders Hasselqvist <Anders.Hasselqvist@tss.teleca.se>

	* qm/fields.py (ChoiceField.FormatValueAsHtml): Make sure there is
	a name for the field.

2004-01-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/explicit_suite.py (ExplicitSuite.is_implicit):
	Give it a default value of false.
	(ExplicitSuite.IsImplicit): Fix thinko.
	* qm/test/classes/xml_database.py (XMLDatabase._GetSuiteFromPath):

2004-01-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (_version_output): Add 2004 to list of
	copyright dates.

2004-01-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/xml_database.py
	(XMLDatabase.__MakeDataFilePath): Use a relative, rather than
	absolute, path for the file location.

2004-01-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (Attachment.Move): New method.
	(AttachmentStore.Store): Do not return a value.
	(TemporaryAttachmentStore.Store): Do not check
	is_temporary_location.
	(is_temporary_location): Remove.
	(make_dom_node): Do not check is_temporary_location.
	* qm/extension.py (Extension.MakeDomElement): Remove debugging
	code.
	* qm/fields.py (Field.GetSubfields): New method.
	(Field.ParseFormValue): Take a dictionary of attachment stores as
	a parameter, not a single attachment store.
	(TextField.ParseFormValue): Likewise.
	(TupleField.GetSubfields): New method.
	(TupleField.ParseFormValue): Take a dictionary of attachment
	stores as a parameter, not a single attachment store.
	(SetField.GetContainedField): Remove.
	(SetField.GetHelp): Adjust.
	(SetField.GetSubfields): New method.
	(SetField.MakeDomNodeForValue): Do not use GetContainedField.
	(SetField.ParseFormValue): Likewise.  Take a dictionary of attachment
	stores as a parameter, not a single attachment store.
	(UploadAttachmentPage.__next_temporary_location): Remove.
	(UploadAttachmentPage.__init__): Add attachment_store parameter.
	(AttachmentField.FormatValueAsHTML): Encode the attachment store.
	(AttachmentField.ParseFormValue): Decode it.
	* qm/web.py (WebServer.__init__): Create a temporary attachment
	store.
	(WebServer.GetTemporaryAttachmentStore): New method.
	* qm/test/runnable.py (Runnable.GetAttachments): New method.
	(Runnable.__GetAttachments): Likewise.
	* qm/test/classes/xml_database.py
	(XMLDatabase.__StoreAttachments): Rewrite.
	* qm/test/web/web.py (QMTestServer.__init__): Do not create a
	temporary attachment store.
	(QMTestServer.HandleSubmitItem): Pass all available attachment
	stores to ParseFormValue.  Do not try to remove unused attachments
	here.
	* share/dtml/attachment.dtml: Encode the attachment store id.

2004-01-13  Stefan Seefeld  <seefeld@sympatico.ca>

	* qm/test/file_database.py: Fix little bug.

2004-01-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/share/dtml/show.dtml: Add is_new field to form.
	* qm/test/web/web.py (QMTestServer.HandleShowItem): Pass a correct
	value for "new" to ShowItemPage.

	* qm/test/classes/python.py (BaseExceptionTest.Run): Use
	has_exception_argument to keep track of whether or not an argument
	was provided.
	(BaseExceptionTest.CheckArgument): Use it.
	(ExceptionTest.CheckArgument): Likewise.  Handle the case of a
	class that does not provide the "args" interface.
	* tests/regress/exception_test/arg1.qmt: New test.

2004-01-08  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/doc/reference.xml: Fix typo.

2004-01-02  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (Extension.MakeDomElement): New method.
	(Extension.MakeDomDocument): Likewise.
	(Extension.Write): Likewise.
	* qm/test/base.py (extension_kinds): Add "suite".
	(qm.test.suite): Import it.
	(__extension_bases): Mention "suite".
	* qm/test/datbase.py (Database.WriteTest): Remove.
	(Database.RemoveTest): Likewise.
	(Database.WriteResource): Likewise.
	(Database.RemoveResource): Likewise.
	(Database.WriteSuite): Likewise.
	(Database.RemoveSuite): Likewise.
	(Database.IsModifiable): Adjust comment.
	(Database.RemoveExtension): New method.
	(Database.WriteExtension): Likewise.
	* qm/test/directory_suite.py (DirectorySuite.__init__): Adjust for
	the fact that 'Suite' is now an 'Extension.
	(DirectorySuite.IsImplicit): New method.
	* qm/test/file_database.py (FileDatabase.RemoveTest): Remove.
	(FileDatabase.RemoveResource): Likewise.
	(FileDatabase.RemoveSuite): Likewise.
	(FileDatabase._GetPath): New method.
	(FileDatabase._RemoveEntity): Remove.
	(FileDatabase.RemoveExtension): New test.
	* qm/test/suite.py (Suite): Derive from Extension.
	* qm/test/classes/explicit_suite.py: New file.
	* qm/test/classes/classes.qmc: Regenerate.
	* qm/test/classes/mount_database.py (MountedSuite.__init__):
	Adjust for the fact that 'Suite' is now an 'Extension.
	(MountedSuite.IsImplicit): New method.
	* qm/test/clasess/xml_database.py (XMLDatabase.WriteTest): Remove.
	(XMLDatabase.WriteResource): Likewise.
	(XMLDatabase.WriteSuite): Likewise.
	(XMLDatabase.__StoreAdjustments): Rework to adjust for the fact
	that actual extension instances are provided.
	(XMLDatabase._GetSuiteFromPath): Deal with old and new suite
	formats.
	(XMLDatabse.WriteExtension): New method.
	* qm/test/doc/reference.xml: Do not mention WriteTest or
	RemoveTest.
	* qm/test/web/web.py (QMTestServer.HandleCreateSuite): Adjust for
	changes above.
	(QMTestServer.HandleDeleteItem): Likewise.
	(QMTestServer.HandleDeleteSuite): Likewise.
	(QMTestServer.HandleSubmitItem): Likewise.

2003-12-03  Mark Mitchell  <mark@codesourcery.com>

	* setup.py: Use glob expressions for documentation.
	* doc/qm-sgml.dsl: Do not produce a manifest.
	* qmdist/command/build_doc.py (build_doc.run): Tidy.
	* qmdist/command/install_data.py (glob): Import it.
	(types.StringType): Likewise.
	(install_data.initialize_options): New method.

2003-11-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/file_database.py: Remove misleading comments about
	methods that cannot be overridden.

2003-11-24  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (fnctl): Import it.
	(close_file_on_exec): New method.
	* qm/executable.py (qm.common): Import it.
	(Executable.Run): Use close_file_on_exec.
	(Executable._MakeCloseOnExec): Remove.
	(RedirectedExecutable._CreatePipe): Use close_file_on_exec.
	* qm/test/file_result_stream.py (qm.common): Import it.
	(FileResultStream.__init__): Use close_file_on_exec.

2003-11-24  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (QM_TOOLS): Do not set it.
	(clean): Remove generated documentation.
	(distclean): Do not remove qm/__version.py.
	* MANIFEST.in: Include GNUmakefile.in, configure.in, and
	configure.
	* config.guess: Remove.
	* install-sh: Likewise.

	* configure.in (QM_MAJOR_VER): Do not AC_SUBST it.
	(QM_MINOR_VER): Likewise.
	(QM_RELEASE_VER): Likewise.
	(QM_VERSION): Likewise.
	* configure: Regenerated.
	* version: Remove.
	* qm/__version.py.in: Likewise.
	* qm/__version.py: New file.

	* qm.spec.in: Remove.
	* .cvsignore: Remove qm.spec.
	* GNUmakefile.in (distclean): Do not remove qm.spec.
	* configure.in: Do not generate it.

2003-11-24  Stefan Seefeld  <seefeld@sympatico.ca>

	* qm/test/result.py: Replace 'property' by 'annotation'.
	* qm/test/share/dtds/result.dtd: Likewise.

2003-11-23  Mark Mitchell  <mark@codesourcery.com>

	* setup.py: Tidy up.  Use "qmtest.py" as the name of the main
	script under Windows.
	* qm/__init__.py: Do not honor qm.config settings under Windows.
	* qm/test/.cvsignore: Add qmtest.py.
	* qm/test/execution_engine.py
	(ExecutionEngine.IsTerminationRequested): Rename to ..
	(ExecutionEngine._IsTerminationRequested): ... this.
	* qm/test/execution_thread.py
	(ExecutionThread.IsTerminationRequested): Rename to ..
	(ExecutionEngine._IsTerminationRequested): ... this.
	* qm/test/qmtest: Do not honor rel_libdir on Windows.
	* qm/test/clasess/pickle_result_stream.py
	(PickleResultStream._is_binary_file): Set it.
	* qm/test/doc/tour.xml: Update for changes in installation
	procedures.
	* qmdist/command/install_scripts.py (install_scripts.run): Process
	both the "qmtest" and the "qmtest.py" script.
	* scripts/qm-release: Remove.

	* .cvsignore: Add build, dist, and MANIFEST.
	* MANIFEST.in: Update for recent changes.
	* setup.py: Put qm/test/classes in lib, not share.  Add more
	metadata.  Correct documentation handling.
	* qm/__init__.py: Import lib_dir from qm.config.
	* common.py (get_lib_directory): New function.
	* qm/test/base.py (get_extension_directories): Use
	get_lib_directory, not get_share_directory.
	* qm/test/clases/__init__.py: New file.
	* qmdist/.cvsignore: Likewise.
	* qmdist/command/.cvsignore: Likeiwse.
	* qmdist/command/__init__.py (get_relative_path): Robustify.
	* qmdist/command/build.py: New file.
	* qmdist/command/build_doc.py (build_doc.call_jade): Put generated
	files in the source directory.
	(build_doc.run): Update accordingly.
	* qmdist/command/install_data.py (install_data.run): Set
	lib_dir in config.py.
	* qmdist/command/install_lib.py: New file.
	* qmdist/command/install_scripts.py: Generalize prefix handling.

2003-11-19  Mark Mitchell  <mark@codesourcery.com>

	* test/regress/xml1/asdfasdf.qmt: Do not hard-code path to test.
	* test/regress/xml1/fnord.qmt: Do not hard-code path to true.

	* qm/test/doc/reference.xml: Improve documentation for "qmtest
	create".

2003-11-13  Jeffrey D. Oldham  <oldham@codesourcery.com>

	* qm/test/context.py (Context.GetBoolean): Correctly support the
	default.

2003-11-13  Jeffrey D. Oldham  <oldham@codesourcery.com>

	* qm/test/context.py (Context.GetBoolean): Fix typos in
	introductory comment.  Modify documentation of 'default'
	parameter.  Use 'default' parameter.

2003-11-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/context.py (Context.DB_PATH_CONTEXT_PROPERTY): New
	variable.
	(Context.ID_CONTEXT_PROPERTY): Likewise.
	(Context.TMPDIR_CONTEXT_PROPERTY): Likewise.
	* qm/test/target.py (Target.RunTest): Set them.
	(Target._FinishResourceSetUp): Clear ID_CONTEXT_PROPERTY.
	(Target._SetUpResource): Set ID_CONTEXT_PROPERTY.

	* qm/common.py (parse_boolean): New function.
	* qm/fields.py (BooleanField.Validate): New method.
	* qm/test/context.py (ContextException.__init__): Generalize.
	(Context.GetBoolean): New method.
	* qm/test/result.py (Result.NoteException): Simplify.
	* qm/test/share/messages/diagnostics.txt (invalid boolean context
	var): New message.
	(missing context variable): Likewise.

	* qm/common.py (open_temporary_file): Fix typo.

2003-11-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/qmtest: If SIGINT is received, make sure that our exit
	code reflects that fact.
	* qm/test/classes/text_result_stream.py
	(TextResultStream._FormatStatistics): Robustify.

	* qm/test/classes/text_result_stream.py
	(TextResultStream.arguments): Add statistics_format.
	(TextResultStream._DisplayArguments): Do not write out the
	heading here.  Honor the statistics_format, if provided.
	(TextResultStream._SummarizeTestStats): Use _FormatStatistics.
	(TextResultStream._SummarizeRelativeTestStats): Likewise.
	(TextResultStream._FormatStatistics): New function.

2003-11-09  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (.PHONY): Add build and doc.
	(build): New target.
	(doc): Likewise.
	(check-serial): Depend on build, not all.
	(check-threads): Likewise.
	(check-processes): Likewise.
	(check-rsh): Likewise.

	* qm/temporary_directory.py (sys): Import it.

	* GNUmakefile.in (DOCUMENTATION): Set value to MAINTAINER_MODE.
	(TIDY): Likewise.
	(TIDYFLAGS): Likewise.
	* configure.in: Do not search for Jade, tidy, DocBook stylesheets,
	etc.
	* configure: Regenerated.

2003-10-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (SetField.ParseFormValue): Correct logic
	determining whether or not to redisplay the form.

2003-10-14  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in: Sipmlify drastically, relying on distutils to do
	all of the work.
	* setup.py: Tidy.  Add support for DTML files and other missing
	GUI functionality.
	* qm/__init__.py: Pull in data_dir from the configuration file.
	* qm/common.py (get_share_directory): Use it.
	(get_doc_directory): Likewise.
	* qm/qm.sh: Remove.
	* qm/test/.cvsignore: Remove qmtest and qmtest.bat.
	* qm/test/base.py (get_extension_directories): Use
	get_share_directory to find test classes.
	* qm/test/cmdline.py (QMTest.__init__): Add 'path' argument.
	* qm/test/qmtest.py: Rename to ...
	* qm/test/qmtest: ... this.  Add logic to allow QMTest to find its
	own modules.
	* qm/test/doc/reference.xml: Remove QM_PYTHON.
	* qmdist/command/__init__.py (get_relative_path): New function.
	* qmdist/command/check.py: Revise to reference "qmtest", not
	"qmtest.py".
	* qmdist/command/install_data.py (install_data.run): Output
	data_dir as a relative path.
	* qmdist/command/install_scripts.py: New file.
	* NEWS: Update.

2003-10-02  Stefan Seefeld  <seefeld@sympatico.ca>

	* qm/test/share/dtds/result.dtd: Convert 'outcome' to an attribute.
	* qm/test/result.py: Likewise.
	* qm/test/classes/xml_result_stream.py: Likewise.
	* tests/results_files/README: Report new xml result file format.
	* tests/results_files/xml_results_v3.qmr: New reference results file.

2003-10-02  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (get_extension_directories): Use ";" as the
	QMTEST_CLASS_PATH separator on Windows.
	* NEWS: Mention recent improvements.

2003-09-30  Stefan Seefeld  <seefeld@sympatico.ca>

	* qmdist/command/check.py: New file.
	* setup.py: Register new check command.

2003-09-28  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in ($(SCRIPTS)): Don't set QM_BUILD.
	* qm/__init__.py: Set common.is_installed.
	* qm/common.py (get_share_directory): Don't use QM_BUILD.
	(get_doc_directory): Likewise.
	(is_installed): New variable.
	* qm/diagnostic.py (__diagnostic_set): New variable.
	(__help_set): Likewise.
	(get_diagnostic_set): New function.
	(get_help_set): Likewise.
	(message): Use them.
	(error): Likewise.
	(warning): Likewise.
	(load_messages): Likewise.
	(__initialize_module): Remove.
	(diagnostic_set): Likewise.
	(help_set): Likewise.
	* qm/qm.sh: Eliminate QM_BUILD.
	* qm/web.py (make_help_link): Use diagnostic.get_help_set().
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Don't use
	QM_BUILD.
	* qmdist/command/install_data.py (install_data.run): Simplify.

	* doc/qm-opl.xml: Remove Software Carpentry references.
	* doc/manual/common-manual.xml: Likewise.
	* qm/test/doc/manual.xml: Update version number.

	* qm/test/doc/reference.xml: Remove documentation for non-existant
	--summary and --no-summary options to "qmtest run".  Fix typo in
	-O documentation for "qmtest summarize".  Improve --pid-file
	documentation.

	* qm/test/classes/pickle_result_stream.py
	(PickleResultReader.__init__): Treat cPickle.UnpicklingError like
	EOFError.

	* qm/test/cmdline.py (QMTest.summary_formats): Rearrange order.
	(QMTest.commands_spec): Automatically generate lists of --format
	options.
	* qm/test/classes/text_result_stream.py
	(TextResultStream.arguments): Specify valid enumerals for format.

	* qm/test/cmdline.py (commands_spec): Add --help support for
	"qmtest remote".

2003-09-26  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable.Kill): Fix typo.

2003-09-25  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ExecTestBase.arguments): Improve
	documentation for exit_code.
	* qm/test/doc/tour.xml: Remove discussion of carriage-returns in
	execution tests.

	* qm/executable.py (Executable.Kill): New method.
	(Executable._GetChildPID): Improve documentation.
	(TimeoutExecutable): Update documentation about timeouts on
	Windows.
	(TimeoutExecutable.__init__): Do not ignore timeouts on Windows.
	(TimeoutExecutable._HandleChild): Create a monitoring thread on
	Windows.
	(TimeoutExecutable.Run): Wiat for the monitoring thread to exit.
	(TimeoutExecutable.__Monitor): New method.

2003-09-21  Mark Mitchell  <mark@codesourcery.com>

	* qm/xmlutil.py (get_children): Remove.
	(get_child_texts): Don't use it.
	* qm/test/base.py (get_extension_class_names_in_directory):
	Support new class directory format.
	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Generate the
	class directory using the new directory format.
	* qm/test/database.py (load_database): Do not use get_children.
	* qm/test/result.py (Result.MakeDomNode): Revise result format.
	(__all__): New variable.
	* qm/test/classes.qmc: Regenerated.
	* qm/test/classes/xml_result_stream.py
	(XMLResultStream.WriteAnnotation): Use indentation when writing
	out results.
	(XMLResultStream.WriteResult): Likewise.
	(XMLResultReader._get_result_from_dom): Rename to ...
	(XMLResultReader._GetResultFromDomNode): ... this.  Support old
	and new formats.
	* qm/test/share/dtds/result.dtd: Update.
	* qm/test/share/dtds/class-directory.dtd: Likewise.

2003-09-16  Stefan Seefeld  <seefeld@sympatico.ca>

	* qmdist/command/install_data.py: Do not generate data_dir,
	as this isn't reliable (windows installer).
	* qm/__init__.py: Do not use predefined data_dir.
	* qm/test/qmtest.py: Deduce data_dir from sys.argv[0].

2003-09-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (make_dom_document): Simplify.
	* qm/user.py (XmlDatabase.Write): Likewise.
	* qm/xmlutil.py (make_system_id): Use CodeSourcery URLs.
	(make_public_id): New function.
	(create_dom_document): Compute full system and public identifiers
	here.
	* qm/test/base.py (dtds): Remove.
	* qm/test/cmdline.py (QMTest.__ExecuteCreateTarget): Adjust call
	to create_dom_document.
	(QMTest.__ExecuteRegister): Likewise.
	* qm/test/classes/xml_database.py: Likewise.
	* qm/test/classes/xml_result_stream.py: Likewise.

2003-09-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (TimeoutExecutable.__init__): Ignore timeouts
	under Windows.  Accept any representation of "timeout" that can be
	converted to a float.
	(__all__): Define.
	* qm/test/cmdline.py (QMTest.__init__): Improve documentation.

2003-09-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable._MakeCloseOnExec): Deal with
	missing fcntl.FD_CLOEXEC.

2003-09-09  Stefan Seefeld  <seefeld@sympatico.ca>

	* setup.py: Factor out commands into ...
	* qmdist/command/build_doc.py: ...this
	* qmdist/command/install_data.py: ...and this.
	* qmdist/__init__.py: New file.
	* qmdist/command/__init__.py: New file.
	* MANIFEST.in: Provide file list for source distribution.

2003-09-07  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (cStringIO): Do not import.
	(StringIO): Import.
	(tokenize): Import.
	(Field.FormatValueAsText): Use StringIO.
	(Field.ParseTextValue): Improve documentation.
	(SetField.FormatValueAsText): Make output match format expected
	by ...
	(SetField.ParseTextField): ... this new method.
	* qm/test/cmdline.py (QMTest.attribute_option_spec): Generalize
	help text.
	* share/diagnostics/common.txt (invalid set value): New message.

	* NEWS: Mention correction of critical resource defect.

2003-09-05  Mark Mitchell  <mark@codesourcery.com>

	* qm/qm.sh (PYTHONPATH): Break "export PTYHONPATH=..." into two
	statements.

2003-08-29  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/target.py (Target.__init__): Do not set __resources.
	(Target.Start): Initialize __resources.
	(Target.Stop): Remove entries created by Target.Start.

	* GNUmakefile.in (check): Remove dependency on check-rsh.

	* README: Mention Win32 extensions and update reference to ZPL.
	* qm/external/DocumentTemplate/LICENSE.txt: New file.

2003-08-28  Stefan Seefeld  <stefan.seefeld@orthosoft.ca>

	* setup.py: Make documentation compliant with qmtest's standard.
	(qm_build_doc): Tidy up the code and make it more clear.
	(qm_build_doc): Use os.path.join and os.path.normpath for better
	portability.

2003-08-27  Stefan Seefeld  <seefeld@sympatico.ca>

	* setup.py: Add build_doc command.

2003-08-27  Stefan Seefeld  <seefeld@sympatico.ca>

	* setup.py: New file.
	* qm/__init__.py: Import qm.config for data path and version info.
	* qm/test/base.py: Add config.data_dir + '/test/classes' to search
	path.
	* qm/test/qmtest.py: Insert magic number so this becomes a real script.

2003-08-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/web/web.py (LoadContextPage.prompt): Fix quoting.

2003-08-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (QMTest.__ExecuteCreate): Return 2 for
	failure, not 1.
	(QMTest.__ExecuteCreateTdb): Likewise.
	(QMTest.__ExecuteCreateTarget): Likewise.
	(QMTest.__ExecuteExtensions): Likewise.
	(QMTest.__ExecuteRegister): Likewise.
	(QMTest.__ExecuteSummarize): Return 2 when a test fails, not 1.
	(QMTest.__ExecuteRun): Likewise.
	* qm/test/qmtest.py: Use 2 as the default exit code, not 1.
	* qm/test/doc/reference.xml: Update accordingly.

	* NEWS: Mention documentation of exit status.
	* qm/test/cmdline.py (QMTest.Execute): Use the return value from
	__ExecuteCreateTdb.
	(QMTest.__ExecuteCreate): Return a value explicitly.
	(QMTest.__ExecuteCreateTdb): Likewise.
	(QMTest.__ExecuteCreateTarget): Likewise.
	(QMTest.__ExecuteSummarize): Likewise.
	(QMTest.__ExecuteRun): Likewise.
	* qm/test/qmtest.py: Simplify handling of exit codes.
	* qm/test/classes/mount_database.py: Fix typo in doc-string.
	* qm/test/doc/reference.xml: Document exit status.

2003-08-18  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (verbose): Remove variable.
	* qm/test/cmdline.py (QMTest.verbose_option_spec): Remove.
	(QMTest.global_options_spec): Remove 'verbose_option_spec'.
	(QMTest.Execute): Don't set 'qm.common.verbose'.
	* qm/test/doc/reference.xml: Don't document -v/--verbose switch.

2003-08-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/executable.py (Executable.Spawn): Remove __has_*_run variables.
	(Executable._InitializeParent): Likewise.
	(Executable._HandleChild): Likewise.
	(Executable._InitializeChild): Likewise.
	(Executable._DoParent): Likewise.
	* qm/platform_win32.py (get_user_name): Remove.
	* qm/platform_unix.py (send_email): Remove.
	(get_user_name): Remove.
	* qm/regression_test.py: Remove file.

	* qm/test/doc/reference.xml (Field Classes): Fix typo.

	* qm/test/file_result_stream.py (FileResultStream.__init__): Fix
	indentation.

2003-08-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/executable.py (TimeoutExecutable._HandleChild): Close all
	fds in the monitor process.
	* tests/xmldb/test.qms/classes.qms/scripttest_closes_stdin.qmt:
	New test.

2003-08-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/executable.py (RedirectedExecutable._InitializeChild): Fix
	indentation.

2003-08-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (TimeoutExecutable.__init__): Document -2 value
	for timeout.
	(TimeoutExecutable._InitializeChild): Create the monitor pid in
	the -2 case as well.
	(TimeoutExectuable.Run): Kill the entire process group, not just
	the monitor pid.
	(TimeoutExectuable.__UseSeparateProcessGroupForChild): New
	method.
	(Filter.__init__): Adjust documentation of timeout parameter.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Pass -2 to
	Filter when no timeout is specified.

2003-08-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/executable.py (Executable._MakeCloseOnExec): New function.
	(Executable.Run): Use it.
	(RedirectedExecutable._CreatePipe): Use it; document that fds
	will be closed on exec.
	(RedirectedExecutable._InitializeChild): Close all pipe fd's.

2003-08-13  Nathaniel Smith  <njs@codesourcery.com>

	* qm/executable.py (Executable): Typo in docstring.

2003-08-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/text_result_stream.py
	(TextResultStream.WriteResult): Don't save results when using the
	"stats" format.

2003-08-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ExecTestBase.RunProgram): Use the
	exit code returned by Filter.Run on Windows.

2003-08-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/platform_unix.py (SignalException.__init__): Tweak message
	formatting.
	(_initialize): Tidy.
	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Honor
	termination requests.
	* qm/test/target.py: Import qm.platform and signal.
	(Target.RunTest): Honor temination requests in the form of
	SIGTERM.

2003-08-11  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/command.py (ExecTestBase.MakeEnvironment):
	Replace "." with "__" when turning context keys into environment
	variables.  Document in class docstring.
	(ExecTest.Run): Fix indentation.
	* qm/test/doc/reference.xml: Document new handling of context
	variables with "."s in them.
	* tests/regress/QMTest/selftest.py: Import os.path.  Add more
	documentation.
	(RegTest.Run): Check for a context file, and if one is found,
	use it.
	* tests/regress/env_context1: New directory.
	* tests/regress/env_context1/QMTest: New directory.
	* tests/regress/env_context1/QMTest/configuration: New file.
	* tests/regress/env_context1/context: New file.
	* tests/regress/env_context1/results.qmr: New file.
	* tests/regress/env_context1/exectest_nodot.qmt: New file.
	* tests/regress/env_context1/exectest_dot.qmt: New file.
	* tests/regress/env_context1/shellcommandtest_nodot.qmt: New file.
	* tests/regress/env_context1/shellcommandtest_dot.qmt: New file.
	* tests/regress/env_context1/shellscripttest_nodot.qmt: New file.
	* tests/regress/env_context1/shellscripttest_dot.qmt: New file.

2003-08-10  Nathaniel Smith  <njs@codesourcery.com>

	* qm/common.py (get_lib_directory): Remove.
	(get_share_directory): Move path lookup logic to here from
	setup_path.py.  Clarify docstring.
	(get_doc_directory): Move path lookup logic to here from
	setup_path.py.  Clarify docstring.
	* qm/setup_path.py: Remove file.
	* qm/test/qmtest.py: Don't execfile setup_path.py.
	* GNUmakefile.in ($(SCRIPTS)): Don't set QM_TRUE_LIBDIR.
	* qm/qm.sh: Don't set QM_TRUE_LIBDIR.

2003-08-10  Nathaniel Smith  <njs@codesourcery.com>

	* qm/version.py.in: Rename to...
	* qm/__version.py.in: ...this.
	* qm/__init__.py: Adjust for new name.
	* qm/.cvsignore: Likewise.
	* qm/GNUMakefile.in: Likewise.
	* qm/configure.in: Likewise.
	* qm/configure: Regenerate.

2003-08-10  Nathaniel Smith  <njs@codesourcery.com>

	* qm/version.py.in: New file.
	* qm/setup_path.py.in: Remove version handling, and rename to...
	* qm/setup_path.py: ...this.
	* qm/.cvsignore: Add version.py, remove setup_path.py.
	* configure.in (AC_OUTPUT): Munge qm/version.py.in instead of
	qm/setup_path.py.in.
	* configure: Regenerate.
	* GNUmakefile.in (all): Remove qm/setup_path.py.
	(distclean): Delete qm/version.py, don't delete
	qm/setup_path.py.
	* qm/__init__.py: Import version, version_info from qm.version.
	* qm/test/qmtest.py (main): Don't pass version to QMTest
	initializer.
	* qm/test/cmdline.py (QMTest.__init__): Don't accept or record
	version information.
	(QMTest.GetVersion): Remove.
	(QMTest.Execute): Don't call QMTest._GetVersionString.
	(QMTest._GetVersionString): Remove.

2003-08-08  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/context.py (ContextException.__safe_for_unpickling__):
	Set to 1.
	(ContextWrapper): New class.
	* qm/test/result.py (Result.__setstate__): New method.
	(Result.__getstate__): New method.

	* tests/results_files: New directory.
	* tests/results_files/QMTest: Likewise.
	* tests/results_files/QMTest/configuration: New file.
	* tests/results_files/QMTest/classes.qmc: New file.
	* tests/results_files/QMTest/results_file_database.py: New
	file.
	* tests/results_files/QMTest/results_file_test.py: New file.
	* tests/results_files/README: New file.
	* tests/results_files/xml_results.qmr: New file.
	* tests/results_files/result_class_v0-file_format_v0-pickling_format_v0.qmr:
	New file.
	* tests/results_files/result_class_v1-file_format_v0-pickling_format_v0.qmr:
	New file.
	* tests/results_files/result_class_v1-file_format_v1-pickling_format_v0.qmr:
	New file.
	* tests/results_files/result_class_v1-file_format_v1-pickling_format_v1.qmr:
	New file.
	* tests/results_files/tdb: New directory.
	* tests/results_files/tdb/QMTest: New directory.
	* tests/results_files/tdb/QMTest/configuration: New file.
	* tests/results_files/tdb/pass.qmt: New file.
	* tests/results_files/tdb/fail.qmt: New file.
	* tests/results_files/tdb/error.qmt: New file.
	* tests/results_files/tdb/untested.qmt: New file.
	* tests/results_files/tdb/tmpdir_resource.qma: New file.
	* tests/results_files/tdb/fail_with_tmpdir.qmt: New file.

2003-08-07  Nathaniel Smith  <njs@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py: Improve documentation.
	(ExecutionEngine.__TARGET_IDLE): New variable.
	(ExecutionEngine.__TARGET_BUSY): Likewise.
	(ExecutionEngine.__TARGET_STARVING): Likewise.
	(ExecutionEngine.__num_idle_targets): Replace with...
	(ExecutionEngine.__has_idle_targets): ...this.
	(ExecutionEngine._RunTests): Incorporate above changes.
	(ExecutionEngine.__AddResult): Likewise.
	(ExecutionEngine.__AddToTargetPatternQueue): Fix typo.
	* GNUMakefile.in (check-threads): Set new context variable
	qmtest_target.
	(check-processes): Likewise.
	(check-rsh): Likewise.
	* qm/qm.sh: Correct handling of QM_PATH when both QM_HOME and
	QM_BUILD are set.
	* tests/regress/QMTest/selftest.py (RegTest.Run): Use context
	variable qmtest_target if defined.
	* tests/regress/bad_target1/bad_target.qmt: Use a target group
	that does not match the empty string.
	* tests/regress/bad_target2/bad_target.qmt: Use a target group
	that does not match the empty string.

	* qm/test/classes/xml_database.py: Do not import dircache.

	* scripts/qm-release: Improve snapshot generation.

2003-08-06  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release: Add support for snapshot releases.

2003-08-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (split_results_by_expected_outcome): Remove.
	* qm/test/cmdline.py (QMTest.__GetResultStreams): Remove
	test_suites parameter.
	* qm/test/result_stream.py (ResultStream.arguments): Remove
	suite_ids.
	* qm/test/classes/text_result_stream.py
	(TextResultStream.__init__): Do not save test and resource
	results.
	(TextResultStream.WriteResult): Update outcome counts, but do not
	save results.
	(TextResultStream.Summarize): Adjust accordingly.
	(TextResultStream._SummarizeTestStats): Remove results parameter.
	(TextResultStream._SummarizeRelativeTestStats): Likewise.
	(TextResultStream._CountOutcomes): Remove.
	(TextResultStream._SummarizeTestSuiteStats): Remove.

2003-07-31  Nathaniel Smith  <njs@codesourcery.com>
	    Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py: Rewrite to improve scalability.
	* test/regress/bad_target1: New test.
	* test/regress/bad_target2: Likewise.
	* test/regress/nocycle1: Likewise.
	* test/regress/nocycle2: Likewise.
	* benchmarks/throughput: New benchmark.

	* qm/test/classes/text_result_stream.py (TextResultStream): Fix
	typo in documentation.
	* qm/test/doc/tour.xml: Update instructions to match GUI changes.

2003-07-30  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Recommend Mozilla, even on Windows.  Mention use of
	line-ending independent comparisons in "command" test classes.
	* qm/fields.py (IntegerField.FormatValueAsHtml): Insert space before
	tag closing.
	(TextField.FormatValueAsHtml): Likewise.
	(TextField.ParseFormValue): Correct typo in comment.
	(TupleField.FormatValueAsHtml): Pretty-print.
	(SetField.FormatValueAsHtml): Likewise.
	(AttachmentField.FormatValueAsHtml): Insert space before
	tag closing.
	(EnumerationField): Derive from ChoiceField.
	* qm/web.py (DtmlPage.GenerateXMLHeader): Change encoding field to
	match that used in generated HTML.
	(make_select): Remove.
	* qm/test/classes/command.py (ExecTestBase.Run): Use __CompareText.
	(ExecTestBase.__CompareText): New method.
	* qm/test/share/dtml/navigation-bar.dtml: Use "javascript:
	void(0)" as a go-nowhere URL.
	* qm/test/share/dtml/show.dtml: Embed the id as a hidden field.
	* qm/test/web/web.py (ShowItemPage.MakeSubmitUrl): Do not encode
	the id in the URL.

2003-07-29  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (RELLIBDIR): Set correctly under Windows.
	(PYTHON_PKG_PREFIX): Likewise.
	(SCRIPTS): Update generation of Windows batch files accordingly.
	(scripts-install): Robustify.
	* install-sh: Update to newer version.
	* install.bat: Remove.
	* qm/setup.py (find_packages_r): Fix typo.
	* qm/fields.py (SetField.FormatValueAsHtml): Do not generate empty
	tables.
	(SetField.ParseFormValue): Update accordingly.
	* qm/web.py (WebRequestHandler.do_GET): Simplify.
	(WebRequestHandler.do_POST): Likewise.
	(make_select): Correct HTML generation.
	* qm/test/.cvsignore: Add qmtest.bat.
	* qm/test/web/web.py (QMTestServer.HandleSubmitItem): Generate
	valid URLs for next submission when redisplaying.

2003-07-24  Nathaniel Smith  <njs@codesourcery.com>

	* GNUmakefile.in (RELLIBDIR): Don't add slashes to prefix when
	matching for removal.  Strip slashes after prefix removal.
	(RELSHAREDIR): Likewise.
	(RELINCDIR): Likewise.

2003-07-24  Nathaniel Smith  <njs@codesourcery.com>

	* tests/xmldb/common.qms/graph_complete.qmt: Delete.
	* tests/xmldb/common.qms/graph_cycle.qmt: Likewise.
	* tests/xmldb/common.qms/graph_pass.qmt: Likewise.

2003-07-24  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (QMTest.GetVersion): New method.

2003-07-24  Mark Mitchell  <mark@codesourcery.com>

	* version: Update.

2003-07-23  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/base.py (qm.graph): Don't import.
	* qm/graph.py: Delete.

2003-07-22  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (Field._GetHtmlFormFieldName): Rename to ...
	(Field.GetHtmlFormFieldName): ... this.
	(IntegerField.FormatValueAsHtml): Adjust accordingly.
	(TextField.FormatValueAsHtml): Likewise.
	(TupleField.FormatValueAsHtml): Likewise.
	(SetField.FormatValueAsHtml): Likewise.
	(SetField.ParseFormValue): Do not validate newly added values.
	(AttachmentField.FormatValueAsHtml): Adjust use of
	_GetHtmlFormFieldName.
	(EnumerationField.FormatValueAsHtml): Likewise.
	(ChoiceField.FormatValueAsHtml): Always have at least one choice.
	(ChoiceField.Validate): New method.
	* qm/test/test.py (Test.arguments): Adjust the test_id field to
	allow creation from the GUI.
	* qm/test/web/web.py (QMTestServer.HandleSubmitItem): Simplify.

	* tests/regress/tuple1: New test.

2003-07-21  Nathaniel Smith  <njs@codesourcery.com>

	* qm/fields.py (TupleField.Validate): Return the computed
	value.

2003-07-21  Vladimir Prus <ghost@cs.msu.su>
	    Mark Mitchell <mark@codesourcery.com>

	* qm/attachment.py (FileAttachmentStore.GetDataFile): Fix typo.
	* tests/regress/attachment1/attachment1: New file.
	* tests/regress/attachment1/results.qmr: Likewise.
	* tests/regress/attachment1/test.qmt: Likewise.
	* tests/regress/attachment1/QMTest/.cvsignore: Likewise.
	* tests/regress/attachment1/QMTest/attachment_test.py: Likewise.
	* tests/regress/attachment1/QMTest/classes.qmc: Likewise.
	* tests/regress/attachment1/QMTest/configuration: Likewise.

2003-07-15  Vladimir Prus <ghost@cs.msu.su>
	    Mark Mitchell <mark@codesourcery.com>

	* qm/attachment.py (AttachmentStore.__init__): Remove.
	(FileAttachmentStore.__init__): New method.
	(FileAttachmentStore.GetDataFile): Support relative paths.
	(TemporaryAttachmentStore.__init__): Adjust accordingly.
	(TemporaryAttachmentStore.GetDataFile): Remove.
	* qm/test/classes/xml_database.py (XMLDatabase.__init__): Use the
	database root when creating the attachment store.

2003-07-15  Vladimir Prus <ghost@cs.msu.su>

	* qm/test/web/web.py (DirPage.GetTestResultsForDirectory): Call
	__IsLabelInDirectory with two parameters.  Fix typo.

	* qm/test/web/web.py (QMTestServer.HandleSaveExpectations): Do not
	pass 'context' parameter to Result.__init__.

	* qm/test/web/web.py (StorageResultStream.__init__): Initialize
	__annotations.

2003-07-14  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/pickle_result_stream.py
	(PickleResultReader.GetResult): Don't catch UnpicklingError;
	it's not necessary with Python 2.2.
	(PickleResultReader.__init__): Likewise.
	Also, fix typo (call self._ResetUnpickler, not
	self._ResetPickler).

2003-07-09  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/context.py (Context.items): New method.

2003-07-02  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/base.py (load_results): Rename 'ResultSource' to
	'ResultReader' everywhere.
	(extension_kinds): Rename "result_source" kind to
	"result_reader".
	(__extension_bases): Likewise.  And same for the imports just
	above.
	* qm/test/result_source.py: Rename to...
	* qm/test/result_reader.py: ...this.  Also rename classes, etc.
	* qm/test/file_result_source.py: Rename to...
	* qm/test/file_result_reader.py: ...this.  Also rename classes,
	etc.

	* qm/common.py (format_time_iso): New function.
	* qm/db.py: New file.
	* qm/extension.py (get_class_arguments): Support diamond
	inheritance.

	* qm/test/classes/pickle_result_source.py: Remove.
	(PickleResultSource): Move to...
	* qm/test/classes/pickle_result_stream.py: ...here.
	(PickleResultSource): Rename to 'PickleResultReader'.  Also
	rewrite for new metadata handling regime.
	(PickleResultStream): Rewrite for new metadata handling regime.
	* qm/test/classes/xml_result_source.py: Remove.
	(XMLResultSource): Move to...
	* qm/test/classes/xml_result_stream.py: ...here.
	(XMLResultSource): Rename to 'XMLResultReader', plus associated
	renames.  Update for new metadata handling regime.
	(XMLResultStream): Update for new metadata handling regime.

	* qm/test/result_stream.py (ResultStream.WriteAnnotation): New
	function.
	(ResultStream.WriteAllAnnotations): New function.
	(ResultStream.WriteResult): More detail in docstring.

	* qm/test/classes/classes.qmc: Add SQL result handling classes,
	rename 'ResultSource' to 'ResultReader'.

	* qm/test/cmdline.py (QMTest.__ExecuteSummarize): Copy
	metadata.
	* qm/test/execution_engine.py: import time.
	(ExecutionEngine.Run): Create and write metadata.
	* qm/test/web.py (StorageResultsStream.__init__): Use 'super'.
	Handle annotations.
	(StorageResultsStream.GetAnnotations): New method.
	(StorageResultsStream.WriteAnnotations: New method.
	(QMTestServer.HandleSubmitResults): Write out annotations.
	(QMTestServer.HandleSaveResults): Likewise.

	* scripts/create-test-database.py: New file.
	* qm/test/classes/sql_result_stream.py: New file.

2003-07-03  Vladimir Prus <ghost@cs.msu.su>

	* qm/attachment.py (AttachmentStore.GetIndex): Remove.
	* qm/fields.py (SetField.FormatValueAsHtml): Don't use it.
	* qm/test/clases/xml_database.py
	(XMLDatabase. __MakeDataFilePath): Fix typos.

2003-07-03  Vladimir Prus <ghost@cs.msu.su>

	* qm/test/web/web.py (ShowItemPage.MakeDeleteScript): Fix typo.

2003-06-27  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/classes.qmc: Add
	pickle_result_source.PickleResultSource.

2003-06-24  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/result_source.py: New file.
	* qm/test/file_result_source.py: New file.
	* qm/test/classes/classes.qmc: Add XMLResultSource.
	* qm/test/base.py (load_results): Take a database argument,
	return a ResultSource. Use PickleResultSource/XMLResultSource.
	(load_outcomes): Take a database argument, use new
	load_results interface.
	(_result_from_dom): Move to...
	* qm/test/classes/xml_result_source.py: ...here.  New file.
	* qm/test/classes/pickle_result_source.py: New file.
	* qm/test/cmdline.py (qm.test.result.Result): import it.
	(QMTest.__ExecuteSummarize): Rewrite to	use new load_results
	interface.
	(QMTest.__GetExpectedOutcomes): Pass database to
	load_outcomes.
	(QMTest.__FilterTestsToRun): Likewise.
	* qm/test/web/web.py (QMTestServer.HandleSubmitExpectations):
	Likewise.
	(QMTestServer.HandleSubmitResults): Likewise.

2003-06-24  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (commands_spec): Add support for "qmtest
	register --help".

2003-06-23  Nathaniel Smith  <njs@codesourcery.com>

	* qm/fields.py: Fix typo in comment.

	* qm/test/file_result_stream.py (FileResultStream.__doc__):
	Fix typo.

2003-06-23  Nathaniel Smith  <njs@codesourcery.com>

	* templates/Makefile: It's 2003 now.
	* templates/xml: Likewise.
	* templates/py: Likewise.
	* templates/html: Likewise.
	* templates/dtml: Likewise.
	* templates/docbook-chapter: Likewise.
	* templates/docbook: Likewise.

2003-06-22  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (Attachment): Move to start of file.
	(AttachmentStore.Store): Simplify interface.
	(FileAttachmentStore.__init__): Remove.
	(FileAttachmentStore.Store): Adjust.
	(TemporaryAttachmentStore): Derive from FileAttachmentStore.
	* qm/fields.py (SetField.__init__): Restore backwards-compatible
	handling of 'title' and 'description' attributes.
	(AttachmentField.ParseFormValue): Remove broken code.
	* qm/label.py (Label): Replace 'sep' with '_sep' throughout.
	(Label.Components): Remove.
	(Label.ToPath): Remove.
	* qm/test/database.py (Database.LabelBasename): Remove.
	(Database.LabelDirname): Remove.
	(Database.LabelSeparator): Remove.
	(Database.GetLabelComponents): Simplify.
	* qm/test/file_database.py (FileDatabase._IsTestFile): Do not use
	_IsFile.
	(FileDatabase._IsResourceFile): Likewise.
	(FileDatabse._IsSuiteFile): Likewise.
	(FileDatabase._IsFile): Use _IsTestFile, _IsResourceFile, and
	_IsSuiteFile.
	(FileDatabase._GetRelativeLabelPath): New method.
	(ExtensionDatabase._IsTestFile): New method.
	(ExtensionDatabase._IsResourceFile): New method.
	(ExtensionDatabase._IsSuiteFile): New method.
	(ExtensionDatabase._IsFile): Remove.
	(ExtensionDatabase._GetRelativeLabelPath): New method.
	* qm/test/classes/file_label.py (FileLabel.sep): Rename to ...
	(FileLabel._sep): ... this.
	(FileLabel.Components): Remove.
	* qm/test/classes/python_label.py (PythonLabel.sep): Rename to ...
	(PythonLabel._sep): ... this.
	(PythonLabel.__valid_label_regexp): Adjust accordingly.
	* qm/test/classes/xml_database.py (XMLDatabase.__init__): Use
	FileAttachmentStore for the attachment store.
	(XMLDatabase.__StoreAttachments): Adjust accordingly.
	(XMLDatabase.__MakeDataFilePath): New method.
	(XMLDatabase.AttachmentStore): Remove.
	* qm/test/web/web.py (QMTestPage.FormatId): Avoid use of label
	separator.
	(DirPage.__IsLabelInDirectory): New method.
	(ShowSuitePage.MakeAbsoluteId): Remove.

	* qm/test/doc/reference.xml: Improve test database documentation.

2003-06-21  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/classes/pickle_result_stream.py: import qm.fields.
	(PickleResultStream): New variable _max_pinned_results.
	New argument protocol_version.
	(PickleResultStream.__init__): Use protocol_version.
	Initialize count of processed `Result's.
	(PickleResultStream.WriteResult): Keep count of processed
	`Result's, and call `clear_memo' every after every
	_max_pinned_results.

2003-06-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (diagnostic): Do not import it.
	(label): Likewise.
	(user): Likewise.
	(DomNodeError): Remove.
	(Field.Validate): Update documentation.
	(IntegerField.GetValueFromDomNode): Raise QMException, not
	DomNodeError.
	(TextField.GetValueFromDomNode): Likewise.
	(SetField.GetValueFromDomNode): Likewise.
	(AttachmentField.GetValueFromDomNode): Likewise.
	(EnumerationField.GetValueFromDomNode): Likewise.
	* qm/test/context.py (Context.__init__): Update documentation
	string.
	* qm/test/classes/xml_database.py (XMLDatabase._GetTestFromPath):
	Handle all exceptions.
	(XMLDatabase._GetResourceFromPath): Handle all exceptions.
	* qm/test/doc/manual.xml (context_class): New entity.
	(result_class): Likewise.
	* qm/test/doc/reference.xml: Update sections on writing test and
	resource classes.

	* qm/fields.py: More massive reorganization and cleanup.
	* qm/test/doc/manual.xml: Add links to onlin documentation.
	* qm/test/doc/reference.xml: Describe Field classes.

2003-06-18  Mark Mitchell  <mark@codesourcery.com>

	* README: Correct typo.
	* qm/test/base.py (load_results): Likewise.

	* GNUmakefile.in (PYTHON_VERSION): Remove.
	(PYTHON_PREFIX): Remove.
	(doc-python): Conditionalize on the avaialability of happydoc.
	* configure.in (PYTHON_VERSION): Don't AC_SUBST it.
	(PYTHON_PREFIX): Likewise.
	* configure: Regenerated.
	* qm/fields.py: Remove all traces of PropertyDeclaration.
	* qm/xmlutil.py (load_xml): Update comments.
	* qm/test/qmtest.py: Try to make sure that gc.collect is called.
	* qm/test/doc/reference.xml: Correct typos.
	* qm/test/share/dtml/show.dtml: Use Field.IsHidden.
	* qm/test/web/web.py (ShowItemPage.FormatFieldValue): Likewise.
	(QMTestServer.HandleRunTests): Tidy.

2003-06-16  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/qmtest.py (check_python_version): Call `str' on
	numbers before joining them.

2003-06-16  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/qmtest.py: Import sys.
	(_required_python_version): New variable.
	(check_python_version): New function.
	(main): Call it.

	* qm/setup_path.py.in (__unsupported_python_version): Remove,
	and remove calls below.

	* qm/setup_path.py.in (add_to_python_path): Remove, and don't
	call it.
	(__doc__): Remove now inaccurate docstring.

	* qm/setup_path.py.in: Move warnings filtering to...
	* qm/external/__init__.py: ...here.

2003-06-15  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/text_result_stream.py: Move into classes/.
	* qm/test/classes/classes.qmc: Add TextResultStream.
	* qm/test/cmdline.py: Don't import text_result_stream.
	(QMTest.__init__): New variable	__text_result_stream_class_name.
	(QMTest.GetTextResultStreamClass): New function.
	(QMTest.__GetResultStream): Use it.

	* qm/test/cmdline.py (QMTest.__init__): Remove variable
	__file_result_stream_class.
	(QMTest.GetFileResultStreamClass): Don't use it.
	(QMTest.__init__): Remove unused variable
	__result_stream_class.

	* qm/test/cmdline.py (QMTest.__init__): Typo in comment.

	* qm/test/execution_engine.py (ExecutionEngine.__init__):
	Remove unused variables self.__test_results,
	self.__resource_results.
	(ExecutionEngine._AddResult): Likewise.

	* qm/test/web/web.py: Remove from __future__ import
	nested_scopes line.
	* qm/test/cmdline.py: Likewise.
	* qm/fields.py: Likewise.
	* qm/test/classes/file_label.py: Likewise.
	* qm/test/classes/xml_database.py: Likewise.
	* qm/test/classes/python_label.py: Likewise.
	* qm/test/test.py: Likewise.
	* qm/test/database.py: Likewise.

	* qm/extension.py (parse_descriptor): Typo in docstring.

2003-06-12  Nathaniel Smith  <njs@codesourcery.com>

	* qm/qm.sh (qm_python_path_dir): New variable.
	(PYTHONPATH): Use it.

2003-06-10  Ricardo Anguiano  <anguiano@codesourcery.com>

	* qm/test/doc/reference.xml: Fixed typo.

2003-06-08  Nathaniel Smith  <njs@codesourcery.com>

	* qm/test/base.py (get_extension_directories): Search for
	builtin extension classes relative to __file__ rather than
	QM_LIB_DIR.
	* GNUmakefile.in (PYTHON_PKG_PREFIX): New variable.
	(RELLIBDIR): Base on PYTHON_PKG_PREFIX, not @libdir@.
	(RELLIBDIR, RELSHAREDIR, RELINCDIR): Move up in file, so
	$(SCRIPTS) rule can see RELLIBDIR.
	(lib-install): Install classes.qmc into PYTHON_PKG_PREFIX.
	($(SCRIPTS)): Bake library directory into installed scripts.
	* qm/qm.sh (qm_rel_libdir): New variable to hold baked-in
	library directory.  Use it.
	(QM_TRUE_LIBDIR): New exported variable to help qmtest.py find
	setup_path.py.
	* qm/test/qmtest.py: Use it.

2003-06-06  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (FieldEditPage.__init__): Add server parameter.
	(FieldEditPage.MakeDefaultValueControl): Pass it to
	FormatValueAsHtml.
	(Field.FormatValueAsText): Adjust call to FormatValueAsHtml.
	(Field.FormatValueAsHtml): Add server parameter.
	(Field.GenerateEditWebPage): Likewise.
	(Field.MakePropertyControls): Likewise.
	(IntegerField.FormatValueAsHtml): Add server parameter.
	(TextField.FormatValueAsHtml): Likewise.
	(TextField.MakePropertyControls): Likewise.
	(TupleField.FormatValueAsHtml): Likewise.
	(SetField.FormaatValueAsHtml): Likewise.
	(SetField.MakePropertyControls): Likewise.
	(AttachmentField.FormatValueAsHtml): Likewise.
	(EnumerationField.FormatValueAsHtml): Likewise.
	(EnumerationField.MakePropertyControls): Likewise.
	(ChoiceField.FormatValueAsHtml): Likewise.
	(TimeField.FormatValueAsHtml): Likewise.
	(UidField): Remove.
	* qm/web.py (WebRequestHandler.__HandlePageCacheRequest): Use
	WebServer.GetCachedPage.
	(WebRequestHandler.__HandleSessionCacheRequest): Likewise.
	(WebServer.__init__): Create a page cache.
	(WebServer.MakeButtonForCachedPopup): New method.
	(WebServer.MakeConfirmationDialog): Likewise.
	(WebServer.MakePopupDialog): Likewise.
	(WebServer.CachePage): Likewise.
	(WebServer.GetCachedPage): Likewise.
	(WebServer.__GetPathForCachedPage): Likewise.
	(make_popup_dialog): Remove.
	(make_confirmation_dialog): Likewise.
	(make_popup_page): Likewise.
	(make_button_for_cached_popup): Likewise.
	(cache_page): Likewise.
	(_get_path_for_cache_page): Likewise.
	(get_from_cache): Likewise.
	(format_user_id): Likewise.
	(_page_cache_path): Likewise.
	* qm/test/web/web.py (ShowItemPage.FormatFieldValue): Adjust calls
	to FormatValueAsHtml.
	(ShowItemPage.MakeDeleteScript): Use
	WebServer.MakeConfirmationDialog.
	(ShowSuitePage.MakeDeleteScript): Likewise.

	* qm/external/DocumentTemplate/.cvsignore: Likewise.

2003-06-04  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dejagnu_test.py (DejaGNUTest._ParseTclWords):
	Recognize that "[]" does not represent command substitution.

	* zope-dtml/DocumentTemplate/.cvsignore: Remove.
	* zope-dtml/ExtensionClass/.cvsignore: Remove.

2003-06-03  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/dg_test.py (DGTest.DGException): New class.
	(DGTest._RunDGTest): Tweak annotation formatting.
	(DGTest._ExecuteFinalCommand): Use DGException to signal problems,
	rather than NotImplementedError.

2003-06-02  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (INSTALL_DOCUMENTATION): New variable.
	(doc-install): Guard it by testing INSTALL_DOCUMENTATION.
	* configure.in (INSTALL_DOCUMENTATION): Set it.
	* configure: Regenerated.

	* README: Mention HappyDoc.
	* qm/test/classes/dejagnu_stream.py
	(DejaGNUStream.__summary_outcomes): New variable.
	(DejaGNUStream.Summarize): Use it.
	* qm/test/classes/dejagnu_test.py (DejaGNUTest._ParseTclWords):
	Correct variable substitution.

	* qm/test/classes/dejagnu_stream.py: New file.
	* qm/test/classes/dejagnu_test.py: New file.
	* qm/test/classes/dejagnu_base.py: New file.
	* qm/test/classes/dg_test.py: New file.
	* qm/test/classes/classes.qmc: Update.

2003-05-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py: Import result_stream.
	(QMTest.summary_formats): Add "batch".
	(QMTest.__init__): Set __expected_outcomes to None.
	(QMTest.__ExecuteSummarize): Simplify.
	(QMTest.__ExecuteRun): Likewise.
	(QMTest.__ExecuteGUI): Likewise.
	(QMTest.__FilterTestsToRun): Remove expectations parameter; use
	__GetExpectedOutcomes.
	(QMTest.__GetExpectedOutcomes): Cache results.
	(QMTest.__GetResultStreams): Create the TextResultStream here.
	* qm/test/execution_engine.py (ExecutionEngine.__init__): Add
	expectations parameter.
	(ExecutionEngine.Run): Return a value.
	(ExecutionEngine._AddResult): Set any_unexpected_outcomes if
	appropriate.
	* qm/test/execution_thread.py (ExecutionThread.__init__): Add
	expectations parameter.
	* qm/test/result_stream.py (ResultStream.arguments): New
	variable.
	* qm/test/text_result_stream.py (TextResultStream): Inherit from
	FileResultStream.
	(TextResultStream.__init__): Remove parameters.
	* qm/test/web/web.py (QMTestServer.HandleRunTests): Update
	creation of ExecutionThread.
	* qm/test/doc/reference.xml: Document "batch" output format.
	* qm/test/doc/tour.xml: Update sample output.

2003-05-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (atexit): Do not import it.
	(temporary_directory): Import it.
	(AttachmentStore.all_stores): Remove.
	(AttachmentStore.__init__): Do not update it.
	(FileAttachmentStore): Use TemporaryDirectory.
	(FileAttachmentStore.__CleanUpTemporaryDirectory): Likewise.
	(is_temporary_location): Use string.startswith.
	(get_attachment_store): Remove.
	* qm/common.py (load_class): Support new-style classes.
	(rmdir_recursively): Remove.
	(make_temporary_directory): Likewise.
	(find_program_in_path): Remove.
	(starts_with): Remove.
	(ends_with): Likewise.
	(read_assignments): Use string.startswith.
	* qm/executable.py (F_GETFD): Do not set it.
	(F_SETFD): Likewise.
	(FD_CLOEXEC): Likewise.
	(Executable.__init__): Remove.
	(Executable.Run): Use fnctl.F_GETFD, etc.
	(RedirectedExecutable): Inherit from TimeoutExecutable.  Make
	adjustments accordingly.
	(Filter): New class.
	* qm/extension.py (Extension): Make it a new-sytle class.
	* qm/fields.py (Field.ParseFormValue): Add attachment_store
	parameter.
	(Field.FormDecodeValue): Likewise.
	(UploadAttachmentPage): Do not encode an attachment store.
	(AttachmentField.FormDecodeValue): Do not decode it either.
	* qm/platform_unix.py (get_temp_directory): Remove.
	* qm/temporary_directory.py: New file.
	* qm/web.py (atexit): Do not import it.
	(temporary_directory): Import it.
	(cache_page): Use TemporaryDirectory.
	* qm/test/base.py (_result_from_dom): Do not use a context when
	creating 'Result' objects.
	* qm/test/cmdline.py (QMTest.__ExecuteSummarize): Handle -fnone.
	* qm/test/context.py (Context): Inherit from types.DictType.
	(ContextWrapper): Remove.
	* qm/test/database.py (ItemDescriptor._Execute): Compare context
	to None, rather than using "if context".
	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Do not
	use a context when creating 'Result' objects.
	* qm/test/file_result_stream (FileResultStream.arguments): Add
	default value for 'filename' attribute.
	* qm/test/qmtest.py (main): New method.
	Collect garbage.
	* qm/test/result.py (Result.__init__): Remove 'context'.
	(Result.GetContext): Remove.
	* qm/test/result_stream.py (ResultStream.kind): Define.
	* qm/test/target.py (Target.RunTest): Do not use a context when
	creating 'Result' objects.
	(Target._FinishResourceSetUp): Add 'properties' parameter.
	(Target._SetUpResource): Adjust accordingly.
	(Target._CleanUPResource): Do not use a context when
	creating 'Result' objects.
	* qm/test/classes/command.py (ExecTestBase.InputExecutable):
	Remove.
	* qm/test/classes/process_target.py (ProcessTarget.RunTest): Do
	not use a context when creating 'Result' objects.
	* qm/test/classes/serial_target.py (SerialTarget.__init__): Create
	a temporary directory.
	* qm/test/classes/temporary.py (TempDirectoryResource):
	Reimplement in terms of TemporaryDirectory.
	* qm/test/classes/thread_target.py (LocalThread.__init__): Create a
	temporary directory.
	(LocalThread.GetTemporaryDirectory): New method.
	(ThreadTarget._FinishResourceSetUp): Adjust call to
	_FinishResourceSetUp.
	(ThreadTarget._GetTemporaryDirectory): New method.
	* qm/test/doc/reference.xml: Fix typo.
	* qm/test/web/web.py (QMTestServer.__init__): Create a temporary
	attachment store.

2003-04-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/context.py (Context.GetAddedProperties): New method.
	(ContextWrapper.GetAddedProperties): Recur.
	* qm/test/target.py (Target._SetUpResource): Handle resources
	dependent on other resources.

	* qm/test/file_database.py (ExtensionDatabase._IsFile): Handle
	empty extensions more gracefully.

	* qm/test/result.py (Result.SetOutcome): Add cause and annotations
	parameters.
	(Result.Fail): Use it.

2003-04-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable.Spawn): Close the write end of the
	exception_pipe here.  Call _HandleChild.
	(Executable.Run): Do not close the write end of the
	exception_pipe.
	(Executable._InitializeChild): Fix thinko.
	(Executable._HandleChild): New method.
	(RedirectedExecutable._HandleChild): New method.
	(RedirectedExecutable._DoParent): Do not close pipe ends here.
	(TimeoutExecutable._DoParent): Rename to ...
	(TimeoutExecutable._HandleChild): ... this.
	(TimeoutExecutable.Run): Robustify.
	(TimeoutRedirectedExecutable._DoParent): Remove.
	(TimeoutRedirectedExecutable._HandleChild): New method.

	* qm/test/database.py (TestDescriptor.__init__): Correct error in
	doc-string.
	* qm/test/resource.py (Resource.SetUp): Improve doc-string.
	* qm/test/target.py (Target._SetUpResource): Fix typo in comment.
	* qm/test/doc/reference.xml: Improve target documentation.

2003-04-15  Nathaniel Smith  <njs@pobox.com>

	* qm/setup_path.py.in: Make warnings filtering more fine-grained.

2003-04-15  Nathaniel Smith  <njs@pobox.com>

	* qm/test/base.py (get_extension_directories): typo in comment.
	* qm/test/classes/process_target.py (QMTestExecutable): typo in
	docstring.

2003-04-15  Nathaniel Smith  <njs@pobox.com>

	* zope-dtml/ExtensionClass/: Remove.
	* qm/external/: New directory.
	* qm/external/__init__.py: New file.
	* zope-dtml/DocumentTemplate/: Move to...
	* qm/external/DocumentTemplate/: ...here.
	* qm/external/DocumentTemplate/DT_String.py (String._ParseTag):
	Tweak so it can find modules in the same directory.
	* qm/external/DocumentTemplate/__init__.py: Tweak to work even if
	ExtensionClass doesn't exist.
	* qm/external/local-DocumentTemplate-patch: Record the above two
	changes to ease future upgrades of DocumentTemplate.
	* GNUMakefile.in (PYTHONDIRS): Remove mention of zope-dtml/.
	(PYTHON_PACKAGES): Likewise.
	* qm/web.py: Import DocumentTemplate from new location.

2003-04-13  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Remove --result-format item and add --result-stream item.
	Mention "qmtest create".
	* qm/extension.py (write_extension_file): New function.
	(read_extension_file): Likewise.
	(parse_descriptor): Likewise.
	* qm/fields.py (PythonField): New class.
	* qm/test/cmdline.py (QMTest.__extension_kinds_string): New
	variable.
	(QMTest.extension_output_option_spec): New spec.
	(QMTest.result_format_spec): Remove.
	(QMTest.result_stream_spec): New spec.
	(QMTest.commands_spec): Add "qmtest create".  Remove
	"--result_format".  Add "--result_stream" for "qmtest run" and
	"qmtest summarize".
	(QMTest.__version_output): Update copyright date.
	(QMTest.__init__): Set __file_result_stream_class_name and
	__file_result_stream_class.
	(QMTest.GetCommandOption): Add documentation.
	(QMTest.Execute): Add "qmtest create" support.
	(QMTest.GetFileResultStreamClass): New method.
	(QMTest.GetResultStreamClass): Remove.
	(QMTest.__ExecuteCreate): New method.
	(QMTest.__ExecuteCreateTdb): Use it.
	(QMTest.__ExecuteExtensions): Use __CheckExtensionKind.
	(QMTest.__ExecuteSummarize): Use __GetResultStreams.
	(QMTest.__ExecuteRun): Likewise.
	(QMTest.__CheckExtensionKind): New method.
	(QMTest.__GetResultStreams): Likewise.
	* qm/test/database.py (create_database): Remove.
	* qm/test/file_result_stream.py: New file.
	* qm/test/classes/pickle_result_stream.py (PickleResultStream):
	Inherit from FileResultStream.
	* qm/test/classes/xml_database.py (XMLDatabase.WriteTest): Use
	write_extension_file.
	(XMLDatabase.WriteResource): Likewise.
	* qm/test/classes/xml_result_stream.py (XMLResultStream): Inherit from
	FileResultStream.
	* qm/test/doc/reference.xml: Document new command-line options.
	* qm/test/web/web.py (QMTestServer.HandleSaveResults): Use
	QMTest.GetFileResultStreamClass.
	(QMTestServer.HandleSaveExpectations): Likewise.
	* share/diagnostics/common.txt: Add invalid descriptor syntax message.

	* qm/executable.py: Fix typo in comment.

2003-04-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (signal): Import it.
	(time): Likewise.
	(Executable): Derive from object.
	(Executable.Spawn): Deal with multiple inheritance.
	(Executable._InitializeParent): Likewise.
	(Executable._InitializeChild): Likewise.
	(Executable._DoParent): Likewise.
	(Executable._GetChildPID): New method.
	(TimeoutExecutable): New class.
	(TimeoutRedirectedExecutable): Likewise.
	* NEWS: Mention TimeoutExecutable.
	* README: Note that Python 2.2 is now required.
	* qm/setup_path.py.in: Reflect Python 2.2 requirement.

	* qm/test/classes/command.py (ExecTestBase.arguments): Add timeout field.
	(ExecTestBase.InputExecutable): Use
	TimeoutRedirectedExecutable as a base class.
	(ExecTestBase.InputExecutable.__init__): Adjust accordingly.
	(ExecTestBase.Run): Likewise.

	* qm/test/classes/mount_database.py (MountDatabase.GetIds): Fix thinko.

	* qm/test/classes/process_target.py (ProcessTarget.RunTest):
	Handle unexpected death of the child process.
	(ProcessTarget.__ReadResults): Likewise.

2003-04-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/read_thread.py: Remove.
	* qm/write_thread.py: Likewise.

	* qm/qm.sh: Remove qmtest-remote handling.

2003-03-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/process_target.py (ProcessTarget.__init):  Move
	initialization of children to ...
	(ProcessTarget.Start): ... here.
	(ProcessTarget.Stop): Call Target.Stop.

2003-03-27  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (.PHONY): Mention more targets.
	(check): Add check-rsh.
	(check-rsh): New target.
	* qm/extension.py (Extension._allow_arg_names_matching_class_vars): New
	variable.
	(get_class_arguments): Use it.
	* qm/test/classes/command.py
	(ExecTest._allow_arg_names_matching_class_vars): Set it.
	(ShellScriptTest._allow_arg_names_matching_class_vars): Likewise.
	* qm/test/classes/rsh_target.py
	(RSHTarget._allow_arg_names_matching_class_vars): Likewise.
	(RSHTarget.__init__): Always set "arguments".
	(RSHTarget._GetInterpreter): Fix thinko.
	* qm/test/doc/reference.xml: Mention the fact that test classes
	should not use fields with the same names as class variables in
	base classes.
	* NEWS: Mention changes.

2003-03-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (format_traceback): Tweak formatting of generated
	structured text.
	* qm/test/base.py (CouldNotLoadExtensionError): New class.
	(get_extension_class_from_directory): Use it.
	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Remove explicit
	exception-handling code.
	* qm/test/database.py (TestDescriptor.__init__): Use symbolic
	constants, not hard-coded string, for prerequisites.
	(NoSuchItemError): New class.
	(NoSuchTestError): Inherit from it.
	(NoSuchSuiteError): Likewise.
	(NoSuchResourceError): Likewise.
	(Database.RESOURCE): Tweak spelling.
	(Database.SUITE): Likewise.
	(Database.TEST): Likewise.
	(Database._item_exceptions): Likewise.
	(Database.GetTest): Raise NoSuchTestError.
	(Database.GetSuite): Raise NoSuchSuiteError.
	(Database.GetResource): Raise NoSuchResourceError.
	(Database.GetItem): Implement in terms of GetTest, GetSuite, and
	GetResource.
	(Database.GetClassPaths): Do not raise an exception.
	* qm/test/file_database.py (GetItem): Remove.
	* qm/test/test.py (Test.PREREQUISITES_FIELD_ID): New variable.
	* qm/test/classes/classes.qmc: Register
	mount_database.MountDatabase.
	* qm/test/classes/mount_database.py: New file.
	* qm/test/share/messages/diagnostics.txt (no such resource):
	Remove.
	(no such test): Likewise.
	(no such suite): Likewise.
	(no such item): New message.
	* qm/test/web/web.py (QMTestServer.HandleShowItem): Simplify.
	* tests/QMTest/classes.qmc: Remove selftest.RegTest.
	* tests/QMTest/configuration: Use MountDatabase.
	* tests/QMTest/selfdb.py: Remove.
	* tests/QMTest/selftest.py: Likewise.
	* tests/regress/QMTest/classes.qmc: New file.
	* tests/regress/QMTest/configuration: Likewise.
	* tests/regress/QMTest/regression_database.py: Likewise.
	* tests/regress/QMTest/selftest.py: Likewise.

2003-03-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (ItemDescriptor.GetResources): Use
	Runnable.RESOURCE_FIELD_ID.
	(ResourceDescriptor.__init__): Remove dead code.
	(Database.kind): Remove.
	(Database.RESOURCE): New variable.
	(Database.TEST): Likewise.
	(Database.SUITE): Likewise.
	(Database.ITEM_KINDS): Likewise.
	(Database.GetTest): Use GetItem.
	(Database.GetTestIds): Use GetIds.
	(Database.GetSuite): Use GetItem.
	(Database.GetSuiteIds): Use GetIds.
	(Database.GetResource): Use GetItem.
	(Database.GetResourceIds): Use GetIds.
	(Database.GetItem): New method.
	(Database.GetIds): Likewise.
	(Database.ExpandIds): Optimize.
	* qm/test/file_database.py (FileDatabase.GetTestIds): Remove.
	(FileDatabase.GetSuiteIds): Likewise.
	(FileDatabase.GetResourceIds): Likewise.
	(FileDatabase._IsTestFile): Use _IsFile.
	(FileDatabase._IsSuiteFile): Likewise.
	(FileDatabase._IsResourceFile): Likewise.
	(FileDatabase._IsFile): New method.
	(FileDatabase.GetIds): New method.
	(FileDatabase.GetItems): Likewise.
	* qm/test/result.py: Fix formatting.
	* qm/test/runnable.py (Runnable.RESOURCE_FIELD_ID): New variable.
	(Runnable.arguments): Use it.
	* qm/test/classes/xml_database.py (UnknownTestClassError): Remove.
	(UnknownResourceClassError): Likewise.

2003-03-06  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/command_thread.py (sys): Import it.
	(CommandThread.run): Remove use of eval.  Make use of trace
	facilities.
	(CommandThread._Trace): Use it.
	* qm/test/target.py (Target.__ResourceSetUpException): New class.
	(Target.RunTest): Make it exception-safe.
	(Target.__BeginResourceSetUp): 	Do not create results here when a
	test cannot be set up; instead, raise an exception.
	(Target._SetUpResource0: Make it exception-safe.
	* qm/test/classes/thread_target.py: Add trace messages throughout.
	* NEWS: Mention defect correction.

2003-02-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/cmdline.py (_make_comma_separated_string): New
	function.
	(QMTest.commands_spec): Use it.
	(QMTest.__ExecuteExtensions): Use base.extension_kinds.
	(QMTest.__ExecuteRegister): Likewise.

	* qm/test/cmdline.py (QMTest.commands_spec): Add -O.
	(QMTest.__ExecuteServer): Pass expectations to
	QMTestServer.__init__.
	* qm/test/web.py (QMTestServer.__init__): Add expectations
	parameter.
	* qm/test/doc/reference.xml: Add documentation for -O.
	* NEWS: Mention new -O option.

2003-02-24  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release (build_rpm): Use rpmbuild, rather than rpm,
	to build an RPM.

2003-02-24  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/share/dtml/navigation-bar.dtml (hide_menu): Tweak for
	Mozilla 1.0.1 compatibility.

2003-02-17  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/common-manual.xml: Remove documentation about
	sendmail configuration option.

2003-01-30  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (Field.class_name): Remove.
	(Field.MakeDomNode): Adjust accordingly.
	(IntegerField.class_name): Remove.
	(TextField.class_name): Likewise.
	(TupleField.class_name): Likewise.
	(SetField.class_name): Likewise.
	(AttachmentField.class_name): Likewise.
	(EnumerationField.class_name): Likewise.
	(TimeField.class_name): Likewise.
	(UidField.class_name): Likewise.
	(from_dom_node): Remove.
	* qm/test/database.py (ItemDescriptor.GetResources): New method.
	(TestDescriptor.GetResources): Remove.
	* qm/test/runnable.py (Runnable.ResourceField): New class.
	(Runnable.arguments): Add resources.
	* qm/test/target.py (Target.RunTest): Use __SetUpResources.
	(Target._SetUpResource): Likewise.
	(Target.__SetUpResources): New method.
	* qm/test/test.py (Test.ResourceField): Remove.
	(Test.ResourceField): Remove.
	(Test.arguments): Remove resources field.
	* qm/test/classes/file.py (SubstitutionField.class_name): Remove.

2003-01-21  Jeffrey D. Oldham  <oldham@codesourcery.com>

	* qm/fields.py (AttachmentField): Fix typo in introductory
	comment.

2003-01-21  Jeffrey D. Oldham  <oldham@codesourcery.com>

	* qm/test/target.py (Target._RecordResult): Always record the
	target which the concurrent execution code assumes exists.

2003-01-21  Jeffrey D. Oldham  <oldham@codesourcery.com>

	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Fix
	documentation mistake.  Fix typo in comment.
	(ExecutionEngine._Trace): Remove extraneous comma in parameter
	list.

2003-01-03  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (ItemDescriptor.__init__): Do not set
	__working_directory.
	(ItemDescriptor.SetWorkingDirectory): Remove.
	(ItemDescriptor.GetWorkingDirectory): Likewise.
	(ItemDescriptor._Execute): Do not change directories.
	* qm/test/classes/xml_database.py (XMLDatabase.__LoadItem): Do not
	use SetWorkingDirectory.

2003-01-02  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention --result-format.
	* qm/test/base.py (extension_kinds): Add result_stream.
	(__extension_bases): Likewise.
	* qm/test/cmdline.py (PickleResultStream): Don't import it.
	(QMTest.result_format_spec): New variable.
	(QMTest.commands_spec): Use it.
	(QMTest.__init__): Initialize __result_stream_class.
	(QMTest.GetResultStreamClass): New method.
	(QMTest.UnexpectedOutcomesStream.__init__): Adjust call to
	ResultStream.__init__.
	(QMTest.__ExecuteRun): Use GetResultStreamClass.
	* qm/test/pickle_result_stream.py: Remove.
	* qm/test/result_stream.py (ResultStream): Derive from Extension.
	* qm/test/text_result_stream.py (TextResultStream.__init__):
	Adjust call to ResultStream.__init__.
	* qm/test/xml_result_stream.py: New file.
	* qm/test/classes/classes.qmc: Add XMLResultStream and
	PickleResultStream.
	* qm/test/classes/pickle_result_stream.py: New file.
	* qm/test/doc/reference.xml: Document --result-format.
	* qm/test/web/web.py (PickleResultStream): Do not import it.
	(StorageResultStream.__init__): Adjust call to
	ResultStream.__init__.
	(QMTestServer.HandleSaveExpectations): Use
	QMTest.GetResultStreamClass.
	(QMTestServer.HandleSaveResults): Likewise.

2002-12-31  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/common-manual.xml: Document click_menus option.
	* qm/common.py (RcConfiguration): Derive from ConfigParser.
	(RcConfiguration.__init__): Load the configuration file.
	(RcConfiguration.Load): Do not call __Load.
	(RcConfiguration.Get): Simplify.
	(RcConfiguration.GetOptions): Likewise.
	(RcConfiguration.__Load): Remove it.
	* qm/test/share/dtml/navigation-bar.dtml: Suppose clickable menus.
	* qm/test/web/web.py (QMTestPage.GenerateStartBody): Likewise.

	* qm/test/doc/reference.xml: Fix typo.

2002-12-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (get_class_arguments): Use the __dict__ of the
	class, rather than a direct attribute reference, when checking to
	see if the argument list has already been computed.
	(get_class_arguments_as_dictionary): Likewise.

2002-12-23  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/test.py (Test.TestField): Fix typo in comment.

2002-12-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (get_class_arguments): Allow derived classe
	arguments to override base class arguments.
	(get_class_arguments_as_dictionary): Reimplement.
	* tests/xmldb/QMTest/test_inheritance.py: New file.
	* tests/xmldb/QMTest/classes.qms: Update.
	* tests/xmldb/api.qms/test.qms/derived.qmt: New test.

2002-12-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/file.py (SubstitutionField): Rework, using
	TupleField as a base class.
	(FileContentsTest.Run): Remove exception-handling code.
	(FileContentsTest.__PerformSubstitutions): Correct.
	* NEWS: Mention change.

2002-12-18  Vladimir Prus <ghost@cs.msu.su>
	    Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (parse_dom_element): Add attachment_store
	parameter.
	* qm/test/classes/xml_database.py:
	(XMLDatabase._StoreAttachments): New method
	(XMLDatabase.WriteTest): Call it.
	(XMLDatabase.WriteResource): Likewise.
	(XMLDatabase.__ParseTestDocument): Pass store to parse_dom_element.
	(AttachmentStore.__init__): Call base class __init__.
	(AttachmentStore.Store): Correct typo.
	(AttachmentStore.__MakeDataFilePath): Fix path calculation.

2002-12-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (ChoiceField): New class.
	* qm/test/test.py (Test.ResourceField): Likewise.
	(Test.TestField): Likewise.
	(Test.arguments): Use them.

2002-12-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/result.py (Result): Update documentation string to more
	clearly describe annotations.
	* qm/test/web/web.py (ResultPage.__init__): Do not add a "This
	Test" link to the run menu for a resource.
	(ResultPage.MakeRunUrl): Rename to ...
	(ResultPage.GetRunURL): ... this.
	(ResultPage.GetResultURL): ... new method.
	(StorageResultsStream.GetResult): New method.
	(QMTestServer.HandleShowResults): Use it.
	* qm/test/share/dtml/result.dtml: Display links to resources, as
	appropriate.
	* NEWS: Note that links to results are now available.

2002-12-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/web/web.py (NewItemPage.GetClassDescriptions): Use
	self.class_names to get the list of classes.
	* NEWS: Note that "File/New Resource" now operates correctly.

2002-12-02    <Mark Mitchell <mark@codesourcery.com>>

	* qm/test/cmdline.py (QMTest.__ExecuteSummarize): Use binary mode
	to read and write results files.
	(QMTest.__GetExpectedOutcomes): Likewise.
	(QMTest.__FilterTestsToRun): Likewise.

2002-12-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/doc/tour.xml: Update for QM 2.0.

2002-12-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (SetPopupPage): Remove.
	(TupleField.GetValueFromDomNode): Fix typo.
	(TupleField.MakeDomNodeForValue): Likewise.

2002-11-29  Mark Mitchell <mark@codesourcery.com>

	* qm/web.py (WebRequestHandler.__HandleFileRequest): Open files in
	binary mode.
	* qm/test/share/dtml/dir.dtml: Avoid constructs which IE does not
	like.
	* qm/test/share/dtml/navigation-bar.dtml: Support IE event model.
	* qm/test/share/web/images/logo.png: Remove.
	* qm/test/share/web/images/logo.gif: New file.

2002-11-28  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Note that Netscape 4 is no longer a supported browser.
	* doc/manual/common-manual.xml: Likewise.
	* qm/platform_unix.py (open_in_browser): Default to mozilla.
	* qm/web.py (DTMLPage.GenerateEndBody): Remove Problems? link.
	(DTMLPage.MakeMenuItem): Remove.
	(WebRequestHandler.__HandleScriptRequest): Change shutdown
	message.
	* qm/test/share/dtml/dir.dtml: Add logo.
	* qm/test/share/dtml/navigation-bar.dtml: Rework menu logic.
	* qm/test/web/web.py (QMTestPage.__init__): Update menu items to
	use URLs, not JavaScript code.
	* share/dtml/problems.dtml: Remove second parameter to
	GenerateEndBody.
	* share/dtml/user.dtml: Likewise.
	* share/web/common.js (get_left): New function.
	(get_right): Likewise.
	(get_top): Likewise.
	(get_bottom): Likewise.
	(is_parent_of): Likewise.
	* share/web/images/logo.png: New file.
	* share/web/stylesheets/qm.css: Update style for menus.

2002-11-27  Vladimir Prus <ghost@cs.msu.su>

	* qm/test/web/web.py (ResultPage.__init__): Add "This Test" to run
	menu.
	(ResultPage.MakeRunUrl): New method.
	* qm/test/share/dtml/result.dtml (run_test): New method.

2002-11-25  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (load_results): Support pickled results files.
	* qm/test/cmdline.py (xml_result_stream): Don't import it.
	(pickle_result_stream): Do import it.
	(QMTest.__ExecuteRun): Use PickleResultStream.
	* qm/test/pickle_result_stream: New file.
	* qm/test/web/web.py (xml_result_stream): Don't import it.
	(pickle_result_stream): Do import it.
	(QMTestServer.HandleSaveResults): Use PickleResultStream.
	(QMTestServer.HandleSaveExpectations): Likewise.
	* share/dtml/exception.dtml: Remove out-of-date language.

	* qm/test/context.py (ContextException.__init__): Initialize the
	base class.
	* qm/test/result.py (ContextException): Import it.
	(Result.NoteException): Handle ContextExceptions specially.
	* qm/test/target.py (Target.RunTest): But don't do so here.
	* qm/test/text_result_stream.py (TextResultStream.WriteResult):
	Output annotations.
	(TextResultStream._DisplayAnnotations): New method.

2002-11-22  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (Executable.Spawn): Refine previous patch.

	* qm/executable.py (Executable.Spawn): Handle relative pathnames
	in a platform-independent manner.
	(RedirectedExecutable._DoParent): Fix typo.

2002-11-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (is_database): Check more carefully.
	* qm/test/text_result_stream.py (TextResultStream._DisplayResult):
	Show annotations for failing tests even in "brief" mode.
	* tests/QMTest/selfdb.py (RegressionDatabase.GetTestIds): Use
	is_database.
	* tests/QMTest/selftest.py (RegTest.Run): Use <pre> tags to tidy
	output.

2002-11-19  Mark Mitchell  <mark@codesourcery.com>

	* README: Update installation instructions.

2002-11-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py (cPickle): Import it.
	(fcntl): Likewise.
	(select): Likewise.
	(F_GETFD): New constant.
	(F_SETFD): Likewise.
	(FD_CLOEXEC): Likewise.
	(Executable.Spawn): Add exception_pipe parameter.  Return the PID
	of the child.
	(Executable.Run): Create the exception_pipe.
	* qm/platform_unix.py (RunProgramError): Remove.
	(ProgramStoppedError): Likewise.
	(ProgramTerminatedBySignalError): Likewise.
	(replace_program): Likewise.
	(run_program): Likewise.
	(run_program_captured): Likewise.
	* qm/test/classes/process_target.py
	(ProcessTarget.QMTestExecutable): New class.
	(ProcessTarget.Start): Use it.
	* tests/QMTest/selftest.py (RegTest.Run): Use Executable.

2002-11-15 Mark Mitchell <mark@codesourcery.com

	* qm/executable.py (string): Import it.
	(msvcrt): Likewise.
	(pywintypes): Likewise.
	(Executable.Run): Fix typo.
	(Executable._DoParent): Correct Windows logic.
	* qm/test/file_database.py: Use normpath throughout.

2002-11-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/executable.py: New file.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Use
	RedirectedExecutable to encapsulate execution.

	* qm/read_thread.py: New file.
	* qm/write_thread.py: Likewise.
	* qm/test/classes/command.py: Use them.

2002-11-12  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention uniform extension file format.
	* qm/extension.py (parse_dom_element): Extend backwards
	compatibility tricks.
	* qm/test/base.py (_get_db_configuration_path): Remove.
	(is_database): Likewise.
	(load_database): Likewise.
	(create_database): Likewise.
	(count_outcomes): Likewise.
	* qm/test/cmdline.py (QMTest.GetDatabase): Adjust call to
	load_database.
	* qm/test/database.py (get_configuration_file): New function.
	(is_database): Likewise.
	(create_database): Likewise.
	(load_database): Likewise.
	* qm/test/text_result_stream.py (TextResultStream._CountOutcomes):
	New method.
	* qm/test/share/dtds/resource.dtd: Remove.
	* qm/test/share/dtds/target.dtd: Likewise.
	* qm/test/share/dtds/test.dtd: Likewise.
	* qm/test/share/dtds/tdb-configuration.dtd: Likewise.

2002-11-11  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention automatic use of context files.
	* qm/common.py (MapReplacer): Remove.
	(OrderedMap): Likewise.
	(replace_by_map): Likewise.
	(invert_map): Likewise.
	* qm/tetst/cmdline.py (QMTest.MakeContext): Use Context.Read.
	* qm/test/context.py (Context.Read): New method.
	* qm/test/doc/reference.xml: Document automatic use of -C option.

2002-11-06  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (BooleanField): New class.
	* qm/xmlutil.py (ParseError): Remove.
	(load_xml_file): Revise documentation.
	(load_xml): Likewise.
	* qm/test/cmdline.py (__ExecuteSummarize): Handle XML parse errors
	gracefully.
	* qm/test/database.py (Database.arguments): Add modifiable.
	(Database.IsModifiable): New method.
	* qm/test/execution_engine.py (ExecutionEngine._AddResult): Tweak
	handling of resource results.
	* qm/test/file_database.py (FileDatabase._AreLabelsPaths): New
	method.  Use it throughout.
	* qm/test/result.py (Result.RESOURCE_SETUP): New variable.
	(Result.RESOURCE_CLEANUP): Likewise.
	(Result.ACTION): Remove.
	(Result.kinds): Update.
	(Result.NoteException): Use HTML formatting for traceback.
	* qm/test/target.py (Target._RecordResult): Do not record the
	target if it is the local target.
	(Target._SetUpResource): Use RESOURCE_SETUP.
	(Target._CleanUpResource): Use RESOURCE_CLEANUP.
	* qm/test/text_result_stream.py (TextResultStream.WriteResult):
	Tweak handling of resource results.
	(TextResultStream._DisplayResult): Process HTML formatting.
	Adjust calls to _WriteOutcome.
	(TextResultStream._WriteOutcome): Distinguish resource results
	from test results.
	* qm/test/classes/command.py (ExecTestBase.Run): Use HTML
	formatting.
	* qm/test/classes/file_label.py (FileLabel.IsValid): Remove.
	* qm/test/classes/xml_database.py (XMLDatabase._GetTestFromPath):
	Hande XML parse errors gracefully.
	(XMLDatabase._GetResourceFromPath): Likewise.
	* qm/test/share/dtml/result.dtml: Take advantage of HTML
	formatting of annotations.
	* qm/test/web/web.py (QMTestPage.__init__): Do not show editing
	choices if the database is not modifiable.
	* tests/QMTest/.cvsignore: New file.

2002-11-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (Database._LabelToPath): Rename to ...
	(Database.LabelToPath): ... this.
	* qm/test/file_database.py (FileDatabase._GetPathFromLabel):
	Adjust.
	(ExtensionDatabase._GetPathFromLabel): Likewise.
	* qm/test/classes/xml_database.py
	(XMLDatabase.__MakeDataFilePath): Likewise.

2002-10-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/extension.py (make_dom_element): Add element parameter.
	(make_dom_document): New method.
	* qm/test/base.py (dtds): Update.
	* qm/test/database.py: Import Runnable.
	(ItemDescriptor.GetItem): Pass along the test database to the
	newly created item.
	* qm/test/resource.py (Resource): Derive from Runnable.
	(Resource.arguments): Remove.
	* qm/test/result.py: Fix formatting.
	* qm/test/runnable.py (Runnable): New file.
	* qm/test/test.py (Test): Derive from Runnable.
	(Test.arguments): Remove.
	(Test.GetId): Remove.
	* qm/test/classes/command.py (ExecTestBase.GetEnvironment): Be
	careful about what kinds of context variables are propagated into
	the environment.
	* qm/test/classes/file.py (FileContentsTest): Simplify.
	* qm/test/clasess/python.py (ExecTest): Likewise.
	* qm/test/classes/xml_database.py (WriteTest): Just use
	make_dom_document.
	(WriteResource): Likewise.
	* qm/test/doc/reference.xml: Update context documentation.
	* qm/test/web/web.py (QMTestServer): Adjust checking of new test
	names.
	* tests/xmldb/QMTest/.cvsignore: New file.
	* tests/xmldb/QMTest/classes.qmc: Likewise.
	* tests/xmldb/QMTest/test_interface.py: Likewise.
	* tests/xmldb/api.qms/test.qms/test_interface.qmt: Likewise.

2002-10-11  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (check-threads): Create the target file on the
	fly.
	(check-processes): Likewise.
	* qm/attachment.py: Use atexit.
	* qm/common.py (add_exit_function): Remove.
	(exit): Likewise.
	(print_message): Likewise.
	(_exit_functions): Likewise.
	(_foreign_exit_functions): Likewise.
	* qm/extension.py (Extension.__init__): Use
	get_class_arguments_as_dictionary.
	(get_class_arguments): Rework.
	(get_class_arguments_as_dictionary): Likewise.
	(get_class_description): New method.
	(get_extension_class_name): Likewise.
	(validate_arguments): Likewise.
	(make_dom_element): Likewise.
	(parse_dom_element): Likewise.
	* qm/fields.py: Substantial revisions.
	(TupleField): New class.
	(SetField): Rework display logic.
	* qm/qm.sh (QM_PATH): Export it.
	* qm/user.py (XmlDatabase.Write): Tidy.
	* qm/web.py (WebServer.Bind): Use atexit.
	* qm/xmlutil.py (write_dom_document): Remove.
	* qm/test/base.py (get_db_configuration_directory): Remove.
	(_get_db_configuration_path): Update.
	(is_database): Likewise.
	(create_database): Likewise.
	(get_extension_directories): Tidy.
	(get_class_description): Remove.
	* qm/test/cmdline.py: Add create-target option.
	(QMTest.GetTargetFileName): New method.
	(QMTest.GetTargetsFromFile): Likewise.
	(QMTest.GetTargets): Use them.
	(QMTest.__ExecuteCreateTarget): New method.
	* qm/test/database.py (TestDescriptor.__init__): Remove
	prerequisites, categories, resources.
	(TestDescriptor.GetCategories): Remove.
	(Database.GetConfigurationDirectory): New method.
	(get_configuration_directory): New function.
	* qm/test/qmtest.py (print_error_message): Simplify.
	Use sys.exit, not qm.exit.
	* qm/test/resource.py (Resource.kind): New class variable.
	* qm/test/target.py (Target.kind): Likewise.
	(Target.RunTest): Provide more information about interrupted
	tests.
	* qm/test/test.py (Test.kind): New class variable.
	(Test.arguments): Mark "id" as computed.  Add prerequisites.  Add
	resources.
	* qm/test/classes/process_target.py: Use integer fields where
	possible.
	* qm/test/classes/rsh_target.py: Fix typo in comment.
	* qm/test/classes/thread_target.py: Use integer fields where
	possible.
	* qm/test/classes/xml_database.py: Use XML processing code from
	the extension module throughout.
	* qm/test/doc/reference.xml: Update.
	* qm/test/share/dtml/show.dtml: Simplify.
	* qm/test/share/dtml/add-category.dtml: Remove.
	* qm/test/share/dtml/add-prerequisite.dtml: Remove.
	* qm/test/share/dtml/add-resource.dtml: Remove.
	* qm/test/share/messages/diagnostics.txt: Update.
	* qm/test/web/web.py (AddPrerequisitePage): Remove.
	(AddResourcePage): Remove.
	(MakePrerequisitesControl): Likewise.
	(MakeResourcesControl): Likewise.
	(HandleAddPrerequisite): Likewise.
	(QMTestServer.SubmitItem): Simplify.
	* tests/QMTest/selfdb.py (QMSelftestDatabase._QualifyTests):
	Adjust.

2002-09-29  Mark Mitchell  <mark@codesourcery.com>

	* README: Fix formatting.
	* qm/common.py (FileSystemMutex): Remove.
	* qm/common.py (open_temporary_file): Raise QMExceptions, not
	other varieties of Exception.
	(make_temporary_directory): Likewise.
	* qm/fields.py (Field.GetProperty): Likewise.
	* qm/platform.py (MailError): Derive from QMException.
	* qm/platform_unix.py (SignalException.__init__): Fix typo.
	(send_email): Raise QMExceptions.
	(run_program): Likewise.
	(run_program_captured): Likewise.
	* qm/web.py: Likewise.
	(AddressInUseError): Derive from QMException.
	(PrivilegedPortError): Likewise.
	(NoSessionError): Likewise.
	(InvalidSessionError): Likewise.
	* qm/test/base.py (create_database): Allow the creation of
	databases in existing directories.
	* qm/test/cmdline.py (qm.test.web.web): Import it.
	(signal): Likewise.
	(QMTest.daemon_option_spec): New class variable.
	(QMTest.pid_file_option_spec): Likewise.
	(QMTest.commands_spec): Add them.
	(QMTest.ExecuteServer): Handle them.
	* qm/test/qmtest.py: Handle SignalExceptions.
	* qm/test/doc/reference.xml: Add documentation for --daemon and
	--pid-file.
	* qm/test/share/messages/diagnostics.txt: Remove db path exists
	message.
	* qm/test/util/README: New file.
	* qm/test/util/svr4_init/red_hat_linux: Likewise.
	* qm/test/web/web.py: Use qm.test.cmdline.QMTest instead of QMTest
	throughout.

2002-08-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py (ExecutionEngine._CheckForResponse):
	Decrement running here.
	(ExecutionEngine._AddResult): Not here.
	(ExecutionEngine._AddUntestedResult): Do not muck with running here.

2002-08-22  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (check): Use check-serial, check-threads,
	check-processes.
	(check-serial): New target.
	(check-threads): Likewise.
	(check-processes): Likewise.
	* qm/test/cmdline.py (QMTest.Execute): Return a value.
	(QMTest.GetTargets): Handle errors in the target file more
	gracefully.
	(QMTest.__ExecuteRun): Return a value.
	(QMTest.__ExecuteRemote): Likewise.
	(QMTest.__ExecuteSummarize): Likewise.
	(QMTest.__GetExpectedOutcomes): Always return a valid map.
	* qm/test/qmtest.py: Return a non-zero exit code if there are
	unexpected outcomes.
	* qm/test/resource.py (Resource.arguments): Correct use of hidden
	parameter.
	* qm/test/test.py (Test.arguments): Likewise.
	* qm/test/classes/process_target.py (ProcessTarget.arguments): Fix
	typo in default_value for database_path.
	(ProcessTarget.__init__): Fix
	typo.
	(ProcessTarget.Start): Use "self.processes" not "self.concurrency".
	* qm/test/classes/rsh_target.py (RSHTarget.__init__): Likewise.
	* qm/test/classes/thread_target.py (ThreadTarget.arguments): Fix
	use of default_value.
	(ThreadTarget.__init__): Expect "concurrency" to be a string.
	* qm/test/share/dtml/dir.dtml: Fix grammar in displayed message.
	* qm/test/share/messages/diagnostics.txt: Add message.
	* tests/QMTest/thread_target: New file.
	* tests/QMTest/process_target: New file.

2002-08-08  Zack Weinberg  <zack@codesourcery.com>

	Revised test suite.

	* New files:
	tests/QMTest/classes.qmc
	tests/QMTest/selfdb.py
	tests/QMTest/selftest.py
	tests/regress/cycle1/QMTest/configuration
	tests/regress/cycle1/a.qmt
	tests/regress/cycle1/b.qmt
	tests/regress/cycle1/results.qmr
	tests/regress/cycle2/QMTest/configuration
	tests/regress/cycle2/a.qmt
	tests/regress/cycle2/b.qmt
	tests/regress/cycle2/c.qmt
	tests/regress/cycle2/results.qmr
	tests/regress/cycle3/QMTest/configuration
	tests/regress/cycle3/a.qmt
	tests/regress/cycle3/b.qmt
	tests/regress/cycle3/c.qmt
	tests/regress/cycle3/results.qmr
	tests/regress/cycle4/QMTest/configuration
	tests/regress/cycle4/a.qmt
	tests/regress/cycle4/b.qmt
	tests/regress/cycle4/c.qmt
	tests/regress/cycle4/d.qmt
	tests/regress/cycle4/e.qmt
	tests/regress/cycle4/f.qmt
	tests/regress/cycle4/results.qmr
	tests/regress/cycle5/QMTest/configuration
	tests/regress/cycle5/a.qmt
	tests/regress/cycle5/b.qmt
	tests/regress/cycle5/results.qmr
	tests/regress/gilles1/QMTest/configuration
	tests/regress/gilles1/a.qmt
	tests/regress/gilles1/b.qmt
	tests/regress/gilles1/c.qmt
	tests/regress/gilles1/results.qmr
	tests/regress/noresource/QMTest/configuration
	tests/regress/noresource/results.qmr
	tests/regress/noresource/test.qmt
	tests/regress/noresource/test2.qmt
	tests/regress/xml1/QMTest/configuration
	tests/regress/xml1/asdfasdf.qmt
	tests/regress/xml1/fnord.qmt
	tests/regress/xml1/results.qmr
	tests/xmldb/.cvsignore
	tests/xmldb/QMTest/configuration

	* Renamed files from:
	tests/unit.qms/common.qms/format_time1.qmt
	tests/unit.qms/common.qms/graph_complete.qmt
	tests/unit.qms/common.qms/graph_cycle.qmt
	tests/unit.qms/common.qms/graph_pass.qmt
	tests/unit.qms/common.qms/label_is_valid.qmt
	tests/unit.qms/common.qms/label_thunk.qmt
	tests/unit.qms/common.qms/parse_time1.qmt
	tests/unit.qms/common.qms/parse_time2.qmt
	tests/unit.qms/common.qms/parse_time3.qmt
	tests/unit.qms/common.qms/parse_time4.qmt
	tests/unit.qms/common.qms/parser_create.qmt
	tests/unit.qms/common.qms/parser_dup_command_long.qmt
	tests/unit.qms/common.qms/parser_dup_command_short.qmt
	tests/unit.qms/common.qms/parser_help.qmt
	tests/unit.qms/common.qms/parser_no_long.qmt
	tests/unit.qms/common.qms/parser_parse.qmt
	tests/unit.qms/common.qms/parser_two_char_short.qmt
	tests/unit.qms/test.qms/classes.qms/scripttest1.qmt
	tests/unit.qms/test.qms/classes.qms/tempdir1.qma
	tests/unit.qms/test.qms/classes.qms/tempdir1.qmt

	* to:
	tests/xmldb/common.qms/format_time1.qmt
	tests/xmldb/common.qms/graph_complete.qmt
	tests/xmldb/common.qms/graph_cycle.qmt
	tests/xmldb/common.qms/graph_pass.qmt
	tests/xmldb/common.qms/label_is_valid.qmt
	tests/xmldb/common.qms/label_thunk.qmt
	tests/xmldb/common.qms/parse_time1.qmt
	tests/xmldb/common.qms/parse_time2.qmt
	tests/xmldb/common.qms/parse_time3.qmt
	tests/xmldb/common.qms/parse_time4.qmt
	tests/xmldb/common.qms/parser_create.qmt
	tests/xmldb/common.qms/parser_dup_command_long.qmt
	tests/xmldb/common.qms/parser_dup_command_short.qmt
	tests/xmldb/common.qms/parser_help.qmt
	tests/xmldb/common.qms/parser_no_long.qmt
	tests/xmldb/common.qms/parser_parse.qmt
	tests/xmldb/common.qms/parser_two_char_short.qmt
	tests/xmldb/test.qms/classes.qms/scripttest1.qmt
	tests/xmldb/test.qms/classes.qms/tempdir1.qma
	tests/xmldb/test.qms/classes.qms/tempdir1.qmt

	* Modified files:
	GNUmakefile.in (check): Pass -c qmtest_path= to qmtest run.
	tests/QMTest/configuration: Use QMSelftestDatabase.

	* Deleted files:
	tests/common.qms


2002-08-08  Zack Weinberg  <zack@codesourcery.com>

	* qm/test/target.py: Import NoSuchResourceError from
	qm.test.database.
	(Target._SetUpResource): If GetResource throws NoSuchResourceError,
	note the exception and return.

	* qm/common.py (load_module): If imp.load_module fails,
	remove the broken object from sys.modules.

	* qm/label.py (Label.SplitLeft): New method.
	* qm/test/database.py (Database.SplitLabelLeft): New method.
	* qm/test/result.py (Result.Annotate): New method.
	(Result.Fail): Use it.

2002-08-08  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (QMException.__init__): New method.
	(PythonException): New class.
	* qm/test/base.py (get_extension_class_from_directory): Raise
	a PythonException.
	* qm/test/cmdline.py (QMTest.__ExecuteRegister): Handle it.

2002-08-07  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (load_database): Add documentation.  Adjust call
	to get_extension_class.
	(get_extension_directories): Add database_path parameter.  Search
	the QMTest subdirectory of that directory as well.
	(get_extension_class_names): Add database_path parameter.
	(get_extension_class): Likewise.
	* qm/test/cmdline.py (QMTest.__ExecuteExtensions): Pass it.
	(QMTest.__ExecuteRegister): Likewise.

	* qm/test/execution_engine.py
	(ExecutionEngine._CheckForResponse): Update trace message.  Do
	not block.
	(ExecutionEngine._AddResult): Add consistency check.
	(ExecutionEngine._AddUntestedResult): Mark untested tests as
	running before they are marked as untested.

	* qm/test/base.py (get_extension_directories): Make sure the
	QMTest subdirectory of the database is searched
	* qm/test/datbase.py (Database.GetClassPaths): Do not search it
	here.
	* qm/test/doc/reference.xml: Update description of locations
	searched for test classes.

	* GNUmakefile.in (doc-python): Simplify.

	* qm/fields.py (Field.__init__): Check that properties provided
	make sense for this class.

	* qm/test/execution_engine.py (ExecutionEngine.__init__): Set
	__running.
	(ExecutionEngine.RunTests): Use it to detect deadlock.  Remove
	__debug__ guards over all calls to _Trace.
	(ExecutionEngine._AddResult): Decrement running when a test result
	is seen.
	(ExecutionEngine._Trace): Check __debug__ here.
	* qm/test/classes/thread_target (ThreadTarget.__init__): Correct
	typo.
	* qm/test/share/messages/diagnostics.txt: Move dependency cycle
	message here.
	* share/diagnostics/common.txt: Remove it from here.

	* NEWS: Mention "qmtest extensions" and "qmtest register".
	* qm/common.py (load_module): Separate path parameter into
	search_path and load_path.
	(load_class): Likewise.
	* qm/extension.py: New class.
	* qm/test/base.py (dtds): Mention class-directory.
	(load_database): Handle "xmldb.Database" and
	"qm.test.xmldb.Database" specially for backwards compatibility.
	(get_extension_directories): Do not require a database.
	(get_extension_class_from_directory): New method.
	(get_extension_class): Use it.
	(get_class_arguments): Remove.
	(__extension_bases): New variable.
	* qm/test/cmdline.py (QMTest.extension_kind_option_spec): New variable.
	(commands_spec): Add "extensions", "register", and "help".
	(QMTest.Execute): Support them.
	(QMTest.GetDatabase): Instantiate the database if it does not
	already exist.
	(QMTest.GetTargets): Adjust for changes to Target.
	(QMTest.__ExecuteCreateTdb): Adjust name of default database
	class.
	(QMTest.__ExecuteExtensions): New method.
	(QMTest.__ExecuteRegister): Likewise.
	(QMTest.__WriteCommandHelp): New method.
	* qm/test/database.py: Import qm.extension, qm.fields.
	(ItemDescriptor.GetClassArguments): Use
	qm.extension.get_class_arguments.
	(ItemDescriptor._MakeItem): Remove.
	(Database): Inherit from Extension.
	(Database.arguments): New field.
	(Database.__init__): Adjust accordingly.
	* qm/test/file_database.py: (ExtensionDatabase.__init__): Remove.
	(ExtensionDatabase.arguments): New variable.
	(ExtensionDatabase.GetTestExtension): Adjust.
	(ExtensionDatabase.GetSuiteExtension): Likewise.
	(ExtensionDatabase.GetResourceExtension): Likewise.
	(ExtensionDatabase.GetTestPath): Likewise.
	(ExtensionDatabase._IsTestFile): Likewise.
	(ExtensionDatabase._IsSuiteFile): Likewise.
	(ExtensionDatabase._IsResourceFile): Likewise.
	* qm/test/resource.py (Resource): Inherit from Extension.
	(Resource.__init__): Remove.
	(Resource.arguments): Add "id".
	* qm/test/target.py (Target): Inherit from Extension.
	(Target.__init__): Simplify.
	(Target.attributes): New variable.
	(Target.GetName): Adjust.
	(Target.GetGroup): Likewise.
	(Target.GetProperty): Remove.
	* qm/test/test.py (Test): Inherit from Extension.
	(Test.arguments): Add "id".
	(Test.__init__): Simplify.
	(Test.GetTargetGroup): Adjust.
	* qm/test/xmldb.py: Remove.
	* qm/test/classes/classes.qmc: Add xml_database.XMLDatabase.
	* qm/test/classes/file.py (SubstitutionField.__init__): Simplify.
	(FileContentsTest.arguments): Fix typos.
	(FileContentsTest.__init__): Adjust.
	* qm/test/classes/process_target.py (ProcessTarget.__init__):
	Simplify.
	(ProcessTarget.arguments): New variable.
	(ProcessTarget.Start): Adjust.
	* qm/test/classes/python.py (ExecTest.__init__): Adjust.
	(BaseExceptionTest.__init__): Likewise.
	(ExceptionTest.__init__): Likewise.
	(StringExceptionTest.arguments): Fix typo.
	* qm/test/clases/rsh_target.py (RSHTarget.arguments): New variable.
	(RSHTarget.GetInterpreter): Adjust.
	* qm/test/classes/serial_target.py: Adjust class description.
	* qm/test/classes/thread_target.py (ThreadTarget.__init__):
	Adjust.
	(ThreadTarget.arguments): New variable.
	(ThreadTarget.start): Adjust.
	* qm/test/classes/xml_database.py: New file.
	* qm/test/doc/reference.xml: Update to mention new command-line
	options.
	* qm/test/share/dtml/dir.dtml: Correct grammar in displayed pages.
	* qm/test/share/messages/diagnostics.txt: Add more messages.
	* qm/test/web/web.py (ShowSuitePage.__init__): Fix typo.
	(QMTestServer.HandleSubmitItem): Adjust call to get_class_arguments.
	* share/diagnostics/common.txt: New messages.

2002-07-31  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Discuss requirement that classes be listed in classes.qmc.
	* qm/test/share/doc/reference.xml: Update description of extension
	classes.

2002-07-24  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention ProcessTarget.
	* qm/qm.sh (QM_BUILD): Do not override an existing value.
	* qm/test/cmdline.py (QMTest.GetTargets): Adjust handling of
	concurrency values.
	(QMTest.__ExecuteRemote): Likewise.
	* qm/test/execution_engine.py (ExecutionEngine.AddInputHandler):
	New method.
	(ExecutionEngine._CheckForResponse): Dispatch to input handlers if
	appropriate.
	* qm/test/target.py (Target.__init__): Remove concurrency
	parameter.
	(Target.GetConcurrency): Likewise.
	* qm/test/classes/classes.qmc: Add ProcessTarget..
	* qm/test/classes/process_taret.py: New file.
	* qm/test/classes/rsh_target.py: Build atop ProcessTarget
	* qm/test/doc/reference.xml: Describe ProcessTarget.
	* qm/test/share/dtds/target.dtd: Remove concurrency field.

2002-07-23  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (lib-install): Improve portability.

2002-07-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/thread_target.py: Remove tabs.
	* qm/common.py (lock): Import it.
	(__load_module_lock): New variable.
	(load_module): Use it to enforce thread safety when loading
	modules.
	* qm/lock.py: New file.
	* qm/test/execution_engine.py (ExecutionEngine.__init__): Do not
	initialize busy_targets.
	(ExecutionEngine.Run): Add additional trace output.
	(ExecutionEngine._RunTests): Do not use busy_targets.  Use the
	length of idle_targets to detect deadlock.

2002-07-04  Mark Mitchell  <mark@codesourcery.com>

	* NEWS: Mention qmtest run --rerun.
	* qm/test/base.py (get_class_arguments): Remove Python 1.5.2
	compatibility code.
	* qm/test/cmdline.py (QMTest.rerun_option_spec): New class
	variable.
	(QMTest.commands_spec): Use it.
	(QMTest.__ExecuteSummarize): Use __GetExpectedOutcomes.
	(QMTest.__ExecuteRun): Likewise.  Use __FilterTestsToRun.
	(QMTest.__GetExpectedOutcomes): New method.
	(QMTest.__FilterTestsToRun): Likewise.

2002-06-30  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/file_database.py (FileDatabase.GetTestPath): Fix typo.
	(FileDatabase._GetLabelFromBasename): New method.
	(FileDatabase._GetLabels): Use it.
	(ExtensionDatabase._GetLabelFromBasename): New method.

2002-06-28  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/file_database.py (FileDatabase.GetRoot): New method.
	(FileDatabase._GetPathFromLabel): Use it.
	(ExtensionDatabase.GetSuitePath): Likewise.
	(ExtensionDatabase._IsSuiteFile): Likewise.
	(ExtensionDatabase._GetPathFromLabel): Likewise.

	* qm/test/file_database.py (ExtensionDatabase): New class, split
	out from ...
	(FileDatabase): ... here.
	* qm/test/xmldb.py (Database): Use 'ExtensionDatabase' as the
	immediate base class.
	(Database.__init__): Adjust accordingly.

	* qm/common.py (timegm): Remove.

2002-06-24  Zack Weinberg  <zack@codesourcery.com>

	* share/diagnostics/common.txt: Add entry for "dependency cycle".
	* qm/test/execution_engine.py (class ExecutionEngine): Implement
	dependency-cycle detection.

2002-06-21  Zack Weinberg  <zack@codesourcery.com>

	* qm/platform_unix.py: Use URL quoting convention (%xx) to escape
	single quotes.

2002-06-19  Zack Weinberg  <zack@codesourcery.com>

	* qm/xmlutil.py: Use xml.dom.minidom.getDOMImplementation() so
	that writexml() will work when xmlplus is installed.

2002-06-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (sequence_difference): Remove.
	(make_map_from_list): Likewise.
	(purge_keys): Likewise.
	* qm/test/file_database.py (FileDatabase._GetLabels): Use
	JoinLabels, not qm.label.join.
	* qm/test/share/dir.dtml: Remove insertion of "." before test name.

2002-06-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (MethodShouldBeOverriddenError): Remove.
	* qm/test/qmtest.py: Handle NotImplementedError specially.
	* qm/test/share/messages/diagnostics.txt (not implemented): New
	error message.
	* qm/attachment.py: Use NotImplementedError, not
	MethodShouldBeOverriddenError.
	* qm/fields.py: Likewise.
	* qm/user.py: Likewise.
	* qm/test/command_thread.py: Likewise.
	* qm/test/database.py: Likewise.
	* qm/test/file_database.py: Likewise.
	* qm/test/resource.py: Likewise.
	* qm/test/result_stream.py: Likewise.
	* qm/test/target.py: Likewise.
	* qm/test/test.py: Likewise.

	* NEWS: Mention --version option.
	* qm/test/doc/reference.xml: Add --version description.
	* GNUmakefile.in: Fix typo in comment.
	* qm/cmdline.py (CommandParser.__init__): Do not raise exceptions
	on invalid input.
	* qm/common.py (program_name): Initialize it to 'None'.
	* qm/setup_path.py.in (major_version): New variable.
	(minor_version): Likewise.
	(release_version): Likewise.
	* qm/test/cmdline.py (QMTest.version_option_spec): New variable.
	(QMTest.global_options_spec): Add it.
	(QMTest.__version_output): New variable.
	(QMTest.__init__): Add version number parameters.
	(QMTest.__Execute): Handle --version.
	(QMTest._GetVersionString): New method.
	* qm/test/qmtest.py: Remove duplicate import.  Reorder exception
	handling clauses.

	* NEWS: Mention that --random is no longer the default.
	* qm/test/doc/reference.xml: Update accordingly.

	* qm/common.py (shuffle): Remove.
	* qm/test/cmdline.py (whrandom): Do not import.
	(random): Import.
	(QMTest.random_option_spec): New option.
	(QMTest.commands_spec): Use it.
	(QMTest.__ExecuteRun): Only randomize test order if --random is
	present.
	* qm/test/execution_engine.py (ExecutionEngine._RunTests):
	Preserve the order that tests were presented in the test queues.

	* qm/fields.py (Field.__init__): Remove check for valid labels.
	* qm/label.py: Rework completely so that Label is an abstract
	base class.
	* qm/platform_win32.py (default_shell): Correct spelling of
	COMSPEC environment variable.
	* qm/user.py (Group.__init__): Remove check for valid labels.
	* qm/xmlutil.py (load_xml): Remove incorrect comment.
	* qm/test/base.py (validate_id): Remove.
	(load_database): Convert Unicode strings to ordinary strings
	for use as keyword arguments.
	(extension_kinds): Add label.
	* qm/test/cmdline.py (QMTest.__ExecuteRun): Use the empty string,
	not ".", to indicate that all tests should be run.
	* qm/test/database.py: Rework to provide label manipulation
	functions in terms of a particular label class.
	* qm/test/file_database.py: Likewise.
	* qm/test/xmldb.py (Database): Likewise.
	* qm/test/classes/classes.qmc: Add FileLabel and PythonLabel.
	* qm/test/classes/file_label.py: New file.
	* qm/test/classes/python_label.py: Likewise.
	* qm/test/share/dtds/class-directory.dtd: Add labels.
	* qm/test/web/web.py: Adjust manipulation of labels throughout.
	(QMTestPage.GetDatabase): New method.
	(QMTestPage.FormatId): New method.
	* tests/unit.qms/common.qms/label_is_valid.qmt: Update.
	* tests/unit.qms/common.qms/label_thunk.qmt: Likewise.

2002-06-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/execution_engine.py (ExecutionEngine._CheckForResponse):
	Use _UpdateDependentTests.
	(ExecutionEngine._UpdateDependentTests): New method.

2002-06-09  Zack Weinberg  <zack@codesourcery.com>

	* qm/track: Remove .cvsignore files.
	* configure.in: No need to configure gadfly.
	* configure: Regenerate.

2002-05-28  Mark Mitchell  <mark@codesourcery.com>

	* share/web/images/left-arrow.gif: Merge from release-1-1-branch.

	* GNUMakefile.in (PYTHON_PACKAGES): Remove PyXML and xmlrpc.
	* README: Update licensing information about zope-dtml.
	* qm/fields.py (SetField.GetValueFromDomNode): Be tolerant of
	TEXT_NODEs mixed in with the contained elements.
	* qm/qm.sh (QM_PYTHON_FLAGS): Only use -O when running installed
	code; do not use optimization when running from the build tree.
	* qm/trace.py (Tracer.Write): Tweak output format.
	* qm/web.py (xmlrpclib): Do not import it.  Remove XML-RPC
	handling throughout.
	* qm/xmlutil.py: Remove uses of PyXML throughout.
	* qm/test/base.py: Do not default to xmldb for databases that
	have no configuration file.
	(load_results): Do not pass a validate parameter to load_xml.
	* qm/test/database.py (Database.ExpandIds): Tidy.
	* qm/test/execution_engine.py (ExecutionEngine._RunTests): If
	loading a test fails, put the exception traceback in the result.
	* qm/test/xml_result_stream.py (XMLResultStream.WriteResult):
	Use only methods available in DOM, not PyXML extensions.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Add trace
	output.
	(Database.__ParseResourceDocument): Likewise.
	(Database.__GetArgumentsFromDomNode): Likewise.  Be tolerant of
	embedded TEXT_NODEs.
	(Database._Trace): New method.

2002-05-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/track: Remove directory.
	* GNUmakefile.in (QM_TOOLS): Remove QMTrack.

 	Merge from release-1-1-branch.

2002-05-20  Mark Mitchell  <mitchell@doubledemon.codesourcery.com>

	* qm/common.py (load_module): Insert the path appropriate for the
	loaded module in front of the default directories, rather than
	behind them.
	* NEWS: Update it.

2002-05-15  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release (upload): Update Windows logic.

2002-05-14  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release (tag_qm): Return to the top level directory.

	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Correct
	punctuation in error message.
	* scripts/qm-release (upload): Upload manuals, too.
	(build_exec): Use Python 2.2.
	(build_binary): Use zcat.

	* scripts/qm-release: Set the umask before building distributions.

	* scripts/qm-release (upload): New function.
	* config.guess: New file.

	* scripts/qm-release (TAG): Initialize it.

	* configure.in: Use version to get the version number.
	* configure: Regenerated.

	* scripts/qm-release (tag_qm): Overwrite version, rather than
	appending to it.

	* scripts/qm-release (tag_qm): New function.

	* version: New file.

2002-05-12  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/web/web.py (ShowSuitePage.__init__): Add is_new_suite
	parameter.
	(QMTestServer.HandleCreateSuite): Pass it.
	(QMTestServer.HandleShowSuite): Likewise.
	* qm/test/share/dtml/suite.dtml: Make cancellation of new suite
	requests redirect to the main directory page.

2002-05-01  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/file.py (FileContentsTest.fields): Rename to ...
	(FileContentsTest.arguments): ... this.

2002-04-30  Mark Mitchell  <mitchell@doubledemon.codesourcery.com>

	* qm/cmdline.py (CommandParser.ParseCommandLine): Avoid joining
	and splitting command-line arguments.

2002-04-15  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Compute PYTHON_MAJOR and PYTHON_MINOR without
	using here documents inside command substitution.
	* configure: Regenerated.

2002-03-13  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release (build_rpm): Use sudo.
	(TAR_OPTS): Use "root" rather than "0" in owner options.

	* qm/test/cmdline.py (QMTest.MakeContext): Fix typo.
	* NEWS: Note fix.

2002-03-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/common.py (string_types): New variable.

	* qm/test/context.py: Permit Unicode strings throughout.
	* qm/test/result.py: Likewise.

2002-03-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/doc/tour.xml: Update tutorial instructions to reflect
	changes in QMTest 1.1.2.
	* qm/test/share/dtml/set-expectations.dtml: Clarify form.

	* configure.in (PYTHON_MAJOR): Robustify checks.
	(PYTHON_MINOR): Likewise.
	* configure: Regenerated.
	* qm/web.py (DocumentTemplate): Guard import with try-block to
	improve error messages.

2002-03-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/share/dtml/results.dtml: Simplify.
	* qm/test/web/web.py (StorageResultsStream.__init__): Initialize
	__test_results_in_order.
	(StorageResultsStream.WriteResult): Update it.
	(StorageResultsStream.Start): Likewise.
	(StorageResultsStream.GetTestResultsInOrder): New method.
	(TestResultsPage.__init__): Use it.
	(TestResultsPage.GetTotalUnexpected): Take advantage of the fact
	that test_results is now a list, not a dictionary.
	(TestResultsPage.GetResultsWithOutcome): Likewise.
	(TestResultsPage.GetTestIds): Remove.

	* qm/test/web/web.py (StorageResultsStream.Start): Add test_ids
	parameter; remove existing results for tests that are going to be
	re-run.

	* qm/common.py (starts_with): Simplify.
	(ends_with): Likewise.
	(parse_assignment): New function.
	(read_assignments): Likewise.
	* qm/test/cmdline.py (context_file_name): New member.
	(QMTest.MakeContext): Use read_assignments.
	(QMTest.__ParseContextAssignment): Remove.
	(QMTest.__ParseKeywordArgument): Likewise.
	(QMTest.__ExecuteCreateTdb): Use parse_assignment.
	* qm/test/qmtest.py: Tidy interrupted message.
	* qm/test/share/dtml/load-expected-results.dtml: Remove.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/load.dtml: New file.
	* qm/test/share/dtml/navigation-bar.dtml (load_context): New
	function.
	* qm/test/share/dtml/set-expectation.dtml: New file.
	* qm/test/web/web.py (QMTestPage.__init__): Add load context and
	save context functions to the file menu.
	(LoadExpectedResultsPage): Reimplement using load.dtml.
	(LoadResultsPage): Likewise.
	(LoadContxtPage): Likewise.
	(QMTestServer.__init__): Register context load and save URLs.
	(QMTestServer.HandleClearResults): Summarize the new results
	stream.
	(QMTestServer.HandleLoadContext): New method.
	(QMTestServer.HandleSaveContext): Likewise.
	(QMTestServer.HandleSubmitContext): Likewise.
	(QMTestServer._ClosePopupAndRedirect): New method.

	* COPYING: Replace with the GPL.
	Replace all other copyright notices with references to COPYING.
	* README: Note license change.

2002-03-06  Mark Mitchell  <mark@codesourcery.com>

	* GNUMakefile.in (PYTHON_PACKAGES): Remove sgmlop.
	* qm/attachment.py (AttachmentStore.HandleDownloadRequest): Update
	documentation.
	(AttachmentStore.Store): New method.
	(FileAttachmentStore.Store): Likewise.
	(TemporaryAttachmentStore.Add): Rename to ...
	(TemporaryAttachmentStore.Store): ... this.
	* qm/common.py (QMException): New class.
	(MethodShouldBeOverridenError): Derive from it.
	(MutexError): Likewise.
	(MutexLockError): Likewise.
	(ConfigurationError): Likewise.
	(UserError): Likewise.
	(load_class): Raise QMException, not ValueError.
	(make_temporary_directory): Remove FIXME.
	* qm/fields.py (SetField.FormatValueAsHtml): Tidy.
	(AttachmentField.FormatValueAsHtml): Likewise.
	(EnumerationField.MakePropertyControls): Likewise.
	* qm/platform_unix.py (RunProgramError): Derived from QMException.
	(SignalException): Likewise.
	* qm/web.py (qm_bug_system_url): Use the mailing list address.
	(WebServer.__init__): Register self._HandleProblems, not
	_handle_problems.
	(WebServer._HandleProblems): New method.
	(make_set_control): Remove counter manipulations.
	(make_button_for_popup): Don't cache it.
	(make_button_for_cached_popup): New function.
	(_handle_problems): Remove.
	* qm/xmultil.py (xml.dom.minidom): Import it.
	(load_xml): Use it.
	* qm/test/base.py (valid_id): Raise QMException, not RuntimeError.
	(load_database): Raise QMException, not ValueError.  Allow
	attributes to be passed to the database.
	(create_database): Allow attributes to be stored in the database
	configuration file.
	(get_extension_class): Turn ImportError into QMException.
	(load_results): Do not validate the incoming results file.
	* qm/test/cmdline.py (QMTest.attribute_option_spec): New member.
	(QMTest.Execute): Simplify exception-handling.
	(QMTest.__ParseContextAssignment): Break out ...
	(QMTest.__ParseKeywordArgument): ... this method.
	* qm/test/context.py (ContextException): New class.
	(Context.__getitem__): Raise it instead of KeyError.
	* qm/test/database.py (DatabaseError): Derived from QMException.
	(__init__): Do not require an attachment store.
	(Database.GetAttachmentStore): Require that it be overridden.
	* qm/test/file_database.py (FileDatabase.__init__): Remove the
	store parameter.
	* qm/test/qmtest.py (print_errror_message): Indent the message.
	* qm/test/result.py (Result.outcomes): Order from most
	interesting to least interesting.
	* qm/test/target.py (Target.RunTest): Catch ContextException and
	introduce appropriate failure notices.
	* qm/test/test.py (Test.GetId): New method.
	* qm/test/text_result_stream.py (TextResultStream.Summarize): Tidy
	output.
	* qm/test/xmldb.py (Database.__init__): Do not pass down the
	attachment store.
	(Database.GetAttachmentStore): New method.
	* qm/test/classes/command.py (ExecTestBase): Robustify.
	* qm/test/share/dtds/tdb-configuration.dtd: Allow database
	attributes.
	* qm/test/share/dtml/dir.dtml: Rework display.
	* qm/test/share/dtml/navigation-bar.dtml: Simplify.
	* qm/test/share/dtml/result.dtml: Likewise.
	* qm/test/share/dtml/results.dtml: Rework display.
	* qm/test/share/messages/diagnostics.txt (invalid context
	assignment): Remove.
	(invalid keyword assignment): Add.
	(extension class not found): Likewise.
	* qm/test/web/web.py: Rework substantially.
	* scripts/.cvsignore: New file.
	* share/dtml/problems.dtml: Rework to mention mailing list.
	* share/web/common.js (property_add_or_change): Do not
	restrict to valid labels.
	* share/web/images/left-arrow.gif: New file.
	* share/web/stylesheets/qm.css: Update and extend.
	* qm/test/doc/reference.xml: Document -a option to create-tdb.

2002-02-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.Run): Remove exception-handling code.
	* qm/test/cmdline.py (QMTest.expectations_file_name): New
	variable.
	(QMTest.results_file_name): Likewise.
	* qm/test/share/dtml/load-expected-results.dtml: Use it.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/navigation-bar.dtml (handle_menu_select):
	Reset menus after use.
	* qm/test/web/web.py (QMTestPage.__init__): Use
	QMTest.expectations_file_name and QMTest.results_file_name.  Store
	the global QMTest object for DTML pages.
	(QMTestServer.__init__): Use QMTest.expectations_file_name and
	QMTest.results_file_name.

2002-02-13  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (Command.ExecTestBase.RunProgram):
	Make sure that result annotations are stored as strings, not
	integers.

	* qm.spec.in (Release): Increment.

2002-02-13  Vladimir Prus <ghost@cs.msu.su>

	* qm/test/web.py (ShowSuitePage.__init__): Fix typo.
	* qm/test/file_database.py (FileDatabase._GetLabels): Likewise.

2002-01-29  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/result.py (Result.MakeDomNode): Fix typo.
	* qm/test/classes/temporary.py (TempDirectoryResource.__init__):
	Remove.
	(TempDirectoryResource.SetUp): Fix typo.
	(TempDirectoryResource.CleanUp): Likewise.

	* qm/test/database.py (ItemDescriptor._MakeItem): Tell a newly
	created test or resource what its name is.

	* qm/xmlutil.py (discard_node): Remove.
	* qm/test/xml_result_stream.py (XMLResultStream.WriteResult):
	Do not use it.
	* qm/test/qmtest.py: Remove Python 1.5 work-around.
	* qm/test/result.py: Alphabetize annotations in results file.

	* qm/test/cmdline.py (QMTest.MakeContext): Fix spelling of
	context file option.

2002-01-27  Mark Mitchell  <mark@codesourcery.com>

	* README (REQUIREMENTS): Note that Python 2.1 or higher
	is required.
	* README.sources: Remove restriction that software must work with
	Python 1.5.
	* configure.in: Check for Python 2.1 or higher.
	* configure: Regenerated.
	* qm/qm.sh (QM_PYTHON_FLAGS): New variable.
	(qm_python): Check /usr/bin/python2 before falling back to
	the python in the PATH.
	* qm/queue.py: Fix copyright notice.
	* qm/setup_path.py.in: Issue an error if an old version of
	Python is in use.
	* qm/trace.py: New file.
	* qm/test/cmdline.py (QMTest.__init__): Create a trace object.
	(QMTest.GetTracer): Return it.
	* qm/test/commnd_thread.py: Fix copyright notice.
	* qm/test/execution_engine.py: Likewise.
	(ExecutionEngine): Add trace message throughout.
	(ExecutionEngine._Trace): New method.
	* qm/test/target.py (Target.RunTest): Remove unnecessary code.
	* qm/test/doc/reference.xml: Update description of how QMTest
	locates the python interpreter to use.

2002-01-23  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (INSTALL_DIR): Set the mode of the installed
	directory.

2002-01-17  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Issue an error if distutils is not installed.
	* configure: Regenerated.
	* qm/test/doc/tour.xml: Update output display.

	* GNUmakefile.in (SCRIPTS): Add $(SCRIPT_EXT).

2002-01-16  Mark Mitchell  <mark@codesourcery.com>

	* qm/structured_text.py: Substantial changes to support a verbatim
	markup.
	* qm/test/result.py (Result.AsStructuredText): Remove.
	* qm/test/text_result_stream.py (TextResultStream._DisplayResult):
	Do not use it.
	* qm/test/classes/command.py (ExecTestBase): Change name of
	"Expected Standard Error" field to "Standard Error".
	(ExecTestBase.RunProgram): Use verbatim formatting for output
	and standard error annotations.
	* qm/test/doc/tour.xml: Update accordingly.
	* qm/test/share/dtml/result.dtml: Adjust formatting.
	* qm/test/web/web.py (TestResultsPage.FormatResult): Remove.
	(QMTestServer.HandleSaveResults): Fix typos.

2002-01-15  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/xmldb.py (Database.WriteSuite): Fix typo.
	* qm/test/classes/command.py (_make_result_for_exception): Remove.
	(ExecTestBase.RunProgram): Use execvpe, not execve.
	* qm/test/web/web.py (qm.test.suite): Import it.
	(QMTestServer.HandleCreateSuite): Pass the server, not the
	test database, to ShowSuitePage.
	(QMTestServer.HandleShowSuite): Likewise.
	(QMTestServer.HandleSubmitSuite): Use Suite, not qm.test.base.Suite.

	* qm.spec.in (Release): Reset to zero.

	* scripts/qm-release (build_source): Change destination for
	PDF manual.

	* configure.in (QM_MINOR_VER): Increment.
	* configure: Regenerated.

	* scripts/qm-release (build_source): Correct copying of PDF
	documentation.

	* scripts/qm-release (build_source): Correct documentation
	building.

	* GNUmakefile.in (lib-install): Correct installation location
	of classes.qmc.
	* qm/web.py (WebServer.handle_error): New method.

2002-01-07  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Do not build gadfly if it does not exist.

	* scripts/qm-release (build_source): Remove QMTrack from
	the release tarball.

	* NEWS: New file.

	* qm/queue.py: New file.
	* qm/test/base.py (get_extension_class_names_in_directory): Remove
	debugging statement.
	* qm/test/cmdline.py (web.web): Do not import it unconditionally.
	(QMTest.__ExecuteServer): Import it here.
	* qm/test/execution_engine.py (Queue): Do not import it.
	(qm.queue): Import it.
	(ExecutionEngine.__init__): Use qm.queue.Queue, not Queue.Queue.
	(ExecutionEngine.__CheckForResponse): Use qm.queue.Empty, not
	Queue.Empty.

	* qm/test/execution_engine.py (ExecutionEngine.Run): Pass
	self to Target.Start.
	(ExecutionEngine._RunTests): Do not add untested results for
	tests that were not run if immediate termination was requested.
	(ExecutionEngine._AddResult): Do not assume that Result.TARGET
	will be present for all results.
	* qm/test/target.py (Target.Start): Add engine parameter.
	(Target.RunTest): Handle KeyboardInterrupts by stopping the
	execution engine.
	(Target._SetUpResource): Likewise.
	* qm/test/classes/rsh_target.py (RSHTarget.Start): Add engine
	parameter.
	* qm/test/classes/rsh_target.py (ThreadTarget.Start): Likewise.

	* qm/label.py (__label_regex): Add hyphens.
	(__label_regex_with_sep): Likewise.
	* qm/xmlutil.py (discard_node): Implement with
	xml.dom.ext.ReleaseNode.
	* qm/test/context.py (Context.ValidateKey): Allow hyphens.
	* qm/test/execution_engine.py (ExecutionEngine._RunTests): Keep
	the list of idle targets up to date.
	(ExecutionEngine._AddResult): Likewise.
	* qm/test/text_result_stream.py (TextResultStream._DisplayResult):
	Use XPASS and XFAIL where possible.
	(TextResultStream._WriteOutcome): New method.
	* qm/test/classes/ThreadTarget.py (TestResultStream.RunTest): Add
	assertions.
	* qm/test/share/messages/diagnostics.txt: Update documentation
	about labels.
	* qm/test/share/messages/help.txt: Likewise.
	* qm/track/share/messages/diagnostics.txt: Likewise.
	* qm/track/share/messages/help.txt: Likewise.
	* qm/test/doc/reference.xml: Likewise.
	* share/xml/.cvsignore: Add *.dtd.
	* configure.in (AC_PROG_MAKE_SET): Remove.

	* qm/test/share/dtds/result.dtd: Correct version number.

2002-01-06  Zack Weinberg  <zack@codesourcery.com>

	* GNUmakefile.in (PYTHON): Remove unnecessary use of 'env'.
	(clean): Don't use pushd and popd.  Don't delete documentation
	if we didn't build it.
	($(HTML_MANUALS)): Disable use of .tidyrc.
	* configure.in: Add Debian-specific locations of xml.dcl and
	DocBook stylesheets.  Fix typo.
	* configure: Regenerate.

2002-01-04  Mark Mitchell  <mark@codesourcery.com>

	* scripts/qm-release: New file.

2002-01-03  Mark Mitchell  <mark@codesourcery.com>

	* GNUmakefile.in (QM_TOOLS): Compute it automatically.

	* GNUmakefile.in (QM_TOOLS): New variable.
	(MAKEFILE_PRE_IN): Remove.
	(SCRIPTS): Calculate it automatically.
	(DTD_CATALOG): New variable.
	(COMMON_DTDS): Likewise.
	(TOOL_DTDS): Likewise.
	(COPIED_TOOL_DTDS): Likewise.
	(DTDS): Likewise.
	(JADECMD): Likewise.
	(DOCBOOK_MAIN): Remove.
	(DOCBOOK_SOURCES): Likewise.
	(HTMLDIR): Likewise.
	(HTMLINDEX): Likewise.
	(HTMLMANIFEST): Likewise.
	(HTMLTARBALL): Likewise.
	(PRINTDIR): Likewise.
	(PRINTTEX): Likewise.
	(PRINTPDF): Likewise.
	(HTML_MANUALS): New variable.
	(TEX_MANUALS): Likewise.
	(PDF_MANUALS): Likewise.
	(all): Add dependencies.
	(PYTHON_PACKAGES): Use -q option to setup.py.
	(DTD_CATALOG): New taret.
	(COPIED_TOOL_DTDS): Likewise.
	(clean): Clean up more stuff.
	(distclean): Remove GNUmakefile, not Makefile.
	(doc-html): Depend on HTML_MANUALS.
	(HTML_MANUALS): New rule.
	(TEX_MANUALS): Likewise.
	Adjust installation rules.
	* doc/qm-html.dsl: Rename to ...
	* doc/qm-sgml.dsl: ... this.
	* doc/qm-print.dsl: Rename to ...
	* doc/qm-tex.dsl: ... this.
	* doc/manual/introduction.xml: Remove.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* doc/manual/track-email.xml: Likewise.
	* doc/manual/track-manual.xml: Likewise.
	* doc/manual/track-tour.xml: Likewise.
	* qm/.cvsignore: Add build.
	* qm/common.py (rmdir_recursively): Remove bogus assertion.
	(add_exit_function): Simplify.
	(_at_exit): Rename to ...
	(exit): This.
	* qm/diagnostic.py (load_messages): New function.
	(__initialize_module): Tweak.
	* qm/qm.sh: Fix typo in comment.
	* qm/setup.py: Automatically compute names of packages.
	* qm/setup_path.py.in: Add zope-dtml/ExtensionClass build
	directory to list of directories to search in build tree.
	* qm/test/.cvsignore: Remove qmtest-remote.
	* qm/test/cmdline.py (QMTest.commands_spec): Add "remote".
	(QMTest.Execute): Dispatch it.
	(QMTest.__ExecuteRemote): New method.
	* qm/test/qmtest-remote.py: Remove.
	* qm/test/qmtest.py: Use load_messages and qm.exit.
	* qm/test/classes/rsh_target.py (RSHTarget.Start): Use qmtest, not
	qmtest-remote, on the remote system.
	* qm/test/doc/.cvsignore: New file.
	* qm/test/doc/introduction.xml: Likewise.
	* qm/test/doc/manual.xml: Likewise.
	* qm/test/doc/reference.xml: Likewise.
	* qm/test/doc/tour.xml: Likewise.
	* qm/test/share/dtds/class-directory.dtd: New file.
	* qm/test/share/dtds/resource.dtd: Likewise.
	* qm/test/share/dtds/result.dtd: Likewise.
	* qm/test/share/dtds/suite.dtd: Likewise.
	* qm/test/share/dtds/target.dtd: Likewise.
	* qm/test/share/dtds/tdb-configuration.dtd: Likewise.
	* qm/test/share/dtds/test.dtd: Likewise.
	* qm/test/share/dtml/add-category.dtml: Likewise.
	* qm/test/share/dtml/add-prerequisite.dtml: Likewise.
	* qm/test/share/dtml/add-resource.dtml: Likewise.
	* qm/test/share/dtml/context.dtml: Likewise.
	* qm/test/share/dtml/dir.dtml: Likewise.
	* qm/test/share/dtml/expectations.dtml: Likewise.
	* qm/test/share/dtml/load-expected-results.dtml: Likewise.
	* qm/test/share/dtml/load-results.dtml: Likewise.
	* qm/test/share/dtml/navigation-bar.dtml: Likewise.
	* qm/test/share/dtml/new-suite.dtml: Likewise.
	* qm/test/share/dtml/new.dtml: Likewise.
	* qm/test/share/dtml/result.dtml: Likewise.
	* qm/test/share/dtml/results.dtml: Likewise.
	* qm/test/share/dtml/show.dtml: Likewise.
	* qm/test/share/dtml/suite.dtml: Likewise.
	* qm/test/share/messages/diagnostics.txt: Likewise.
	* qm/test/share/messages/help.txt: Likewise.
	* qm/test/share/tutorial/tdb/exec0.qmt: Likewise.
	* qm/test/share/tutorial/tdb/exec1.qmt: Likewise.
	* qm/test/share/tutorial/tdb/exec2.qmt: Likewise.
	* qm/test/share/tutorial/tdb/QMTest/configuration: Likewise.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): New method.
	(QMTestServer.__Init__): Change path to manual.
	* qm/track/qmtrack.py: Use load_messages and qm.exit.
	* qm/track/server.py (WebServer.__init__): Change path to
	manual.
	* qm/track/doc/.cvsignore: New file.
	* qm/track/doc/email.xml: Likewise.
	* qm/track/doc/introduction.xml: Likewise.
	* qm/track/doc/manual.css: Likewise.
	* qm/track/doc/manual.xml: Likewise.
	* qm/track/doc/reference.xml: Likewise.
	* qm/track/doc/tour.xml: Likewise.
	* qm/track/share/dtds/idb-configuration.dtd: Likewise.
	* qm/track/share/dtds/issue-classes.dtd: Likewise.
	* qm/track/share/dtds/issue.dtd: Likewise.
	* qm/track/share/dtds/user.dtd: Likewise.
	* qm/track/share/dtds/users.xml.template: Likewise.
	* qm/track/share/dtds/users.xml.test-values: Likewise.
	* qm/track/share/dtml/add-category-name.dtml: Likewise.
	* qm/track/share/dtml/add-issue-class.dtml: Likewise.
	* qm/track/share/dtml/add-issue-field.dtml: Likewise.
	* qm/track/share/dtml/add-notification-address.dtml: Likewise.
	* qm/track/share/dtml/add-notification-uid.dtml: Likewise.
	* qm/track/share/dtml/config-idb.dtml: Likewise.
	* qm/track/share/dtml/configuration-navigation-bar.dtml: Likewise.
	* qm/track/share/dtml/history.dtml: Likewise.
	* qm/track/share/dtml/index.dtml: Likewise.
	* qm/track/share/dtml/issue-class.dtml: Likewise.
	* qm/track/share/dtml/navigation-bar.dtml: Likewise.
	* qm/track/share/messages/diagnostics.txt: Likewise.
	* qm/track/share/messages/help.txt: Likewise.
	* share/diagnostics/test-help.txt: Remove.
	* share/diagnostics/test.txt: Remove.
	* share/diagnostics/track-help.txt: Remove.
	* share/diagnostics/track.txt: Remove.
	* share/dtml/test: Remove all files.
	* share/dtml/track: Likewise.
	* share/tutorial/test: Likewise.
	* share/xml/.cvsignore: New file.
	* share/xml/CATALOG: Remove.
	* share/xml: Remove all DTDs.
	* tests/unit.qms/test.qms/classes.qms/scripttest1.qmt: Fix
	erroneous XML.

2002-01-02  Mark Mitchell  <mark@codesourcery.com>

	* .cvsignore (standard.mk): Remove.
	(Makefile): Likewise.
	(GNUmakefile): Ignore it.
	* Makefile.in: Rename to ...
	* GNUmakefile.in: ... this.
	* Makefile: New file.
	* standard.mk.in: Remove.
	* doc/.cvsignore (Makefile): Remove.
	* doc/Makefile.in: Remove.
	* doc/design/qmtest/.cvsignore (Makefile): Remove.
	* doc/manual/.cvsignore (Makefile): Remove.
	* doc/manual/Makefile.in: Remove.
	* doc/manual/track-manual.xml: Add user database description.
	* doc/manual/track-tour.xml: Update links.

	* qm/common.py (threading): Do not import it.
	(Lock): Remove.
	(MutexMixin): Likewise.
	* qm/test/cmdline.py (QMTest.__ExecuteRun): Use ExecutionEngine,
	not ExecutionThread.
	* qm/test/command_thread.py: New file.
	* qm/test/database.py (Database): Update documentation.
	* qm/test/execution_engine.py: New file.
	* qm/test/execution_thread.py (ExecutionThread): Move
	majority of contents to execution_engine.py.
	* qm/test/qmtest-remote.py (threading): Do not import it.
	* qm/test/target.py (CommandThread): Remove.
	* qm/test/xmldb.py (Database): Do not inherit from MutexMixin.
	Remove all references to locks and mutexes.
	* qm/test/classes/rsh_target.py (RSHTarget.NoteIdle): Remove.
	(RSHTarget._RecordResult): Mark the target idle when recording
	a test result.
	* qm/test/classes/thread_target.py (qm.test.command_thread):
	Import it.

	* standard.mk.in (TESTFLAGS): Remove.
	(test): Likewise.

2001-12-30  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (AttachmentStore.GetSize): Provide a default
	implementation.
	(FileAttachmentStore): New class.
	* qm/common.py (load_class): Fix typo in error message.
	* qm/xmlutil.py (discard_node): New function.
	* qm/test/base.py (run_test): Remove.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (profile): Do not import it.
	(QMTest.profile_option_spec): Remove.
	(QMTest.GetTargets): Use SerialTarget if concurrent execution has
	not been requested.
	(QMTest.__ExecuteSummarize): Fix typo.
	(QMTest.__ExecuteRun): Improve keyboard interrupt handling.
	* qm/test/context.py (re): Import it.
	(Context.get): Fix typo.
	(Context.ValidateKey): Accept keys that include periods and
	underscores.
	(ContextWrapper.Get): Fix typo.
	* qm/test/database.py (ItemDescriptor._Execute): Allow the context
	to be None.
	(ResourceDescriptor.CleanUp): Do not take a context parameter.
	(Database.GetResource): Fix formatting.
	* qm/test/execution_thread.py: Rework substantially throughout.
	* qm/test/file_database.py (FileDatabase._GetLabels): Simplify.
	* qm/test/qmtest-remote.py: Rework for revised target interface.
	* qm/test/qmtest.py: Improve keyboard interrupt handling.
	* qm/test/resource.py (Resource.CleanUp): Do not take a context
	parameter.
	* qm/test/result.py (Result.RESOURCE): New constant.
	* qm/test/target.py (Target): Rework substantially.
	(CommandThread): Likewise.
	* qm/test/xmldb.py (Database.__init__): Remove create parameter.
	* qm/test/classes/classes.qmc: Add serial_target.SerialTarget.
	* qm/test/classes/rsh_target.py: Rework substantially.
	* qm/test/classes/temporary.py (TempDirectoryResource.SetUp):
	Remember the path to the directory created.
	(TempDirectoryResource.CleanUp): Remove context parameter.
	* qm/test/classes/thread_target.py: Rework substantially.
	* qm/test/web/web.py (QMTestServer.__init__): Do not register
	a download URL if the database does not have an attachment
	store.
	* share/diagnostics/test.txt: Adjust documentation.
	* doc/test-manual.xml: Update description of context.

2001-12-13  Mark Mitchell  <mark@codesourcery.com>

	* qm.spec.in (Release): Increment.

2001-12-12  Mark Mitchell  <mark@codesourcery.com>

	* doc/test-manual.xml: Fix typo.

2001-12-12  Mark Mitchell  <mark@codesourcery.com>

	* PyXML/.cvsignore: New file.
	* doc/qm-opl.xml: Update copyright date.
	* doc/manual/common-manual.xml: Tweak language.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/classes/python.py (ExecTest.Run): Fix typo in comment.
	* share/dtml/set.dtml: Clarify help documentation.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (make_button_for_popup): Spell "resizeable" without
	the "e" in JavaScript code.
	(format_user_id): Likewise.
	* share/dtml/help.dtml (popup_manual): Likewise.
	* share/web/common.js (show_help): Likewise.
	(popup_manual): Likewise.

	* share/dtml/test/result.dtml: Sort the annotations.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (doc-install): Do not assume $(INSTALL) understands
	wildcards.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SCRIPTS): Use backslashes on Windows.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (install): Don't depend on install -D.
	(share-install): Likewise.
	* configure.in (AC_PROG_INSTALL): Remove.
	* configure: Regenerated.
	* standard.mk.in (INSTALL): Define explicitly.
	(INSTALL_DATA): Likewise.
	(INSTALL_PROGRAM): Likewise.
	(INSTALL_SCRIPT): Likewise.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SCRIPTS): Hardwire destination path.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (PYTHON_PACKAGES_INSTALL): Do not attempt
	to set permissions on installed files.

2001-12-11  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (RELINCDIR): New variable.
	(PYTHON_PACKAGES_INSTALL): Use it.
	* standard.mk.in (INSTALLINCDIR): New variable.
	(NATPREFIX): Likewise.

	* Makefile.in (PYTHON_PACKAGES_INSTALL): Use relative paths.
	* README: Document Distutils version required.

	* Makefile.in (SCRIPTS): Fix typo.
	* qm.spec (Release): Increment.

	* Makefile.in (SCRIPTS): Generate files with DOS line-ending
	convention under Windows.
	* doc/manual/introduction.xml: Expand.
	* doc/manual/test-tour.xml: Explain that Cygwin will not work with
	QMTest.

2001-12-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py (TemporaryAttachmentStore.HandleUploadRequest):
	Add type attribute to <script>.
	* qm/web.py (DtmlPage.common_javascript): New variable.
	(DtmlPage.GenerateXMLHeader): New method.
	(DtmlPage.GenerateEndBody): Generate correctl XHTML.
	(DtmlPage.GenerateStartScript): New method.
	(DtmlPage.GenerateEndScript): Likewise.
	(WebRequest): Update extensions_map to map .js to text/javascript.
	(WebServer.__init__): Register "/common.js".
	(WebServer.TranslateRequest): Do not add a trailing '/' unless
	there is going to be something after the '/'.
	(make_set_control): Generate correct XHTML.
	(encode_set_control_contents): Likewise.
	(make_properties_control): Likewise.
	(make_help_link_html): Likewise.
	(make_popup_dialog): Likewise.
	(make_choose_control): Likewise.
	(_common_javascript): Remove.
	(_initialize_module): Likewise.
	* qm/test/web/web.py (QMTestPage.GenerateStartBody): Generate correct
	XHTML.
	* share/dtml: Likewise, for all files.
	* share/web/common.js (property_add_or_change): Change
	documentation text.
	(label_is_valid): Allow periods.
	* share/web/stylesheets/qm.css: Make sure it is valid CSS.

	* standard.mk.in (all): Remove doc.
	(doc): Rename to ...
	(doc-all): ... this.
	* doc/manual/Makefile.in (all): Depend on doc-all.
	* doc/manual/test-tour.xml: Clarify.
	* qm/platform_unix.py (find_in_path): Remove.
	(open_in_browser): Do not use it.
	* qm/web.py (WebServer.__init__): Point '/' at self._HandleRoot.
	(WebServer._HandleRoot): New method.
	(_handle_root): Remove.
	* qm/test/result.py (Result.AsStructuredText): Sort annotations.
	* qm/test/classes/python.py (ExecTest.Run): Give the expression
	for a failing test.
	* qm/test/web/web.py (QMTestServer._HandleRoot): Redirect '/' to
	'/test/dir'.
	* share/diagnostics/common.txt (browser error): Tidy.
	* share/dtml/help.dtml: Arrange for the manual to appear in a
	separate window.
	* share/web/common.js (show_help): Do not create the toolbar.
	* share/web/static/index.html: Remove.
	* share/xml/class-directory.dtd (class): Add target to the list
	of allowed class kinds.

	* configure.in (AC_OUTPUT): Do not create qm/Makefile.
	* configure: Regenerated.
	* scripts/qm-release (QM_INSTALL_DIR): Use an absolute path.

	* Makefile.in (SCRIPTS): Correct typo.
	* gadfly/.cvsignore: Remove.
	* scripts/qm-release: Remove empty directories manually.

	* Makefile.in (SCRIPTS): Generate them here.
	* qm/Makefile.in: Remove.
	* scripts/qm-release (build_source): Tell CVS not to export
	empty directorieds.

	* Makefile.in: Completely rework installation logic.
	* README: Document requirement that GNU Make be used.
	* configure.in (AC_OUTPUT): Do not generate sgmlop/Makefile
	or zope-dtml/ExtensionClass/Makefile.
	* configure: Regenerated.
	* install-sh: Replace contents with the version that comes
	with autoconf.
	* install.py: Remove.
	* standard.mk.in (PYTHON): Add -O.
	(INSTALL_DATA): New variable.
	(INSTALL_DIR): Likewise.
	(INSTALL_PROGRAM): Likewise.
	(INSTALL_SCRIPT): Likewise.
	(SCRIPT_EXT): Likewise.
	(all): Use a double-colon rule.
	* qm/Makefile.in (SCRIPTS): Use SCRIPT_EXT.
	* qm/setup.py: New file.
	* qm/setup_path.py.in: Adjust for new installation location of
	PyXML.
	* qm/web.py (WebRequestHandler): Update extensions_map to
	map .css to text/css.
	* qm/test/classes/classes.qmc: List target classes.
	* scripts/qm-release: Adjust location of installation directory.
	Create tar files with appropriate modes and owners.
	* sgmlop/Makefile.in: Remove.
	* sgmlop/setup.py: List Python modules.
	* share/dtml/test/new-suite.dtml: Fix typo.
	* share/dtml/test/new.dtml: Likewise.
	* share/web/images/sc-logo.png: Remove.
	* xmlrpc/setup.py: New file.
	* zope-dtml/DocumentTemplate/setup.py: Likewise.
	* zope-dtml/ExtensionClass/Makefile.in: Remove.
	* zope-dtml/ExtensionClass/setup.py: Set ext_package.

2001-12-06  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-tour.xml: Tweak explanation of saving
	expectations.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Use
	execvpe to execute programs.

	* qm/test/web/web.py (QMTestServer.HandleSaveResults): Fix
	typos.

	* scripts/qm-release: Fix typo.

  	* scripts/qm-release: Update documentation copying rules.

	* README: Remove stale link.
	* doc/manual/test-tour.xml: Fix typos.
	* qm/Makefile.in (SCRIPTS): Do not hard code prefix.
	* qm/test/cmdline.py: Do not import run.
	* scripts/qm-release (build_exec): New function.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* configure.in: Remove divert statements.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ShellCommandTest): Use
	ShellCommandTest.command_shell, not just command_shell, as a
	context variable.
	(ShellScriptTest): Use ShellScriptTest.script_shell, not just
	script_shell.

2001-12-05  Mark Mitchell  <mark@codesourcery.com>

	* standard.mk.in (PRINTTEX): Fix -- problem with TeX formatting.
	* doc/qm.mod (dashdash): Remove FIXME comment.
	* doc/manual/common-manual.xml: Update.
	* doc/manual/text-manual.xml: Fix command-line reference.
	Spell-check.
	* doc/manual/test-tour.xml: Spell-check.
	* qm/cmdline.py (CommandParser.GetOptionsHelp): Tweak help
	string formatting.
	* qm/platform_unix.py (SignalException): Derive from
	RuntimeError.
	* qm/web.py (DtmlPage.GenerateHtmlHeader): Allow pages to
	insert additional headers.
	(WebServer.Run): Handle exceptions.
	(_handle_root): Fix typo.
	* qm/test/base.py (create_database): Raise a RuntimeError,
	not a ValueError, when something goes wrong.
	* qm/test/cmdline.py (Command._ExecuteRun): Create an
	ExecutionThread to run the tests.
	* qm/test/execution_thread.py: New file.
	* qm/test/run.py: Remove.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Remove
	menu logic.
	(DefaultDtmlPage.GenerateStartBody): Likewise.
	(DtmlPage): Rename to ...
	(QMTestPage): ... this.
	(QMTestPage.__init__): Include menu logic.
	(QMTestPage.GetServer): New method.
	(QMTestPage.GenerateStartBody): Likewise.
	(AddPrerequisitePage): Adjust to use QMTestPage.
	(AddResourcePage): Likewise.
	(ContextPage): Likewise.
	(DirPage): Likewise.
	(ExpectationsPage): Likewise.
	(LoadExpectedResultsPage): Likewise.
	(LoadResultsPage): Likewise.
	(NewItemPage): Likewise.
	(NewSuitePage): Likewise.
	(ResultPage): Likewise.
	(ShowItemPage): Likewise.
	(ShowSuitePage): Likewise.
	(StorageResultStream.__init__): Create lock to guard
	to __test_results and __resource_results.
	(TestResultsPage): Adjust to use QMTestPage.
	(QMTestServer): Pass server to page constructors.
	(QMTestServer.HandleStopTests): New method.
	* share/diagnostics/test.txt: Add execution terminated diagnostic.
	* share/dtml/test/results.dtml: Indicate incomplete vs.
	complete test results.
	* share/web/stylesheets/qm.css (span.warning): New class.

2001-11-29  Mark Mitchell  <mark@codesourcery.com>

	* doc/qm.mod (prompt): Reformat as >, not $.
	* doc/manual/test-tour.xml: Focus more attention on the graphical
	user interface.  Reorganize.
	* qm/fields.py (Field.GetHtmlHelp): Tweak message.
	* qm/web.py (qm_bug_system_url): Use qm.codesourcery.com, not
	qm.software-carpentry.com.
	* qm/test/classes/python.py (ExecTest): Tweak doc string.
	* share/dtml/test/results.dtml: Highligh unexpected results.
	* share/tutorial/test/tdb/exec1.qmt: Change this test so that
	it FAILs, rather than ERRORs.
	* share/web/stylesheets/qm.css (td.unexpected): Set
	background-color.
	(tr.fail): Change background-color.

2001-11-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (TestDescriptor.__init__): Correct
	documentation.
	* qm/test/test.py (TargetGroupField.GetDescription): Remove
	debugging statement.
	* qm/test/xmldb.py (Database.__MakeDomNodeForTest): Remove
	unncessary creation of target-group element.
	(Database.__ParseTestDocument): Do not restore it, either.
	(AttachmentStore.Adopt): Remove.
	* qm/test/web/web.py (QMTestServer.HandeSubmitItem): Remove
	category code.
	* share/dtml/test/show.dtml: Do not display categories.
	* share/xml/test.dtd: Remove target-group attribute.
	* qm/test/classes/command.py (ExecTestBase.RunProgram): Clarify
	error message.

	* PyXML/xml/parsers/xmlproc/xmlproc.py (XMLProcessor.parse_start_tag):
	Handle out-of-data condition correctly.

	* qm/test/base.py (get_class_arguments): Fix typo in comment.
	(get_class_description):
	* qm/test/cmdline.py (Command): Rename to ...
	(QMTest): ... this.
	(_the_qmtest): New variable.
	(QMTest.__init__): Set it.
	(QMTest.GetTargets): Store the resulting list of targets.
	(get_qmtest): New function.
	* qm/test/database.py (Database.GetTestClasses): Rename to
	...
	(Database.GetTestClassNames): ... this.
	(Database.GetResourceClasses): Rename to ...
	(Database.GetResourceClassNames): ... this.
	* qm/test/qmtest.py: Create a QMTest object, not a Command object.
	* qm/test/test.py (TargetGroupField): New class.
	(Test.arguments): Use it.
	* qm/test/web/web.py (NewItemPage.__init__): Adjust for Database
	method name changes.
	(NewItemPage.GetClassDescriptions): New method.
	(ShowItemPage.GetClassDescription): Use get_class_description.
	(ShowItemPage.GetBriefClassDescription): Likewise.
	(QMTestServer.MakeNewTest): Fix typo.
	(QMTestServer.MakeNewResource): Likewise.
	* share/diagnostics/test-help.txt: Update.
	* share/diagnostics/test.txt: Likewise.
	* share/dtml/problems.dtml: Remove references to Software Carpentry.
	* share/dtml/test/new.dtml: Update online help.
	* share/dtml/test/show.dtml: Improve resource formatting.

2001-11-21  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/web/web.py (FormatId): Add documentation.
	* share/dtml/test/result.dtml: Allow navigation on the
	test id.

2001-11-21  Mark Mitchell  <mark@codesourcery.com>

	* README: Document --prefix.  Remove getting started
	documentation.
	* README.sources: Remove obsolete information.  Document
	environment variable format.
	* doc/manual/test-manual.xml: Document environment variables
	used by QMTest.
	* qm/qm.sh: Use QM_PYTHON to find the Python interpreter if
	it is set.
	* qm/test/base.py (get_extension_directories): Change
	QMTEST_CLASSPATH to QMTEST_CLASS_PATH.
	* qm/test/text_result_stream.py (TextResultStream.__init__):
	Display "TEST RESULTS" heading.
	(TextResultStream.WriteResult): Display the
	result of the test immediately.
	(TextResultStream.Summarize): Use _DisplayHeading.
	(TextResultStream._SummarizeResults): Use _DisplayResult.
	(TextResultStream._DisplayResult): New method.
	(TextResultStream._DisplayHeading): Likewise.

2001-11-21  Jeffrey Oldham <oldham@codesourcery.com>
	    Ricardo Anguiano <anguiano@codesourcery.com>

	* README.sources: Fix typo.
	* doc/manual/test-manual.xml: Likewise.

2001-11-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (get_class_arguments): Retrofit to Python 1.5.2.

2001-11-19  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (install): Quote directory names.
	* install.py (scripts): Use .bat extension on Windows.
	(install_package): Include .pyd files on Windows.
	* qm/Makefile.in (SCRIPTS): Generate batch files under Windows.
	* qm/platform.py: Treat unknown platforms as UNIX.
	(get_shell_for_command): New function.
	(get_shell_for_script): Likewise.
	* qm/platform_unix.py (get_shell_for_command): Remove.
	(get_shell_for_script): Likewise.
	* qm/platform_win32.py (default_shell): New variable.
	* qm/test/suite.py (Suite.__init__): Remove unnecessary assertion.
	* qm/test/classes/command.py (ReadThread): New class.
	(WriteThread): Likewise.
	(ExecTestBase.exit_code): Revise documentation.
	(ExecTestBase.Run): Rename to ...
	(ExecTestBase.RunProgram): ... this.  Support Windows.
	(ExecTest.RunProgram): Rename to ...
	(ExecTest.Run): ... this.
	(ShellCommandTest.RunProgram): Rename to ...
	(ShellCommandTest.Run): ... this.
	(ShellScriptTest.RunProgram): Rename to ...
	(ShellScriptTest.Run): ... this.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.RegisterPathTranslation): Do not require
	the target path to be an extant directory.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_SRPM): Remove target.
	* qm.spec.in: Make relocatable, use build root.

2001-11-16  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_TAR_GZ): Modify logic.
	* install.py (bin_handler): Remove.

2001-11-15  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (QM_MAJOR_VER): New variable.
	(QM_MINOR_VER): Likewise.
	(QM_VERSION): Likewise.
	(QM_TAR_GZ): Likewise.
	(CVS_SERVER): Likewise.
	(CVS_REPOSITORY): Likewise.
	(CVS): Likewise.
	(RPM_ARCH): Likewise.
	(RPM_BASE): Likewise.
	(QM_RPM): Likewise.
	(QM_SRPM): Likewise.
	(dist): New target.
	(rpm): Likewise.
	(release): Likewise.
	* configure.in (QM_MAJOR_VER): Substitute it.
	(QM_MINOR_VER): Likewise.
	(QM_RELEASE_VER): Likewise.
	(QM_VERSION): Likewise.
	(DOCBOOK_DTD): Revisit logic.
	(AC_OUTPUT): Generate qm.spec.
	* configure: Regenerated.
	* qm.spec: Remove.
	* qm.spec.in: New file.

2001-11-15  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (check): New target.
	* doc/qm-html.dsl: Fix typo.
	* doc/manual/test-manual.xml: Update for simplifications below.
	* qm/test/base.py (get_class_arguments): New method.
	* qm/test/cmdline.py (Command.Execute): Fix thinko.
	* qm/test/context.py (Context.get): New method.
	(ContextWrapper.get): Likewise.
	* qm/test/database.py (ItemDescriptor.GetClassArguments): New
	method.
	(ItemDescriptor._MakeItem): Use it.
	* qm/test/resource.py (Resource.arguments): Update documentation.
	(Resource.__init__): Simplify.
	* qm/test/test.py (Test.arguments): Update documentation.
	(Test.__init__): Simplify.
	(Test.GetTargetGroup): Update.
	* qm/test/xmldb.py (Database.__GetArgumentsFromDomNode): Use
	get_class_arguments.
	* qm/test/classes/command.py: Update test classes.
	* qm/test/classes/file.py: Likewise.
	* qm/test/classes/python.py: Likewise.
	* qm/test/classes/temporary.py: Update resource classes.
	* qm/test/web/web.py (ShowItemPage.__init__): Update
	documentation.
	(QMTestServer.HandleSubmitItem): Use get_class_arguments.
	(QMTestServer.MakeNewTest): Use get_class_arguments.
	(QMTestServer.MakeNewResource): Use get_class_arguments.

2001-11-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/memory_issue_store.py (IssueStore.__Write): Store
	issues safely.
	* qm/track/triggers/notification.py
	(NotifyFixedTrigger.property_declarations): New attribute.
	(NotifyFixedTrigger.GetRecipientAddresses): Handle empty list.
	(NotifyFixedTrigger.GetRecipientUids): Likewise.
	(NotifyByUidFieldTrigger.Preupdate): Use field_name property.

2001-11-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_unix.py (send_email): Reimplement, with support for
	attachments.

2001-11-09  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/database.py (TestDescriptor.GetTargetGroup): Robustify.

	* doc/manual/test-tour.xml: Clarify command sequence for running
	tests.
	* qm/common.py (find_program_in_path): Use the PATH environment
	variable if no path is specified.
	* qm/test/cmdline.py (Command.HasGlobalOption): Remove.
	(Command.Execute): Normalize the database path.
	* qm/test/database.py (TestDescriptor.__init__): Remove target_group
	parameter.
	(TestDescriptor.GetTargetGroup): Reimplement.
	* qm/test/qmtest.py (print_error_message): Tidy up the message.
	(program_name): Use only the basename.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Correct typo.
	* qm/test/classes/Command.py (ExecTest.Run): Report the expected
	standard output when a test fails.  Do not use the "path"
	context variable.
	* qm/test/web/web.py (QMTestServer.MakeNewTest): Correct typos.
	(QMTestServer.MakeNewResource): Likewise.
	* share/diagnostics/test.txt: Reformat some error messages.

2001-11-08  Mark Mitchell  <mark@codesourcery.com>

	* COPYING: Fix typo.

2001-11-06  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Fix typos.
	* qm/test/base.py (CommandFailedError): Remove.
	(Context): Remove.
	(ContextWrapper): Remove.
	(set_up_resource): Use Result.ACTION, not action, to
	when constructing the result.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add -C and -c
	options to the GUI interface.
	(Command.GetTargets): Remove response_queue parameter.
	(Command.__ExecuteServer): Adjust.
	(Command.__ExecuteRun): Likewise.
	* qm/test/context.py: New file.
	* qm/test/qmtest-remote.py: Likewise.
	* qm/test/result.py (Result.ACTION): New constant.
	* qm/test/run.py (TestRun.Run): New method.
	(test_run): Remove.
	* qm/test/target.py (Target.__init__): Remove response_queue
	parameter.
	(Target.IsInGroup): New method.
	(Target.Start): Add response_queue parameter.
	* qm/test/classes/rsh_target.py (RSHThread._RunTest): Robustify.
	(RSHThread._SetUpResource): Likewise.
	(RSHThread._CleanUpResource): Likewise.
	(RSHThread._Stop): Likewise.
	(RSHTarget.__init__): Adjust documentation.
	(RSHTarget.Start): Add response_queue parameter.
	(ThreadTarget.__init__): Remove response_queue parameter.
	(ThreadTarget.Start): Add response_queue parameter.
	* qm/test/web/web.py (QMTestServer.__init__): Remove
	response_queue parameter.
	(QMTestServer.HandleRunTests): Use TestRun.

2001-11-05  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Add command-line reference for
	"qmtest gui".
	* doc/manual/track-tour.xml: Fix typo.
	* qm/test/base.py (ItemDescriptor): Remove.
	(TestDescriptor): Likewise.
	(ResourceDescriptor): Likewise.
	(Suite): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add -T and -j
	options to the GUI interface.
	(Command.GetTargets): New method.
	(Command.__ExecuteRun): Use it.  Adjust call to test_run.
	(Command.__ExecuteServer): Use GetTargest.
	* qm/test/database.py (ItemDescriptor): New class.
	(TestDescriptor): Likewise.
	(ResourceDescriptor): Likewise.
	* qm/test/directory_suite.py: Adjust module from which to import
	Suite.
	* qm/test/qmtest-remote.py: Simplify target creation.
	* qm/test/run.py (ProtocolError): Remove.
	(TargetSpec): Remove.
	(test_run): Accept Targets, not TargetSpecs.
	(load_target_specs): Remove.
	(_target_spec_from_dom): Remove.
	* qm/test/target.py (Target.__init__): Remove target_spec
	parameter and replace with several others.
	(Target.GetName): Adjust.
	(Target.GetGroup): Likewise.
	(Target.GetConcurrency): Likewise.
	(Target.GetProperties): Likewise.
	(Target.Start): New method.
	(CommandThread.run): Simplify dynamic dispatch.
	* qm/test/xmldb.py: Adjust for changes in locations of descriptors.
	* qm/test/classes/rsh_target.py (RSHTarget.__init__): Adjust
	to match changes to Target.__init__.
	(RSHTarget.Start): New method.
	(RSHTarget.Stop): Join the thread.
	* qm/test/classes/thread_target.py (ThreadTarget.__init__): Adjust
	to match changes to Target.__init__.
	(ThreadTarget.Start): New method.
	* qm/test/web/web.py (QMTestServer.__init__): Accept targets as
	a parameter.
	(QMTestServer.HandleRunTests): Use them.

	* qm/test/base.py (InstanceBase): Rename to ...
	(InstanceDescriptor): ... this.
	(TestDescriptor): Derive from InstanceDescriptor.
	(ResourceDescriptor): Likewise.
	(extension_kinds): Add "target".
	* qm/test/cmdline.py: Use "ThreadTarget" not "SubprocessTarget".
	* qm/test/qmtest-remote.py: Adjust for reworking of target
	machinery.
	* qm/test/run.py (CommandThread): Remove.
	(Target): Likewise.
	(LocalThread): Likewise.
	(SubprocessTarget): Likewise.
	(RemoteThread): Likewise.
	(RemoteShellTarget): Likewise.
	(TestRun.Schedule): Simplify.
	(TestRun.AddResult): Likewise.
	(TestRun.__TargetIsReady): Remove.
	(test_run): Simplify.
	* qm/test/target.py: New file.
	* qm/test/classes/rsh_target.py: Likewise.
	* qm/test/classes/thread_target.py: Likewise.

2001-10-29  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/resource.py: New file.

	* doc/manual/test-manual.xml: Fix typo.
	* qm/test/base.py (InstanceBase.__init__): Remove properties
	parameter.
	(InstanceBase.SetProperty): Remove.
	(InstanceBase.GetProperty): Remove.
	(InstanceBase.GetProperties): Likewise.
	(InstanceBase.MakeItem): Add target_group parameter.
	(TestDescriptor.__init__): Adjust accordingly.
	(TestDescriptor.GetTargetGroup): New method.
	(ResourceDescriptor.__init__): Remove properties parameter.
	* qm/test/run.py (Target.Stop): Adjust comment.
	(SubprocessTarget.Stop): Remove assertion.
	(RemoteShellTarget.Stop): Likewise.
	(TestRun.Schedule): Use GetTargetGroup, not properties, to
	get the tests target group.
	(TestRun.GetTestResults): Remove.
	(TestRun.GetResourceResults): Remove.
	(TestRun.__ValidateTest): Always check the target group.
	(TestRun.__FindBestTarget): Adjust documentation.  Simplify
	handling of target groups.
	(test_run): Adjust documentation.  Do not return results.
	Terminate targets in the event of an exception.
	* qm/test/test.py: Fix comments.
	(Test.arguments): Add target_group field.
	(Test.__init__): Adjust accordingly.
	(Test.GetTargetGroup): New method.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Retrieve
	the target group.  Do not look for properties.
	(Database.__ParseResourceDocument): Likewise.
	(Database.__MakeDomNodeForItem): Do not write out properties.
	* qm/test/classes/command.py (ExecTest.arguments): Include
	Test.arguments.
	(ExecTest.__init__): Adjust accordingly.
	(ShellCommandTest.__init__): Likewise.
	(ShellScriptTest.__init__): Likewise.
	* qm/test/classes/file.py (FileContentsTest): Derived from Test.
	(FileContentsTest.arguments): Include Test.arguments.
	(FileContentsTest.__init__): Adjust accordingly.
	* qm/test/classes/python.py (ExecTest.arguments): Include
	Test.arguments.
	(ExecTest.__init__): Adjust accordingly.
	(BaseExceptionTest.arguments): Include Test.arguments.
	(BaseExceptionTest.__init__): Adjust accordingly.
	(ExceptionTest.arguments): Include Test.arguments.
	(BaseExceptionTest.__init__): Adjust accordingly.
	* qm/test/classes/temporary.py (TempDirectoryResource): Derive
	from Resource.
	* qm/test/web/web.py (QMTestServer.HandleSubmitItem): Do not
	deal with properties.
	* share/dtml/test/show.dtml: Remove properties handling.
	* share/xml/resource.dtd: Remove properties.
	* share/xml/test.dtd: Likewise.  Add target-group.

	* qm/test/qmtest.py: Remove the first directory from sys.path.

2001-10-28  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/track-manual.xml: Revise section on issue IDs.
	* doc/manual/track-tour.xml: Likewise.
	* qm/track/cmdline.py (Command.__PerformCreate): Assign issue
	IDs automatically.
	(Command.__HandleServerOptions): Add default_port parameter.
	(Command.__PerformConfigureIdb): By default, only allow
	connections from localhost.
	* qm/track/issue_class.py (IssueClass.__init__): Add next_id
	parameter.  Make the iid field hidden.
	(IssueClass.AllocateNextId): New method.
	(IssueClass.MakeDomNode): Write out the next available ID.
	(from_dom_node): Read it back in.
	* qm/track/web/show.py (handle_submit): Assign issue IDs
	automatically.
	* share/diagnostics/track.txt: After creating an issue database,
	tell the user how to configure it.
	* share/xml/issue-classes.dtd (issue-class): Add next-id
	attribute.

2001-10-27  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/test-manual.xml: Note that -D is no lnoger required.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/cmdline.py (Command.Execute): If no database is
	specified, assume the database is in the current directory.
	* qm/test/xmldb.py (GetResource): Fix typo.
	* qm/test/web/web.py (DirPage.__init__): Do not show implicit
	test suites.
	(DirPage.MakeRunUrl): New method.
	* share/dtml/test/dir.dtml (run_dir): New method.

	* qm/.cvsignore: Add *.pyo.
	* qm/test.cvsignore: Likewise.
	* qm/test/classes/.cvsignore: Likewise.
	* qm/test/web/.cvsignore: Likewise.
	* qm/track/.cvsignore: Likewise.
	* qm/track/triggers/.cvsignore: Likewise.
	* qm/track/web/.cvsignore: Likewise.

	* qm/test/base.py (InstanceBase.__init__): Take 'database' as a
	parameter.
	(TestDescriptor.__init__): Likewise.
	(ResourceDescriptor.__init__): Likewise.
	(Suite.__init__): Likewise.
	(Suite.GetAllTestAndSuiteIds): New method.
	(get_suite_contents_recursively): Remove.
	(expand_ids): Likewise.
	(get_database): Likewise.
	(load_database): Return the new database.
	(get_extension_directories): Take the database as a parameter.
	(get_extension_class_names): Likewise.
	(get_test_class): Likewise.
	(get_resource_class): Likewise.
	(make_new_test): Remove.
	(make_new_resource): Likewise.
	(_database): Remove.
	* qm/test/cmdline.py (Command.Execute): Remember the newly loaded
	database.
	(Command.GetDatabase): Adjust.
	* qm/test/database.py (Database.GetTestClasses): Adjust
	call to get_extension_class_names.
	(Database.GetResourceClasses): Likewise.
	(Database.ExpandIds): New method.
	* qm/test/directory_suite.py (DirectorySuite.__init__): Take
	the database as a parameter.
	* qm/test/run.py (Target.__init__): Take the database as
	a parameter.
	(SubprocessTarget.__init__): Likewise.
	(RemoteShellTarget.__init__): Likewise.
	(TestRun.__init__): Likewise.
	(test_run): Likewise.
	(_send): Remove.
	(_receive): Likewise.
	* qm/test/text_result_stream.py (TextResultStream.__init__): Take
	the database as a parameter.
	* qm/test/xmldb.py (Database): Adjust for removal of global
	database variable.
	* qm/test/web/web.py: Likewise.

2001-10-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml (track-email): New entity.
	* doc/manual/track-manual.xml: Reference it (but commented out).
	* doc/manual/track-email.xml: New file.

2001-10-20  Mark Mitchell  <mark@codesourcery.com>

	* qm/doc/manual/common-manual.xml: Adjust configuration file
	description.
	* qm/test/base.py (load_outcomes): Take a file object, not a path.
	* qm/test/cmdline.py (Command.__ExecuteRun): Adjust.
	(Command.__ExecuteSummarize): Likewise.
	* qm/test/web/run.py (TestResultsPage): Take expected_outcomes
	as a parameter.
	* qm/test/web/show.py (ShowPage.__init__): Adjust menu item
	handling.
	* qm/test/web/suite.py (ShowPage.__init__): Adjust menu item
	handling.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Add menu items
	for loading and saving expectations.
	(ExpectationsPage): New class.
	(LoadExpectedResultsPage): Likewise.
	(QMTestServer.__init__): Add support for loading and saving
	expectations.
	(QMTestServer.GetExpectedOutcomes): New method.
	(QMTestServer.HandleEditExpectations): Likewise.
	(QMTestServer.HandleLoadExpectedResults): Likewise.
	(QMTestServer.HandleSaveExpectations): Likewise.
	(QMTestServer.HandleRunTests): Pass expected outcomes to
	TestResultsPage.
	(QMTestServer.HandleSubmitExpectations): New method.
	(QMTestServer.HandleSubmitExpectationsForm): Likewise.
	* qm/share/dtml/test/expectations.dtml: New file.
	* qm/share/dtml/test/load-expected-results.dtml: Likewise.
	* qm/share/dtml/test/navigation-bar.dtml (handle_menu_select):
	Simplify menu handling.

2001-10-19  Mark Mitchell  <mark@codesourcery.com>

	* qm/doc/test-manual.xml: Update for changes to GUI.
	* qm/test/base.py (load_outcomes): Adjust for changes to ...
	(load_results): ... this function.  Take a file object, not
	a path, as input.  Return one combined sequence of all results.
	* qm/test/cmdline.py (Command.__ExecuteSummarize): Adjust
	accordingly.
	* qm/test/web/web.py (DefaultDtmlPage): Add loading and
	saving results to the file menu.
	(LoadResultsPage): New class.
	(QMTestServer.__init__): Add support loading and saving
	results.
	(QMTestServer.HandleLoadResults): New method.
	(QMTestServer.HandleSaveResults): Likewise.
	(QMTestServer.HandleSubmitResults): Likewise.
	* share/dtml/test/load-results.dtml: New file.
	* share/dtml/test/navigation-bar.dtml: Add support for
	loading results.
	* share/web/common.js: Fix HTML.

	* qm/web.py (DtmlPage.MakeMenuItem): New method.
	(WebRequestHandler): Print thank you message when shutting down.
	(WebServer.Bind): Remove getsockname call.
	* qm/test/web/show.py (ShowPage.__init__): Add menu items.
	(ShowPage.MakeEditUrl): New method.
	(ShowPage.MakeRunUrl): Likewise.
	(ShowPage.MakeDeleteScript):  Fix comment.
	* qm/test/web/suite.py (ShowPage.__init__): Add menu items.
	(ShowPage.MakeEditUrl): New method.
	(ShowPage.MakeRunUrl): Likewise.
	(ShowPage.MakeDeleteScript):  Fix comment.
	* qm/test/web/web.py (DefaultDtmlPage.__init__): Set up menu
	items.
	(DefaultDtmlPage.GenerateStartBody): Provide the menu items to
	the navigation bar.
	(QMTestServer.__init__): Handle show-results.  Store results
	permanently.
	(QMTestServer.HandleRunTests): Treat an empty set of test
	ids as the "." test suite.  Use HandleShowResults to implement
	results display.
	(QMTestServer.HandleShowResults): New method.
	* share/dtml/test/dir.dtml: Rework for menus.
	* share/dtml/test/navigation-bar.dtml: Likewise.
	* share/dtml/test/results.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.

	* qm/platform_win32.py (open_in_browser): Implement.

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/test-manual.xml (sec-specifying-test-class): Update.

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (_get_db_configuration_directory): Rename to...
	(get_db_configuration_directory): ... this.
	Update accordingly throughout.
	* qm/test/database.py (Database.GetClassPaths): Rewrite.
	* qm/test/xmldb.py (Database.GetClassPaths): Use base class
	implementation.

2001-10-19  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (load_xml_file): Don't handle exceptions here.
	* qm/web.py (WebRequestHandler.do_POST): Expand fields here.
	(WebRequestHandler.__HandleXmlRpcRequest): Dump exception if
	verbose.
	(parse_form_query): Remove.
	* qm/structured_text.py (StructuredTextProcessor.NormalizeSpaces):
	Remove FIXME.  Expand tabs.
	(__entity_char_regex): Remove FIXME.
	* qm/platform.py (open_in_browser): Remove.
	* qm/platform_win32.py (open_in_browser): Remove.
	* qm/platform_unix.py (get_user_name): Reimplement.
	* qm/fields.py (Field.MakePropertyControls): Remove FIXME.
	(TextField.CompareValues): Likewise.
	* qm/common.py (RcConfiguration): Remove FIXME.
	(format_traceback): Likewise.
	(find_program_in_path): Use os.pathsep.  Use is_executable.
	(is_executable): Rewrite.
	(split_argument_list): Remove FIXME.
	(parse_time): Change FIXME to note.
	* qm/track/server.py (_script_base): Remove FIXME.
	* qm/track/issue_database.py (open): Remove FIXMEs.
	* qm/track/cmdline.py (Command.__PerformCreate): Remove FIXME.
	(Command.__PerformCreateIdb): Likewise.
	(Command.__ImportIssues): Likewise.
	* qm/track/web/query.py (QueryPage.MakePythonQueryHelp): Remove
	FIXME.
	(QueryPage.MakeCategorySelect): Likewise.
	(QueryPage.MakeStateSelect): Likewise.
	* qm/track/web/issue_class.py: Remove FIXME.
	(handle_submit_class): Remove FIXME.  Don't try to handle new
	issue classes here.
	* qm/track/triggers/notification.py
	(NotifyFixedTrigger.GetSubscriberAddresses): Remove FIXME.
	(NotifyByUidFieldTrigger.GetSubscriberAddresses): Likewise.
	* qm/test/result.py (Result.MakeDomNode): Update comment.
	* qm/test/cmdline.py (Command.tdb_class_option_spec): New
	attribute.
	(Command.commands_spec): Add create-tdb.  Alphabetize.
	(Command.Execute): Reorganize.  Handle create-tdb.
	(Command.__ExecuteCreateTdb): New.
	(Command.__ExecuteRun): Remove FIXME.
	* qm/test/base.py (dtds): Add tdb-configuration.
	(_get_db_configuration_directory): New function.
	(_get_db_configuration_path): Likewise.
	(is_database): Likewise.
	(load_database): Use them.
	(create_database): Change database directory semantics.
	(_result_from_dom): Remove FIXME.
	* qm/test/web/web.py (QMTestServer.HandleRunTests): Remove FIXME.
	* qm/test/classes/command.py (make_result_for_exception): Rename
	to...
	(_make_result_for_exception): ... this.  Comment it.
	Update accordingly throughout.
	* share/xml/tdb-configuration.dtd (class_name): Rename to...
	(class-name): ... this.
	* share/diagnostics/common.txt (xmlrpc exception): New
	diagnostic.
	* share/diagnostics/test.txt (new db message): Likewise
	(not test database): Likewise.
	* doc/manual/test-manual.xml (sec-testcmd-create-tdb): New
	section.
	(sec-reg-writing-database-classes): Update.
	* doc/manual/test-tour.xml (sec-testtut-setting-up): Likewise.
	* tests/QMTest: New directory.
	* tests/QMTest/configuration: New file.

2001-10-18  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/run.py (CommandThread.__init__): Initialize Queue
	in a way that works with Python 1.5.2.
	(test_run): Likewise.

	* qm/test/result.py (Result.GetCause): New function.
	(Result.keys): Fix typo.
	* qm/test/web/run.py (TestResultsPage): Do not derived from
	ResultStream.
	(TestResultsPage.GetOutcomes): New function.
	(TestResultsPage.GetTotal): Likewise.
	(TestResultsPage.GetTotalUnexpected): Likewise.
	(TestResultsPage.GetResultsWithOutcome): Likewise.
	(TestResultsPage.GetCount): Likewise.
	(TestResultsPage.GetUnexpectedCount): Likewise.
	(TestResultsPage.GetRelativeResults): Likewise.
	(TestResultsPage.GetDetailUrl): Likewise.
	* qm/test/web/web.py (ResultPage): New class.
	(StorageResultsStream): Likewise.
	(QMTestServer.HandleRunTests): Use it.
	(QMTestServer.HandleShowResult): New function.
	* share/dtml/test/result.dtml: New file.
	* share/dtml/test/results.dtml: Revise.

2001-10-18  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Mention quotes for string literals.

2001-10-17  Mark Mitchell  <mark@codesourcery.com>

	* qm/fields.py (SetField.__init__): Fix typo in comment.

	* qm/web.py (make_properties_control): Sort the keys.  Pass
	more information to JavaScript functions.
	* qm/test/cmdline.py (Command._ExecuteServer): Use QMTestServer,
	not make_server.
	* qm/test/web/dir.py (DirPage.__init__): Add the "." suite at
	the top level.
	* qm/test/web/run.py (handle_run_tests): Remove.
	* qm/test/web/web.py (make_server): Turn into ...
	(QMTestServer): ... new class.
	(handle_shutdown): Turn into ...
	(QMTestServer.HandleShutdown): ... this.
	(ContextPage): New class.
	* qm/share/dtml/test/context.dtml: New file.
	* qm/share/dtml/test/dir.dtml: Add "Edit Context" button.
	* qm/share/web/common.js (property_add_or_change): Clear
	the name/value fields after an addition.
	(property_remove): Likewise.

2001-10-16  Mark Mitchell  <mark@codesourcery.com>

	* install.py: Install the class manifest.

	* qm/async.py: Remove.
	* qm/common.py (parse_time): Handle Windows format for GMT.
	* qm/qm.sh: Handle qmtest-remote correctly.
	* qm/test/base.py (set_up_resource): Fix typo.
	(clean_up_resource): Likewise.
	* qm/test/qmtest-remote.py: Rework to avoid use of qm.async.
	* qm/test/run.py (CommandThread): New class.
	(Target.GetChannels): Remove.
	(Target.EnqueueRunTest): Use EnqueueCommand, not _EnqueueCommand.
	(Target.EnqueueSetUpResource): Likewise.
	(Target.EnqueueCleanUpResource): Likewise.
	(Target.OnReplyReady): Rename to ...
	(Target.OnReply): ... this.  Rework.
	(LocalThread): New class.
	(SubprocessTarget): Use it throughout.
	(RemoteThread): New class.
	(RemoteShellTarget): Use it throughout.
	(RemoteDemultiplexerTarget): Remove.
	(TestRun.AddTestResult): Fold with ...
	(TestRun.AddResourceResult): ... into ...
	(TestRun.Result): ... this.
	(test_run): Adjust.
	(process_commands): Remove.
	* qm/test/classes/command.py (ExecTest): Adjust file closing
	for exception safety.

2001-10-14  Mark Mitchell  <mark@codesourcery.com>

	* qm/share/web/stylesheets/qm.css: Modify to work with Internet
	Explorer.

	* qm/web.py (WebServer.TranslateRequest): Use os.path.isabs
	for robustness.

	* qm/common.py (RcConfiguration.__Load): Do not crash if the
	HOME environment variable is not defined.

	* doc/manual/common-manual.xml: Revise.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-reference.xml: Remove.
	* doc/manual/test-tour.xml: Revise.
	* doc/manual/track-tour.xml: Revise.
	* doc/manual/track-reference.xml: Merge into...
	* doc/manual/track-manual.xml: ... here.

2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml (track-reference): New entity.
	Reference it.
	* doc/manual/track-manual.xml (sec-qmtrack-configuration): New
	section.
	* doc/manual/track-reference.xml: New file.

2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* configure.in (DOCBOOK_DTD): Look for it in the standard place.
	* configure: Regenerate.

2001-10-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (FieldPropertyDeclaration): Rename to...
	(PropertyDeclaration): ... this.
	Adjust accordingly throughout.
	* qm/track/server.py (make_server): Use
	handle_shutdown_by_administrator.
	(handle_shutdown): Rename to...
	(handle_shutdown_by_administrator): ... this.
	(handle_shutdown): New function.
	* qm/track/issue_database.py (setup_for_test): Use
	SetSubscriptionCondition.
	* qm/track/issue_class.py (Trigger.class_name): New variable.
	(Trigger.property_declarations): Likewise.
	(Trigger.__init__): Rewrite.
	(Trigger.GetProperty): New method.
	(Trigger.SetProperty): Likewise.
	(Trigger.GetName): Use GetProperty.
	(Trigger.MakeDomNode): New method.
	(StateField.property_declarations): Adjust for
	PropertyDeclaration.
	(IssueClass.GetField): Fix error code.
	(IssueClass.MakeDomNode): Store triggers.
	(trigger_from_dom_node): New function.
	(from_dom_node): Load triggers.
	* qm/track/triggers/state.py (Trigger.class_name): New variable.
	(Trigger.property_declarations): Likewise.
	(Trigger.__init__): Pass propertis to parent.  Don't use object
	attributes.
	(Trigger.Preupdate): Use GetProperty.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.property_declarations): New variable.
	(_NotifyTrigger.__init__): Pass properties to parent.  Don't use
	object attributes.
	(_NotifyTrigger.GetCondition): Use GetProperty.
	(_NotifyTrigger.SetFromAddress): Use SetProperty.
	(_NotifyTrigger.SetSubjectPrefix): Use GetProperty.
	(_NotifyTrigger.Postupdate): Likewise.
	(NotifyFixedTrigger.class_name): New variable.
	(NotifyFixedTrigger.__init__): Pass properties to parents.  Don't
	use object attributes.
	(NotifyFixedTrigger.GetSubscriberAddresses): Use user database.
	(NotifyFixedTrigger.SetRecipientAddresses): New method.
	(NotifyFixedTrigger.GetRecipientAddresses): Use GetProperty.
	(NotifyFixedTrigger.SetRecipientUids): new method.
	(NotifyFixedTrigger.GetRecipientUids): Use GetProperty.
	(NotifyFixedTrigger.AddRecipientAddress): Use GetRecipientAddress
	and SetRecipientAddress.
	(_NotifyByFieldTrigger.property_declarations): New variable.
	(_NotifyByFieldTrigger.__init__): Pass properties to parent.
	Don't use object attributes.
	(_NotifyByFieldTrigger.GetFieldName): New method.
	(_NotifyByFieldTrigger.GetFieldContents): Use it.
	(NotifyByAddressFieldTrigger.class_name): New variable.
	(NotifyByAddressFieldTrigger.__init__): Pass properties to
	parent.  Don't use object attributes.
	(NotifyByUidFieldTrigger.class_name): New variable.
	(NotifyByUidFieldTrigger.property_declarations): Likewise.
	(NotifyByUidFieldTrigger.__init__): Pass properties to parent.
	Don't use object attributes.
	(NotifyByUidFieldTrigger.SetAutomaticSubscription): Rename to...
	(NotifyByUidFieldTrigger.SetSubscriptionCondition): ... this.
	(NotifyByUidFieldTrigger.GetAutomaticSubscriptionCondition):
	Rename to...
	(NotifyByUidFieldTrigger.GetSubscriptionCondition): ... this.
	(NotifyByUidFieldTrigger.Preupdate): Use accessor.
	* qm/track/triggers/discussion.py (DiscussionTrigger.class_name):
	New variable.
	(DiscussionTrigger.property_declarations): Likewise.
	(DiscussionTrigger.__init__): Pass properties to parent.  Don't
	use object attributes.
	(DiscussionTrigger.Preupdate): Use GetProperty.
	* qm/track/web/issue_class.py (handle_submit_subscription): Use
	SetSubscriptionCondition.
	* share/dtml/track/config-idb.dtml: Add shutdown button.
	* share/xml/issue-classes.dtd (issue-class): Add triggers.
	(trigger): New element.

2001-10-12  Mark Mitchell  <mark@codesourcery.com>

	* doc/manual/introduction.xml: Revise.
	* doc/manual/manual.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.
	* qm/test/cmdline.py (Command.db_path_option_spec): Change
	--db-path to --tdb.
	(Command.start_browser_option_spec): Remove.
	(Command.no_browser_option_spec): New variable.
	(Command.commands_spec): Adjust summarize command syntax.
	Rename server to gui.
	* qm/test/text_result_stream.py (TextResultSream.Summarize): Tweak.
	* qm/test/classes/file.py (FileContentsTest.Run): Fix typo.
	* share/diagnostics/test-help.txt: Revise description of
	test classes.
	* share/dtml/test/new.dtml: Revise.
	* share/tutorial/test/tdb/exec1.qmt: Right code that throws an
	exception, rather than simply computing an incorrect value.
	* share/tutorial/test/tdb/_classes/count.py: Revise for new test
	class API.

2001-10-11  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (set_up_resource): Set up the action
	annotation when the result is created.
	* qm/test/base.py (clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteRun): Use unbufferred
	output for the results file.
	* qm/test/result.py (Result.__init__): Correct handling of
	default parameter.
	* qm/test/classes/command.py (Command.Run): Fix typos.

	* qm/test/base.py (base.dtds): Change version number for
	result DTD.
	(write_results): Remove.
	(save_results): Likewise.
	(_test_results_from_dom): Likewise.
	(_resource_results_from_dom): Likewise.
	(load_results): Adjust.
	(_result_from_dom): Likewise.
	(_count_outcomes): Rename to ...
	(count_outcomes): ... this.
	(summarize_test_stats): Remove.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	(run_test): Indicate that the new result is for a test.
	(set_up_resource): Indicate that the new result is for a resource.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteSummarize): Use
	TextResultStream.
	(Command.__ExecuteRun): Likewise.  Use XMLResultStream.
	(Command.__ProgressCallback): Remove.
	(Command.__SummarizeResults): Remove.
	(Command.__WriteResults): Remove.
	* qm/test/file_database.py: Tweak documentation.
	* qm/test/result.py (Result.RESOURCE): New constant.
	(Result.TEST): Likewise.
	(Result.kinds): New variable.
	(Result.__init__): Add kind parameter.
	(Result.GetKind): New method.
	(Result.MakeDomNode): Write out kind attribute.
	* qm/test/result_stream.py: New file.
	* qm/test/run.py (TestRun.__init__): Take result_streams,
	not progress_function, as a parameter.
	(TestRun.AddTestResult): Call __ReportResult, not
	__ProgressMessage.
	(TestRun.AddResourceResult): Likewise.
	(TestRun.__ReportResult): New function.
	(TestRun.__ProgressMessage): Remove.
	(test_run):  Take result_streams, not message_function, as a
	parameter.
	* qm/test/text_result_stream.py: New file.
	* qm/test/xml_result_stream.py: Likewise.
	* qm/test/web/run.py (TestResultsPage): Inherit from ResultStream.
	(TestResultsPage.__init__): Adjust.
	(TestResultsPage.WriteResult): New method.
	(TestResultsPage.Summarize): Likewise.
	(handle_run_tests): Adjust.
	* qm/test/web/show.py: Fix typo.
	* qm/test/web/web.py: Likewise.
	* share/xml/CATALOG: Update result.dtd version.
	* share/xml/result.dtd: Remove test-results and resource-results
	elements.

2001-10-10  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (InstanceBase): Tweak documentation.
	(InstanceBase.GetClass): Use TestDescriptor, not Test, and
	ResourceDescriptor, not Resource.
	(Test): Rename to TestDescriptor.
	(Resource): Rename to ResourceDescriptor.
	(make_new_test): Adjust.
	(make_new_resource): Likewise.
	* qm/test/xmldb.py (Database.__ParseTestDescriptor): Likweise.
	(Database.__ParseResourceDescriptor): Likewise.
	* qm/test/web/show.py (handle_sumbit): Likewise.

	Use 'arguments' not 'fields' in test classes.
	Change API for 'Run' method in tests.
	* qm/test/base.py: Import qm.test.result.
	(standard_test_class_names): Remove.
	(standard_resource_class_names): Likewise.
	(InstanceBase.__MakeItem): Use 'arguments', not 'fields'.
	(Test.Run): Take result parameter.
	(Resource.SetUp): Likewise.
	(Resource.CleanUp): Likewise.
	(Resource.__Do): Likewise.
	(Result): Remove.
	(ResultWrapper): Remove.
	(make_result_for_exception): Likewise.
	(make_new_test): Use arguments, not fields.
	(make_new_resource): Likewise.
	(write_results): Adjust documentation.
	(save_results): Likewise.
	(load_results): Likewise.
	(_test_results_from_dom): Likewise.
	(_result_from_dom): Construct a Result, not a ResultWrapper.
	(split_results_by_expected_outcome): Adjust documentation.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	(run_test): Adjust for new API.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/cmdline.py (Command): Adjust documentation.
	(Command.__SummarizeResults): Tweak.
	* qm/test/result.py: New file.
	* qm/test/run.py (TestRun): Adjustments throughout to use
	Result instead of ResultWrapper.
	* qm/test/test.py: New file.
	* qm/test/xmldb.py (Database.__GetArgumentsFromDomNode): Use
	arguments, not fields.
	(Database.__MakeDomNodeForItem): Likewise.
	* qm/test/command.py: Adjustments throughout.
	* qm/test/file.py: Likewise.
	* qm/test/python.py: Likewise.
	* qm/test/temporary.py: Likewise.
	* qm/test/web/run.py (TestResultsPage.__init__): Adjust
	documentation.
	(TestResultsPage.FormatResult): Likewise.
	* qm/test/web/show.py (ShowPage.AddPrerequisitePage): Tweak.
	(handle_submit): Likewise.

	* qm/test/base.py (InstanceBase.GetClass): Use
	get_extension_class.
	(load_databse): Likewise.
	(get_extension_directories): Add kind parameter.
	(get_extension_class_names_in_directory): New function.
	(get_extension_class_names): Likewise.
	(get_extension_class): Likewise.
	(get_test_class): Likewise.
	(get_resource_class): Likewise.
	(get_class): Remove.
	(make_new_test): Use get_test_class.
	(make_new_resource): Use get_resource_class.
	(__loaded_classes): Remove.
	(__builtin_class_path): Likewise.
	(extension_kinds): New variable.
	(__class_caches): Likewise.
	* qm/test/database.py (GetTestClasses): Use
	get_extension_class_names.
	(GetResourceClasses): Likewise.
	* qm/test/run.py (SubprocessTarget.__init__): Fix typo in comment.
	* qm/test/xmldb.py (Database.__ParseTestDocument): Use get_test_class.
	(Database.__ParseResourceDocument): Use get_resource_class.
	* qm/test/classes/__init__.py: Remove.
	* qm/test/classes/classes.qmc: New file.
	* qm/test/web/show.py (handle_show): Use get_extension_class.
	(handle_submit): Likewise.
	* share/xml/CATALOG: Add class-directory.dtd.
	* share/xml/class-directory.dtd: New file.

2001-10-07  Mark Mitchell  <mark@codesourcery.com>

	* qm/label.py (MakeRelativeTo): Rename to ...
	(AsAbsolute): ... this.
	(UnmakeRelativeTo): Rename to ...
	(AsRelative): ... this.
	* qm/test/base.py (Suite.IsImplicit): Update comment.
	(ResultWrapper.AsStructuredText): Fix thinko.
	* qm/test/database.py (Database.GetSuite): Update documentation.
	(Database.HasSuite): Likewise.
	(Database.GetSubdirectories): New method.
	(Database.GetTestClasses): Fix typo.
	(Database.GetResourceClasses): Fix typo.
	* qm/test/file_database.py (FileDatabase.GetSubdirectories): New
	method.
	(FileDatabase._GetLabels): Use AsAbsolute, not MakeRelativeTo.
	* qm/test/web/dir.py (DirItem): Remove.
	(DirPage.__init__): Store subdirectories, tests, suites, and
	resources.
	(handle_dir): Use the 'id' attribute to figure out which directory
	to display.
	* qm/test/web/show.py (NewItemPage.__init__): Use
	Database.GetResourceClasses.
	* qm/test/web/web.py (FormatId): Handle '.' specially.
	(make_server): Register 'show-dir'.
	* qm/test/share/dtml/test/dir.dtml: Rework for hierarchical
	directory display.
	* qm/share/dtml/test/suite.dtml: Remove bogus commentary about
	implicit suites.

2001-10-06  Mark Mitchell  <mark@codesourcery.com>

	* qm/label.py (to_path): Add extension parameter.
	* qm/test/base.py (Suite.GetTestIds): Revise documentation.
	(Suite.GetSuiteIds): Likewise.
	* qm/test/database.py (NoSuchTestError.__str__): Fix typo.
	(NoSuchSuiteError.__str__): Likewise.
	(NoSuchResourceError.__str__): Likewise.
	(Database): Update documentation.
	(Database.GetTestIds): Add scan_subdirs parameter.
	(Database.GetSuite): Update documentation.
	(Database.HasSuite): Likewise.
	(Database.GetSuiteIds): Add scan_subdirs parameter.
	(Database.GetResourceIds): Likewise.
	* qm/test/directory_suite.py: New file.
	* qm/test/file_database.py: Likewise.
	* qm/test/xmldb.py (test_file_extension): Remove.
	(suite_file_extension): Likewise.
	(resource_file_extension): Likewise.
	(Database): Inherit from FileDatabase.
	(Database.__init__): Adjust accordingly.
	(Database.GetTest): Rename and modify to become ...
	(Database._GetTestFromPath): ... this.
	(Database.GetTestIds): Remove.
	(Database.GetSuite): Rename and modify to become ...
	(Database._GetSuiteFromPath): ... this.
	(Database.GetSuiteIds): Remove.
	(Database.GetResource): Rename and modify to become ...
	(Database._GetResourceFromPath): ... this.
	(Database.GetResourceIds): Remove.
	(DirectorySuite): Remove.
	(AttachmentStore.__init__): Add database parameter.
	(AttachmentStore.__MakeDataFilePath): Use it to get the spellings
	of the various attachments.

	* qm/test/xmldb.py (Database.__init__): Pass the attachment
	store down to the base class.
	(Database.GetAttachmentStore): Remove.
	(Database.__GetArgumentsFromDomNode): Use GetAttachmentStore
	to access the attachment store.

2001-10-05  Mark Mitchell  <mark@codesourcery.com>

	* README.sources: Fix typo.

	* qm/label.py: Revise documentation.

	* qm/test/base.py: Move Database to ...
	* qm/test/database.py: New file.
	* qm/test/cmdline.py: Use it throughout in place of base.
	* qm/test/qmtest-remote.py (program_name): Fix initialization.
	* qm/test/qmtest.py (program_name): Likewise.
	* qm/test/xmldb.py: Import database.  Use it throughout in place
	of base.
	* qm/test/web/show.py: Likewise.
	* share/diagnostics/test.txt (no such resource): New error message.

	* qm/structured_text.py (HtmlFormatter.FinishDefinedTerm):
	Write the <dd> tag corresponding to the beginning of the
	definition itself.
	* qm/test/base.py (ResultWrapper.AsStructuredText): New method.
	(summarize_results): Use it.
	* qm/test/web/run.py (TestResultsPage.ShouldShowProperty): Remove.
	(TestResultsPage.FormatProperty): Remove.
	(TestResultsPage.FormatResult): New method.
	* share/dtml/test/results.dtml: Update accordingly.

	* qm/test/base.py (Database.__init__): New method.
	(Database.GetPath): Return the stored value.
	* qm/test/cmdline.py (Command.Execute): Convert the database
	path to an absolute path, if it isn't already one.
	* qm/test/xmldb.py (Database.__init__): Call the base class
	initializer.  Don't store path.
	(Database.GetClassPaths): Use GetPath, not __path, to retrieve
	the database path.
	(Database.GetPath): Remove.

2001-10-04  Mark Mitchell  <mark@codesourcery.com>

	* Makefile.in (SUBDIRS): Add doc.
	(install): Change invocation of install.py.
	(clean): New target.
	* configure.in (AC_OUTPUT): Add qm/setup_path.py.
	* configure: Regenerated.
	* install.py: Rework generation of scripts.
	* standard.mk.in (.PHONY): Add clean.
	* doc/manual/Makefile.in (clean::): New rule.
	* qm/Makefile.in (setup_path.py): Remove rule.
	(SCRIPTS): Simplify.
	* qm/attachment.py: Fix formatting.
	* qm/qm.sh: New file.
	* qm/test/qmtest-remote.in: Rename to ...
	* qm/test/qmtest-remote.py: ... this.
	* qm/test/qmtest.in: Rename to ...
	* qm/test/qmtest.py: ... this.
	* qm/track/qmtrack.in: Rename to ...
	* qm/track/qmtrack.py: ... this.
	* sgmlop/Makefile.in (clean): Use double-colon rule.
	* zope-dtml/ExtensionClass/Makefile.in (clean): Likewise.

2001-10-04  Alex Samuel  <samuel@codesourcery.com>

	* README: Mention test suite.

2001-10-04  Alex Samuel  <samuel@codesourcery.com>

	* unit.qms/test.qms/classes.qms/scripttest3.qmt: Update.
	* unit.qms/track.qms/export.qms/export1.qmt: Remove obsolete test.
	* unit.qms/track.qms/export.qms/export2.qmt: Likewise.
	* unit.qms/track.qms/export.qms/setup_idb.qmt: Likewise.
	* unit.qms/track.qms/export.qms/idb.qma: Remove action.

2001-10-04  Mark Mitchell  <mark@codesourcery.com>

	* qm/web.py (WebServer.__init__): Document meaning of using
	0 as the port.
	(WebServer.Bind): Handle port 0 specially.
	* qm/test/cmdline.py (Command.__ExecuteServer): Use port 0
	as the default port and 127.0.0.1 as the default address
	for the web server.
	* qm/test/web/web.py (make_server): Do not provide a default
	argument for address.

2001-10-03  Mark Mitchell  <mark@codesourcery.com>

	* qm/attachment.py: Attempt to fix formatting.

2001-10-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetValueFromDomNode): Rename store parameter
	to attachment_store.
	Likewise for all subclasses.
	(from_dom_node): Likewise.  Pass it recursively.
	* qm/track/memory_issue_store.py (IssueStore.UpdateIssueClass):
	Fix brackets.
	(open): Add attachment_store parameter.
	* qm/track/issue_database.py (AttachmentStore.__init__): Call base
	class __init__.
	(AttachmentStore.Store): Accept None for issue.
	(AttachmentStore.Adopt): Remove.
	(AttachmentStore.StoreFromFile): New method.
	(_IssueDatabase.UpdateIssueClass): New function.
	(open): Open the attachment store first, and pass it to the issue
	store open function.
	* qm/track/issue.py (get_issues_from_dom_node): Add
	attachment_store parameter.
	(_get_field_values_from_dom_node): Likewise.
	(get_issue_from_dom_node): Likewise.
	(get_issue_difference_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(load_issue_histories): Likewise.
	* qm/track/issue_class.py (from_dom_node): Likewise.
	(load): Likewise.
	* qm/track/cmdline.py (Command.__PerformCreate): Use correct
	module for Issue.
	(Command.__PerformConfigureIdb): Call web_server.Run directly.
	* qm/track/web/web.py (store_attachment_data): New function.
	* qm/track/web/issue_class.py (handle_submit_field): Call
	store_attachment_data for attachment field default values.
	(handle_new_class): Use idb.GetConfiguration.
	* qm/track/web/show.py (handle_new): Likewise.
	Use correct module for Issue.
	(handle_submit): Likewise.
	(_store_attachment_data): Remove.

2001-10-03  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Clarify blank lines.
	* qm/track/test.py: Remove.
	* qm/track/web/issue_class.py: Remove spurious import.

2001-10-02  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/classes/command.py (ShellCommandTest): Fix typo in comment.

	* qm/fields.py (SetField.GetValueFromDomNode): Correct thinko.

	* qm/test/classes/command.py (ExecTest.fields): Adjust
	documentation for environment.
	(ExecTest.MakeEnvironment): Include the contents of the current
	environment.
	* doc/manual/test-reference.xml: Note change.

	* doc/manual/test-reference.xml: Add section on writing database
	classes.

	* qm/test/base.py (load_database): Rework.
	(get_extension_directories): New function.
	(get_class): Use it.
	(get_database_class): New function.
	* share/xml/tdb-configuration.dtd: New file.
	* share/xml/CATALOG: Add it.

	* qm/common.py (rmdir_recursively): Remove the directory itself.

	* qm/attachment.py (TemporaryAttachmentStore): Derived from
	AttachmentStore.  Add all_stores variable.
	(AttachmentStore.__init__): Add the new store to all_stores.
	(AttachmentStore.GetIndex): New method.
	(TemporaryAttachmentStore.__init__): Initialize the base
	class.
	(TemporaryAttachmentStore.Add): Close the file after the
	data has been written out.
	(Attachment): Include a reference to the associated attachment
	store.
	(Attachment.__init__): Take an attachment store as a parameter.
	(Attachment.__cmp__): Compare the attachment store along with
	the other fields.
	(AttachmentWrapper): Remove.
	(from_dom_node): Add attachment store parameter.
	(get_attachment_store): New function.
	* qm/common.py (make_unique_tag): Return something more likely
	to be unique.
	(_unique_tag): New variable.
	* qm/fields.py (Field.FromDecodeValue): Adjust comment.
	(UploadAttachmentPage.__init__): Fix typo in comment.  Put the
	attachment store into the context for the DTML page.
	(AttachmentField.FromEncodeValue): Encode the attachment store.
	(AttachmentField.FormDecodeValue): Decode the attachment store
	value.
	* qm/test/base.py (InstanceBase.__MakeItem): Remove special
	handling for attachments.
	(Database.WriteTest): Update comments.
	* qm/test/web/show.py (_retrieve_attachment_data): Remove.
	(handle_submit): Remove special handling for attachments.
	Remove temporary attachments when they are no longer needed.
	* qm/test/web/web.py (make_server): Fix typo in comment.
	* qm/track/server.py (_make_server): Fix typo in comment.
	* share/dtml/attachment.dtml: Encode the attachment store
	when returning information to the server.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__SummarizeResults): Only show
	resource results section if there are some failing.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__SummarizeResults): Always show
	non-relative stats in full format.
	* tests/unit.qms/track.qms/export.qms/export2.qmt: Fix.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field): Rename __attributes to __properties
	throughout.
	(Field.GetAttribute): Rename to...
	(Field.GetProperty): ... this.
	(Field.SetAttribute): Rename to...
	(Field.SetProperty): ... this.
	(Field.GetAttributeNames): Rename to ...
	(Field.GetPropertyNames): ... this.
	(Field.IsAttribute): Rename to...
	(Field.IsProperty): ... this.
	Adjust accordingly throughout.
	* qm/track/issue_class.py (StateField.GetStateModel): Use
	GetProperty.
	(StateField.SetStateModel): Use SetProperty.
	* qm/test/base.py (ContextWrapper): Rename attributes to
	properties throughout.
	* qm/test/web/show.py (ShowPage.FormatFieldValue): Use IsAttribute.
	* qm/test/classes/file.py (SubstitutionField.__init__): Rename
	attributes to properties.
	(SubstitutionField): Rename path_attribute to path_property
	throughout.
	* qm/track/cmdline.py (Command.__PrintResults): Likewise.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Likewise.
	* qm/track/web/show.py (ShowPage.IsShowField): Likewise.
	(ShowPage.FormatFieldValue): Likewise.
	* qm/track/web/summary.py (DisplayOptionsPage.__init__): Likewise.
	* qm/track/web/issue_class.py (handle_submit_subscription): Use
	SetProperty.
	* share/dtml/track/issue-class.dtml: Use IsAttribute.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/diagnostics/test.txt
	(context attribute cannot be deleted): Rename to ...
	(context property cannot be deleted): ... this.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/file.py (SubstitutionField.class_name): New
	attribute.
	(SubstitutionField.GetHelp): Fix link in help text.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue_class.py (IssueClass.__init__): Adjust field
	descriptions.
	* qm/track/cmdline.py (Command.GetIdbPath): Fix exception.
	(run_command): Handle IdbError.
	* qm/track/qmtrack.in: Load diagnostics.
	* qm/track/server.py: Remove obsolete import.
	* qm/track/web/query.py: Likewise.
	* qm/test/classes/command.py (ExecTest.fields): Fix description of
	exit_code field.
	* share/dtml/track/show.dtml: Show brief field descriptions when
	editing.
	* share/dtml/test/show.dtml: Fix indentation.
	* share/diagnostics/track.txt (idb locked): Adjust.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/command.py (ExecTest.Run): Open input files for
	read.

2001-09-27  Mark Mitchell  <mark@codesourcery.com>

	* qm/test/base.py (Database.GetTestClasses): New method.
	* qm/test/web/show.py (NewItemPage.__init__): Use it, instead
	of qm.test.base.standard_test_class_names.
	* share/dtml/test/new.dtml: Remove test class text field.
	* share/dtml/test/show.dtml: Only show explanatory text about
	properties when editing.

	* qm/fields.py (Field.GetDescription): Update docstring.
	(Field.GetBriefDescription): New method.
	* qm/structured_text.py (StructuredTextProcessor.__call__): Use
	get_paragraphs.
	(get_paragraphs): New function.
	(get_first_paragraph): Likewise.
	(__paragraph_regexp): New variable.
	* qm/test/web/show.py (ShowPage.GetBriefClassDescription): New
	method.
	* share/dtml/test/new.dtml: Correct typo.
	* share/dtml/test/show.dtml: Reduce verbosity; reoder some
	comments.

	* qm/test/classes/command.py (ExecTest): Revise doc strings.
	(ShellCommandTest): Likewise.
	(ShellScriptTest): Likewise.
	* qm/test/classes/file.py (SubstitutionField): Likewise.
	(FileContentsTest): Likewise.
	* qm/test/classes/python.py (ExecTest): Likewise.
	(ExceptionTest): Likewise.
	(StringExceptionTest): Likewise.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (wrap_lines): Add indent parameter.
	* qm/test/cmdline.py (Command.summary_formats): New attribute.
	(Command.summary_option_spec): Remove.
	(Command.no_summary_option_spec): Likewise.
	(Command.conflicting_option_specs): Remove them.
	(Command.format_option_spec): New attribute.
	(Command.comamnds_spec): Add "summarize".  Adjust.
	(Command.Execute): Handle summarize.
	(Command.__ExecuteSummarize): New method.
	(Command.__ExecuteRun): Open results file later.  Adjust for
	__SummarizeResults.
	(Command.__WriteSummary): Remove.
	(Command.__SummarizeResults): New method.
	* qm/test/base.py (load_outcomes): Adjust for load_results.
	(read_results): Remove.
	(load_results): Return resource results too.
	(_results_from_dom): Remove.
	(_test_results_from_dom): New function.
	(_resource_results_from_dom): Likewise.
	(_result_from_dom): Adjust.
	(_count_outcomes): New function.
	(split_results_by_expected_outcomes): Likewise.
	(summarize_test_stats): Likewise.
	(summarize_relative_test_stats): Likewise.
	(summarize_test_suite_stats): Likewise.
	(summarize_results): Likewise.
	* share/diagnostics/test.txt (invalid results file): New
	diagnostic.
	(invalid results format): Likewise.
	(no results file specified): Likewise.
	(no such ID): Likewise.
	* tests/unit.qms/test.qms/suite3.qmt (suite_ids): Update.

2001-09-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/label.py (thunk): Call normpath on result.
	* qm/attachment.py (AttachmentStore): Add to doc string.
	(_temporary_location_prefix): Change.
	* qm/test/xmldb.py (AttachmentStore.Adopt): Fix doc string.
	(AttachmentStore.__MakeDataFilePath): Make safer file names.
	* qm/test/cmdline.py (Command.__WriteSummary): Bail early if no tests.

2001-09-27  Mark Mitchell  <mark@codesourcery.com>

	* share/dtml/test/new-suite.dtml: Fix typo.

2001-09-26  Mark Mitchell  <mark@codesourcery.com>

	* qm/structured_text.py (TextFormatter.__style_markers): New
	variable.
	(TextFormatter.StartItem): Remove label parameter.
	(TextFormatter.StartStyle): Emit markers to indicate the style.
	(TextFormatter.EndStyle): Emit markers to indicate the style.
	(TextFormatter.FinishDefinedTerm): New
	function.
	(HtmlFormatter.__start_item_tags): Change definition list format.
	(HtmlFormatter.StartItem): Remove label parameter.
	(HtmlFormatter.FinishDefinedTerm): Likewise.
	(StructuredTextProcessor): Use __WriteText to format the label in
	a defined term.

	* configure.in (DOCBOOK_STYLESHEETS): Add another directory
	in which to locate xml.dcl.
	(--with-docbook-dtd): New option.
	* configure: Regenerated.
	* standard.mk.in (SGMLDIRS): Add @DOCBOOK_STYLESHEETS@.

2001-09-26  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/test/results.dtml: New file.
	* share/dtml/track/configuration-navigation-bar.dtml: Likewise.

2001-09-26  Alex Samuel  <samuel@codesourcery.com>

	* README: Update QMTRACK_DB_PATH name.
	* doc/manual/track-tour.xml: Explain configuration server.

	* qm/attachment.py: Rework entirely.
	* qm/xmlutil.py (load_xml_file): Add validate parameter.
	(load_xml): Likewise.
	(child_tag_predicate): New function.
	(get_child): Likewise.
	(get_children): Likewise.
	(get_child_text): Likewise.
	(get_child_texts): Likewise.
	(get_dom_child_text): Remove.
	(get_dom_children_texts): Likewise.
	* qm/web.py (HttpRedirect.__init__): New method.
	(WebRequestHandler.__HandleScriptRequest): Adjust accordingly.
	(WebServer.HandleNoSessionError): Likewise.
	(WebRequest.copy): Copy the client address.
	(handle_login): Adjust for change to HttpRedirect.
	(handle_logout): Likewise.
	(cache_page): Adjust for rmdir_recursively.
	(_handle_root): Adjust for change to HttpRedirect.
	* qm/user.py: Adjust for changes in xmlutil.
	* qm/label.py (root): New variable.
	(split): Rewrite.
	(split_fully): New function.
	(dirname): Use sep.
	* qm/fields.py: Adjust throughout for changes to xmlutil.
	(Field.class_name): New attribute.
	(Field.MakeDomNode): New method.
	(IntegerField.class_name): New attribute.
	(TextField.class_name): Likewise.
	(SetField.class_name): Likewise.
	(SetField.FormatValueAsHtml): Use attachment accessors.
	(SetField.MakeDomNode): New method.
	(UploadAttachmentPage.__init__): Use make_temporary_location.
	(UploadAttachmentPage.MakeSubmitUrl): Use upload_url.
	(AttachmentField.class_name): New attribute.
	(AttachmentField.upload_url): Likewise.
	(AttachmentField.download_url): Likewise.
	(AttachmentField.MakeDownloadUrl): Remove.
	(AttachmentField.FormatValueAsHtml): Use attachment accessors.
	(AttachmentField.FormEncodeValue): Likewise.
	(AttachmentField.FormDecodeValue): Don't use attachment_class.
	(AttachmentField.FormatSummary): Use attachment accessors.
	(AttachmentField.MakeDomNodeForValue): Use make_dom_node always.
	(EnumerationField.class_name): New attribute.
	(EnumerationField.__init__): Decode enumerals if necessary.
	(TimeField.class_name): New attribute.
	(UidField.class_name): New attribute.
	(from_dom_node): New function.
	* qm/common.py (Configuration): Remove.
	(remove_directory_recursively): Rename to...
	(rmdir_recursively): ... this.
	(load_module): Add default for path.
	(load_class): Likewise.
	(add_exit_function): Store external exit functions separately, and
	call them at the end.
	(make_map_from_list): New function.
	(purge_keys): Likewise.
	(make_unique_tag): Likewise.
	(_foreign_exit_functions): New variable.
	* qm/cmdline.py: Reformat comments.

	* qm/track/__init__.py: Remove imports.
	* qm/track/config.py: Remove.
	* qm/track/idb.py: Likewise.
	* qm/track/memory_idb.py: Likewise.
	* qm/track/issue_database.py: New file.
	* qm/track/issue_store.py: Likewise.
	* qm/track/memory_issue_store.py: Likewise.
	* qm/track/qmtrack.in: Simplify, using run_command.
	* qm/track/issue_class.py (issue_classes_dtd): New constant.
	(IidField.class_name): New attribute.
	(StateField.class_name): Likewise.
	(StateField.__init__): Take state model from an attribute.
	(DiscussionField.class_name): New attribute.
	(DiscussionField.__init__): Take the contained field as a
	parameter.
	(IssueClass.MakeDomNode): New method.
	(from_dom_node): New function.
	(load): Likewise.
	(save): Likewise.
	* qm/track/issue.py (ExpressionNameError): New exception class.
	(ExpressionSyntaxError): Likewise.
	(Attachment): Remove.
	(Issue.GetRevision): Rename to...
	(Issue.GetRevisionNumber): ... this.  Adjust accordingly
	throughout.
	(get_issues_from_dom_node): Add issue_classes parameter.
	(get_issue_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(export_issues): Rename to...
	(write_issue_histories): ... this.  Adjust DOM format.
	(load_issue_histories): New function.
	(eval_issue_expression): Translate expression exceptions.
	(_initialize_module): Don't set qm.attachment.attachment_class.
	* qm/track/cmdline.py: Adjust throughout for changes to IDB
	objects.
	(idb_environment_variable_name): New constant.
	(Command.idb_type_option_spec): Remove.
	(Command.issue_store_implementation_option_spec): New attribute.
	(Command.qmtrack_commands): Use it.  Add configure-idb.  Remove
	initialize.
	(Command.__init__): Adjust dispatch accordingly.
	(Command.GetIdbPath): Use idb_environment_variable_name.
	(Command.RequiresIdb): Adjust for changes to commands.
	(Command.Execute): Add idb parameter.
	(Command.__PerformCreate): Likewise.
	(Command.__PerformEdit): Likewise.
	(Command.__PerformSplit): Likewise.
	(Command.__PerformJoin): Likewise.
	(Command.__PerformQuery): Likewise.
	(Command.__PerformConfigureIdb): New method.
	(Command.__PerformServer): Rewrite.
	(Command.__PerformShow): Add idb parameter.
	(Command.__PerformCreateIdb): Likewise.
	(Command.__PerformDestroyIdb): Likewise.  Don't lock here.
	(Command.__PerformImport): Likewise.
	(Command.__ImportIssueHistories): Likewise.
	(Command.__PrintResults): Likewise.  Build list of histories for
	export.
	(run_command): New function.

	* qm/track/web/web.py (DefaultDtmlPage.navigation_bar_template):
	New attribute.
	(DefaultDtmlPage.GenerateStartBody): Use it.
	(DefaultDtmlPage.GetName): Use qm.common.program_name.
	(handle_download_attachment): Remove.
	(make_url_for_attachment): Remove.
	(_initialize_module): Don't set MakeDownloadUrl.
	* qm/track/web/summary.py: Get IDB from session and use issue
	store throughout.
	(handle_summary): Simplify query.  Handle query exceptions.
	* qm/track/web/show.py: Get IDB from session and use issue store
	throughout.
	(ShowPage.__init__): Don't get revisions here.  Initialize
	__history.
	(ShowPage.FormatFieldValue): Use GetHistory.
	(ShowPage.FormatHistory): Likewise.
	(ShowPage.GetHistory): New method.
	(retrieve_attachment_data): Remove.
	(handle_submit): Use _store_attachment_data.
	(_store_attachment_data): New function.
	* qm/track/web/query.py: Get IDB from session throughout.
	* qm/track/web/issue_class.py: Get IDB from session throughout.
	Adjust for HttpRedirect throughout.
	(handle_add_discussion): Construct TextField for DiscussionField.
	* qm/track/web/index.py (IndexPage.__init__):
	(IndexPage.__init__): Don't get issue classes.
	(IndexPage.GetIssueClasses): New method.
	(IndexPage.GetDefaultIssueClass): Likewise.
	* qm/track/server.py (_script_base): New constant.
	(WebServer): New class.
	(_make_server): New function.
	(make_server): Use it.
	(make_configuration_server): New function.
	(run_server): Remove.
	(execute): Likewise.
	(execute_locally): New function.
	(execute_remotely): Likewise.

	* share/xml/CATALOG: Add idb-configuration and issue-classes
	DTDs.
	* share/xml/idb-configuration.dtd: New file.
	* share/xml/issue-classes.dtd: Likewise.
	* share/xml/fields.mod (mimetype): Rename to...
	(mime-type): ... this.
	* share/web/stylesheets/qm.css (tr.pass): New style.
	(tr.fail): Likewise.
	(tr.untested): Likewise.
	(tr.error): Likewise.
	(span.outcome): Likewise.
	(span.cause): Likewise.
	(span.id): Likewise.

	* qm/test/xmldb.py: Rework entirely.
	* qm/test/run.py: Adjust for changes in xmlutil throughout.
	(TestRun.Schedule): Improve diagnostics.
	* qm/test/cmdline.py (Command.Execute): Catch exception when
	loading database.
	(Command.MakeContext): Don't add path to context here.
	(Command.__ExecuteRun): Use expand_ids.
	(Command.__ExecuteServer): Pass database to make_server.
	* qm/test/base.py: Adjust for changes in xmlutil throughout.
	(Attachment): Remove.
	(InstanceBase.SetWorkingDirectory): Don't call
	__SetAttachmentPaths.
	(InstanceBase.__MakeItem): Wrap attachments in arguments.
	(InstanceBase.__SetAttachmentPaths): Remove.
	(Suite): Reimplement.
	(Database.GetSuiteIds): Remove implicit parameter.
	(Database.GetAttachmentStore): New method.
	(Database.SetAttachmentData): Remove.
	(ResultWrapper.keys): New method.
	(get_suite_contents_recursively): New function.
	(expand_ids): Likewise.
	(load_database): Don't primt a message when the database module
	can't be imported.
	(run_test): Add path to context.
	Don't set qm.attachment.attachment_class.
	* qm/test/web/run.py: New file.
	* qm/test/web/web.py (DefaultDtmlPage.FormatTestId): Remove.
	(DefaultDtmlPage.FormatResourceId): Likewise.
	(DefaultDtmlPage.FormatSuiteId): Likewise.
	(DefaultDtmlPage.FormatId): New method.
	(make_server): Add database parameter.  Register attachment
	scripts.
	* qm/test/web/suite.py: Adjust for changes in Suite.
	(handle_submit): Adjust for HttpRedirect.
	* qm/test/web/show.py (retrieve_attachment_data): Remove.
	(_retrieve_attachment_data): New function.
	(handle_submit): Adjust accordingly.  Adjust for HttpRedirect.
	(handle_delete): Likewise.
	* qm/test/web/dir.py (DirPage.FormatItem): Remove.
	* qm/test/classes/temporary.py (TempDirectoryResource.CleanUp):
	Adjust for rmdir_recursively.

	* share/dtml/track/show.dtml: Adjust for changes to Issue.
	* share/dtml/track/navigation-bar.dtml: Replace SC logo.
	* share/dtml/track/index.dtml: Use GetIssueClasses.  Remove Config
	IDB button.
	* share/dtml/track/history.dtml: Adjust for changes to Issue.
	* share/dtml/test/suite.dtml: Use FormatId.  Add Run button.
	Handle suites uniformly.
	* share/dtml/test/show.dtml: Use FormatId.  Add Run button.
	* share/dtml/test/navigation-bar.dtml: Replace SC logo.
	* share/dtml/test/dir.dtml: Adjust format.
	* share/dtml/exception.dtml: Escape type and value.

	* share/diagnostics/track.txt (idb directory missing): Adjust.
	(idb problem): Remove.
	(idb in use): New diagnostic.
	(idb path exists): Adjust.
	(initialize invalid idb class): Remove.
	(idb problem): New diagnostic.
	(idb server not accessible): Likewise.
	(issue store module error): Likewise.
	(new idb message): Adjust.
	(using local idb): New diagnostic.
	(using remote idb): Likewise.
	* share/diagnostics/test.txt (error loading xml resource): New
	diagnostic.
	(error loading xml test): Adjust.
	(failed prerequisite): New diagnostic.
	(failed resource): Adjust.
	(incorrect prerequisite outcome): Remove.
	(no such action): Adjust
	(no such suite): New diagnostic.
	(no such test): Adjust.
	(no target for group): Likewise.
	* share/diagnostics/common.txt (invalid property): New
	diagnostic.

	* tests/unit/common/format_time1.qmt: Remove.
	* tests/unit/common/graph_complete.qmt: Likewise.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parse_time1.qmt: Likewise.
	* tests/unit/common/parse_time2.qmt: Likewise.
	* tests/unit/common/parse_time3.qmt: Likewise.
	* tests/unit/common/parse_time4.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.
	* tests/unit/test/classes/commandtest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qma: Likewise.
	* tests/unit/test/classes/tempdir1.qmt: Likewise.
	* tests/unit/track/export/export1.qmt: Likewise.
	* tests/unit/track/export/export2.qmt: Likewise.
	* tests/unit/track/export/idb.qma: Likewise.
	* tests/unit/track/export/setup_idb.qmt: Likewise.
	* tests/unit.qms/common.qms/format_time1.qmt: New file.
	* tests/unit.qms/common.qms/graph_complete.qmt: Likewise.
	* tests/unit.qms/common.qms/graph_cycle.qmt: Likewise.
	* tests/unit.qms/common.qms/graph_pass.qmt: Likewise.
	* tests/unit.qms/common.qms/label_is_valid.qmt: Likewise.
	* tests/unit.qms/common.qms/label_thunk.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time1.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time2.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time3.qmt: Likewise.
	* tests/unit.qms/common.qms/parse_time4.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_create.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_dup_command_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_dup_command_short.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_duplicate_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_duplicate_short.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_help.qmt: Likewise.: Likewise.
	* tests/unit.qms/common.qms/parser_no_long.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_parse.qmt: Likewise.
	* tests/unit.qms/common.qms/parser_two_char_short.qmt: Likewise.
	* tests/unit.qms/test.qms/suite1.qmt: Likewise.
	* tests/unit.qms/test.qms/suite2.qmt: Likewise.
	* tests/unit.qms/test.qms/suite3.qmt: Likewise.
	* tests/unit.qms/test.qms/test_suite1.qms: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest1.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest2.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/scripttest3.qmt: Likewise.
	* tests/unit.qms/test.qms/classes.qms/tempdir1.qma: Likewise.
	* tests/unit.qms/test.qms/classes.qms/tempdir1.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/export1.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/export2.qmt: Likewise.
	* tests/unit.qms/track.qms/export.qms/idb.qma: Likewise.
	* tests/unit.qms/track.qms/export.qms/setup_idb.qmt: Likewise.

2001-09-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py: Really remove it.

2001-09-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py: Rename to...
	* qm/platform_unix.py: ... this.
	(default_shell): New variable.
	(get_shell_for_command): New function.
	(get_shell_for_script): Likewise.
	* qm/platform.py: Adjust accordingly.
	* qm/common.py (split_argument_list): New function.
	* qm/test/classes/command.py (CommandTest): Rename too...
	(ShellCommandTest): ... this.
	(ShellCommandTest.fields): Remove interpreter field.
	(ShellCommandTest.__init__): Adjust accordingly.
	(ShellCommandTest.RunProgram): Likewise.
	(ScriptTest): Rename to...
	(ShellScriptTest): ... this.
	(ShellScriptTest.fields): Remove interpreter field.
	(ShellScriptTest.__init__): Adjust accordingly.
	(ShellScriptTest.RunProgram): Likewise.
	* qm/test/base.py (standard_test_class_names): Adjust accordingly.
	* doc/manual/common-manual.xml (sec-rc-common): Document
	command_shell and script_shell.xo
	* share/diagnostics/test.txt (no shell executable): New diagnostic.
	* tests/unit/test/classes/commandtest1.qmt: New test.
	* tests/unit/test/classes/scripttest1.qmt: Adjust.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install-sh: Restore, with corrected permissions.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install-sh: Remove.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py (copy_tree): Use makedirs.
	Warn on missing documentation files.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py (copy_tree): New function.
	Use it.
	* qm/test/classes/python.py (ExecTest.__init__): Make sure source
	is newline-terminated.

2001-09-07  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Substitute @python_version@ and @python_platform@.

2001-09-06  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Exec setup_path.py.
	(packages): Build PyXML path.
	* doc/manual/test-tour.xml: Fix typos.

2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk.in (doc): Check for empty SUBDIRS.
	($(HTMLMANIFEST)): Likewise.
g
2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* qm/Makefile.in (setup_path.py): Use left-quotes.
	($(SCRIPTS):%): Likewise.
	* qm/platform.py: Use Linux module for Irix.
	* qm/test/cmdline.py (Command.context_file_spec): Rename long
	option to load-context.
	* share/web/stylesheets/qm.css (a.help-link): Adjust color.
	* doc/manual/test-manual.xml: Adjust accordingly.
	* doc/manual/test-reference.xml: Likewise.

2001-09-05  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Set up gadfly.
	* configure: Regenerate.
	* Makefile.in (setup): Remove rule.
	(gadfly/sqlwhere.py): Likewise.
	* standard.mk.in (.PHONY): Remove setup.
	(setup): Remove rule.
	* qm.spec (build): Don't make setup.
	* README: Adjust accordingly.

2001-09-04  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Extract PYTHON_VERSION, PYTHON_PREFIX,
	PYTHON_PLATFORM.
	* configure: Regenerate.
	* standard.mk.in (PYTHON_VERSION): New variable.
	(PYTHON_PREFIX): Likewise.
	(PYTHON_PLATFORM): Likewise.
	(MAKEFILE_PRE_IN): Likewise.
	* Makefile.in (zope-dtml/ExtensionClass/Makefile): Remove rule.
	(sgmlop/Makefile): Use MAKEFILE_PRE_IN.
	* qm/Makefile.in (setup_path.py): Substitute @python_version@ and
	@python_platform@.
	* qm/setup_path.py.in (get_python_version): New function.
	(__python_version): New variable.
	(__python_platform): Likewise.
	Use them for PyXML path.
	* qm/structured_text.py (__entity_char_regex): Handle
	single-character entities only.
	(__entity_char_replacement): Likewise.
	* zope-dtml/ExtensionClass/Makefile.in (TOPDIR): New variable.
	Include standard.mk.
	(all): Use PYTHON.
	* sgmlop/Makefile.in (TOPDIR): New variable.
	Include standard.mk.
	(all): Use PYTHON.

2001-09-04  Alex Samuel  <samuel@codesourcery.com>

	* configure.in: Rewrite.
	* configure: Regenerate.
	* standard.mk.in: Rewrite documentation portions.
	* qm/test/base.py (Database.HasTest): Implement here.
	(Database.HasSuite): Likewise.
	(Database.HasResource): Likewise.
	* qm/label.py (to_path): Comment.

2001-08-30  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Describe conventions for private names.
	* qm/setup_path.py.in (add_to_python_path): Adjust comment.
	* qm/test/cmdline.py (Command.__ExecuteServer): Adjust message.
	* share/dtml/track/index.dtml: Initialize style field.
	* share/diagnostics/common.txt (server url): New diagnostic.

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (Database.GetTest): Handle ParseError.
	* qm/test/classes/command.py (ExecTest.fields): Change stdin,
	stdout, stderr fields to TextFields.
	(ExecTest.Run): Adjust accordingly.
	* tests/unit/test/classes/scripttest1.qmt: Likewise.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* doc/manual/test-reference.xml: Likewise.

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/command.py (ScriptTest.fields): Make script
	field multiline.
	(ScriptTest.__init__): Test for empty string intepreter field.
	* tests/unit/test/classes/scripttest1.qmt: New test.
	* tests/unit/test/classes/scripttest2.qmt: Likewise.
	* tests/unit/test/classes/scripttest3.qmt: Likewise.
	* doc/manual/test-tour.xml: Fix typo.
	* doc/manual/test-reference.xml: Document some test classes.

2001-08-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (ContextWrapper.items): Fix.
	* qm/test/cmdline.py (Command.__init__): Reformat.
	* qm/test/web/show.py (retrieve_attachment_data): Only process
	temporary attachments.
	* qm/test/classes/command.py (ExecTest.MakeEnvironment): Add
	context variables to environment.

2001-08-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/setup_path.py.in (add_to_python_path): Prepend to path.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (files): Add qmtest-remote.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* install.py (scripts): Fix qmtest-remote script.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_win32.py (get_host_name): Fix syntax error.

2001-08-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (DirectorySuite.__ScanDirectory): Construct
	absolute test IDs.
	* qm/test/run.py (RemoteShellTarget.__init__): Use arguments
	property.
	(TestRun.AddResourceResult): Immediately try to clean up after
	failed setup.
	* qm/test/cmdline.py (Command.commands_spec): Put ID in brackets.
	(Command.__ExecuteRun): Run all tests if none specified.  Collect
	explicit test suites.
	(Command.__WriteSummary): Print statistics by suite.  Supress null
	output.
	* share/diagnostics/test.txt (no ids specified): Remove.
	* doc/qm.mod (PASS): New entity.
	(FAIL): Likewise.
	(ERROR): Likewise.
	(UNTESTED): Likewise.
	* doc/manual/test-manual.xml: Update and expand.
	* doc/manual/test-reference.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.

2001-08-19  Alex Samuel  <samuel@codesourcery.com>

	* install.py (scripts): Add qmtrack-remote.
	* qm.spec (files): Likewise.
	* qm/Makefile.in (SCRIPTS): Likewise.
	* qm/async.py (Channel.IsOpen): New method.
	(Multiplexer.Wait): Close channels if connection vanishes.
	(fork_with_stdio_channel): New function.
	* qm/test/run.py (Target.EnqueueRunTest): Implement here.
	(Target.EnqueueSetUpResource): Likewise.
	(Target.EnqueueCleanUpResource): Likewise.
	(Target.OnReplyReady): Likewise.
	(SubprocessTarget): Rename __children to _children and
	__ready_children to _ready_children.
	(SubprocessTarget.EnqueueSetUpResource): Likewise.
	(SubprocessTarget.EnqueueCleanUpResource): Likewise.
	(SubprocessTarget.OnReplyReady): Likewise.
	(SubprocessTarget.GetQueueLength): Subtract number of ready
	children.
	(SubprocessTarget.OnReplyReady): Use base implementation.
	(SubprocessTarget.__EnqueueCommand): Rename to...
	(SubprocessTarget._EnqueueCommand): ... this.
	(RemoteShellTarget): New class.
	(_RemoteDemultiplexerTarget): Likewise.
	(test_run): Read multiple times from channels, if necessary.
	(_target_spec_from_dom): Fix duplicate variable name.
	* qm/test/qmtest-remote.in: New file.

2001-08-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (__host_name): Remove.
	(get_host_name): Likewise.
	(shuffle): New function.
	(sequence_difference): Likewise.
	* qm/async.py: New file.
	* qm/web.py (HTTPServer.server_bind): Use platform.get_host_name.
	* qm/platform_win32.py (get_host_name): New function.
	(_get_host_name): Likewise.
	* qm/platform_linux.py (run_program): Fix comment.
	(get_host_name): New function.

	* qm/track/cmdline.py (Command.__PerformServer): Use
	platform.get_host_name.
	* qm/track/triggers/notification.py (_NotifyTrigger.__init__):
	Likewise.

	* qm/test/run.py: New file.
	* qm/test/cmdline.py (Command.summary_option_spec): Remove
	short-form option.
	(Command.profile_option_spec): Adjust.
	(Command.concurrent_option_spec): Likewise.
	(Command.remote_option_spec): Remove.
	(Command.targets_option_spec): New attribute.
	(Command.seed_option_spec): Likewise.
	(Command.commands_spec): Remove remote_option_spec.  Add
	targets_option_spec and seed_option_spec.  Sort.
	(Command.add_test_id): Adjust for new test run mechanism.
	(Command.__ExecuteServer): Use platform.get_host_name.
	(Command.__WriteSummary): Summarize resource results too.  Adjust
	output.
	* qm/test/base.py (dtds): Add target DTD.
	(Resource.DoSetup): Rename to...
	(Resource.SetUp): ... this.
	(Resource.DoCleanup): Rename to...
	(Resource.CleanUp): ... this.
	(Resource.__Do): Use SetUp and CleanUp.
	(ResultWrapper.GetTestId): Rename to...
	(ResultWrapper.GetId): ... this.
	(ResultWrapper.MakeDomNode): Adjust accordingly.
	(ResultWrapper.__setitem__): New method.
	(ResultWrapper.__delitem__): Likewise.
	(PrerequisiteMapAdapter): Remove.
	(RemoteTestHost): Likewise.
	(Engine): Likewise.
	(InProcessEngine): Likewise.
	(ConcurrentyEngine): Likewise.
	(SubprocessEngine): Likewise.
	(MultiProcessEngine): Likewise.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Likewise.
	(LocalCommandEngine): Likewise.
	(MultiRshEngine): Likewise.
	(RshEngine): Likewise.
	(write_results): Write resource results too.
	(read_results): Adjust for new DTD.
	(load_results): Likewise.
	(_results_from_dom): Likewise.
	(run_test): New function.
	(set_up_resource): Likewise.
	(clean_up_resource): Likewise.
	* qm/test/classes/temporary.py (TempDirectoryResource.DoSetup):
	Rename to...
	(TempDirectoryResource.SetUp): ... this.  Handle errors.
	(TempDirectoryResource.DoCleanup): Rename to...
	(TempDirectoryResource.CleanUp): ... this.  Handle errors.

	* share/xml/CATALOG: Add target DTD.
	* share/xml/result.dtd: Adjust to include resource results.
	(results): Rename to...
	(test-run): ... this.
	(test-results): New element.
	(resource-results): Likewise.
	* share/xml/target.dtd: New file.
	* share/diagnostics/test.txt (concurrency not integer): New
	diagnostic.
	(failed resource): Likewise.
	(incorrect prerequisite outcome): Likewise.
	(no target for group): Likewise.
	(seed not integer): Likewise.
	* tests/unit/common/parser_create.qmt: Adjust.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qmt: Likewise.

2001-07-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (Database.__ParseResourceDocument): Fix wrong
	variabel name.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py: Rename "action" to "resource" throughout.
	(InstanceBase.__init__): Add properties parameter
	(InstanceBase.SetProperty): New method.
	(InstanceBase.GetProperty): Likewise.
	(InstanceBase.GetProperties): Likewise.
	(Test.__init__): Add properties parameter.
	(Test.GetPrerequisites): Remove absolute parameter.
	(Test.GetResources): Likewise.
	(Resource.__init__): Add properties parameter.
	(Suite.GetTestIds): Assume absolute IDs.
	(Suite.GetRawTestIds): Likewise.
	(Suite.GetRawSuiteIds): Likewise.
	(PrerequisiteMapAdapter.__getitem__): Remove absolute argument.
	(PrerequisiteMapAdapter.get): Likewise.
	* qm/test/xmldb.py: Rename "action" to "resource" throughout.
	(Database.WriteSuite): Assume absolute IDs.
	(Database.__ParseTestDocument): Load properties.
	(Database.__ParseResourceDocument): Likewise.
	(Database.__GetPropertiesFromDomNode): New method.
	(Database.__MakeDomNodeForItem): Include properties.
	* qm/test/cmdline.py (Command.unexpected_sorter): Rename "action"
	to "resource".
	* qm/test/web/web.py: Rename "action" to "resource" throughout.
	(DefaultDtmlPage.FormatTestId): Remove relative_to and within
	parameters.
	(DefaultDtmlPage.FormatResourceId): Likwise.
	(DefaultDtmlPage.FormatSuiteId): Remove within parameter.
	* qm/test/web/dir.py: Rename "action" to "resource" throughout.
	* qm/test/web/show.py: Likewise.
	(handle_submit): Handle properties.
	* qm/test/web/suite.py (ShowPage.FormatSuiteId): Remove.
	* qm/test/classes/temporary.py: Rename "action" to "resource"
	throughout.
	* share/diagnostics/test-help.txt: Likewise.
	* share/dtml/test/dir.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.  Show properties.  Adjust
	formatting.
	* share/xml/test.dtd: Rename "action" to "resource" throughout.
	* share/xml/CATALOG: Likewise.
	* share/xml/action.dtd: Remove.
	* share/xml/resource.dtd: New file.
	* share/web/common.js (property_add_or_change): Check if name is
	valid.
	* share/web/dtml/test/add-action.dtml: Remove.
	* share/web/dtml/test/add-resource.dtml: New file.
	* unit/common/parser_help.qmt: Make IDs absolute.
	* unit/common/parser_parse.qmt: Likewise.
	* unit/test/classes/tempdir1.qma: Likewise.
	* unit/test/classes/tempdir1.qmt: Likewise.
	* unit/track/export/export1.qmt: Likewise.
	* unit/track/export/export2.qmt: Likewise.
	* unit/track/export/idb.qma: Likewise.
	* unit/track/export/setup_idb.qmt: Likewise.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (setup_idb_for_internal_use): Make
	description field multiline.
	(setup_idb_for_test): Likewise.

2001-07-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (open_idb): Fix IDB check.  Improve
	diagnostics.
	* share/diagnostics/track.txt (idb directory missing): New
	diagnostic.
	(idb problem): Likewise.
	(idb path inaccessible): Likewise.
	(idb path wrong): Likewise.
	* share/dtml/track/summary-color-key.dtml: Adjust formatting.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* README: No longer require PyXML.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* PyXML: New imported module.
	* install.py (packages): Include PyXML dir.
	* Makefile.in (SUBDIRS): Add PyXML.
	(PyXML): New rule.
	* qm/setup_path.py.in: Add PyXML dir to Python path.

	* qm/web.py (escape): Rename second definition to...
	(javascript_escape): ... this.
	(unescape): Rename second definition to...
	(javascript_unescape): ... this.
	* qm/track/issue_class.py (encode_state): Use javascript_escape.
	(encode_transition): Likewise.
	(decode_state): Use javascript_unescape.
	(decode_transition): Likewise.
	* qm/test/classes/python.py (ExecTest.fields): Make text fields
	multiline.
	(BaseExceptionTest.fields): Likewise.
	(BaseExceptionTest.CheckArgument): Improve diagnostic.
	(ExceptionTest.CheckArgument): Likewise.
	* qm/test/classes/file.py (FileContentsField.fields): Make text
	field multiline.
	* share/diagnostics/test.txt (test raised wrong argument): Reword.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (DtmlPage.__init__): Remove show_decorations parameter.
	(DtmlPage.GenerateStartBody): Add decorations parameter.
	(DtmlPage.GenerateEndBody): Likewise.
	(DtmlPage.MakeSubmitButton): Remove.
	(DtmlPage.MakeButton): Add css_class parameter.
	(format_exception): Use DtmlPage.default_class.
	(make_button_for_request): Add css_class parameter.
	(make_button_for_url): Likewise.
	(generate_error_page): Use DtmlPage.default_class.
	(generate_login_form): Likewise.
	(make_submit_button): New function.
	* qm/track/web/web.py (DtmlPage): Split off...
	(DefaultDtmlPage): ... this base class.
	(DefaultDtmlPage.GenerateStartBody): Add decorations parameter.
	(_initialize_module): Use DefaultDtmlPage as default_class.
	* qm/track/web/summary.py (DisplayOptionsPage.__init__): Remove
	show_decorations argument.
	(ColorKeyPage.__init__): Likewise.
	* qm/track/issue_class.py (StateField.MakePropertyControls):
	Adjust popup size.
	* qm/test/web/web.py (DtmlPage): Split off...
	(DefaultDtmlPage): ... this base class.
	(__initialize_module): Use DefaultDtmlPage as default_class.
	* qm/test/web/show.py (ShowPage.MakeCategoriesControl): Remove
	show_decorations argument.
	(AddPrerequisitePage.__init__): Likewise.
	(AddActionPage.__init__): Likewise.
	* share/web/stylesheets/qm.css (tr.form-submit): New class.
	(input.submit): Likewise.
	* share/dtml/field.dtml: Adjust formatting.
	* share/dtml/problems.dtml: Likewise.
	* share/dtml/track/summary-display-options.dtml: Likewise.
	* share/dtml/track/summary-color-key.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/issue-class.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/user.dtml: Likewise.
	* share/dtml/track/state-model.dtml: Likewise.  Add help link.
	* share/diagnostics/track-help.txt (state model help): New help
	page.

2001-07-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (escape): New function.
	(unescape): Likewise.
	* qm/fields.py (Field.UpdateFromRequest): Remove debugging output.
	(EnumerationField.__init__): Handle 'None' default.
	(EnumerationField.CompareValues): Handle values not among
	enumerals.
	(EnumerationField.SetAttribute): Don't muck with the default value.
	* qm/track/server.py (make_server): Register state-model.
	* qm/track/qmtrack.in: Handle all other exceptions.
	* qm/track/issue_class.py (Transition.__init__): Make condition
	parameter not a list.
	(Transition.GetConditions): Rename to...
	(Transition.GetCondition): ... this.
	(StateField.property_declarations): New attribute.
	(StateField.__init__): Don't stort state model as object
	attribute.  Call SetStateModel.
	(StateField.SetStateModel): New method.
	(StateField.GetStateModel): Use field attribute.
	(StateField.GetEnumerals): Use GetStateModel.
	(StateField.FormatValueAsHtml): Handle value not among enumerals.
	(StateField.MakePropertyControls): New method.
	(encode_state_model): New function
	(encode_state): Likewise.
	(encode_transition): Likewise.
	(decode_state_model): Likewise.
	(decode_state): Likewise.
	(decode_transition): Likewise.
	(_initialize_module): Reformat descriptions.
	* qm/track/config.py (__global_lock): Rename to...
	(_global_lock): ... this.
	Adjust accordingly throughout.
	(open_idb): Improve diagnostic.
	* qm/track/web/issue_class.py (handle_state_model): New.
	* qm/track/triggers/state.py (Trigger.Preupdate): Handle old state
	not in state model.  Adjust for single condition.
	* share/web/common.js (popup_box): New function.
	(label_is_valid): Likewise.
	(select_item): Likewise.
	(get_selected_value): Likewise.
	* share/dtml/track/state-model.dtml: New template.

2001-07-14  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/attachment.dtml: Use file name if description not
	specified.

2001-07-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetHtmlHelp): Don't print field name in
	smaller font.
	* qm/structured_text.py (TextFormatter.__init__): Add attributes.
	(TextFormatter.End): New method.
	(TextFormatter.StartLink): Implement.
	(TextFormatter.EndLink): Likewise.
	(HtmlFormatter.End): New method.
	(StructuredTextProcessor.__punctuation): Reformat.
	(StructuredTextProcessor.__verbatim_regex): Accept line-end
	terminator.
	(StructuredTextProcessor.__strong_regex): Likewise.
	(StructuredTextProcessor.__emph_regex): Likewise.
	(StructuredTextProcessor.__underline_regex): Likewise.
	(StructuredTextProcessor.__link1_regex): Remove.
	(StructuredTextProcessor.__link2_regex): Likewise.
	(StructuredTextProcessor.__link_regex): New attribute.
	(StructuredTextProcessor.__link_footnote_regex): Likewise.
	(StructuredTextProcessor.__init__): Add attribute.
	(StructuredTextProcessor.__call__): Process hyperlink footnotes.
	(StructuredTextProcessor.End): Call formatter's End method.
	(StructuredTextProcessor.__WriteText): Rewrite hyperlink
	processing.
	* qm/track/web/summary.py (SummaryPage.__init__): Build dictionary
	map.
	(SummaryPage.MakeDisplayOptionsButton): Pass field dictionary to
	DisplayOptionsPage.
	(SummaryPage.MakeColorKeyButton): Pass fields to ColorKeyPage.
	(DisplayOptionsPage.__init__): Take field dictionary parameter.
	(DisplayOptionsPage.GetTitle): Handle IndexError.
	(ColorKeyPage.__init__): Take field parameters.
	(_hls_transform): Improve doc string.
	* share/dtml/track/summary.dtml: Adjust formatting.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/index.py (handle_index): Make a function.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (FieldEditPage.MakeDefaultValueControl): New method.
	(Field.UpdateFromRequest): Process default value.
	(TextField.FormatValueAsHtml): Don't escape structured text HTML.
	(EnumerationField.FormatValueAsHtml): Don't use
	_GetAvailableEnumerals.
	(EnumerationField._GetAvailableEnumerals): Remove.
	* qm/track/issue_class.py (StateField.FormatValueAsHtml): New
	method.
	(IssueClass.__init__): Make some more mandatory fields read-only.
	* share/web/stylesheets/qm.css (th): Make background black.
	(a#colhead): Likewise.
	* share/dtml/field.dtml: Add control for default value.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (TextFormatter.WriteText): Don't print
	spaces at the start of a line.
	* qm/common.py (MutexError): New exception.
	(MutexLockError): Update doc string.
	(FileSystemMutex.Lock): Raise MutexError.
	* qm/cmdline.py: Rename "flag" to "option" throughout.
	* qm/track/server.py (execute): Don't handle CommandError here.
	* qm/track/qmtrack.in: Use GetIdbPath.  Improve diagnostics.
	* qm/track/config.py (initialize_idb): Improve diagnostics.
	* qm/track/cmdline.py (Command.force_option_spec): New attribute.
	(Command.qmtrack_commands): Use it.  Change flags for initialize
	and destroy.
	(Command.__init__): Fix dispatch map.
	(Command.GetIdbPath): New method.
	(Command.Execute): Don't check for missing command here.
	(Command.__Parse): Do it here instead.
	(Command.__PerformInitialize): Use GetIdbPath.
	(Command.__PerformDestroy): Likewise.
	* share/diagnostics/common.txt (invalid enum value): New
	diagnostic.
	(missing command): Rewrite.
	(unrecognized command): New diagnostic.
	* share/diagnostics/track.txt (create field error): Fix
	substitution.
	(create issue error): Likewise.
	(create no equals): Likewise.
	(edit issue error sem): Likewise.
	(field exist): Likewise.
	(field set use equal): Likewise.
	(field set use plus): Likewise.
	(idb locked): Likewise.  Adjust wording.
	(idb parent directory inaccessible): New diagnostic.
	(idb parent directory missing): Likewise.
	(idb path exists): Likewise.
	(initialize no idb path): Remove.
	(initialize wrong flag): Likewise.
	(invalid enum value): Likewise.
	(join iid error sem): Fix substitution.
	(join issue error sem): Likewise.
	(join issue error syn): Likewise.
	(no idb at path): New diagnostic.
	(show no iid): Fix substitution.
	(show wrong args): Likewise.
	(split issue error sem): Likewise.
	* doc/manual/track-tour.xml: Update for changes in initialize
	syntax.

2001-07-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (TextField.property_declarations): Rename nonempty
	to not_empty_text.
	(TextField.CompareValues): Re-compare strings case-sensitively.
	(TextField.Validate): Adjust for not_empty_text.
	(TextField.GetHelp): Likewise.
	(SetField.set_property_declarations): New attribute.
	(SetField.__init__): Use it.
	(SetField.CompareValues): Recompare set contents if they're the
	same length.
	(SetField.Validate): Check not_empty_set attribute.
	* qm/track/issue_class.py (IssueClass.__init__): Use
	not_empty_text.
	* qm/track/web/web.py (HistoryPageFragment.FormatRevisionDiff):
	Use field titles in output.
	* share/diagnostics/common.txt (empty set field value): New
	diagnostic.
	(empty text field value): Likewise.
	* share/diagnostics/track.txt (empty field value): Remove.

2001-07-12  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.ValuesAreEqual): Rename to...
	(Field.CompareValues): ... this.
	(TextField.CompareValues): New method.
	(TextField.FormatValueAsHtml): Truncate to 80 characters.
	(SetField.CompareValues): New method.
	(EnumerationField.CompareValues): Likewise.
	* qm/web.py (format_color): New function.
	* qm/track/issue.py (IssueSortPredicate.__init__): Take field as
	parameter.
	(IssueSortPredicate.__call__): Use CompareValues.
	(get_differing_fields): Likewise.
	(difference_issues): Likewise.
	* qm/track/web/summary.py (SummaryPage.__init__): Add
	hue_field_name, lightness_field_name, saturation_field_name
	parameters.  Pass field to IssueSortPredicate.
	(SummaryPage.MakeDisplayOptionsButton): Pass coloring fields to
	display options page.
	(SummaryPage.IsIssueShown): Remove.
	(SummaryPage.MakeColorKeyButton): New method.
	(SummaryPage.GetBackgroundColor): Reimplement.
	(SummaryPage.GetForegroundColor): Remove.
	(SummaryPage.MakeIssueUrl): Likewise.
	(DisplayOptionsPage.__init__): Add hue_field_name,
	lightness_field_name, saturation_field_name parameters.
	(DisplayOptionsPage.MakeColorableFieldSelect): New method.
	(ColorKeyPage): New class.
	(handle_summary): Set up issue coloring.
	(_color_value_for_enum_field): New function.
	(_color_value_for_enum): Likewise.
	(_hls_transform): Likewise.
	* share/dtml/track/summary.dtml: Add color key button.  Don't use
	IsIssueShown, MakeIssueUrl, GetForegroundColor.
	* share/dtml/track/summary-display-options.dtml: Add heading and
	help link.  Add controls for coloring.
	* share/dtml/track/summary-color-key.dtml: New file.
	* share/diagnostics/track-help.txt (summary display options help):
	New help message.

2001-07-11  Alex Samuel  <samuel@codesourcery.com>

	* COPYING: Update year.

	* qm/web.py (WebRequestHandler.do_POST): Improve error handling.
	(format_exception): Don't use default_class.
	(generate_login_form): Likewise.
	(make_set_control): Add ordered parameter.
	(make_choose_control): Adjust for encode_select_options.
	(format_user_id): DOn't use default_class.
	* qm/user.py (XmlDatabase.__init__): Improve exception.
	* qm/platform_linux.py (open_in_browser): Improve error handling.
	* qm/fields.py (Field.property_declarations): Fix swapped
	attribute descriptions.
	(TextField.property_declarations): Add multiline attribute.
	(TextField.Validate): Remove line breaks if not multiline.
	(TextField.FormatValueAsHtml): Reorganize for multiline.
	(TextField.MakePropertyControls): Add control for multiline.
	(EnumerationField.property_declarations): Augment description.
	(EnumerationField.MakePropertyControls): Make ordered set
	control.
	(TimeField.FormatValueAsHtml): Improve full output format.
	* qm/common.py (add_exit_function): Handle foreign exit function
	better.
	(print_message): Allow zero min_verbose.
	* qm/track/qmtrack.in: Use qm.track.server module.
	* qm/track/server.py (start_server): Rename to...
	(make_server): ... this.  Don't start serving.
	(run_server): New function.
	* qm/track/issue_class.py (StateField.UpdateEnumeration): Remove.
	(StateField.GetEnumerals): New method.
	(StateField.GetHelp): Put state names in italics.
	* qm/track/cmdline.py (Command.start_browser_option_spec): New
	attribute.
	(Command.qmtrack_commands): Include it.  Don't list GadflyIdb.
	(Command.__PerformServer): Print a message if port number isn't
	specified.  Handle --start-browser option.
	* qm/test/cmdline.py (Command.__ExecuteServer): Improve message.

	* share/web/common.js: Comment throughout.
	(remove_from_set): Adjust for encode_select_options.
	(add_to_set): Likewise.
	(move_in_set): New function.
	(update_from_select_list): Replace with...
	(encode_select_options): ... this.
	(property_add_or_change): Adjust for encode_select_options.
	(property_remove): Likewise.
	* share/dtml/field.dtml: Adjust layout.
	* share/dtml/track/show.dtml: Fix Cancel button.
	* share/dtml/track/issue-class.dtml: Don't list triggers.
	* share/dtml/track/add-issue-class.dtml: Improve help text.
	* share/diagnostics/track.txt (initialize invalid idb class): Fix.

	* doc/manual/track-tour.xml (sec-tractut-user-db): Document
	--start-browser option.
	* doc/manual/test-manual.xml (sec-database-contents): New section.

2001-07-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo): Rename to...
	(DtmlPage): ... this.
	(DtmlPage.html_header): Remove.
	(DtmlPage.html_footer): Likewise.
	(DtmlPage.table_attributes): Likewise.
	(DtmlPage.__init__): Remove request parameter.
	(DtmlPage.__call__): New method.
	(DtmlPage.FormatStructuredText): Remove.
	(DtmlPage.MakeUrl): Likewise.
	(DtmlPage.WebRequest): New method.
	(DtmlPage.GenerateHtmlHeader): Put application name in title.
	(DtmlPage.GenerateEndBody): Conditionalize "problems" message.
	(DtmlPage.MakeSubmitButton): New method.
	(DtmlPage.MakeUrlButton): Remove.
	(DtmlPage.MakeHelpLink): Likewise.
	(DtmlPage.MakeHelpLinkHtml): Likewise.
	(format_exception): Use DtmlPage.
	(generate_html_from_dtml): Remove.
	(generate_error_page): Use DtmlPage.
	(generate_login_form): Likewise.
	(make_help_link): Add default for label parameter.
	(make_help_link_html): Likewise.  Use DtmlPage.
	(make_choose_control): Adjust button spacing.
	(_handle_problems): Convert to DtmlPage object.
	(format_user_id): Use DtmlPage.
	* qm/fields.py: Adjust throughout for DtmlPage.

	* qm/track/web/web.py (PageInfo): Rename to...
	(DtmlPage): ... this, and convert.
	Adjust accordingly throughout.
	(DtmlPage.GenerateStartBody): Use document template.
	(generate_html_from_dtml): Remove.
	* qm/track/web/index.py: Adjust throughout for DtmlPage.
	* qm/track/web/issue_class.py: Likewise.
	* qm/track/web/query.py: Likewise.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.

	* qm/test/web/web.py (PageInfo): Rename to...
	(DtmlPage): ... this, and convert.
	(generate_html_from_dtml): Remove.
	* qm/test/web/dir.py: Adjust throughout for DtmlPage.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/suite.py: Likewise.

	* share/dtml/attachment.dtml: Adjust for DtmlPage.
	* share/dtml/set.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/new-suite.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/test/suite.dtml: Likewise.
	* share/dtml/test/navigation-bar.dtml: New file.
	* share/dtml/track/add-issue-class.dtml: Adjust for DtmlPage.
	* share/dtml/track/add-issue-field.dtml: Likewise.
	* share/dtml/track/config-idb.dtml: Likewise.
	* share/dtml/track/history.dtml: Likewise.
	* share/dtml/track/index.dtml: Likewise.
	* share/dtml/track/issue-class.dtml: Likewise.
	* share/dtml/track/notification.dtml: Likewise.
	* share/dtml/track/query.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/track/summary-display-options.dtml: Likewise.
	* share/dtml/track/summary.dtml: Likewise.

2001-07-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (iid): New entity.
	* doc/manual/track-tour.xml: Add "Adding Fields", "Special
	Features" sections.

2001-07-04  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.qm_bug_system_url): Update.
	* share/dtml/track/navigation-bar.dtml: Adjust URLs.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/show.py (handle_submit): Handle IssueExistsError.
	* share/dtml/track/summary.dtml: Top-align issue rows.
	* share/diagnostics/track.txt (iid already used): New diagnostic.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (SetField.__init__): Use contained field property
	declarations.
	(SetField.MakePropertyControls): New method.
	(EnumerationField.property_declarations): New
	attribute.
	(EnumerationField.__init__): Change enumeration parameter to
	enumerals.
	(EnumerationField.SetAttribute): New method.
	(EnumerationField.SetEnumerals): Simplify.
	(EnumerationField.GetEnumerals): Handle empty enumerals.
	(EnumerationField.MakePropertyControls): New method.
	* qm/track/issue_class.py (StateField.__init__): Adjust base class
	initializer call.
	* qm/track/config.py (setup_idb_for_internal_use): Adjust priority
	enumerals.
	(setup_idb_for_test): Adjust severity enumerals.
	* qm/track/web/issue_class.py (_get_issue_class_for_session):
	Don't check issue object ID.
	(handle_show_class): Don't set issue object ID in request.
	(handle_submit_field): Redirect after processing field.
	(handle_delete_field): Don't copy request.
	(handle_new_field): Likewise.
	(handle_new_class): Likewise.
	(handle_submit_notification): Likewise.
	(handle_submit_subscription): Likewise.
	(handle_add_discussion): Likewise.
	* share/dtml/track/issue-class.dtml: Don't open edit page in new
	browser window.
	* share/dtml/add-enumeral.dtml: New template.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (Enumeral): Remove.
	* qm/fields.py (EnumerationField): Reimplement as TextField subclass.
	* qm/track/issue_class.py (StateField.__init__): Adjust accordingly.
	(StateField.UpdateEnumeration): Likewise.
	(StateField._EnumerationField__GetAvailableEnumerals): Rename to...
	(StateField._GetAvailableEnumerals): ... this.
	* qm/track/web/query.py (QueryPageInfo.MakeCategorySelect): Adjust
	accordingly.
	(QueryPageInfo.MakeStateSelect): Likewise.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (idb): New entity.
	* doc/manual/manual.xml (track-tour.xml): New entity.
	Use it.
	* doc/manual/track-tour.xml: New file.

2001-07-03  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/issue_class.py (NotificationPageInfo): New class.
	(handle_show_notification): New function.
	(handle_submit_notification): Likewise.
	(handle_show_subscription): Likewise.
	(handle_submit_subscription): Likewise.
	(handle_add_discussion): Likewise.
	* qm/track/triggers/notification.py (NotifyFixedTrigger.__init__):
	Separate recpients by email address and UID.
	(NotifyFixedTrigger.GetSubscriberAddresses): Reimplement.
	(NotifyFixedTrigger.GetRecipientAddresses): New method.
	(NotifyFixedTrigger.GetRecipientUids): Likewise.
	(NotifyFixedTrigger.AddSubscriberAddress): Rename to...
	(NotifyFixedTrigger.AddRecipientAddress): ... this.
	(NotifyFixedTrigger.AddSubscriberUid): Rename to...
	(NotifyFixedTrigger.AddRecipientUid): ... this.
	* qm/track/server.py (start_server): Register add-discussion,
	show-notification, show-subscription, submit-notification,
	submit-subscription.
	* qm/track/issue_class.py (IssueClass.__init__): Adjust descriptions.
	(IssueClass.RegisterTrigger): Remove existing trigger.
	(IssueClass.GetTrigger): New method.

	* share/dtml/track/issue-class.dtml: Add buttons for special
	features.
	* share/dtml/track/add-notification-address.dtml: New template.
	* share/dtml/track/add-notification-uid.dtml: Likewise.
	* share/dtml/track/subscription.dtml: Likewise.
	* share/dtml/track/notification.dtml: Likewise.
	* share/dtml/track/add-issue-class.dtml: Clean up.

2001-07-02  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_set_control): Add ellipsis to Add...
	(make_select): Add update_external_field parameter.
	* qm/track/web/query.py (QueryPageInfo.MakePythonQueryHelp):
	Handle no issue classes case.
	(QueryPageInfo.MakeCategorySelect): Likewise.
	(QueryPageInfo.MakeStateSelect): Likewise.
	* qm/track/web/issue_class.py (AddClassPageInfo): New class.
	(handle_add_class): New function.
	(handle_new_class): Likewise.
	* qm/track/web/index.py (IndexPageInfo.__init__): Don't set
	default_issue_class if there are none.
	* qm/track/server.py (start_server): Register add-issue-class,
	new-issue-class.
	* qm/track/issue_class.py (default_categories): Make it a list.
	(IssueClass.__init__): Convert categories from list to map.
	* qm/track/config.py (setup_idb_for_internal_use): Make categories
	a list.
	* share/diagnostics/track.txt (invalid class name): New
	diagnostic.
	(missing class title): Likewise.
	* share/dtml/track/issue-class.dtml: Use issue class title.
	Adjust.
	* share/dtml/track/index.dtml: Handle no issue class case.
	* share/dtml/track/config-idb.dtml: Adjust formatting.  Add button
	to add a new class.
	* share/dtml/track/add-issue-class.dtml: Likewise.
	* share/dtml/track/add-category-name.dtml: New template.

2001-07-02  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Add default_user_id
	parameter.
	(generate_login_form): Set default_user_id attribute.
	* qm/track/server.py (do_command_for_xml_rpc): Fix typos.
	* qm/track/qmtrack.in: Handle remote-idb option.
	* qm/track/config.py (set_remote_mode): New function.
	(open_idb): Use it.
	* qm/track/cmdline.py (Command.database_option_spec): Change short
	form to D.
	(Command.remote_database_option_spec): New attribute.
	(Command.qmtrack_option_specs): Include it.
	* qm/test/classes/file.py (FileContentsTest.__init__): Remove
	debugging output.
	* share/dtml/login_form.dtml: Use default_user_id in login form.

2001-07-01  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/server.py (start_server): Move imports of qm.track.web
	modules here.  Register add-issue-field, delete-issue-field,
	new-issue-field.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Add sanity checks.
	(MemoryIdb.UpdateIssueClass): Rewrite field handling code.  Update
	issues.
	* qm/track/issue_class.py (mandatory_field_names): New constant.
	(IssueClass.RemoveField): New method.
	* qm/track/web/summary.py (SummaryPageInfo.FormatFieldValue):
	Watch for missing fields.
	* qm/track/web/issue_class.py (ShowPageInfo.madatory_field_names):
	New attribute.
	(NewFieldPageInfo): New class.
	(handle_delete_field): New function.
	(handle_add_field): Likewise.
	(handle_new_field): Likewise.
	* share/dtml/track/issue-class.dtml: Use MakeButton.  Activate
	buttons.
	* share/dtml/track/add-issue-field.dtml: New template.
	* share/diagnostics/track.txt (invalid field type): New
	diagnostic.

2001-06-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/idb.py: Remove obsolete imports.

2001-06-26  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_set_control): Escape text.
	* qm/fields.py (TextField.FormatValueAsHtml): Adjust verbatim output.
	(SetField.FormatValueAsHtml): Use FormatValueAsText for contents.
	* qm/track/memory_idb.py (MemoryIdb.AddRevision): Fix typo.
	* qm/test/web/suite.py (ShowPageInfo.FormatSuiteId): New method.
	* qm/test/classes/file.py: New file.
	* qm/test/classes/command.py (ScriptTest.fields): Make script
	field a text field.
	(ScriptTest.__init__): Adjust correspondingly.
	* qm/test/cmdline.py (Command.__ExecuteServer): Use print_message.
	* qm/test/base.py (standard_test_class_names): Add
	file.FileContentsTest.
	* share/dtml/test/suite.dtml: Use FormatSuiteId.
	* share/diagnostics/test.txt (file invalid pattern): New
	diagnostic.
	(file invalid substitution): Likewise.
	* tests/unit/track/export/idb.qma: New action.
	* tests/unit/track/export/export1.qmt: New test.
	* tests/unit/track/export/export2.qmt: Likewise.
	* tests/unit/track/export/setup_idb.qmt: Likewise.

2001-06-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (decode_properties): Handle empty properties.
	(format_user_id): Use red instead of blink.
	* qm/fields.py (Field.SetDefaultValue): Don't validate.
	(EnumerationField.Validate): Fix lambda.

	* qm/track/sql_idb.py: Adjust method names throughout.
	* qm/track/memory_idb.py: Likewise.
	(MemoryIdb.AddIssue): Add insert parameter.  Do't use
	__InsertIssue.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.HasIssue): New method.
	(MemoryIdb.__InsertIssue): Remove.
	* qm/track/issue.py (IssueDifference): New class.
	(Issue.Copy): Rename to...
	(Issue.copy): ... this.
	(Issue.SetField): Add assert.
	(load_issues_from_xml_file): Remove.
	(_issues_from_dom): Likewise.
	(difference_issues): New function.
	(patch_issue): Likewise.
	(get_issues_from_dom_node): Likewise.
	(_get_field_values_from_dom_node): Likewise.
	(get_issue_from_dom_node): Likewise.
	(get_issue_difference_from_dom_node): Likewise.
	(get_histories_from_dom_node): Likewise.
	(get_history_from_dom_node): Likewise.
	(export_issues): Likewise.
	* qm/track/idb.py (IssueExistsError): New class.
	(IdbBase.__InvokeGetTriggers): Rename to...
	(IdbBase._InvokeGetTriggers): ... this.
	(IdbBase.__InvokePreupdateTriggers): Rename to...
	(IdbBase._InvokePreupdateTriggers): ... this.
	(IdbBase.__InvokePostupdateTriggers): Rename to...
	(IdbBase._InvokePostupdateTriggers): ... this.
	(import_issue_history): New function.
	* qm/track/config.py (setup_idb_for_internal_use): Add
	documentation to categories.  Add discussion field to
	enhancement_request class.
	* qm/track/cmdline.py: Adjust formatting.
	(Command.formats): Add export.
	(Command.__PerformCreate): Use IssueExistsError.
	(Command.__PerformSplit): Likewise.  Use copy.
	(Command.__PerformJoin): Likewise.
	(Command.__PerformImport): Rewrite.
	(Command.__ImportIssues): New method.
	(Command.__ImportIssueHistories): Likewise.
	(Command.__PrintResults): Handle export format.
	* qm/track/web/summary.py (handle_summary): Rewrite query
	determination logic.

	* share/xml/issue.dtd (histories): New element.
	(history): Likewise.
	(issue-difference): Likewise.
	* share/dtml/track/navigation-bar.dtml: Add banner.
	Don't copy requests.
	* share/diagnostics/track.txt (xml file no revision number): New
	diagnostic.
	(xml file nonconsecutive revisions): Likewise.
	(xml file unknown document element): Likewise.
	(xml file unknown field): Add quotes.

2001-06-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Use AsForm.
	(WebRequest.AsForm): New method.
	(parse_url_query): Print warning instead of error response.
	(make_form_for_request): Remove.
	(make_properties_control): New function.
	(encode_properties): Likewise.
	(decode_properties): Likewise.
	* qm/fields.py (query_field_property_prefix): New variable.
	(FieldPropertyDeclaration): New class.
	(FieldEditPageInfo): Likewise.
	(Field.property_declarations): New attribute.
	(Field.__init__): Initialize properties from property_declarations.
	(Field.GetDescription): Don't specify default here.
	(Field.UnsetDefaultValue): Remove.
	(Field.HasDefaultValue): Likewise.
	(Field.GetAttribute): Make default for default_value None.  Check
	property_declarations for default.
	(Field.IsAttribute): Default to false.
	(Field.GenerateEditWebPage): New method.
	(Field._MakeTextPropertyControl): Likewise.
	(Field._MakeBooleanPropertyControl): Likewise.
	(Field.MakePropertyControls): Likewise.
	(Field.UpdateFromRequest): Likewise.
	(IntegerField): Add doc string.
	(IntegerField.__init__): Pass default_value to base __init__.
	(IntegerField.GetHelp): Assume default value.
	(TextField): Revise doc string.
	(TextField.property_declarations): New attribute.
	(TextField.__init__): Don't initialize properties.
	(TextField.GetHelp): Assume default value.
	(TextField.MakePropertyControls): New method.
	(AttachmentField.__init__): Pass default value to base __init__.
	(EnumerationField.__init__): Likewise.
	(EnumerationField.GetHelp): Assume default value.
	(TimeField.GetTypeDescription): Use FormatValueAsText.
	(TimeField.FormatValueAsText): Accept None value.
	(UidField.__init__): Pass default to base __init__.

	* qm/track/server.py (start_server): Register config-idb,
	show-issue-field, submit-issue-class, submit-issue-field.
	* qm/track/memory_idb.py (MemoryIdb): Reorganize.
	(MemoryIdb.UpdateIssueClass): New method.
	* qm/track/issue_class.py (IidField.__init__): Add default_value
	parameter.
	(IidField.SetDefaultValue): Rewrite.
	(IssueClass.__init__): Don't unset default value for iid.
	* qm/track/issue.py (Issue.__init__): Don't reat IID specially.
	(Issue.GetField): Return field's default value if none in issue.
	(Issue.SetField): Use GetClass.
	(Issue.DiagnosticPrint): Likewise.
	(Issue.Validate): Likewise.
	(Issue.MakeDomElement): Assume a default value.
	* qm/track/idb.py (IdbBase): Reorganize.
	* qm/track/cmdline.py (Command.__PerformCreate): Don't check for
	default value.
	* qm/track/web/query.py (QueryPageInfo.MakeQueryForm): Use AsForm.
	* qm/track/web/issue_class.py (ShowPageInfo.GetFieldType): New
	method.
	(_get_issue_class_for_session): New function.
	(handle_show): Rename to...
	(handle_show_class): ... this.  Rewrite.
	(handle_show_field): New function.
	(handle_submit_field): Likewise.
	(handle_config_idb): Likewise.
	(handle_submit_class): Likewise.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Use AsForm.
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): Likewise.

	* qm/test/cmdline.py (Command.__ExecuteServer): Revise URL message.

	* share/web/common.js: Adjust formatting.
	(property_add_or_change): New function.
	(property_remove): Likewise.
	(property_update_select): Likewise.
	* share/dtml/track/show.dtml: Close input element.
	* share/dtml/track/issue-class.dtml: Rewrite, practically.
	* share/dtml/track/index.dtml: Use MakeButton for administrative
	buttons.
	* share/dtml/field.dtml: New template.
	* share/dtml/track/config-idb.dtml: Likewise.

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/track/show.dtml: Use an ordinary button for OK.

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.GetXmlRpcUrl): Use the explicitly-specified
	host name.
	(WebServer.Bind): Add messages.
	(WebServer.Run): Likewise.
	(handle_login): Close other sessions for same user.
	* qm/track/server.py (start_server): Print XML-RPC URL.
	* qm/track/cmdline.py: Reformat code.
	(Command.verbose_option_spec): New attribute.
	(Command.qmtrack_option_specs): Include it.
	(Command.GetGlobalOptions): Remove.
	(Command.GetCommandOptions): Likewise.
	(Command.HasGlobalOption): New method.
	(Command.GetGlobalOption): Likewise.
	(Command.HasCommandOption): Likewise.
	(Command.GetCommandOption): Likewise.
	Use them throughout.
	(Command.__Parse): Handle verbose option.
	* qm/track/qmtrack.in: Use GetGlobalOption.  Add messages.

2001-06-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/web.py (PageInfo.GenerateStartBody): Use self as
	page info.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Remove.
	(PageInfo.GenerateEndBody): Use _common_javascript.
	(_common_javascript): New variable.
	(_initialize_module): New function.
	Call it.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Generate from
	DTML.
	(__initialize_module): Rename to...
	(_initialize_module): ... this.
	* qm/track/web/summary.py (handle_summary): Process last_query.
	* share/dtml/track/navigation-bar.dtml: New file.
	* share/web/common.js: Likewise.
	* share/web/stylesheets/qm.css (table.navbar): New class.
	(td.navbar): Likewise.
	(a.navbar): Likewise.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* share/dtml/user.dtml: New file.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (create_dom_text_element): Don't add child for
	empty string.
	* qm/web.py (PageInfo.__init__): Make request optional.
	(PageInfo.FormatUserId): Remove.
	(WebServer.__init__): Adjust for _handle_problems and
	_handle_root.
	(_get_path_for_cache_page): New function.
	(get_from_cache): Use it.
	(handle_problems): Rename to...
	(_handle_problems): ... this.
	(handle_root): Rename to...
	(_handle_root): ... this.
	(format_user_id): New function.
	* qm/user.py (xml_user_database_dtd): New variable.
	(User.__init__): Add property parameters.
	(XmlDatabaseUser): Remove class.
	(XmlDatabase.__init__): Remember path.  Use get_user_from_dom and
	get_group_from_dom.
	(XmlDatabase.Write): New method.
	(get_user_from_dom): New function.
	(_get_dom_properties): Likewise.
	(create_dom_for_user): Likewise.
	(_create_dom_properties): Likewise.
	(get_group_from_dom): Likewise.
	(create_dom_for_group): Likewise.
	* qm/fields.py (UidField.FormatValueAsHtml): Use format_user_id.
	* qm/track/config.py (close_idb): Write user database.
	* share/web/stylesheets/qm.css (span.userid): Adjust.
	(a.userid): New class.
	* share/web/images/right-arrow.gif: New bitmap.
	* share/dtml/track/index.dtml: Adjust formatting.
	* share/dtml/track/history.dtml: Use bitmap arrow.  Adjust
	formatting.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (TimeField.GetCurrentTime): Return an int.
	* qm/track/web/web.py (HistoryPageInfo.GetRevisionTime): New method.
	* share/dtml/track/history.dtml: Use it.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* share/diagnostics/track.txt: Alphabetize.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.web): New attribute.
	* qm/common.py (Enumeral.__repr__): Fix typo.
	(Enumeral.__cmp__): Don't check strings against enumeration.
	* qm/track/web/summary.py (DisplayOptionsPageInfo.__init__): Check
	for no issue classes.
	(handle_summary): Handle all exceptions during queries.
	* qm/test/web/web.py (make_server): Register shutdown.
	(handle_shutdown): New function.
	* share/dtml/test/dir.dtml: Add shutdown button.
	* share/diagnostics/track.txt (query misc error): New diagonstic.
	(query name error): Likewise.
	(query syntax error): Likewise.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform_linux.py (find_in_path): New function.
	(open_in_browser): Use it.
	(send_email): Use /usr/lib/sendmail as default.
	* doc/manual/common-manual.xml (sec-rc): New section.
	* doc/manual/test-reference.xml: Add link.
	* doc/manual/test-tour.xml: Likewise.

2001-06-10  Alex Samuel  <samuel@codesourcery.com>

	* configure.in (AC_CONFIG_SUBDIRS): Remove.
	* configure: Regenerate.

2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.__init__): Register /.
	(handle_root): New function.
	* share/web/static/index.html: New file.
	* qm.spec (%files): Revert.

2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (%files): Add /usr/local/share/web/static/*.

2001-06-08  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.qm_bug_system_url): New variable.
	(PageInfo.GetMainPageUrl): New method.
	(PageInfo.GenerateEndBody): Add link to problems page.
	(WebServer.__init__): Register problems.html.
	(format_exception): Rewrite.
	(handle_problems): New function.
	* qm/track/web/web.py (PageInfo.GetMainPageUrl): New method.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	open_only parameter.
	(DisplayOptionsPageInfo.__init__): Likewise.
	(handle_summary): Don't use IsDeleted.  Handle open_only field.
	* qm/track/server.py (start_server): Register /static.
	* qm/track/issue_class.py (State.__init__): Add open parameter.
	(State.IsOpen): New method.
	(StateModel.GetState): Convert state_name to string.
	(StateModel.GetOpenStateNames): New method.
	(_initialize_module): Set open flag for states.
	* qm/track/issue.py (Issue.IsDeleted): Remove.
	(Issue.IsOpen): New method.
	* qm/test/web/web.py (PageInfo.GetMainPageUrl): New method.
	(make_server): Register /static.
	* share/dtml/exception.dtml: New template.
	* share/dtml/problems.dtml: Likewise.
	* share/dtml/track/query.dtml: Align controls better.
	* share/dtml/track/summary-display-options.dtml: Add check box for
	open issues only.
	(do_ok): Process it.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.__WriteSummary): Order results with
	unexpected outcomes better.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Add popup_manual.
	* qm/test/web/web.py (PageInfo.GenerateStartBody): Add manual link.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Likewise.
	* share/dtml/test/dir.dtml: Use GenerateEndBody.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequest.__init__): Copy client_address.
	* qm/fields.py (TimeField.GetDefaultValue): Use
	IntegerField.GetDefaultValue.
	(TimeField.GetHelp): Use default_value attribute.
	* qm/track/issue.py (Issue.GetFieldAsText): New method.
	* qm/track/triggers/discussion.py (DiscussionTrigger.Preupdate):
	Use GetFieldAsText.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Likewise.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (format_time): New function.
	(parse_time): Likewise.
	(timegm): Import or define here.
	* qm/fields.py (SetField.FormatValueAsHtml): Don't coerce to
	string here.
	(TimeField): Rewrite class.
	* tests/unit/common/format_time1.qmt: New test.
	* tests/unit/common/parse_time1.qmt: Likewise.
	* tests/unit/common/parse_time2.qmt: Likewise.
	* tests/unit/common/parse_time3.qmt: Likewise.
	* tests/unit/common/parse_time4.qmt: Likewise.

2001-06-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/classes/python.py (ExecTest.Run): Add expression value
	to failing result.
	* qm/test/cmdline.py (Command.add_test_id): Get rsh program from rc.
	* qm/test/base.py (CommandFailedError): New class.
	(SubprocessEngine._Run): Catch it.
	(CommandEngine.RunTests): Raise it.
	(RshEngine._Run): Likewise.
	* share/tutorial/test/tdb/exec0.qmt: New file.
	* share/tutorial/test/tdb/exec1.qmt: Likewise.
	* share/tutorial/test/tdb/exec2.qmt: Likewise.
	* share/tutorial/test/tdb/test1.qmt: Remove.
	* share/tutorial/test/tdb/test2.qmt: Likewise.
	* share/tutorial/test/tdb/_classes/count.py: Add descriptions.
	* doc/manual/test-tour.xml: Rewrite completely.
	* doc/manual/test-reference.xml: Document some command-line stuff.
	* doc/manual/test-manual.xml: Major revisions and additions.
	* doc/qm.mod (fixme): New entity.

2001-06-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (qmtest-cmd): New entity.
	(qmtrack-cmd): Likewise.
	* doc/manual/track-manual.xml (sec-issue-ids): New section.
	* doc/manual/test-manual.xml: Update.

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (RemoteTestHost.__init__): Change default qmtest
	path.

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/cmdline.py (Command.remote_option_spec): New attribute.
	(Command.conflicting_options_spec): Update.
	(Command.commands_spec): Add --remote-hosts option.
	(Command.add_test_id): Handle --remote-hosts option.
	* qm/test/base.py (RemoteTestHost): New class.
	(MultiProcessEngine): Generalize to...
	(SubprocessEngine): ... this new class.
	(MultiProcessEngine): New class.
	(MultiThreadEngine._Run): Don't call AsMap.
	(MultiRshEngine): New class.
	(RshEngine.__init__): Use RemoteTestHost instances.
	(RshEngine._Run): Likewise.

2001-05-31  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (load_xml_file): Split into...
	(load_xml): ... this new function.
	* qm/platform_linux.py (get_user_name): New function.
	* qm/platform_win32.py (get_user_name): Likewise.

	* qm/test/cmdline.py (Command.MakeContext): Look for
	--context-file and --context arguments at the same time.  Allow
	--context-file from stdin.
	(Command.add_test_id): Use MultiProcessEngine.
	(Command.__WriteResults): Use write_results.
	* qm/test/base.py (MultiThreadEngine): Generalize into...
	(ConcurrentEngine): ... this.
	(MultiProcessEngine): New class.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Reimplement, generalized.
	(LocalCommandEngine): New class.
	(RshEngine): Likewise.
	(write_results): New function.
	(save_results): Likewise.
	(read_results): Likewise.
	(load_results): Use it.
	(__results_from_dom): Rename to...
	(_results_from_dom): ... this.

2001-05-30  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (html_help_text): New variable.
	* qm/fields.py (TextField.FormatValueAsHtml): Show indication when
	editing structured text.
	(EnumerationField.__GetAvailableEnumerals): Add time zone.
	* qm/track/web/show.py (ShowPageInfo.FormatFieldValue): Handle
	user and timezone specially when editing.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* share/diagnostics/track-help.txt: New file.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue.py (Issue.GetField): Use field's default if the
	issue doesn't have a value.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_select): Add form_name parameter.
	* qm/track/web/query.py (QueryPageInfo.__init__): Don't get field
	names.
	(QueryPageInfo.MakeQueryForm): Add name parameter.
	(QueryPageInfo.GetFieldTypeDescription): Remove.
	(QueryPageInfo.MakePythonQueryHelp): New method.
	(QueryPageInfo.MakeCategorySelect): Likewise.
	(QueryPageInfo.MakeStateSelect): Likewise.
	* qm/track/config.py (__initialize_module): Load help diagnostics.
	* share/dtml/track/query.dtml: Remove help info.  Add browse
	controls.
	* share/dtml/track/index.dtml: Adjust labels for query.

2001-05-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (SetField.GetHtmlHelp): Don't add old help twice.
	* qm/common.py (Enumeral.__cmp__): Check RHS against enumerals for
	strings only.
	* qm/track/issue_class.py (IidField.__init__): copy attributes.
	(DiscussionField): New class.
	* qm/track/issue.py (Issue.MakeDomElement): Compare value as string.
	* qm/track/config.py (setup_idb_for_internal_use): Add discussion
	field.
	* qm/track/triggers/discussion.py: New file.
	* qm/track/web/web.py (HistoryPageInfo.FormatRevisionDiff): Handle
	set fields specially.

2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/test-manual.xml: Mention scheduling across threads
	and hosts.

2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/manual.xml: Include track-manual.xml.
	* doc/manual/track-manual.xml: New file.
	* doc/manual/test-manual.xml: Adjust.

2001-05-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/graph.py: Add doc string.
	(CycleError): New class.
	(__sort_helper): Handle node missing from edges map.
	(_partition): New function.
	(partition_as_map): Likewise.
	* qm/common.py (Lock): New class.
	(MutexMixin): Likewise.
	(OrderedMap.AsMap): New method.
	(print_message): Swap order of parameters.
	* share/diagnostics/test.txt (invalid concurrency): Likewise.
	* qm/test/xmldb.py (Database): Also derive from MutexMixin.
	(Database.GetClassPaths): Lock.
	(Database.HasTest): Likewise.
	(Database.GetTest): Likewise.
	(Database.WriteTest): Likewise.
	(Database.RemoveTest): Likewise.
	(Database.GetTestIds): Likewise.
	(Database.HasAction): Likewise.
	(Database.GetAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.RemoveAction): Likewise.
	(Database.GetActionIds): Likewise.
	* qm/test/cmdline.py (Command.concurrent_option_spec): New
	attribute.
	(Command.commands_spec): Include it.
	(Command.add_test_id): Handle --threads option.
	* qm/test/base.py (Engine): Rename to...
	(InProcessEngine): ... this.
	(Engine): New class.
	(MultiThreadEngine): Likewise.
	(CommandEngine): Likewise.
	(load_database): Adjust call to print_message.

2001-05-24  Alex Samuel  <samuel@codesourcery.com>

	* README: Mention Distutils.
	* qm/web.py (Session.__init__): Increase default timeout.
	* qm/platform_linux.py (RunProgramError): New class.
	(ProgramTerminateBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	(run_program_captured): Add doc string.  Use /dev/null for empty
	stdin.
	(get_temp_directory): New function.
	* qm/platform.py (RunProgramError): Remove.
	(ProgramTerminateBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	* qm/label.py (thunk): Change + to x.
	(normpath): Remove multiple separators.
	(join): Normalize result.
	(to_path): Handle root path.
	(is_prefix): New function.
	* qm/fields.py (IntegerField.FormatValueAsHtml): Implement hidden
	style.
	(TextField.FormatValueAsHtml): Likewise.  Convert value to
	string.  Escape preformatted text.
	(SetField.FormatValueAsHtml): Implement hidden style.
	(EnumerationField.FormatValueAsHtml): Likewise.
	* qm/common.py (Enumeral.__cmp__): Check that RHS is valid enumeral.
	(load_module): Adjust Python path while loading module.
	(ends_with): New function.
	* share/dtml/test/suite.dtml: Adjust.
	* share/diagnostics/track.txt (address in use): Remove.
	* share/diagnostics/test.txt (unknown test or suite id): Adjust.
	* share/diagnostics/common.txt (address in use): New diagnostic.
	(could not read file): Likewise.
	* qm/track/qmtrack.in: Write message if KeyboardInterrupt.
	* qm/test/qmtest.in (program_name): Handle KeyboardInterrupt.
	* qm/test/cmdline.py (Command.context_file_spec): New attribute.
	(Command.commands_spec): Include it.
	(Command.MakeContext): Handle context-file option.
	(Command.__ParseContextAssignment): New method.
	(Command.add_test_id): Extract results from profile context.
	(Command.WriteSummary): Treat missing expected outcome as PASS.
	Adjust formatting.
	* qm/test/base.py (InstanceBase.SetWorkingDirectory): Use
	GetArguments.
	(Suite.__init__): Initialize __test_id_cache.
	(Suite.GetTestIds): Cache result.
	(ResultWrapper.MakeDomNode): Handle sequence property values.
	(Engine.RunTests): Pass through KeyboardInterrupt.
	(load_database): Print warning when import fails.
	* qm/test/web/web.py (PageInfo.FormatTestId): Add within parameter.
	(PageInfo.FormatActionId): Likewise.
	(PageInfo.FormatSuiteId): Likewise.
	* qm/test/web/suite.py (ShowPageInfo.MakeAbsoluteId): New method.
	* qm/test/web/show.py (ShowPageInfo.IsShowField): Remove.
	(ShowPageInfo.FormatFieldValue): Handle hidden and read-only fields.

2001-05-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod: Add note.
	* doc/manual/test-manual.xml: Corrections.
	* doc/manual/test-tour.xml: Likewise.

2001-05-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (print_message): New function.
	(verbose): New variable.
	* qm/test/cmdline.py (Command.profile_option_spec): New attribute.
	(Command.commands_spec): Include it.
	(Command.Execute): Set global verbose value.
	(Command.add_test_id): Add profiling.
	* qm/test/base.py (Engine.null_function): Add messages.

2001-05-18  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py (_NotifyTrigger.Postupdate):
	Fix syntax error.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py (_NotifyTrigger.Postupdate):
	Set subject differently for new issues.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (escape): Don't handle empty strings specially.
	(make_help_link_html): Adjust spacing.
	* qm/fields.py (Field.FormatValueAsText): Add columns parameter.
	(Field.GetHtmlHelp): Mention field name at end.
	(IntegerField.FormatValueAsText): Add columns parameter.
	(TextField.FormatValueAsText): Likewise.
	(TextField.FormatValueAsHtml): Adjust output.
	(SetField.FormatValueAsText): Add columns parameter.
	(AttachmentField.FormatValueAsText): Likewise.
	(EnumerationField.FormatValueAsText): Likewise.
	* qm/common.py (indent_lines): New function.
	(wrap_lines): Likewise.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	sort_order parameter.
	(handle_summary): Put sort order in user configuration.
	* qm/track/web/show.py (handle_submit): Don't format structured
	text errors here.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Improve output format.
	* qm/track/server.py (start_server): Register path to manual.
	* qm/track/qmtrack.in: Set qm.common.program_name.
	* qm/track/issue_class.py (StateField.GetHelp): Fix spacing in
	enumeral list.
	* share/web/stylesheets/qm.css (span.error): Use darker red.
	* share/dtml/track/show.dtml: Space Help buttons.

2001-05-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeLoginForm): Adjust HTML.
	(PageInfo.UserIsInGroup): New method.
	(make_form_for_request): Add name parameter.
	(handle_login): Handle exceptions.
	* qm/user.py: Add doc string.
	(Group): New class.
	(DefaultDatabase.GetGroupIds): New method.
	(DefaultDatabase.GetGroup): Likewise.
	(XmlDatabase.__init__): Load groups.
	(XmlDatabase.GetGroupIds): New method.
	(XmlDatabase.GetGroup): Likewise.
	* qm/platform_linux.py (CLOSE_STREAM): New variable.
	(replace_program): New function.
	(run_program): Likewise.
	* qm/platform.py (RunProgramError): New class.
	(ProgramTerminatedBySignalError): Likewise.
	(ProgramStoppedError): Likewise.
	* qm/common.py (Empty): New class.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Specify form
	name.
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeEditForm): Remove.
	(IndexPageInfo.MakeShowAllForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Specify form name.
	(IndexPageInfo.MakeShutdownForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): Likewise.
	* qm/track/server.py (handle_shutdown): Disallow non-administrators.

	* share/xml/users.xml.template: Add a group.
	* share/xml/user.dtd (users): Allow group elements.
	(group): New element.
	(user-id): Likewise.
	* share/web/stylesheets/qm.css (a.help-link): Don't specify
	decorations.
	* share/dtml/track/index.dtml: Adjust buttons.  Show shutdown
	button for administrators only.
	* share/diagnostics/common.txt (disabled account): New diagnostic.
	(invalid login): Likewise.
	(shutdown not allowed): Likewise.

	* doc/manual/manual.xml (common-manual.xml): New entity.  Include it.
	* doc/manual/common-manual.xml: New file.

2001-05-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.GetDefaultValue): Copy the result.
	* qm/common.py (copy): New function.
	* qm/track/server.py (start_server): Don't call get_host_name.
	* qm/test/cmdline.py (Command.Execute): Use load_database.
	* qm/test/base.py (Suite.GetTestIds): Use dirname.  Handle paths
	differently in implicit suites.
	(Database.GetPath): New method.
	(Database.GetClassPaths): Use _classes directory if it exists.
	(load_database): New function.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Fix syntax.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Don't subscribe a user twice.
	* qm/common.py (Enumeral.__cmp__): Handle TypeError.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/triggers/notification.py
	(NotifyByUidFieldTrigger.Preupdate): Handle new issues correctly.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/issue_class.py (IssueClass.__init__): Adjust default
	state model.
	* qm/track/issue.py (eval_revision_expression): Improve doc
	string.  Add _new to namespace.
	* qm/track/config.py (setup_idb_for_internal_use): Adjust.
	* qm/track/triggers/notification.py
	(_NotifyTrigger.__MakeMessage): Handle new issues correctly.

2001-05-15  Alex Samuel  <samuel@codesourcery.com>

	* qm/platform.py: Remove contents and split it into...
	* qm/platform_linux.py: ... this new file, and...
	* qm/platform_win32.py: ... this, likewise.
	* qm/track/server.py (execute): Let SignalException through.
	* qm/track/qmtrack.in: Handle SignalException.
	* qm/track/memory_idb.py (MemoryIdb.Close): Call __Write.
	(MemoryIdb.__Write): New method.
	(MemoryIdb.AddIssueClass): Call __Write.
	(MemoryIdb.__InsertIssue): Likewise.
	* qm/test/qmtest.in: Import qm.platform.

2001-05-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_url_for_request): Remove.
	Use AsUrl instead of make_url_for_request throughout.
	* qm/fields.py: Likewise.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/suite.py: Likewise.
	* qm/test/web/web.py: Likewise.
	* qm/track/web/index.py: Likewise.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.
	* qm/track/web/web.py: Likewise.

2001-05-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequestHandler.__HandlePageCacheRequest): New
	method.
	(WebRequestHandler.__HandleSessionCacheRequest): Likewise.
	(WebRequestHandler.__HandleRequest): Call them.
	(WebRequest.AsUrl): New method.
	(make_set_control): Adjust for using page cache.
	(make_popup_dialog_script): Rename to...
	(make_popup_dialog): ... this and adjust for using page cache.
	(make_confirmation_dialog_script): Rename to...
	(make_confirmation_dialog): ... this, and remove function_name
	parameter.
	(Session.make_button_for_popup): Reimplement using page cache.
	Leave old implementation, but disabled.
	(cache_page): New function.
	(get_from_cache): Likewise.
	(_page_cache_path): New variable.
	(_page_cache_name): Likewise.
	(_session_cache_name): Likewise.
	* qm/platform.py: Adjust formatting.
	* qm/fields.py (TextField.FormatValueAsHtml): Escape field values.
	(AttachmentField.FormatValueAsHtml): Use make_button_for_popup.
	* qm/common.py (make_temporary_directory): New function.
	(add_exit_function): Likewise.
	(_at_exit): Likewise.
	(_exit_functions): New variable.

	* share/diagnostics/common.txt (temp dir error): New diagnostic.
	* share/dtml/test/add-prerequisite.dtml: (add_prerequisite):
	Likewise.
	* share/dtml/test/add-category.dtml (add_category): Likewise.
	* share/dtml/test/add-action.dtml (add_action): Hard-code form
	field names.
	* share/dtml/test/suite.dtml: Adjust for MakeDeleteScript.
	* share/dtml/test/show.dtml: Likewise.

	* qm/track/web/web.py (make_url_for_attachment): Stash attachment
	file name at end of URL.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Pass request
	to make_button_for_popup.
	* qm/test/web/web.py (PageInfo.FormatTestId): Add relative_to
	parameter.
	(PageInfo.FormatActionId): Likewise.
	(make_server): Don't register add-action, add-category,
	add-prerequisite.
	* qm/test/web/suite.py (ShowPageInfo.MakeDeleteScript): Adjust for
	make_confirmation_dialog.
	* qm/test/web/show.py (ShowPageInfo.MakePrerequisitesControl):
	Generate page here for make_set_control.
	(ShowPageInfo.MakeActionsControl): Likewise.
	(ShowPageInfo.MakeCategoriesControl): Likewise.
	(ShowPageInfo.MakeDeleteScript): Adjust for make_confirmation_dialog.
	(AddPrerequisitePageInfo.__init__): Add base_path parameter.
	(AddActionPageInfo.__init__): Add action_path parameter.
	(handle_add_prerequisite): Remove.
	(handle_add_action): Likewise.
	(handle_add_category): Likewise.
	* qm/test/classes/python.py (ExecTest.fields): Set verbatim
	attribute on expression field.
	* qm/test/xmldb.py (Database.__GetPrerequisitesFromDomNode): Don't
	make IDs absolute here.
	(Database.__GetActionsFromDomNode): Likewise.
	(Database.__MakeDomNodeForTest): Don't reverse absolute IDs here.
	(Database.__MakeDomNodeForAction): Likewise.
	* qm/test/base.py (Test.GetPrerequisites): Add absolue parameter.
	(Test.GetActions): Likewise.
	(PrerequisiteMapAdapter.__getitem__): Use absolute IDs.
	(Engine.null_function): Likewise, for prerequisites and actions.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/summary.py (DisplayOptionsPageInfo.__init__): Don't
	show hidden fields.
	* qm/track/config.py (setup_idb_for_test): Make the notification
	field hidden.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (scan_dir_for_suite_dirs): Skip directories
	named CVS.
	* qm/test/web/suite.py (ShowPageInfo.__init__): Construct controls
	for tests and suites here.
	* share/dtml/test/suite.dtml: Use test and suite controls from
	page info.

2001-05-11  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Rename update_set to
	update_from_select_list.  Add move_option and swap_option.
	(__counter): Remove.
	(make_set_control): Use _counter.
	(_help_counter): Remove.
	(make_help_link_html): Use _counter.
	(make_select): Add default arguments.
	(make_choose_control): New function.
	(make_button_for_popup): Likewise.
	(_counter): New variable.
	* qm/fields.py (EnumerationField.GetTypeDescription): Fix quoting.
	(UidField.FormatValueAsHtml): Remove extraneous arguments to
	make_select.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Add
	field_names parameter.  Generate display options page.
	(SummaryPageInfo.IsLinkToIssue): Remove.
	(DisplayOptionsPageInfo): New class.
	(handle_summary): Figure out fields to show.
	* share/dtml/track/summary.dtml: Add Display Options button.
	Adjust.
	* share/dtml/track/summary-display-options.dtml: New file.

	* doc/manual/manual.xml: Fix title.

2001-05-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_select): New function.
	* qm/user.py (DefaultDatabase.keys): New method.
	(XmlDatabase.keys): Likewise.
	* qm/fields.py (EnumerationField.FormatValueAsHtml): Use
	make_select.
	(UidField.FormatValueAsHtml): New method.
	* share/xml/users.xml.test-values: New file.
	* qm/track/config.py (initialize_idb): Add test_values parameter.
	Initialize test values and test user database.
	* qm/track/cmdline.py (Command.__PerformInitialize): Don't
	generate test values here.

2001-05-10  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_javascript_string): Don't escape slashes.
	* qm/platform.py: New class.
	(MailError.send_email): New function.
	* qm/fields.py (Field.FormatValueAsText): New method.
	(IntegerField.FormatValueAsText): Likewise.
	(TextField.FormatValueAsText): Likewise.
	(SetField.FormatValueAsText): Likewise.
	(AttachmentField.FormatValueAsText): Likewise.
	(EnumerationField.FormatValueAsText): Likewise.
	(UidField.__init__): Use default user ID as default value.
	* qm/common.py (RcConfiguration.Get): Return default if no rc file
	loaded.
	* share/diagnostics/common.txt (sendmail error): New diagnostic.
	* qm/track/triggers/state.py (Trigger.Preupdate): Call
	eval_revision_expression.
	* qm/track/triggers/notification.py: New file.
	* qm/track/qmtrack.in: Load rc file.
	* qm/track/issue.py (eval_expression): Replace with...
	(eval_issue_expression): ... this.
	(eval_revision_expression): New function.
	* qm/track/idb.py (IdbBase.Query): Call eval_issue_expression.
	* qm/track/config.py (setup_idb_for_test): Add notification stuff.

2001-05-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (parse_url_query): Unquote the script URL.
	(make_javascript_string): Escape forward slashes.
	* qm/common.py (Enumeral): New class.
	* qm/fields.py (Field.__init__): Add initialze_to_default attribute.
	(Field.GetAttributeNames): New method.
	(EnumerationField.__init__): Make an Enumeral.
	(EnumerationField.GetTypeDescription): Use enumeral strings.
	(EnumerationField.Validate): Rewrite.
	(EnumerationField.GetEnumerals): Modify for Enumeral.
	(EnumerationField.ValueToName): Remove.
	(EnumerationField.ParseFormValue): Make an Enumeral.
	(EnumerationField.FormEncodeValue): Use enumeral string.
	(EnumerationField.FormDecodeValue): Make an Enumeral.
	(EnumerationField.FormatValueAsHtml): Modify for Enumeral.
	(EnumerationField.MakeDomNodeForValue): Likewise.
	(EnumerationField.GetHelp): Likewise.
	(EnumerationField.__GetAvailableEnumerals): New method.

	* qm/track/web/show.py (ShowPageInfo.__init__): Rename
	field_errors to errors.  Process structured text.
	(ShowPageInfo.FormatFieldValue): Handle initialize_to_default
	attribute.
	(handle_submit): Handle trigger rejections.
	* qm/track/triggers: New directory.
	* qm/track/triggers/__init__.py: New file.
	* qm/track/triggers/state.py: Likewise.
	* qm/track/web/issue_class.py: Likewise.
	* qm/track/server.py (start_server): Register show-issue-class.
	* qm/track/memory_idb.py (MemoryIdb.GetIssue): Fix parameter name
	collision.  Adjust trigger treatment.
	(MemoryIdb.GetAllRevisions): Likewise.
	(MemoryIdb.__InsertIssue): Likewise.
	* qm/track/sql_idb.py (SqlIdb.GetIssues): Likewise.
	(SqlIdb.GetIssue): Likewise.
	(SqlIdb.GetAllRevisions): Likewise.
	(remap): Remove crud.
	(pprint_ast): Likewise.
	* qm/track/issue_class.py (default_states): Remove.
	(default_state_model): New variable.
	(default_state_model): New class.
	(default_state_model): Likewise.
	(TriggerResult): Likewise.
	(Trigger): Likewise.
	(State): Likewise.
	(TransitionCondition): Likewise.
	(Transition): Likewise.
	(StateModel): Likewise.
	(StateField): Likewise.
	(IssueClass.__init__): Replace states parameter with state_model.
	Initialize __triggers.  Create the state field.
	(IssueClass.RegisterTrigger): New method.
	(IssueClass.GetTriggers): Likewise.
	(_initialize_module): New function.
	Call it.
	* qm/track/issue.py (eval_expression): New function.
	(allowed_builtins): New variable.
	(_initialize_module): New function.
	Call it.
	* qm/track/idb.py (Trigger): Remove.
	(TriggerOutcome): Likewise.
	(TriggerRejectError): New class.
	(IdbBase.__init__): Remove __triggers attribute.
	(IdbBase.RegisterTrigger): Remove.
	(IdbBase.UnregisterTrigger): Likewise.
	(IdbBase.GetTriggers): Likewise.
	(IdbBase.Query): Call eval_expression instead of rexec stuff.
	(IdbBase.__InvokeGetTriggers): Rewrite.
	(IdbBase.__InvokePreupdateTriggers): Likewise.
	(IdbBase.__InvokePostupdateTriggers): Likewise.
	* qm/track/cmdline.py (Command.__PerformInitialize): Process
	structured text message.

	* share/dtml/track/show.dtml: Adjust markup to show errors.
	* share/dtml/track/issue-class.dtml: New file.
	* share/diagnostics/track.txt (no changes): New diagonstic.
	(no transition): Likewise.
	(not initial state): Likewise.
	(transition condition failed): Likewise.

2001-05-01  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (RcConfiguration.Get): Remove mention of DEFAULT.
	Use section parameter correctly.
	* qm/platform.py: New file.
	* qm/test/web/web.py (start_server): Rename to...
	(make_server): ... this.  Return server instead of running it.
	* qm/test/xmldb.py (Database.GetClassPaths): New method.
	* qm/test/cmdline.py (Command.start_browser_option_spec): New
	variable.
	(Command.commands_spec): Use it.  Remove edit and template
	commands.
	(Command.HasGlobalOption): New method.
	(Command.HasCommandOption): Likewise.
	(Command.__ExecuteEdit): Remove.
	(Command.__EditTest): Likewise.
	(Command.__ExecuteTemplate): Likewise.
	(Command.__ExecuteServer): Start browser if requested.
	* qm/test/base.py (Database.GetClassPaths): New method.
	(get_class): Remove extra_paths parameter.  Use the database's
	class paths.
	* share/tutorial/test/tdb/_classes/: New directory.
	* share/tutorial/test/count.py: Move to...
	* share/tutorial/test/tdb/_classes/count.py: ... here.
	* share/diagnostics/test-help.txt (action class control): Mention
	_classes subdirectory.
	(test class control): Likewise.
	* share/diagnostics/common.txt (browser error): New diagnostic.
	* doc/manual/manual.xml: Include test-reference.xml.
	* doc/manual/test-manual.xml: Add section on specifying test classes.
	* doc/manual/test-reference.xml: New file.

2001-04-30  Benjamin Chelf  <chelf@codesourcery.com>

	* install.bat: New file.

2001-04-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/core.xml: Paste in text from design document.

2001-04-30  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (PYTHONDOCDIRS): Comment out.
	* install.py (doc_files): Add manual PDF file.
	(doc_dirs): New variable.
	Substitute @qm_doc_path2 in setup_path.py.
	Install documentation directories.
	* qm/Makefile.in (setup_path.py): Substitute @qm_doc_path@.
	* qm/setup_path.py.in (__doc_dir): New variable.
	Set QM_DOC_PATH environment variable.
	* qm/common.py (get_doc_directory): New function.
	* qm/test/web/web.py (start_server): Register manual directory.
	* qm/web.py (PageInfo.html_generator): Remove.
	(session_id_field): In show_help, open window with toolbar and
	scrollbars options.
	(PageInfo.GetProgramName): New method.
	(PageInfo.GenerateHtmlHeader): Use it.
	(make_help_link_html): Generate page from DTML.
	* share/dtml/help.dtml: New file.
	* doc/Makefile.in (SUBDIRS): Remove design doc directories.
	* doc/manual/Makefile.in (DOCBOOKMAIN): Change to manual.xml.
	* doc/manual/main.xml: Rename to...
	* doc/manual/manual.xml: ... this.

2001-04-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/web/web.py (start_server): Register delete-test,
	delete-action, and delete-suite scripts.
	* qm/test/web/suite.py (ShowPageInfo.MakeDeleteScript): New method.
	(handle_delete): New function.
	* qm/test/web/show.py (ShowPageInfo.MakeDeleteScript): New method.
	(handle_delete): New function.
	* qm/test/xmldb.py (Database.RemoveTest): New method.
	(Database.RemoveAction): Likewise.
	(Database.RemoveSuite): Likewise.
	* qm/test/base.py (Database.RemoveTest): New method.
	(Database.RemoveSuite): Likewise.
	(Database.RemoveAction): Likewise.
	* qm/web.py (make_popup_dialog_script): New function.
	(make_confirmation_dialog_script): Likewise.
	(make_popup_page): Likewise.
	* share/web/stylesheets/qm.css (body.popup): New class.
	* share/dtml/test/show.dtml: Add Delete button.
	* share/dtml/test/suite.dtml: Likewise.

2001-04-29  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_help_link_html): Use a.help-link CSS class.
	* qm/test/xmldb.py (Database.__GetSuite): Don't make IDs absolute.
	* qm/test/web/web.py (start_server): Register create-suite and
	new-suite scripts.
	* qm/test/web/suite.py: Improve doc strings.
	(ShowPageInfo.__init__): Fix exclusion of suite's own ID.
	(NewPageInfo): New class.
	(handle_submit): Handle empty ID lists correctly.
	(handle_new): New function.
	(handle_create): Likewise.
	* share/diagnostics/test-help.txt (suite ID): New diagnostic.
	* share/diagnostics/test.txt (suite already exists): Likewise.
	* share/web/stylesheets/qm.css (a.help-link): New class.
	* share/dtml/test/suite.dtml: Adjust.
	* share/dtml/test/new-suite.dtml: New file.

2001-04-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeUrl): New method.
	(make_url): New function.
	* qm/test.py: Remove file.
	* qm/test/web/web.py (PageInfo.FormatSuiteId): New method.
	(start_server): Register edit-suite, show-suite, submit-suite
	scripts.
	* qm/test/web/suite.py: New file.
	* qm/test/web/dir.py (DirPageInfo.FormatItem): Use FormatSuiteId.
	* qm/test/cmdline.py (Command.__ExecuteRun): Process arguments
	here.
	(Command.__ExecuteEdit): Use "unknown test id" diagnostic.
	(Command.__WriteResults): Use base.dtds.
	* qm/test/xmldb.py (Database.WriteTest): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetSuite): Use __GetSuite.
	(Database.WriteSuite): New method.
	(Database.GetSuiteIds): Handle implicit parameter.
	(FileSuite): Remove.
	(DirectorySuite): Reimplement.
	(scan_dir_for_suite_dirs): New function.
	* qm/test/base.py (dtds): New variable.
	(InstanceBase.__MakeItem): New method.
	(Test.GetTest): Use it.
	(Action.GetAction): Likewise.
	(Suite): Reimplement.
	(Database.GetSuiteIds): Add implicit parameter.
	(get_all_test_ids): Remove.
	(expand_and_validate_ids): Likewise.

	* share/xml/CATALOG: Add suite DTD.
	* share/xml/suite.dtd: New file.
	* share/dtml/test/suite.dtml: New file.
	* share/diagnostics/test.txt (no id for edit): Generalize.
	(no id for show): Likewise.
	(no id for submit): Likewise.
	(unknown id): Remove.
	(unknown test id): New diagnostic.
	(unknown test or suite id): Likewise.
	* share/diagnostics/test-help.txt (suite suite IDs): New
	diagnostic.
	(suite suite IDs control): Likewise.
	(suite test IDs): Likewise.
	(suite test IDs control): Likewise.

	* tests/unit/common/label_thunk.qmt: Remove test for thunk of
	empty label.
	* tests/common.qms: Convert to XML format.

2001-04-26  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.common_javascript): Add help_window.  Add
	show_help.
	(PageInfo.MakeHelpButton): Remove.
	(PageInfo.MakeHelpLink): New method.
	(PageInfo.MakeHelpLinkHtml): Likewise.
	(make_set_control): Make popup resizable.  Change popup window
	logic.
	(make_help_button): Remove.
	(make_help_link): New function.
	(_help_counter): New variable.
	(make_help_link_html): New function.
	* qm/structured_text.py (HtmlFormatter.__verbatim_regex): Match at
	start of line.
	(HtmlFormatter.__strong_regex): Likewise.
	(HtmlFormatter.__emph_regex): Likewise.
	* qm/fields.py (Field.GetHelp): New method.
	(Field.GetHtmlHelp): Likewise.
	(IntegerField.GetHelp): Likewise.
	(TextField.GetHelp): Likewise.
	(SetField.FormatValueAsHtml): Specify window size.
	(SetField.GetHelp): New method.
	(SetField.GetHtmlHelp): Likewise.
	(AttachmentField.FormatValueAsHtml): Rename button "Change..."
	(AttachmentField.GetHelp): New method.
	(AttachmentField.GetHtmlHelp): Likewise.
	(EnumerationField.GetHelp): Likewise.
	(UidField.__init__): Pass attributes to base.
	* qm/diagnostic.py (DiagnosticSet.program_name): Remove.
	(DiagnosticSet.Generate): Use common.program_name.
	* qm/common.py (program_name): New variable.
	* qm/Makefile.in ($(SCRIPTS)): Use PYTHONBIN.
	* qm/track/config.py (setup_idb_for_test): Adjust syntax.  Add
	descriptions.
	* qm/track/issue_class.py (IssueClass.__init__): Likewise.
	(IidField.__init__): Pass attributes to base.
	* qm/test/qmtest.in: Set common.program_name.  Load help diagnostics.
	* share/dtml/attachment.dtml: Add help links.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/diagnostics/common-help.txt: New file.
	* share/web/stylesheets/qm.css (body): Specify font-family.
	(a:link): Don't specify background.
	(a:visited): Likewise.
	(a:active): Likewise.
	(a:hover): Likewise.

2001-04-25  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/Makefile.in: Fix typo.

2001-04-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (write_dom_document): Don't write emacs gunk.
	* qm/web.py (PageInfo.common_javascript): New attribute.
	(PageInfo.FormatStructuredText): New method.
	(PageInfo.GenerateEndBody): Include common JavaScript.
	(PageInfo.MakeButton): New method.
	(PageInfo.MakeUrlButton): Reimplement.
	(PageInfo.MakeHelpButton): New method.
	(WebRequest.GetScriptName): Likewise.
	(make_url_button): Remove.
	(make_button_for_request): New function.
	(make_button_for_url): Likewise.
	(generate_error_page): Likewise.
	(__counter): New variable.
	(make_set_control): New function.
	(encode_set_control_contents): Likewise.
	(decode_set_control_contents): Likewise.
	(make_javascript_string): Likewise.
	(make_help_button): Likewise.
	* qm/label.py (UnmakeRelativeTo.__call__): Handle empty path case.
	(basename): New function.
	(dirname): Likewise.
	* qm/structured_text.py (get_first): Likewise.
	(get_rest): Likewise.
	* qm/fields.py (Field.SetAttributes): New method.
	(IntegerField.ParseFormValue): Catch ValueError.
	(AttachmentField.__init__): Pass attributes to base __init__.
	(TextField.__init__): Call SetAttributes.
	(TextField.FormatValueAsHtml): Replace qm.web with web.
	(SetPopupPageInfo): New class.
	(SetField.FormatValueAsHtml): Reimplement editable case.
	(UploadAttachmentPageInfo): New class.
	(AttachmentField.attachment_summary_prefix): Remove.
	(AttachmentField.FormatValueAsHtml): Capitalize None.
	Reimplement editable case.
	(AttachmentField.GenerateFormValue): Handle null case.
	(AttachmentField.FormatSummary): Adjust.
	(EnumerationField.ParseFormValue): New method.
	(EnumerationField.FormEncodeValue): Likewise.
	(EnumerationField.FormDecodeValue): Likewise.
	(EnumerationField.FormatValueAsHtml): Add a hidden control.
	* qm/diagnostic.py (help_set): New variable.
	(__initialize_module): Load common-help.txt.
	* qm/common.py (convert_from_dos_text): Swap CR LF order.
	(starts_with): New function.
	* qm/attachment.py (upload_url): New constant.
	(temporary_attachment_dir): Likewise.
	(_temporary_location_prefix): Likewise.
	(register_attachment_upload_script): New function.
	(_path_for_temporary_attachment): Likewise.
	(is_temporary_attachment_location): Likewise.
	(_next_temporary_location): New variable.
	(get_temporary_location): New function.
	(store_temporary_attachment): Likewise.
	(retrieve_temporary_attachment): Likewise.
	(handle_attachment_upload): Likewise.

	* qm/track/web/web.py (UploadAttachmentPageInfo): Remove.
	(handle_upload_attachment): Likewise.
	(handle_submit_attachment): Likewise.
	(generate_error_page): Likewise.
	* qm/track/web/show.py (ShowPageInfo.__init__): Rename
	invalid_fields to field_errors.
	(retrieve_attachment_data): New function.
	(handle_submit): Use it.  Handle exceptions better.
	* qm/track/server.py (start_server): Call
	register_attachment_upload_script.  Remove submit-addatchment and
	upload-attachment scripts.

	* qm/test/classes/temporary.py (TempDirectoryAction.fields): Add
	default values.
	(TempDirectoryAction.__init__): Remove default arguments.
	* qm/test/classes/python.py (ExecTest.fields): Use text fields
	instead of attachment fields.
	(ExecTest.__init__): Adjust accordingly.
	(BaseExceptionTest.fields): Use text fields instead of attachment
	fields.
	(BaseExceptionTest.__init__): Adjust accordingly.
	(ExceptionTest.fields): Adjust.
	(ExceptionTest.__init__): Remove default arguments.
	(StringExceptionTest.__init__): Likewise.
	* qm/test/classes/command.py (CommandTest.__init__): Remove
	default arguments.  Handle null interpreter.
	* qm/test/xmldb.py (TestFileError): Derive from RuntimeError.
	(Database.GetTest): Handle DomNodeError.
	(Database.GetTestIds): New method.
	(Database.HasAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetActionIds): Likewise.
	(Database.GetSuiteIds): Likewise.
	(Database.SetAttachmentData): Likewise.
	(Database.__InvalidateItem): Likewise.
	(Database.__MakeDomNodeForTest): Rewrite.
	(Database.__MakeDomNodeForAction): New method.
	(Database.__MakeDomNodeForItem): Likewise.
	(scan_dir_for_labels): New function.
	* qm/test/qmtest.in (print_error_message): Process structued text.
	* qm/test/cmdline.py (Command.port_option_spec): New attribute.
	(Command.address_option_spec): Likewise.
	(Command.log_file_option_spec): Likewise.
	(Command.commands_spec): Add server command.
	(Command.GetGlobalOption): Add default parameter.
	(Command.GetCommandOption): Likewise.
	(Command.Execute): Set global database.  Don't set __database
	attribute.
	(Command.GetDatabase): Use get_database.
	(Command.__ExecuteServer): New method.
	(Command.__ExecuteTemplate): Use make_new_test.
	* qm/test/base.py (standard_test_class_names): New variable.
	(standard_action_class_names): Likewise.
	(InstanceBase.__init__): Validate the ID.
	(Test.GetTest): Use default field values.
	(Database.GetTestIds): New method.
	(Database.WriteSuite): Likewise.
	(Database.GetSuiteIds): Likewise.
	(Database.HasAction): Likewise.
	(Database.GetAction): Likewise.
	(Database.WriteAction): Likewise.
	(Database.GetActionIds): Likewise.
	(Database.SetAttachmentData): Likewise.
	(validate_id): New function.
	(get_database): Likewise.
	(get_all_test_ids): Likewise.
	(make_new_test): Likewise.
	(make_new_action): Likewise.
	(_database): New variable.

	* qm/test/web/: New directory.
	* qm/test/web/__init__.py: New file.
	* qm/test/web/dir.py: Likewise.
	* qm/test/web/show.py: Likewise.
	* qm/test/web/web.py: Likewise.

	* tests/unit/common/graph_complete.qmt: Adjust for test class changes.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.

	* share/web/stylesheets/qm.css (a:link): Underlinke links.
	(a:visited): Likewise.
	(a:active): Likewise.
	(a:hover): Likewise.
	(body.help): New class.
	(a.reverse): Likewise.
	(tr.heading): Likewise.
	* share/dtml/attachment.dtml: New file.
	* share/dtml/error.dtml: Likewise.
	* share/dtml/set.dtml: Likewise.
	* share/dtml/test/add-action.dtml: Likewise.
	* share/dtml/test/add-category.dtml: Likewise.
	* share/dtml/test/add-prerequisite.dtml: Likewise.
	* share/dtml/test/dir.dtml: Likewise.
	* share/dtml/test/new.dtml: Likewise.
	* share/dtml/test/show.dtml: Likewise.
	* share/dtml/track/error.dtml: Remove.
	* share/dtml/track/upload-attachment.dtml: Likewise.
	* share/dtml/track/show.dtml: Adjust.
	* share/diagnostics/common.txt (invalid enum key): New diagnostic.
	(invalid integer field value): Likewise.
	* share/diagnostics/test.txt (action already exists): Likewise.
	(class not found): Likewise.
	(error loading xml test): Likewise.
	(invalid class name): Likewise.
	(invalid test id): Likewise.
	(missing argument): Likewise.
	(no id for show): Likewise.
	(no id for submit): Likewise.
	(no such action): Likewise.
	(no such test): Likewise.
	(invalid id): Remove.

2001-04-23  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/Makefile.in: Add CYGWIN to setup_path.py generation.

	* configure.in (AC_CHECK_FILE): Change exit to a warning.
	* configure: Regenerate.

	* configure.in (AC_CHECK_FILE): Remove Makefile.pre.in.
	* configure: Regenerate.

2001-04-18  Benjamin Chelf  <chelf@codesourcery.com>

	* Makefile.in (setup): Remove generation of extension modules.
	* configure.in (AC_OUTPUT): Add sqmlop/Makefile and
	zope-dtml/ExtensionClass/Makefile.
	* configure: Regenerate.
	* sgmlop/Makefile.in: New file.
	* sgmlop/setup.py: Likewise.
	* zope-dtml/ExtensionClass/Makefile.in: Likewise.
	* zope-dtml/ExtensionClass/setup.py: Likewise.

2001-04-13  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/label.py (thunk): Remove rand. Change to raise exception.

2001-04-09  Alex Samuel  <samuel@codesourcery.com>

	* qm/diagnostic.py (message): New function.
	* qm/__init__.py: Import message from diagnostic.
	* share/diagnostics/test.txt (test did not raise): New diagnostic.
	(test raised non-object): Likewise.
	(test raised non-string): Likewise.
	(test raised wrong argument): Likewise.
	(test raised wrong class): Likewise.
	(test raised wrong string): Likewise.
	(unknown test class): Likewise.
	* qm/test/classes/python.py: New file.
	* qm/test/xmldb.py (UnknownTestClassError): Fix typo.  Derive from
	RuntimeError.
	(UnknownActionClassError): Likewise.
	(Database.__ParseTestDocument): Handle ImportError.

	* tests/common.qms: New suite.
	* tests/unit/common/graph_complete.qmt: New test.
	* tests/unit/common/graph_cycle.qmt: Likewise.
	* tests/unit/common/graph_pass.qmt: Likewise.
	* tests/unit/common/label_is_valid.qmt: Likewise.
	* tests/unit/common/label_thunk.qmt: Likewise.
	* tests/unit/common/parser_create.qmt: Likewise.
	* tests/unit/common/parser_dup_command_long.qmt: Likewise.
	* tests/unit/common/parser_dup_command_short.qmt: Likewise.
	* tests/unit/common/parser_duplicate_long.qmt: Likewise.
	* tests/unit/common/parser_duplicate_short.qmt: Likewise.
	* tests/unit/common/parser_help.qmt: Likewise.
	* tests/unit/common/parser_no_long.qmt: Likewise.
	* tests/unit/common/parser_parse.qmt: Likewise.
	* tests/unit/common/parser_two_char_short.qmt: Likewise.
	* tests/unit/test/classes/tempdir1.qmt (<class>): Use
	python.ExecTest.

2001-04-08  Alex Samuel  <samuel@codesourcery.com>

	* doc/manual/: New directory.
	* doc/manual/Makefile.in: New file.
	* doc/manual/main.xml: Likewise.
	* doc/manual/introduciton.xml: Likewise.
	* doc/manual/test-manual.xml: Likewise.
	* doc/manual/test-tour.xml: Likewise.

	* qm/test/base.py (Engine.RunTests): Adjust handling of
	action dependencies and context properties.

2001-04-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/xmldb.py (action_file_extension): New variable.
	(UnknownActionClassError): New exception class.
	(Database.__init__): Initialize __actions.
	(Database.HasTest): Use __HasItem.
	(Database.HasAction): New method.
	(Database.GetTest): Use __GetItem.
	(Database.GetAction): New method.
	(Database.__HasItem): Likewise.
	(Database.__GetItem): Likewise.
	(Database.__ParseTestDocument): Parse actions.
	(Database.__ParseActionDocument): New method.
	(Database.__GetClassNameFromDomNode): Generalize.
	(Database.__GetArgumentsFromDomNode): Likewise.
	(Database.__GetActionsFromDomNode): New method.
	* qm/test/cmdline.py (Command.__ProgressCallback): Simplify.
	(Command.__ExecuteTemplate): Use get_class.
	(Command.divider): Improve error messages.
	* qm/test/base.py (NoSuchActionError): New class.
	(InstanceBase): Likewise.
	(Test): Derive from InstanceBase.
	(Test.__init__): Add some parameter defaults.  Add actions
	parameter.
	(Test.GetClassName): Remove.
	(Test.GetClass): Likewise.
	(Test.GetArguments): Likewise.
	(Test.GetId): Likewise.
	(Test.GetActions): New method.
	(Test.Run): Set working directory.
	(Action): New class.
	(Result.GetOutcome): New method.
	(ResultWrapper.GetContextProperties): Likewise.
	(Context): Don't validate values.
	(Context.__ValidateKey): Rename to...
	(Context.ValidateKey): ... this.
	(Context.__ValidateValue): Remove.
	(ContextWrapper): New class.
	(Engine.RunTests): Reorganize.  Add actions.  Add context property
	handling code.
	(make_result_for_exception): Add outcome parameter.
	(get_test_class): Generalize to...
	(get_class): ... this.
	(__loaded_test_classes): Generalize to...
	(__loaded_classes): ... this.
	(__builtin_test_class_path): Generalize to...
	(__builtin_class_path): ... this.
	* qm/test/classes/temporary.py: New file.
	* qm/test/classes/python.py: Likewise.

	* share/diagnostics/test.txt (context attribute cannot be deleted):
	New diagnostic.
	* share/xml/CATALOG (fields.mod): New entry.
	* share/xml/fields.mod: New DTD module.
	* share/xml/issue.dtd: Use shared fields module.
	* share/xml/test.dtd: Likewise.
	* share/xml/action.dtd: New file.

	* tests/unit/test/classes/tempdir1.qmt: New file.
	* tests/unit/test/classes/tempdir1.qma: Likewise.

2001-04-03  Alex Samuel  <samuel@codesourcery.com>

	* README: Update.
	* qm/test/qmtest.in: Fix import.
	* share/tutorial/: New directory.
	* share/tutorial/test/: Likewise.
	* share/tutorial/test/tdb/: Likewise.
	* share/tutorial/test/count.py: New file.
	* share/tutorial/test/tdb/test1.qmt: Likewise.
	* share/tutorial/test/tdb/test2.qmt: Likewise.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* install.py: Fix order.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk.in (INSTALLDOCDIR): New variable.
	* qm.spec (files): Include doc files.
	* install.py (doc_files): New variable.
	Take doc dir as argument.  Install documentation.
	* README: Improve formatting.  Describe new track features, and
	add test tutorial.
	* Makefile.in (install): Pass doc directory to install script.
	* share/diagnostics/test.txt (missing test id): New diagnostic.
	(test class not fully specified): Likewise.
	* qm/test/cmdline.py (Command.__ExecuteRun): Handle ValueError.
	(Command.__ExecuteTemplate): Likewise.
	(Command.divider): Generate an indication if no tests failed, or
	if no tests produced unexpected outcomes.
	* qm/test/base.py (get_test_class): Fix typo.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* qm.spec (BuildRoot): Reove.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* qm/setup_path.py.in (add_to_python_path): Use __lib_dir.
	(__base_dir): Remove.
	(__lib_dir): New variable.
	(__share_dir): Likewise.
	Set different environment variables.
	* qm/fields.py (EnumerationField.__init__): Adjust call to base
	initializer.  Set default.
	(TimeField.__init__): Likewise.
	* qm/common.py (get_base_directory): Remove.
	(get_lib_directory): New function.
	(get_share_directory): Likewise.
	* qm/Makefile.in (setup_path.py): Adjust substitutions.
	* qm/track/config.py (initialize_idb): Get user db template from
	new location.
	* qm/track/cmdline.py (Command.__PerformInitialize): Print a
	message.
	* qm/test/base.py (__builtin_test_class_path): Use
	get_lib_directory in initializer.

2001-03-30  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (install): New target.
	* configure.in (AC_PROG_INSTALL): Use it.
	* configure: Regenerate.
	* install.py: New file.
	* qm.spec: Likewise.
	* standard.mk.in (INSTALL): New variable.
	(prefix): Likewise.
	(exec_prefix): Likewise.
	(INSTALLBINDIR): Likewise.
	(INSTALLLIBDIR): Likewise.
	(INSTALLSHAREDIR): Likewise.
	* sgmlop/sgmllib.py: Strip CR.
	* sgmlop/xmllib.py: Likewise.
	* xmlrpc/xmlrpc_handler.py: Likewise.
	* xmlrpm/xmlrpclib.py: Likewise.
	* share/diagnostics/track.txt (new idb message): New diagnostic.
	* qm/users.xml.tempalte: Move to...
	* share/xml/users.xml.template: ... here.

2001-03-28  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (write_dom_document): Write emacs configury.
	(__hyphen_regex): New variable.
	(__hyphen_replacement): New function.
	(sanitize_text_for_comment): Likewise.
	* qm/structured_text.py (to_text): Add width and indent
	parameters.
	* qm/label.py (MakeRelativeTo.__init__): Remove label parameter.
	(UnmakeRelativeTo): New class.
	* qm/common.py (is_executable): New function.
	* qm/attachment.py (make_dom_node): Handle 'None' attachments.
	(from_dom_node): Likewise.
	* qm/fields.py (AttachmentField.MakeDomNodeForValue): Likewise.

	* share/xml/test.dtd (attachment): Allow empty element.
	* share/diagnostics/test.txt (invalid class): New diagnostic.
	(mising arg for template): Likewise.
	(no id for edit): Likewise.
	(test already exists): Likewise.
	(unknown id): Likewise.

	* qm/test/xmldb.py (Database.WriteTest): New method.
	(Database.TestIdToPath): New method.
	(Database.__GetClass): Rename to...
	(Database.__GetClassNameFromDomNode): ... this.
	(Database.__GetArguments): Rename to...
	(Database.__GetArgumentsFromDomNode): ... this.
	(Database.__GetPrerequisites): Rename to...
	(Database.__GetPrerequisitesFromDomNode): ... this.
	(Database.__MakeDomNodeForTest): New method.
	(FileSuite.__init__): Adjust for MakeRelativeTo.
	(DirectorySuite.__AddTestsInDirectory): Likewise.
	* qm/test/cmdline.py (Command.commands_spec): Add edit and
	template commands.
	(Command.Execute): Dispatch edit and template.
	(Command.__ExecuteEdit): New method.
	(Command.__EditTest): Likewise.
	(Command.__ExecuteTemplate): Likewise.
	(Command.divider): Print cause on ERROR outcome.
	* qm/test/base.py (Test.__init__): Take test class name as
	parameter.
	(Test.GetClassName): New method.
	(Test.GetClass): Adjust.
	(Test.GetArguments): New method.
	(Test.GetCategories): Likewise.
	(Database.WriteTest): Likewise.
	(ResultWrapper.MakeDomElement): Rename to...
	(ResultWrapper.MakeDomNode): ... this.
	* qm/test/classes/command.py (ExecTest.__init__): Make stdin
	default to None.
	(ExecTest.Run): Initialize result_pipe_file.  Handle null
	attachment for stdin, stdout, stderr.  Fix pipe cleanup.
	(ExecTest.RunProgram): Check executable.  Catch access error.
	(CommandTest.__init__): Make stdin default to None.
	(CommandTest.RunProgram): Check interpreter executable.
	(ScriptTest.__init__): Make stdin default to None.

2001-03-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (Field.__init__): Make attributes parameter a
	catch-all for named arguments.
	(IntegerField.__init__): Add attributes parameter.
	(TextField.__init__): Likewise.
	(AttachmentField.__init__): Likewise.
	(EnumerationField.__init__): Likewise.
	(TimeField.__init__): Likewise.
	* qm/common.py (format_exception): Use format_traceback.
	(format_traceback): New function.
	(decode_data_from_text): Add none encoding.
	(open_temporary_file_fd): New function.
	(open_temporary_file): Likewise.
	(find_program_in_path): Likewise.
	* qm/attachment.py (from_dom_node): Make description, mimetype,
	filename elements optional.
	* share/xml/test.dtd (attachment): Make subelements optional.
	(data): New element.
	* share/diagnostics/common.txt (dom wrong tag for field): Fix.
	(temp file error): New diagnostic.
	* share/diagnostics/test.txt (invalid context assignment): Likewise.
	(invalid environment assignment): Likewise.
	(xml invalid arg name): Fix.
	(xml not int value): Likewise.
	* qm/test/base.py (Context.__ValidateKey): Raise ValueError.
	(Engine.RunTests): Use make_result_for_exception.
	(make_result_for_exception): New function.
	* qm/test/cmdline.py (Command.context_option_spec): New attribute.
	(Command.commads_spec): Add it to the run command.
	(Command.MakeContext): New method.
	(Command.__ExecuteRun): Use it.
	* qm/test/classes/command.py: New file.

2001-03-26  Alex Samuel  <samuel@codesourcery.com>

	Reorganize data files into share directory.

	* qm/xmlutil.py (make_system_id): Adjust.
	(load_xml_file): Use get_share_directory.
	* qm/web.py (PageInfo.html_stylesheet): New attribute.
	(PageInfo.html_generator): Likewise.
	Rename _login_url request field to _redirect_url throughout.
	(PageInfo.default_class): Set it.
	(WebRequestHandler.__HandleScriptRequest): Catch NoSessionError
	and InvalidSessionError.
	(WebServer.HandleNoSessionError): New method.
	(WebRequest.GetSession): Raise NoSessionError.
	(Session.Validate): Raise InvalidSessionError.
	(get_session): Likewise.
	(handle_logout): New function.
	(generate_html_from_dtml): Likewise.
	(generate_login_form): Likewise.
	* qm/diagnostic.py (DiagnosticSet.ReadFromFile): Change path
	parameter.
	(__initialize_module): New function.  Call it.
	* qm/diagnostics.txt: Remove.
	* qm/common.py (get_base_directory): Add components parameter.
	(get_share_directory): New function.
	* qm/track/web/web.py (PageInfo.html_stylesheet): Remove.
	(__initialize_module): New function.  Call it.
	(generate_html_from_dtml): Use generioc generate_html_from_path.
	* qm/track/web/index.py (IndexPageInfo.MakeLogoutForm): Set
	_redirect_url.
	* qm/track/server.py (start_server): Use get_share_directory.
	Register logout.
	* qm/track/config.py (__initialize_module): New function.  Call
	it.
	* qm/test/qmtest.in: Use get_share_directory.

	* qm/dtds/CATALOG: Remove.
	* qm/dtds/issue.dtd: Likewise.
	* qm/dtds/result.dtd: Likewise.
	* qm/dtds/test.dtd: Likewise.
	* qm/dtds/user.dtd: Likewise.
	* qm/test/diagnostics.txt: Likewise.
	* qm/track/diagnostics.txt: Likewise.
	* qm/track/web/images/clear.gif: Likewise.
	* qm/track/web/images/sc-logo.png: Likewise.
	* qm/track/web/stylesheets/qmtrack.css: Likewise.
	* qm/track/web/templates/error.dtml: Likewise.
	* qm/track/web/templates/history.dtml: Likewise.
	* qm/track/web/templates/index.dtml: Likewise.
	* qm/track/web/templates/query.dtml: Likewise.
	* qm/track/web/templates/show.dtml: Likewise.
	* qm/track/web/templates/summary.dtml: Likewise.
	* qm/track/web/templates/upload-attachment.dtml: Likewise.
	* qm/dtds/: Remove directory.
	* qm/track/web/images/: Likewise.
	* qm/track/web/templates/: Likewise.

	* share/: New directory.
	* share/diagnostics/: Likewise.
	* share/dtml/: Likewise.
	* share/dtml/track/: Likewise.
	* share/web/: Likewise.
	* share/web/images/: Likewise.
	* share/web/stylesheets/: Likewise.
	* share/xml/: Likewise.
	* share/diagnostics/common.txt: New file.
	* share/diagnostics/test.txt: Likewise.
	* share/diagnostics/track.txt: Likewise.
	* share/dtml/login_form.dtml: Likewise.
	* share/dtml/track/error.dtml: Likewise.
	* share/dtml/track/history.dtml: Likewise.
	* share/dtml/track/index.dtml: Likewise.
	* share/dtml/track/query.dtml: Likewise.
	* share/dtml/track/show.dtml: Likewise.
	* share/dtml/track/summary.dtml: Likewise.
	* share/dtml/track/upload-attachment.dtml: Likewise.
	* share/web/images/clear.gif: Likewise.
	* share/web/images/sc-logo.png: Likewise.
	* share/web/stylesheets/qm.css: Likewise.
	* share/xml/CATALOG: Likewise.
	* share/xml/issue.dtd: Likewise.
	* share/xml/result.dtd: Likewise.
	* share/xml/test.dtd: Likewise.
	* share/xml/user.dtd: Likewise.

2001-03-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/test/base.py (load_results): Use load_xml_file.

2001-03-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (ParseError): New class.
	(make_system_id): New function.
	(load_xml_file): Likewise.
	(get_dom_text): Handle empty text.
	(create_dom_document): Generate system ID from DTD file name.
	* qm/web.py (session_id_field): New variable.
	(NoSessionError): New class.
	(InvalidSessionError): Likewise.
	(PageInfo.MakeLoginForm): New method.
	(PageInfo.FormatUserId): Likewise.
	(WebRequestHandler.do_GET): Store client IP address in request.
	(WebRequestHandler.do_POST): Likewise.
	(WebRequestHandler.__HandleScriptRequest): Set no-cache header.
	(WebRequestHandler.__HandleFileRequest): Set public caching.
	(WebServer.Bind): Set SO_REUSEADDR.
	(WebRequest.__init__): Add base parameter.
	(WebRequest.SetSessionId): New method.
	(WebRequest.GetSessionId): Likewise.
	(WebRequest.GetSession): Likewise.
	(WebRequest.get): Likewise.
	(WebRequest.copy): Add url, fields parameters.
	(Session): New class.
	(get_session): New function.
	(__clean_up_expired_sessions): Likewise.
	(handle_login): Likewise.
	(sessions): New variable.
	* qm/user.py: New file.
	* qm/users.xml.template: Likewise.
	* qm/diagnostics.txt (bad port number): New diagnostic.
	(xml parse error): Likewise.

	* qm/dtds: New directory.
	* qm/dtds/CATALOG: New file.
	* qm/dtds/issue.dtd: Likewise.
	* qm/dtds/reslt.dtd: Likewise.
	* qm/dtds/test.dtd: Likewise.
	* qm/dtds/user.dtd: Likewise.

	* qm/track/server.py (start_server): Handle index and login pages.
	* qm/track/issue.py (issues_to_xml): Use public ID and DTD file
	name.
	* qm/track/diagnostics.txt (xml parse error): Remove.
	* qm/track/config.py (open_idb): Load user database.
	(initialize_idb): Create user database from template.
	* qm/track/cmdline.py (Command.__PerformServer): Handle bad port
	numbers.
	* qm/track/issue.dtd: Remove.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust title
	bar.
	(UploadAttachmentPageInfo.MakeSubmitUrl): Copy request.
	* qm/track/web/summary.py (SummaryPageInfo.MakeIssueUrl): Copy
	request.
	* qm/track/web/query.py (QueryPageInfo.MakeQueryForm): Likewise.
	* qm/track/web/show.py (ShowPageInfo.MakeSubmitUrl): Likewise.
	(handle_submit): Likewise. Set the user field.
	* qm/track/web/index.py (IndexPageInfo.MakeNewForm): Copy request.
	(IndexPageInfo.MakeShowForm): Likewise.
	(IndexPageInfo.MakeEditForm): Likewise.
	(IndexPageInfo.MakeShowAllForm): Likewise.
	(IndexPageInfo.MakeQueryForm): Likewise.
	(IndexPageInfo.MakeQueryUrl): Likewise.
	(IndexPageInfo.MakeShutdownForm): Likewise.
	(IndexPageInfo.MakeLogoutForm): New method.
	* qm/track/web/templates/index.dtml: Reformat.  Add login controls.
	* qm/track/web/stylesheets/qmtrack.css: Adjust formatting.
	(span.userid): New style.

	* qm/test/xmldb.py (Database.GetTest): Use load_xml_file.
	* qm/test/cmdline.py (Command.__WriteResults): Use public ID and
	DTD file name.
	* qm/test/results.dtd: Remove.
	* qm/test/test.dtd: Likewise.

2001-03-22  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py (create_dom_text_element): New function.
	(__dom_implementation): New variable.
	(create_dom_document): New function.
	(write_dom_document): Likewise.
	* qm/web.py (WebRequestHandler.do_GET): Ignore exceptions during
	shutdown.
	(WebRequestHandler.do_POST): Likewise.
	(WebRequestHandler.__HandleScriptRequest): Ignore IO errors during
	write.
	* qm/fields.py (Attachment): Remove.
	Use attachment.Attachment throughout.
	Replace qm.track.error with qm.error throughout.
	(Field.__repr__): New method.
	(Field.MakeDomNodeForValue): Likewise.
	(IntegerField.MakeDomNodeForValue): Likewise.
	(TextField.MakeDomNodeForValue): Likewise.
	(SetField.MakeDomNodeForValue): Likewise.
	(AttachmentField.MakeDomNodeForValue): Likewise.
	(EnumerationField.MakeDomNodeForValue): Likewise.
	* qm/common.py (encode_data_as_text): New function.
	(decode_data_from_text): Likewise.
	* qm/attachment.py: New file.

	* qm/track/sql_idb.py (SqlIdb.AddIssue): Check IID uniqueness.
	(SqlIdb.__ColumnSpecForField): Add fourth attachment column.
	(SqlIdb.__GetColumnName): Likewise.
	(SqlIdb.__BuildSqlForFieldValue): Likewise.
	(SqlIdb.__GetFieldFromRow): Likewise.
	* qm/track/issue.py (IssueFileError): New class.
	(Attachment): Likewise.
	(Issue.__repr__): New method.
	(Issue.MakeDomElement): Likewise.
	(get_differing_fields): Ignore revision number and timestamp.
	(load_issues_from_xml_file): New function.
	(__issues_from_dom): Likewise.
	(__issue_from_dom): Likewise.
	(issues_to_xml): Likewise.
	Initialize qm.attachment.attachment_class.
	* qm/track/issue.dtd: New file.
	* qm/track/idb.py (IdbBase.Query): Ignore attachment fields.
	* qm/track/diagnostics.txt (missing import files): New diagnostic.
	(xml file unknown class): Likewise.
	(xml file unknown field): Likewise.
	(xml parse error): Likewise.
	(format error): Add output format specifier.
	* qm/track/cmdline.py (Command.output_option): New attribute.
	(Command.qmtrack_commands): Use it for several commands.  Add
	import command.
	(Command.__init__): Dispatch import command.
	(Command.Execute): Handle output option.
	(Command.__PerformQuery): Query all issue classes.
	(Command.__PerformImport): New method.
	(Command.__PrintResults): Adjust comments.  Implement XML format.
	* qm/track/web/web.py (make_url_for_attachment): Use attachment
	attributes.

	* qm/test/test.dtd: Adjust for attachment schema.
	* qm/test/cmdline.py (Command.__WriteResults): Use
	create_dom_document and write_dom_document.
	* qm/test/base.py (Attachment): New class.
	Initialize qm.attachment.attachment_class.

2001-03-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/xmlutil.py: New file.
	* qm/fields.py: Use it throughout.
	* qm/common.py (OrderedMap.__len__): New method.
	(get_dom_node_text): Remove.
	(get_child_dom_node_text): Likewise.
	(get_dom_children_texts): Likewise.
	* qm/cmdline.py (CommandParser.__init__): Add conflicting_options
	parameter.
	(CommandParser.ParseCommandLine): Check for conflicting options.
	* qm/diagnostics.txt (conflicting options): New diagnostic.

	* qm/test/xmldb.py: Use qm.xmlutil throughout.
	* qm/test/cmdline.py (Command.all_results_option_spec): Remove.
	(Command.verbose_option_spec): New attribute.
	(Command.output_option_spec): Likewise.
	(Command.no_output_option_spec): Likewise.
	(Command.summary_option_spec): Likewise.
	(Command.no_summary_option_spec): Likewise.
	(Command.outcomes_option_spec): Likewise.
	(Command.conflicting_option_specs): Likewise.
	(Command.commands_spec): Add options.
	(Command.__init__): Use conflicting_option_specs.
	(Command.Execute): Handle verbose option.
	(Command.__ExecuteRun): Handle summary, output, and outcome
	options.
	(Command.__ProgressCallback): New method.
	(Command.__WriteSummary): Likewise.
	(Command.__WriteResults): Rewrite.
	* qm/test/base.py (Result.__init__): Remove context parameter.
	(Result.__getitem__): Remove.
	(Result.get): Likewise.
	(ResultWrapper): New class.
	(Engine.RunTests): Add progress_callback parameter.  Wrap results
	in ResultWrapper.
	(load_outcomes): New function.
	(load_results): Likewise.
	(__results_from_dom): Likewise.
	(__result_from_dom): Likewise.
	* qm/test/diagnostics.txt (class is not test class): Remove.
	* qm/test/results.dtd: New file.
	* qm/test/test.dtd: Add comments.

2001-03-20  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/sql_idb.py (SqlIdb.GetIssues): import types.
	(SqlIdb.GetIssue): Change type IssueClass to
	qm.track.issue_class.IssueClass to fix bug.
	(SqlIdb.GetAllRevisions): Likewise.

2001-03-18  Alex Samuel  <samuel@codesourcery.com>

	* qm/graph.py: Fix code formatting.
	* qm/common.py (OrderedMap): New class.
	* qm/test/cmdline.py (Command.all_results_option_spec): New
	variable.
	(Command.commands_spec): Include it.
	(Command.__init__): Initialize __show_all_results.
	(Command.Execute): Handle all-results option.
	(Command.__ExecuteRun): Show all results if specified.
	* qm/test/base.py (Test.__init__): Add parameters.
	(Test.GetTest): New method.
	(Test.GetClass): Likewise.
	(Test.AddCategory): Remove.
	(Test.GetPrerequisites): New method.
	(Test.Run): Use GetTest.
	(Result.outcomes): New variable.
	(Result.__str__): Reimplement.
	(Result.get): New method.
	(PrerequisiteMapAdapter): New class.
	(Engine.RunTests): Handle prerequisites.
	* qm/test/xmldb.py (Database.__DOES_NOT_EXIST): New constant.
	(Database.__NOT_LOADED): Likewise.
	(Database.__init__): Initialize test and suite caches.
	(Database.HasTest): Use caches.
	(Database.GetTest): Likewise.
	(Database.HasSuite): Likewise.
	(Database.GetSuite): Likewise.
	(Database.__ParseTestDocument): Parse prerequisites.  Pass info to
	Test initializer.
	(Database.__GetArguments): Treat fields as list.
	(Database.__GetPrerequisites): Get outcome attribute.
	* qm/test/test.dtd (prerequisite): Add attlist.
	* qm/test/diagnostics.txt (invalid result): New diagnostic.

2001-03-17  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (__label_regex): Remove.
	(__Label_regex_with_dot): Likewise.
	(is_valid_label): Likewise.
	(__label_thunk_regex): Likewise.
	(thunk_to_label): Likewise.
	(get_dom_children_texts): New function.
	* qm/label.py: New file.
	* qm/fields.py: Use qm.label.
	* qm/test.py: Likewise.
	* qm/test/xmldb.py: Use qm.label.
	(Database.GetTest): Fix typo.
	(Database.__ParseTestDocument): Rename parameter.  Read categories
	and prerequisites.
	(Database.__GetPrerequisites): New method.
	(FileSuite.__init__): Improve path handling.
	(DirectorySuite.__init__): Likewise.
	(DirectorySuite.__AddTestsInDirectory): Likewise.
	Don't load diagnostics.  Don't load RC.
	* qm/test/qmtest.in (print_error_message): Remove self parameter.
	Initialize qmtest diagnostics.  Load RC.  Fix error message.
	* qm/test/base.py: Use qm.label.
	(Test.IsInCategory): New method.
	(Test.AddCategory): Likewise.
	* qm/track/issue_class.py: Use qm.label.

2001-03-16  Alex Samuel  <samuel@codesourcery.com>

	* qm/Makefile.in (SCRIPTS): New variable.
	(all): Remove track/qmtrack.  Add $(SCRIPTS).
	(track/qmtrack): Generalize to...
	(%: %.in): ... this rule.
	* qm/test/cmdline.py (Command.__WriteOutcomes): Wrap apply
	argument in a tuple.

2001-03-16  Alex Samuel  <samuel@codesourcery.com>

	* README: Update requirements.
	* qm/__init__.py: Import error and warning.
	* qm/diagnostic.py: Add doc string.  Improve comments.
	(DiagnosticSet.__init__): Don't take program name.  Don't load.
	(DiagnosticSet.ReadFile): Rename to...
	(DiagnosticSet.ReadFromFile): ... this.
	(DiagnosticSet.Generate): Rewrite.
	(error): New function.
	(warning): Likewise.
	(diagnostic_set): New variable.
	Initialize generic diagnostics.
	* qm/diagnostics.txt: New file.
	* qm/setup_path.py.in: Put base directory in environment.
	* qm/common.py (base_directory): Remove.
	(get_base_directory): Get from environment.
	(RcConfiguration): New class.
	(__label_regex_with_dot): New variable.
	(is_valid_label): Add allow_periods parameter.
	(get_host_name): Improve comments.
	(format_byte_count): Use constants.
	(get_dom_node_text): New function.
	(get_child_dom_node_text): Likewise.
	(load_module): Likewise.
	(load_class): Likewise.
	(split_path_fully): Likewise.
	(rc): New variable.
	* qm/cmdline.py (CommandParser.GetBasicHelp): Adjust output.
	(CommandParser.GetCommandHelp): Likewise,
	* qm/fields.py (DomNodeError): New class.
	(Field.GetTypeDescription): New method.
	(Field.GetValueFromDomNode): Likewise.
	(IntegerField.GetTypeDescription): Likewise.
	(IntegerField.GetValueFromDomNode): Likewise.
	(TextField.GetTypeDescription): Likewise.
	(TextField.GetValueFromDomNode): Likwise.
	(SetField.GetTypeDescription): Likewise.
	(SetField.GetValueFromDomNode): Likewise.
	(AttachmentField.GetTypeDescription): Likewise.
	(AttachmentField.GetValueFromDomNode): Likewise.
	(EnumerationField.GetTypeDescription): Likewise.
	(EnumerationField.GetValueFromDomNode): Likewise.a
	(TimeField.GetTypeDescription): Likewise.
	(UidField.GetTypeDescription): Likewise.

	* qm/track/__init__.py: Import error and warning.
	* qm/track/qmtrack.in: Use diagnostic "missing idb".
	* qm/track/issue_class.py (IidField.GetTypeDescription): New method.
	* qm/track/idb.py (get_field_type_description_for_query): Remove.
	* qm/track/diagnostics.txt (command error): Remove.
	(missing idb): New diagnostic.
	* qm/track/config.py (__diagnostics): Remove.
	(diagnostic): Likewise.
	(error): Likewise.
	(warning): Likewise.
	Load diagnostics.
	* qm/track/cmdline.py (Command.command): Remove.
	(Command.Execute): Use "missing command" diagnostic.

	* qm/track/web/query.py (QueryPageInfo.GetFieldTypeDescription):
	Use GetTypeDescription method.
	* qm/track/web/templates/summary.dtml: Show groupings only if
	there is more than one issue class.  Improve formatting.
	* qm/track/web/stylesheets/qmtrack.css (th.issue_class): Set
	background-color to grey.

	* qm/test: New directory.
	* qm/test/__init__.py: New file.
	* qm/test/base.py: Likewise.
	* qm/test/cmdline.py: Likewise.
	* qm/test/diagnostics.txt: Likewise.
	* qm/test/qmtest.in: Likewise.
	* qm/test/test.dtd: Likewise.
	* qm/test/xmldb.py: Likewise.
	* qm/test/classes: New directory.
	* qm/test/classes/__init__.py: New file.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PrivilegedPortError): New class.
	(WebServer.Bind): Handle EACCES.
	* qm/track/server.py (start_server): Handle PrivilegedPortError.
	* qm/track/diagnostics.txt (privileged port): New diagnostic.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/config.py (diagnostic): Generate path to diagnostics
	file.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/fields.py (EnumerationField.FormatValueAsHtml): Fix name and
	value defaults.
	* qm/track/config.py (setup_idb_for_internal_use): Don't generate
	issues.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/templates/index.dtml: Fix typo.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebServer.__init__): Add address parameter.
	(WebServer.Bind): Use __address.
	* qm/track/server.py (start_server): Add address parameter.
	* qm/track/cmdline.py (Command.address_option): New variable.
	(Command.qmtrack_commands): Use it.
	(Command.__PerformServer): Handle address option.

2001-03-14  Alex Samuel  <samuel@codesourcery.com>

	* qm/structured_text.py (TextFormatter.__init__): Set default
	width to 78.  Initialize __depth.
	(TextFormatter.StartList): Don't indent outermost paragraphs.
	(TextFormatter.EndList): Likewise.
	(to_text): Fix comment.
	* qm/cmdline.py (CommandParser.GetOptionsHelp): Adjust output.
	(CommandParser.GetCommandHelp): Treat command description as
	structured text.

	* qm/track/issue_class.py (IssueClass.__init__): Add title and
	description.
	(IssueClass.GetTitle): New method.
	(IssueClass.GetDescription): Likewise.
	* qm/track/idb.py (IdbBase.Query): Don't handle multiple issue
	classes here.
	* qm/track/sql_idb.py (SqlIdb.Query): Likewise.
	(SqlIdb.__AddResults): Remove.
	* qm/track/config.py (setup_idb_for_internal_use): New function.
	(setup_idb_for_test): Set class title.
	* qm/track/cmdline.py (Command): Update option descriptions.
	(Command.internal_option): New variable.
	(Command.qmtrack_commands): Use it.
	(Command.__PerformInitialize): Handle internal option.

	* qm/track/web/summary.py (SummaryPageInfo.__init__): Partition
	issues by class.  Handle reverse sort.
	(SummaryPageInfo.MakeResortUrl): Indicate reverse sort where
	appropriate.
	(handle_summary): Loop over issue classes when querying.
	* qm/track/web/index.py (IndexPageInfo.__init__): Extract issue
	classes for IDB.
	* qm/track/web/stylesheets/qmtrack.css (th.issue_class): New
	style.
	* qm/track/web/templates/summary.dtml: Show issues grouped by
	class.
	* qm/track/web/templates/show.dtml: Print class for new issue.
	* qm/track/web/templates/index.dtml: Show select for issue class
	for new issue.

2001-03-13  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (WebRequestHandler.do_GET): Flush and shut down
	socket.
	* qm/fields.py: New file.

	* qm/track/issue.py: Likewise.
	(Attachment): Remove.
	* qm/track/diagnostics.txt (field exist): Don't use class as a
	parameter name.
	* qm/track/cmdline.py (Command.__CheckFieldTypes): Don't use class
	as a parameter name.  Use qm.field.

	* qm/track/web/web.py: Use qm.field.
	(form_field_prefix): Remove.
	(attachment_description_prefix): Likewise.
	(attachment_mime_type_prefix): Likewise.
	(attachment_location_prefix): Likewise.
	(attachment_file_name_prefix): Likewise.
	(make_form_field_value): Likewise.
	(format_field_value): Likewise.
	(format_int_field_value): Likewise.
	(format_text_field_value): Likewise.
	(format_set_field_value): Likewise.
	(format_enum_field_value): Likewise.
	(format_attachment_field_value): Likewise.
	(make_url_for_attachment): Add field argument.  Insert into
	AttachmentField.
	* qm/track/web/show.py (handle_submit): Use qm.field.
	(ShowPageInfo.FormatFieldValue): Handle read_only and
	initialize_only attributes.
	(validate_mime_type): Remove.
	(extract_attachment_field_value): Likewise.
	(decode_set_field_value): Likewise.
	(handle_submit): Simplify, using qm.field.
	* qm/track/sql_idb.py: Use qm.field.
	* qm/track/test.py: Likewise.
	* qm/track/config.py (setup_idb_for_test): Likewise.
	* qm/track/idb.py: Likewise.
	* qm/track/issue_class.py (IssueField): Remove.
	(IssueFieldInteger): Likewise.
	(IssueFieldText): Likewise.
	(IssueFieldSet): Likewise.
	(IssueFieldAttachment): Likewise.
	(IssueFieldEnumeration): Likewise.
	(IssueFieldTime): Likewise.
	(IssueFieldUid).
	(IssueClass.__init__): Use qm.field.
	* qm/track/web/templates/upload-attachment.dtml: Use new
	attachment encoding.

2001-03-13  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/test.py (test_graph_cycle): Define.
	(test_graph_complete): Likewise.
	(test_graph_pass): Likewise.
	(regression_tests): Add the above.
	* qm/graph.py: New file.

2001-03-09  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/diagnostics.txt: Add new error messages.
	* qm/track/cmdline.py: Fixed formatting for raising errors.

2001-03-05  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/web/show.py (handle_submit): Format error messages.
	* qm/track/server.py (start_server): Handle address in use errors.
	(execute): Issue diagnostics.
	* qm/track/issue_class.py: Use diagnostics throughout.
	(IssueFieldText.Validate): Convert from DOS text.
	* qm/track/diagnostics.txt: New file.
	* qm/track/config.py (__diagnostics): New variable.
	(diagnostic): New function.
	(error): Likewise.
	(warning): Likewise.
	* qm/track/cmdline.py (Command.__PerformDestroy): Handle lock error.

	* qm/web.py (AddressInUseError): New class.
	(WebServer.Bind): Raise it.
	(escape): Reimplement.
	(__entity_regex): New variable.
	(__replacement_for_entity): New function.
	(unescape): New function.
	(format_structured_text): Reimplement.
	* qm/diagnostic.py: New file.
	* qm/structured_text.py: Likewise.
	* qm/common.py (FileSystemMutex.GetPath): New method.
	(MapReplacer): New class.
	(replace_by_map): New function.
	(convert_from_dos_text): Likewise.

2001-03-01  Alex Samuel  <samuel@codesourcery.com>

	* README: Adjust tutorial.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust
	navigation bar.
	* qm/track/config.py (setup_idb_for_test): Ajust titles.
	* qm/track/issue_class.py (IssueClass.__init__): Likewise.
	* qm/track/cmdline.py (Command.__PrintResults): Add full format
	style.

2001-03-01  Alex Samuel  <samuel@codesourcery.com>

	* README: Update.
	* qm/web.py (WebRequestHandler.__HandleScriptRequest): Handle
	SystemExit.
	(WebServer.__init__): Initialize __shutdown_requested.
	(WebServer.Run): Run until shutdown request.
	(WebServer.RequestShutdown): New method.
	* qm/common.py (remove_directory_recursively): New function.
	* qm/track/web/templates/show.dtml: Use field title.
	* qm/track/web/templates/index.dtml: Adjust.  Add shutdown.
	* qm/track/web/images/sc-logo.png: New file.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Adjust title
	bar.
	* qm/track/web/index.py (IndexPageInfo.MakeShutdownForm): New
	method.
	* qm/track/issue_class.py (default_categories): Adjust.
	(IssueField.GetTitle): New method.
	(IssueField.GetDescription): Likewise.
	(IssueFieldSet.__init__): Use attributes from contained field.
	(IssueClass.__init__): Adjust mandatory fields.
	* qm/track/config.py (get_idb_lock): New function.
	(open_idb): Use it.
	(setup_idb_for_test): Adjust test values.
	* qm/track/cmdline.py: Adjust command descriptions.  Add destroy
	command.
	(Command.__init__): Register destroy.
	(Command.__PerformDestroy): New method.

2001-02-28  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/sql_idb.py (Query): Define.
	(__AddResults): Likewise.
	(__ConvertToSQL): Likewise.
	(__AstToSQL): Likewise.
	(__AstToSQLHelper): Likewise.
	(__CheckTautology): Likewise.

2001-02-28  Alex Samuel  <samuel@codesourcery.com>

	Support attachments in the web UI.

	* qm/web.py (WebRequestHandler.__HandleScriptRequest): Handle
	results that aren't HTML.
	* qm/common.py (format_byte_count): New function.

	* qm/track/sql_idb.py (SqlIdb.__init__): Pass arguments to base
	class.
	(SqlIdb.Close): New method.
	* qm/track/server.py (start_server): Add upload-attachment,
	submit-attachment, and download-attachment handlers.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Pass arguments to
	base initializer.  Don't create directory.
	(MemoryIdb.Close): Call base-class Close.
	* qm/track/issue.py (Attachment.__init__): Add parameter defaults.
	(Attachment.__cmp__): New method.
	* qm/track/idb.py (IdbBase.__init__): Take more arugments.  Create
	the directory.  Set up attachments.
	(IdbBase.Close): New method.
	(IdbBase.GetNewAttachmentLocation): Likewise.
	(IdbBase.SetAttachmentData): Likewise.
	(IdbBase.GetAttachmentData): Likewise.
	(IdbBase.GetAttachmentSize): Likewise.
	(IdbBase.__GetAttachmentPath): Likewise.
	(get_field_type_description_for_query): Describe attachments.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Pass arguments to
	base initializer.  Don't create directory.
	(GadflyIdb.Close): Call base-class Close.
	* qm/track/config.py (setup_idb_for_test): Add attachments field.
	* qm/track/cmdline.py (Command.__PerformInitialize): Fix exception.

	* qm/track/web/show.py (validate_mime_type): New function.
	(extract_attachment_field_value): Likewise.
	(decode_set_field_value): Likewise.
	(handle_submit): Process attachments and sets using above.  Don't
	add an identical revision.
	* qm/track/web/web.py (UploadAttachmentPageInfo): New class.
	(attachment_description_prefix): New variable.
	(attachment_mime_type_prefix): Likewise.
	(attachment_location_prefix): Likewise.
	(attachment_file_name_prefix): Likewise.
	(format_field_value): Handle attachments.
	(format_int_field_value): Handle form_encoded style.
	(format_text_field_value): Likewise.
	(format_set_field_value): Likewise.  Format brief and full
	differently.  Fill option values with form-encoded elements.
	Generate add function differently for different contained field
	types.
	(format_enum_field_value): Handle form_encoded style.
	(format_attachment_field_value): New function.
	(handle_upload_attachment): Likewise.
	(handle_submit_attachment): Likewise.
	(handle_download_attachment): Likewise.
	(make_url_for_attachment): Likewise.
	* qm/track/web/templates/upload-attachment.dtml: New file.

2001-02-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/server.py (start_server): Bind the server.
	* qm/web.py (HTTPServer): New class.
	(WebServer): Derive from HTTPServer.
	(WebServer.GetXmlRpcUrl): Use GetServerAddress.
	(WebServer.Run): Don't bind here.
	(WebServer.Bind): New function.
	(WebServer.GetServerAddress): New method.

2001-02-27  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/cmdline.py (__Parse): Change formatting to happen from
	command options.

2001-02-27  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (get_host_name): Add fallback logic.

2001-02-26  Alex Samuel  <samuel@codesourcery.com>

	* README: Clarify --test-values flag.

	* qm/track/server.py (execute): Rearrange exception handling.
	* qm/track/issue_class.py (IssueFieldIid.SetDefaultValue): New method.
	* qm/track/config.py (initialize_idb): Check that the IDB path
	doesn't exist.

2001-02-25  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (make_url_button): New function.
	(PageInfo.MakeUrlButton): Call it.
	* qm/cmdline.py (CommandParser.BuildGetoptString): Don't add
	argument indicator if there's no short form.

	* qm/track/issue_class.py (default_categories): Add some bogus
	test values.
	(IssueField.Validate): Raise ValueError instead.
	(IssueFieldText): Add nonempty attribute.
	(IssueFieldText.Validate): Do validation.
	(IssueFieldAttachment.Validate): Raise ValueError.
	(IssueFieldEnumeration.__init__): Likewise.  Validate better.
	(IssueFieldIid.__init__): New method.
	(IssueFieldIid.Validate): Likewise.
	(IssueFieldUid.__init__): Likewise.
	(IssueClass.__init__): Make iid an IssueFieldIid.  Make summary
	nonempty.
	* qm/track/issue.py (Issue.__init__): Don't validate.
	(Issue.SetField): Likewise.
	(Issue.Validate): New function.
	(Issue.AssertValid): Likewise.
	(Issue.IsDeleted): Likewise.
	* qm/track/idb.py (get_field_type_description_for_query): Place
	enumerals in double quotes.
	* qm/track/config.py (setup_idb_for_test): Add problem_reports
	field.
	* qm/track/memory_idb.py (MemoryIdb.AddIssue): Check issue
	validity.
	(MemoryIdb.AddRevision): Likewise.
	* qm/track/sql_idb.py (SqlIdb.AddIssue): Likewise.
	(SqlIdb.AddRevision): Likewise.

	* qm/track/web/web.py (format_field_value): Add name argument.
	(format_int_field_value): Likewise.
	(format_text_field_value): Likewise.  Adjust formatting.
	(format_set_field_value): Implement.
	(format_enum_field_value): Add name argument.  Change option
	values.
	* qm/track/web/summary.py (SummaryPageInfo.IsIssueShown): Always
	return 1.
	(handle_summary): Filter out deleted issues.
	* qm/track/web/show.py (ShowPageInfo.__init__): Add field_errors
	argument.
	(handle_show): Make sure iid is specified.
	(handle_submit): Add is_new.  Issue error on revision
	incoherency.  Handle encoded set fields.  Validate submission and
	generate resubmission pages.
	* qm/track/web/stylesheets/qmtrack.css: Adjust.
	* qm/track/web/templates/show.dtml: Adjust formatting.  Use more
	styles.  Support field error messages.
	* qm/track/web/templates/query.dtml: Adjust table formatting.

2001-02-22  Alex Samuel  <samuel@codesourcery.com>

	* templates/dtml: Adjust.
	* qm/web.py (make_form_for_request): New function.
	* qm/track/sql_idb.py: Fix imports.
	(SqlIdb.__FilterCurrentRows): New function.
	(SqlIdb.GetIssues): Use it.
	* qm/track/issue_class.py: Fix imports.
	* qm/track/server.py (start_server): Add index and query pages.
	* qm/track/idb.py (IdbBase.Query): Use repr instead of quoting
	strings.
	(get_field_type_description_for_query): New function.
	* qm/track/config.py (get_name): New function.
	(get_default_class): Likewise.
	* qm/track/web/web.py (PageInfo.GenerateStartBody): Add stuff to
	nav bar.
	(PageInfo.GetName): New method.
	(generate_error_page): New function.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Accept
	issues as argument.
	(handle_summary): Handle query arguments.
	* qm/track/web/show.py (handle_show): Use generate_error_page.
	* qm/track/web/index.py: New file.
	* qm/track/web/query.py: Likewise.
	* qm/track/web/templates/error.dtml: New file.
	* qm/track/web/templates/index.dtml: Likewise.
	* qm/track/web/templates/query.dtml: Likewise.

2001-02-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/web.py (PageInfo.MakeUrlButton): New method.
	(PageInfo.MakeImageUrl): Likewise.
	(PageInfo.MakeSpacer): Likewise.
	(PageInfo.MakeRule): Likewise.

	* qm/track/sql_idb.py (SqlIdb.__BuildSqlForFieldValue): Call
	escape_for_sql.
	(SqlIdb.__GetFieldFromRow): Call unescape_for_sql.
	(escape_for_sql): New function.
	(unescape_for_sql): Likewise.
	* qm/track/server.py (start_server): Register image path.
	(execute): Pass through KeyboardInterrupt.
	* qm/track/qmtrack.in: Handle KeyboardInterrupt.
	* qm/track/issue_class.py (IssueField.ValuesAreEqual): New method.
	* qm/track/issue.py (get_differing_fields): New function.
	* qm/track/gadfly_idb.py (GadflyCursor.execute): Flush log file.

	* qm/track/web/web.py (HistoryPageInfo): New class.
	(format_text_field_value): Fix brief output of multiline text.
	* qm/track/web/summary.py (SummaryPageInfo.__init__): Use
	GetIssues.
	* qm/track/web/show.py (ShowPageInfo.IsShowField): Show revision
	if it's not current.
	(ShowPageInfo.FormatFieldValue): Generate revision specially.
	(ShowPageInfo.MakeEditUrl): Adjust url.
	(ShowPageInfo.MakeHistoryUrl): Likewise.
	(ShowPageInfo.MakeShowRevisionUrl): New method.
	(ShowPageInfo.FormatHistory): Likewise.
	(handle_show): Set up extra stuff for history or past revisions.
	(handle_new): Fix typo.
	* qm/track/web/templates/show.dtml: Adjust formatting for history.
	* qm/track/web/templates/history.dtml: New file.

	* qm/track/web/images: New directory.
	* qm/track/web/images/clear.gif: New file.

2001-02-20  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (UserError): New class.
	(get_host_name): Use gethostbyname_ex.
	* qm/cmdline.py (CommandError): Derive from UserError.

	* qm/track/sql_idb.py (SqlIdb.GetIssues): New method.
	(SqlIdb.Query): Remove.
	(SqlIdb.GetIssue): Allow none where clause.
	* qm/track/server.py (execute): Catch UserError instead of
	RuntimeError.
	* qm/track/memory_idb.py (MemoryIdb.AddIssueClass): Raise KeyError
	on duplicate.
	(MemoryIdb.GetIssues): Support retrieval of all issues in a single
	class.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Don't lock.
	(GadflyIdb.__del__): Rename to...
	(GadflyIdb.Close): ... this.  Don't unlock.
	* qm/track/config.py (open_idb): Fix typo in exception code.

2001-02-20  Alex Samuel  <samuel@codesourcery.com>

	* templates/py: Set emacs fill-column.

	* Makefile.in (SUBDIRS): Remove doc.  Add sgmlop.
	(setup): Add sgmlop/Makefile.
	(sgmlop/Makefile): New rule.
	* README: Add third-party software list.
	* standard.mk.in (all): Remove doc.

	* qm/web.py (WebRequestHandler.__ProcessRequest): Rename to...
	(WebRequestHandler.__HandleRequest): ... this.
	(WebRequestHandler.__HandleScriptRequest): New method.
	(WebRequestHandler.__HandleXmlRpcRequest): Likewise.
	(WebRequestHandler.__HandleFileRequest): Likewise.
	(WebServer.__init__): Initialize XML-RPC.  Set port and log file here.
	(WebServer.GetXmlRpcUrl): New method.
	(WebServer.IsXmlRpcUrl): Likewise.
	(WebServer.Run): Don't set port and log file here.
	* qm/setup_path.py.in: Add sgmlop and xmlrpc to path.
	* qm/common.py (format_exception): New function.

	* qm/track/qmtrack.in (script_name): Remove.  Set state variable
	instead.
	(exit_code): New variable.
	Handle exceptions differently.
	* qm/track/server.py (do_command_for_xml_rpc): New function.
	(start_server): Enable XML-RPC.  Write XML-RPC URL to URL file.
	(execute): Handle error messages and exit code.  Implement remote
	mode. Handle exceptions.
	* qm/track/config.py (open_idb): Set server_url state in remote mode.
	(close_idb): Clean up correspondingly.
	* qm/track/cmdline.py (Command.GetArgumentList): New function.
	* qm/track/web/summary.py (SummaryPageInfo.IsShowIssue): Rename to...
	(SummaryPageInfo.IsIssueShown): ... this.
	* qm/track/web/templates/summary.dtml: Adjust accordingly

2001-02-18  Alex Samuel  <samuel@codesourcery.com>

	* README: Add more instructions.
	* qm/common.py (label_regex): Rename to...
	(__label_regex): ... this.
	(label_thunk_regex): Rename to...
	(__label_thunk_regex): ... this.
	(__host_name): New variable.
	(get_host_name): New function.
	* qm/track/config.py (open): Rename to...
	(open_idb): ... this.  Catch only IOError.
	(close): Rename to...
	(close_idb): ... this.
	(initialize): Rename to...
	(initialize_idb): ... this.
	* qm/track/cmdline.py: Adjust accordingly.
	* qm/track/qmtrack.in: Likewise.
	* qm/track/server.py (start_server): Write URL file.
	(execute): Fix typo.

2001-02-18  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (SUBDIRS): Add qm.
	(README): Update.
	* configure.in (AC_OUTPUT): Add qm/Makefile.
	* configure: Regenerate.
	* standard.mk.in (PYTHONBIN): New macro.
	(PYTHON): Use it.

	* qm/Makefile.in: New file.
	* qm/command_line.py: Rename to...
	* qm/cmdline.py: ... this, with heavy modifications.
	* qm/common.py (FileSystemMutex.MutexLockError): Remove.
	(FileSystemMutex.Lock): Make sure parnet directory exists.
	(FileSystemMutex.IsLocked): New method.
	(Configuration): New class.
	(base_directory): New variable.
	(get_base_directory): New function.
	* qm/setup_path.py.in: New file.
	* qm/web.py: Likewise.

	* qm/track/qmtrack.in: New file.
	* qm/track/__init__.py: Update imports.
	* qm/track/qmtrack.py: Rename to...
	* qm/track/cmdline.py: ... this, with heavy modifications.
	* qm/track/config.py: New file.
	* qm/track/idb.py: Clean up imports and comments.
	(IdbBase.PerformQuery): Rename to...
	(IdbBase.Query): ... this.  Adjust.
	(get_ib_class): New function.
	* qm/track/issue.py (Issue.__init__): Don't object to missing
	field values.
	(Issue.StampTime): New method.
	(IssueSortPredicate): New class.
	* qm/track/issue_class.py (IssueField.__init__): Initialize more
	attributes.
	(IssueField.IsAttribute): New method.
	(IssueFieldText): Rename multiline attribute to structured.
	(IssueFieldEnumeration.Validate): Try int conversion.
	(IssueFieldEnumeration.GetEnumerals): New method.
	(IssueFieldEnumeration.ValueToName): Likewise.
	(IssueClass.__init__): Adjust mandatory fields.
	(IssueClass): Redefine __fields attribute and add
	__fields_by_name.  Use throughout.
	* qm/track/memory_idb.py (MemoryIdb.__init__): Don't lock.
	(MemoryIdb.__del__): Rename to...
	(MemoryIdb.Close): ... this.
	(MemoryIdb.AddIssue): Stamp time.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.GetIids): New method.
	(MemoryIdb.GetIssues): Return copies of current revisions only.
	(MemoryIdb.GetAllRevisions): Return copies.
	(MemoryIdb.Query): Remove.
	* qm/track/server.py: New file.
	* qm/track/sql_idb.py (SqlIdb.AddIssue): Stamp time.
	(SqlIdb.AddRevision): Likewise.

	* qm/track/web: New directory.
	* qm/track/web/__init__.py: New file.
	* qm/track/web/show.py: Likewise.
	* qm/track/web/summary.py: Likewise.
	* qm/track/web/web.py: Likewise.
	* qm/track/web/stylesheets: New directory.
	* qm/track/web/stylesheets/qmtrack.css: New file.
	* qm/track/web/templates: New directory.
	* qm/track/web/templates/show.dtml: New file.
	* qm/track/web/templates/summary.dtml: Likewise.

	* templates/dtml: New file.

2001-02-16  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: Fix formatting issue.
	* qm/track/qmtrack.py: Likewise. Fix bug to catch exception when
	Validate fails on a SetField.

2001-02-16  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: Fix coding standards issues.
	* qm/track/idb.py (IdbBase::PerformQuery): Define.
	* qm/track/qmtrack.py: Fix split up strings to use 'printf' syntax.
	(CommandLine::PerformQuery): Move code into idb.py. Only do UI stuff.

2001-02-15  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/qmtrack.py: Fix coding standards issues.
	* qm/track/issue_class.py: Likewise.
	* qm/track/memory_idb.py: Likewise.

	* qm/command_line.py (CommandParser::ParseCommandLine): Fix
	to use 'write' instead of print. Add code to check for command
	existence.

2001-02-14  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/issue_class.py (IssueFieldEnumeration::GetEnumeration):
	Define.
	(IssueClass::__init__): Make 'iid' have no default value.

	* qm/track/memory_idb.py (MemoryIdb::GetIssues): Define.

	* qm/track/qmtrack.py (CommandLine::__init__): Initialize
	results.
	(CommandLine::ParseFieldValuePairs): Handle no '=' in string.
	(CommandLine::OpenDatabase): Change warning to error.
	(CommandLine::PerformCreate): Fix bugs and do type checking on
	fields. Do mandatory fields correctly.
	(CommandLine::CheckFieldTypes): Define.
	(CommandLine::PerformEdit): Fix bugs and do type checking on
	fields.
	(CommandLine::PerformQuery): Define.

2001-02-12  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/track/qmtrack.py (__main__): Change to catch exception.
	* qm/command_line.py (ErrorHandler): Change to raise exception.

	* qm/track/qmtrack.py (PrintResults): Change from 'print' to
	write.

2001-02-11  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py (ErrorHandler): New method.
	(__init): Add output parameter.
	(ParseCommandLine): Fix bugs.

	* qm/track/qmtrack.py: New file.

2001-02-08  Alex Samuel  <samuel@codesourcery.com>

	Module zope-dtml is now part of this module.  Add configury to set
	up and use it.

	* configure.in (/usr/lib/python1.5/config/Makefile.pre.in): Check file.
	* configure: Regenerate.
	* Makefile.in (SUBDIRS): Add zope-dtml/ExtensionClass.
	(setup): Add zope-dtml/ExtensionClass/Makefile.
	(zope-dtml/ExtensionClass/Makefile): New rule.
	* standard.mk.in (PYTHON): Build PYTHONPATH.
	(PYTHONDIRS): New variable.

2001-01-09  Benjamin Chelf  <chelf@codesourcery.com>

	* qm/command_line.py: New file.

	* qm/test.py (test_parser_create): Define.
	(test_paresr_parse): Likewise.
	(test_parser_help): Likewise.
	(test_parser_duplicate_long): Likewise.
	(test_parser_duplicate_short): Likewise.
	(test_parser_two_char_short): Likewise.
	(test_parser_no_long): Likewise.
	(test_parser_dup_command_short): Likewise.
	(test_parser_dup_command_long): Likewise.
	(regession_tests): Add above tests.

2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* Makefile.in (PYTHONDOCDIRS): New variable.
	* standard.mk.in (doc-python): Build for PYTHONDOCDIRS only.

2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Clarify naming conventions.
	* templates/py: Add section banners.

	* configure.in: New file.
	* install-sh: Likewise.
	* configure: Likewise.
	* standard.mk.in: New file.
	* standard.mk: Remove.
	* Makefile.in: New file.
	* Makefile: Remove.
	* doc/Makefile.in: New file.
	* doc/Makefile: Remove.
	* doc/design/qmconfig/Makefile.in: New file.
	* doc/design/qmconfig/Makefile: Remove.
	* doc/design/qmtest/Makefile.in: New file.
	* doc/design/qmtest/Makefile: Remove.
	* doc/design/qmtrack/Makefile.in: New file.
	* doc/design/qmtrack/Makefile: Remove.

2001-01-09  Alex Samuel  <samuel@codesourcery.com>

	* README: New file.

2001-01-08  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (BUILDDIR): New macro.
	(DOCDIR): Likewise.
	(HAPPYDOC): Likewise.
	(doc): Depend on doc-python.
	(doc-python): New rule.

2001-01-07  Alex Samuel  <samuel@codesourcery.com>

	* qm/track/__init__.py: Import idb.
	* qm/track/idb.py: New file.
	* qm/track/sql_idb.py (SqlIdb): Drive from IdbBase.
	(SqlIdb.__init__): Initialize base class.
	(SqlIdb.AddIssue): Process triggers.  Return result code.
	(SqlIdb.AddRevision): Likewise.
	(SqlIdb.GetIssue): Process triggers.
	(SqlIdb.GetAllRevisions): Likewise.
	(SqlIdb.RegisterTrigger): Remove.
	(SqlIdb.UnregisterTrigger): Likewise.
	(SqlIdb.GetTriggers): Likewise.
	(SqlIdb.__InsertIssue): New method.
	* qm/track/gadfly_idb.py (GadflyIdb.__init__): Initialize base class.
	* qm/track/memory_idb.py (MemoryIdb): Derive from IdbBase.
	(MemoryIdb.__init__): Initialize base class.
	(MemoryIdb.AddIssue): Process triggers.  Return result code.
	(MemoryIdb.AddRevision): Likewise.
	(MemoryIdb.GetIssue): Process triggers.
	(MemoryIdb.GetAllRevisions): Likewise.
	(MemoryIdb.RegisterTrigger): Remove.
	(MemoryIdb.UnregisterTrigger): Likewise.
	(MemoryIdb.GetTriggers): Likewise.
	(MemoryIdb.__InsertIssue): New method.
	* qm/track/test.py (TestPreupdateTrigger): New class.
	(test_preupdate_trigger): New test.
	(TestGetTrigger): New class.
	(test_get_trigger): New test.
	(TestPostupdateTrigger): New class.
	(test_postupdate_trigger): New test.
	(regression_tests): Add new tests.
	Run memory IDB tests first.

2001-01-04  Alex Samuel  <samuel@codesourcery.com>

	* qm/common.py (MutexLockError): New class.
	(FileSystemMutex): Likewise.
	* qm/regression_test.py (run_regression_test_driver): Don't exit.
	* qm/test.py: New file.

	* qm/track/issue.py (Issue.__init__): Adjust for changes in
	IssueClass.
	(Issue.Copy): New function.
	(Attachment): New class.
	* qm/track/issue_class.py (default_categories): New variable.
	(default_states): Likewise.
	(IssueField.__init__): Handle default values differently.
	(IssueField.GetDefaultValue): Likewise.
	(IssueField.SetDefaultValue): New function.
	(IssueField.UnsetDefaultValue): Likewise.
	(IssueField.HasDefaultValue): Likewise.
	(IssueFieldInteger.__init__): Set default value.
	(IssueFieldText.__init__): Likewise.
	(IssueFieldSet.__init__): Likewise.
	(IssueFieldAttachment.__init__): Likewise.
	(IssueFieldEnumeration.__init__): Likewise.
	(IssueFieldTime.__init__): Likewise.
	(IssueFieldUid.__init__): Likewise.
	(IssueClass.__init__): Create mandatory fields.
	(IssueClass.GetFields): Store fields as a map.
	(IssueClass.HasField): New function.
	* qm/track/gadfly_idb.py: New file.
	* qm/track/sql_idb.py: Likewise.
	* qm/track/memory_idb.py: Likewise.
	* qm/track/test.py: Adjust for new field initializers throughout.
	(test_create_idb): New test.
	(test_add_issue_class): Likewise.
	(test_add_issues): Likewise.
	(test_get_issues): Likewise.
	(test_attachments): Likewise.

2001-01-04  Alex Samuel  <samuel@codesourcery.com>

	* gadfly/__init__.py: New file.

	* templates/Makefile: Update year.
	* templates/docbook: Likewise.
	* templates/docbook-chapter: Likewise.
	* templates/html: Likewise.
	* templates/py: Likewise.
	* templates/xml: Likewise.

2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* gadfly/.cvsignore: New file.

2000-12-28  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design-td.xml: Added new sections and
	details.

	* doc/design/qmconfig/design-lm.xml: Break into sections.
	* doc/design/qmconfig/design-probe.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.

2000-12-27  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/biblio.xml: Add an id.

	* doc/design/qmconfig/design-pdd.xml: New file.
	* doc/design/qmconfig/design-basic.xml: New file.

	* doc/design/qmconfig/figures/pkg_qmconfig.*: Re-scale.
	* doc/design/qmconfig/design.xml: Add format="PNG" to imagedata's.
	* doc/design/qmconfig/design-lm.xml: Likewise.
	* doc/design/qmconfig/design-probe.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-26  R. Lindsay Todd  <toddr@rpi.edu>

	* standard.mk: Run pdfjadetex thrice, to get all references correct.

	* doc/design/qmconfig/design-probe.xml: Updated API for probe
	class, to be consistent with other components.
	* doc/design/qmconfig/figures/cl_probe.*: Updated to match API for
	probe class.

	* doc/design/qmconfig/design-lm.xml: Add figure for LangServ.
	* doc/design/qmconfig/figures/cl_langserv.*: New file.

2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* Makefile (setup): New target.
	(gadfly/sqlwhere.py): Likewise.
	* standard.mk (setup): New phony target.

2000-12-22  Alex Samuel  <samuel@codesourcery.com>

	* Makefile: New file.

2000-12-21  Alex Samuel  <samuel@codesourcery.com>

	* qm/.cvsignore: New file.
	* qm/track/.cvsignore: Likewise.

2000-12-21  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (PRINTTEX): Define as dummy if there's no DocBook.
	(PRINTPDF): Likewise.
	(test): New target.

	* qm/__init__.py: New file.
	* qm/common.py: Likewise.
	* qm/regression_test.py: Likewise.
	* qm/track/__init__.py: Likewise.
	* qm/track/issue.py: Likewise.
	* qm/track/issue_class.py: Likewise.
	* qm/track/test.py: Likewise.

2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design.xml: Reorder some sections.
	* doc/design/qmconfig/design-lm.xml: Add additional ids.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design-probe.xml: Likewise.  Added rough
	draft of probe database.

2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/overview.xml: Remove /> sequences, so as to
	not confuse psgml.
	* doc/design/qmconfig/design-lm.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.

2000-12-15  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design.xml: Add/fix id's.
	* doc/design/qmconfig/intro.xml: Likewise.
	* doc/design/qmconfig/overview.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.
	* doc/design/qmconfig/design-td.xml: Likewise.  Fix images.
	* doc/design/qmconfig/qmconfig.xml: Add qm.mod.

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Return true even if empty
	$(DOCBITMAPS).

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Handle empty $(DOCBITMAPS).

2000-12-14  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Update ChangeLog and documentation instructions.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Copy bitmaps into print
	dir instead of setting paths.
	* doc/design/qmconfig/design-probe.xml: Scale images.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(HTMLMANIFEST)): Put graphics filename in manifest
	only.
	* doc/design/qmconfig/design-probe.xml: Adjust image filenames.
	* doc/design/qmconfig/design-td.xml: Likewise.
	* doc/design/qmconfig/design.xml: Likewise.
	* doc/design/qmconfig/requirements.xml: Likewise.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk ($(PRINTDIR)/$(PRINTPDF)): Set TEXINPUTS.
	* doc/design/qmconfig/Makefile (DOCBITMAPS): Set it.
	* doc/design/qmtext/iface.xml: Always require qmtest subcommand.

2000-12-13  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/iface.xml: Twiddle command-line syntax.

	* doc/design/qmtest/core.xml: Regularize entity ids.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.

2000-12-07  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (gui): New entity.
	(url): Likewise.
	* doc/design/qmtrack/concepts.xml: Fix typos.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.

2000-12-07  Alex Samuel  <samuel@codesourcery.com>

	Tag "version-0-2" for delivery to LANL.

	* standard.mk ($(HTMLINDEX)): Process graphics here.
	($(HTMLMANIFEST)): Remove separate target.

	* doc/qm-html.dsl (%generate-legalnotice-link%): Define true.
	* doc/qm-print.dsl (%chapter-autolabel%): Likewise.
	(%section-autolabel%): Likewise.
	* doc/qm-opl.xml: New file.
	* doc/qm.mod (qmbuild): Use <application> element.
	(qmconfig): Likewise.
	(qmtest): Likewise.
	(qmtrack): Likewise.
	(html): New entity.
	(mime): Likewise.
	(dashdash): Likewise.
	(qmlicense): Likewise.

	* doc/design/qmtest/core.xml: Edit for style, spelling,
	consistency, and markup.
	* doc/design/qmtest/iface.xml: Likewise.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/refs.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.

	* doc/design/qmtrack/concepts.xml: Likewise.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/qmtrack.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.

2000-12-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod (idb): Remove entity.
	(iid): Likewise.
	(faq): New entity.

	* doc/design/qmtest/refs.xml: Strip linefeeds.

	* doc/design/qmtrack/qmtrack.xml (idb): New entity.
	(iid): Likewise.
	(uid): Likewise.
	* doc/design/qmtrack/concepts.xml: Edit.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/triggers.xml: Likewise.
	* doc/design/qmtrack/user-interface.xml: Likewise.
	* doc/design/qmtrack/xml-repr.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Incorporate new text.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/references.xml: New file.
	* doc/design/qmtrack/state-model-example.dia: Likewise.
	* doc/design/qmtrack/state-model-example.png: Likewise.

2000-12-06  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/create1.html: New file.
	* doc/design/qmtrack/create2.html: Likewise.
	* doc/design/qmtrack/edit1.html: Likewise.
	* doc/design/qmtrack/edit2.html: Likewise.
	* doc/design/qmtrack/query1.html: Likewise.
	* doc/design/qmtrack/query2.html: Likewise.
	* doc/design/qmtrack/main1.html: Likewise.

	* doc/design/qmtrack/create1.jpg: Update.
	* doc/design/qmtrack/create2.jpg: Likewise.
	* doc/design/qmtrack/edit1.jpg: Likewise.
	* doc/design/qmtrack/edit2.jpg: Likewise.
	* doc/design/qmtrack/query1.jpg: Likewise.
	* doc/design/qmtrack/query2.jpg: Likewise.
	* doc/design/qmtrack/query3.jpg: Likewise.
	* doc/design/qmtrack/main1.jpg: New file.

	* doc/design/user-interface.xml: Update e-mail section by adding
	headers. Flesh out web section.

2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml (idb-impl.xml): Remove entity.
	* doc/design/qmtrack/idb-impl.xml: Remove.
	* doc/design/qmtrack/implementation.xml: Describe SQL IDB.
	* doc/design/qmtrack/xml-repr.xml: Tune.

2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Tidy up formatting.

2000-12-05  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Fix inconsistencies with
	other sections.
	* doc/design/qmtrack/create1.jpg: Update.
	* doc/design/qmtrack/edit1.jpg: Likewise.
	* doc/design/qmtrack/edit2.jpg: Likewise.
	* doc/design/qmtrack/query1.jpg: Likewise.
	* doc/design/qmtrack/query2.jpg: Likewise.
	* doc/design/qmtrack/query3.jpg: Likewise.

2000-12-05  R. Lindsay Todd  <toddr@rpi.edu>

	* doc/design/qmconfig/design-td.xml: New file

2000-12-05  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/Makefile (DOCBITMAPS): Add *.png.
	* doc/design/qmtrack/web-gui-states.dia: New file.
	* doc/design/qmtrack/web-gui-states.png: Likewise.
	* doc/design/qmtrack/concepts.xml: Add categories section.
	* doc/design/qmtrack/idb-impl.xml: Edit.
	* doc/design/qmtrack/triggers.xml: Explain get triggers better.
	* doc/design/qmtrack/user-interface.xml: Expand.

2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.mod: New file.
	* doc/design/qmtest/qmtest.xml: Don't declare phrase entities.
	Incorporate qm.mod.
	* doc/design/qmtrack/qmtrack.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Add link.
	* doc/design/qmtrack/user-interface.xml: Fix entity.  Fix ulink.
	* doc/design/qmtrack/xml-repr.xml: Improve example.

2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Edit.  Add ids.
	* doc/design/qmtrack/idb-impl.xml: Likewise.
	* doc/design/qmtrack/implementation.xml: Likewise.
	* doc/design/qmtrack/introduction.xml: Likewise.
	* doc/design/qmtrack/requirements.xml: Likewise.
	* doc/design/qmtrack/xml-impl.xml: Likewise.

2000-12-04  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (HTMLINDEX): New macro.
	(PRINTDIR): Likewise.
	(PRINTTEX): Likewise.
	(PRINTPDF): Likewise.
	(html-dir): Remove target.
	(html-output): Likewise.
	(html-graphics): Likewise.
	($(HTMLINDEX)): New target.
	($(HTMLMANIFEST)): Likewise.
	($(HTMLTARBALL)): Change dependencies.
	(docbook-print): Remove target.
	($(PRINTTEX)): New target.
	($(PRINTPDF)): Likewise.
	(%.html): Likewise.

	* doc/design/qmtrack/qmtrack.xml (dtml): New entity.
	(implementation.xml): Likewise.
	(idb-api.xml): Remove entity.
	Add authors.
	* doc/design/qmtrack/concepts.xml: Include triggers and
	user interface sections.
	* doc/design/qmtrack/idb-api.xml: Rename to...
	* doc/design/qmtrack/implementation.xml: ... this.  Add trigger
	API.  Include IDB implementation section.
	* doc/design/qmtrack/idb-impl.xml: Make it a section.
	* doc/design/qmtrack/triggers.xml: Remove API stuff.  Make it a
	section.
	* doc/design/qmtrack/user-interface.xml: Make it a section.
	Reformat.

2000-12-02  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-interface.xml: Update e-mail section.

2000-12-01  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk: Update instructional comments.
	(HTMLDIR): New macro.
	(HTMLMANIFEST): Likewise.
	(HTMLTARBALL): Likewise.
	(docbook-html): Make it a collection target only.
	(html-dir): New target.
	(html-output): Likewise.
	(html-graphics): Likewise.
	($(HTMLTARBALL)): Likewise.
	(docbook-print): Process TeX output for PDF.

	* doc/design/qmtest/iface.xml: Add ids.  Clean up markup and
	identation.
	* doc/design/qmtest/qmtest.xml (prompt): New entity.
	* doc/design/qmtest/req.xml: Remove bogus tag.

	* doc/design/qmtrack/Makefile (DOCBITMAPS): New macro.
	* doc/design/qmtrack/user-interface.xml: Add ids.

2000-12-01  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Add ids.  Rearrange sections.
	* doc/design/qmtrack/idb-api.xml: Remove queries section.
	* doc/design/qmtrack/idb-impl.xml: Fix link.
	* doc/design/qmtrack/introduction.xml: Don't include requirements.xml.
	* doc/design/qmtrack/qmtrack.xml (prompt): New entity.
	(qmtrack-cmd): Likewise.
	Don't include xml-repr.xml.  Include requirements.xml.
	* doc/design/qmtrack/requirements.xml: Make it a chapter.
	* doc/design/qmtrack/user-interface.xml: Edit command-line
	section.  Tidy formatting.
	* doc/design/qmtrack/xml-repr.xml: Make it a section.

2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Don't include user-api.xml.
	* doc/design/qmtrack/user-api.xml: Remove.

2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm-html.dsl (html-manifest): Set true.
	(html-manifest-filename): Set to "docbook-html.manifest".
	(%use-id-as-filename%): Set to true.

	* doc/design/qmtrack/qmtrack.xml (api): New entity.
	(sc): Likewise.
	(introduction.xml): Likewise.
	Include introduction.
	* doc/design/qmtrack/introduction.xml: New file.
	* doc/design/qmtrack/requirements.xml: Make it a section.  Edit.
	* doc/design/qmtrack/concepts.xml: Revise introductory text.
	Add ids.  Rename time field.

2000-11-30  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/desgin/qmtrack/create1.jpg: New file.
	* doc/desgin/qmtrack/create2.jpg: Likewise.
	* doc/desgin/qmtrack/edit1.jpg: Likewise.
	* doc/desgin/qmtrack/edit2.jpg: Likewise.
	* doc/desgin/qmtrack/edit3.jpg: Likewise.
	* doc/desgin/qmtrack/query1.jpg: Likewise.
	* doc/desgin/qmtrack/query2.jpg: Likewise.
	* doc/desgin/qmtrack/query3.jpg: Likewise.

	* doc/design/qmtrack/user-interface.xml: Update to contain new
	ideas for interfaces.

2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Rename mandatory fields.
	Rewrite queries section.
	* doc/design/qmtrack/idb-api.xml: Edit.
	* doc/design/qmtrack/idb-impl.xml: New file.
	* doc/design/qmtrack/qmtrack.xml: Include idb-impl.xml.
	* doc/design/qmtrack/xml-repr.xml: Add ids and links.

2000-11-30  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm-html.dsl (%section-autolabel%): Set to true.
	(chunk-skip-first-element-list): Set to empty list.

2000-11-29  Mark Mitchell  <mark@codesourcery.com>

	* doc/design/qmtest/qmtest.xml: Revise heavily, tightening
	prose, clarifying concepts, etc.
	* doc/design/qmtest/core.xml: Likewise.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.

2000-11-29  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Make acronyms upper-case.
	(dtd): New entity.
	(xml): Likewise.
	Include xml-repr.xml.
	* doc/design/qmtrack/triggers.xml: Finish.
	* doc/design/qmtrack/xml-repr.xml: New file.
	* doc/design/qmtrack/user-interface.xml: Add id's.  Fix some
	indentation.

2000-11-28  Mark Mitchell  <mark@codesourcery.com>

	* doc/design/qmtest/core.xml: Fix DocBook syntax errors.
	* doc/design/qmtest/impl.xml: Likewise.
	* doc/design/qmtest/qmtest.xml: Likewise.
	* doc/design/qmtest/refs.xml: Likewise.
	* doc/design/qmtest/req.xml: Likewise.
	* doc/design/qmtest/design.html: Remove.

2000-11-28  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/triggers.xml: New file.

2000-11-27  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Add user-interface.xml.
	* doc/design/qmtrack/user-api.xml: Fix typos.
	* doc/design/qmtrack/user-interface.xml: New file.

2000-11-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/idb-api.xml: Add missing </section> tag.

2000-11-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtrack/concepts.xml: Continue.
	* doc/design/qmtrack/idb-api.xml: Likewise.

2000-11-25  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/user-api.xml: Make style changes. Update
	based on conversations with Alex.

2000-11-20  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/req.xml: New file.

2000-11-20  Alex Samuel  <samuel@codesourcery.com>

	* README.sources: Add discussion of doc strings.

2000-11-20  Benjamin Chelf  <chelf@codesourcery.com>

	* doc/design/qmtrack/qmtrack.xml: Added user-api.xml.
	* doc/design/qmtrack/user-api.xml: New file.

2000-11-16  Alex Samuel  <samuel@codesourcery.com>

	* doc/concept: New directory.
	* doc/concept/sapcat: Likewise.
	* doc/design/qmconfig/*: Surgically move all repository files to...
	* doc/concept/sapcat/*: ... here.

2000-11-10  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (docbook-html): Fix files to tidy.

2000-11-10  Alex Samuel  <samuel@codesourcery.com>

	Conversion to DocBook.

	* standard.mk (TIDYFLAGS): Use one-space indent.
	(JADE): New variable.
	(JADEEXTRA): Likewise.
	(SGMLDIRS): Likewise.
	(HTMLSS): Likewise.
	(PRINTSS): Likewise.
	(NULLSTIRNG): Likewise.
	(SPACE): Likewise.
	(doc): New rule.
	(doc-html): New rule, conditionally.
	(doc-print): Likewise.
	(docbook-html): New rule.
	(docbook-print): Likewise.
	* doc/GNUmakefile: Rename to...
	* doc/Makefile: ... this.

	* doc/qm-print.dsl: New file.
	* doc/qm-html.dsl: Likewise.

	* doc/design/qmtest/GNUmakefile: Rename to...
	* doc/design/qmtest/Makefile: ... this.
	* doc/design/qmtest/*.xhtml: Remove.
	* doc/design/qmtest/*.xml: New files.

	* doc/design/qmtrack/GNUmakefile: Rename to...
	* doc/design/qmtrack/Makefile: ... this.
	* doc/design/qmtrack/*.xhtml: Remove.
	* doc/design/qmtrack/*.xml: New files.

	* templates/docbook: New file.
	* templates/docbook-chapter: Likewise.
	* templates/xml: Add XML PI.

2000-11-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/GNUmakefile (SUBDIRS): Add design/qmtest.

2000-11-06  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py: Handle multiple term classes.  Use
	pickling for .terms file.
	(terms_classes): New list.
	(terms_def_classes): Likewise.
	* templates/html: Add emacs gunk to set fill-column.

2000-11-03  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py (clean_up_term): New function.
	Use it.  Try to handle pluralized terms.
	* doc/qm.css (div.XML): New class.
	(span.Function): Likewise.

2000-11-01  Alex Samuel  <samuel@codesourcery.com>

	* doc/qm.css (a.Dfn): Remove.
	(a.TermDef): Fix background-color.
	(span.Identifier): Recreate.
	(span.Class): Likewise.
	(table): New style.
	(tr.Heading): New class.
	(span.Fixme): Likewise.

	* templates/html: Add Emacs local variables.

2000-10-31  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk (%.html): Fix.
	* doc/process-xhtml.py: Fix href attribute.
	* doc/qm.css (a.TermDef): Fix font-style.
	(div.api): Rename to...
	(div.API): ... this.
	(span.Identifier): New class.
	(span.Class): Likewise.

	* doc/design/qmtest/terms.xhtml: New file.

2000-10-27  Alex Samuel  <samuel@codesourcery.com>

	* templates/html: Use Open Publication License.
	* doc/design/qmtest/design.html: Likewise.
	* doc/design/qmtrack/index.xhtml: Likewise.
	* doc/design/qmtrack/architecture.xhtml: Likewise.
	* doc/design/qmtrack/requirements.xhtml: Likewise.

2000-10-26  Alex Samuel  <samuel@codesourcery.com>

	* doc/process-xhtml.py: Convert to coding standards.
	* doc/qm.css (div.api): New style.
	* templates/html: Remove emacs variable stuff.
	* templates/py: Add emacs variable stuff.

2000-10-25  Alex Samuel  <samuel@codesourcery.com>

	* stanard.mk: Add comments.
	(.PHONY): Fix typo.
	(TOPDIR): New variable.
	(XHTMLPROCESS): Likewise.
	($(SUBDIRS)): Pass TOPDIR to child make processes.
	(%.html): Use XHTML processor script.
	* doc/process-xhtml.py: New script.
	* doc/design/qmtrack/GNUmakefile: Use TOPDIR.

	* doc/qm.css: Improve comments.

2000-10-25  Alex Samuel  <samuel@codesourcery.com>

	* standard.mk: New file.
	* doc/GNUmakefile: Likewise.
	* doc/qm.css: Likewise.
	* doc/design/qmtrack/GNUmakefile: Likewise.
	* templates/html: Update for XHTML.

2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* templates/html (DOCTYPE): Add.

2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* templates/py: New file.

2000-10-24  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmconfig/...: Import.

2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/design/qmtest/design.html: Import.

2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* doc/design: New directory.
	* doc/design/qmconfig: Likewise.
	* doc/design/qmbuild: Likewise.
	* doc/design/qmtest: Likewise.
	* doc/design/qmtrack: Likewise.

2000-10-22  Alex Samuel  <samuel@codesourcery.com>

	* ChangeLog: New file.
	* README.sources: Likewise.
	* COPYING: Likewise.

	* templates: New directory.
	* doc: Likewise.
