Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 5b7c8b5971147c258fdef4412288013139672cdd)
+++ libcfa/src/Makefile.am	(revision 16f9aca2ea5ad835bf063489ba7b2cc2bf9ee79c)
@@ -78,4 +78,5 @@
 	memory.hfa \
 	parseargs.hfa \
+	parseconfig.hfa \
 	rational.hfa \
 	stdlib.hfa \
Index: libcfa/src/parseconfig.cfa
===================================================================
--- libcfa/src/parseconfig.cfa	(revision 16f9aca2ea5ad835bf063489ba7b2cc2bf9ee79c)
+++ libcfa/src/parseconfig.cfa	(revision 16f9aca2ea5ad835bf063489ba7b2cc2bf9ee79c)
@@ -0,0 +1,95 @@
+#include <iostream>
+#include <fstream>
+#include <limits>										// numeric_limits
+using namespace std;
+#include "parseconfig.hfa"
+
+static bool comments( ifstream & in, string & name ) {
+	for ( ;; ) {
+		in >> name;
+	  if ( in.fail() ) return true;
+	  if ( name.substr(0,1) != "#" ) break;
+		in.ignore( numeric_limits<int>::max(), '\n' );	// ignore remainder of line
+	} // for
+	return false;
+} // comments
+
+// Process the configuration file to set the simulation parameters.
+void processConfigFile( const char *configFile, ConfigParms & cparms ) {
+	enum { Parmnum = 11 };
+	struct {
+		const char * name;								// configuration name
+		bool used;										// already supplied ?
+		unsigned int & value;							// location to put configuration value
+	} static parms[Parmnum] = {
+		{ "StopCost", false, cparms.stopCost },
+		{ "NumStudents", false, cparms.numStudents },
+		{ "NumStops", false, cparms.numStops },
+		{ "MaxNumStudents", false, cparms.maxNumStudents },
+		{ "TimerDelay", false, cparms.timerDelay },
+		{ "MaxStudentDelay", false, cparms.maxStudentDelay },
+		{ "MaxStudentTrips", false, cparms.maxStudentTrips },
+		{ "GroupoffDelay", false, cparms.groupoffDelay },
+		{ "ConductorDelay", false, cparms.conductorDelay },
+		{ "ParentalDelay", false, cparms.parentalDelay },
+		{ "NumCouriers", false, cparms.numCouriers },
+	};
+	string name;
+	int value;
+	unsigned int cnt, posn, numOfParm = 0;
+
+	try {
+		ifstream in( configFile );						// open the configuration file for input
+
+		for ( cnt = 0 ; cnt < Parmnum; cnt += 1 ) {		// parameter names can appear in any order
+		  if ( comments( in, name ) ) break;			// eof ?
+			for ( posn = 0; posn < Parmnum && name != parms[posn].name; posn += 1 ); // linear search
+		  if ( posn == Parmnum ) break;					// configuration not found ?
+		  if ( parms[posn].used ) break;				// duplicate configuration ?
+			in >> value;
+			if ( value < 0 ) {
+				cerr << "Error: file \"" << configFile << "\" parameter " << name
+					 << " value " << value << " must be non-negative." << endl;
+				exit( EXIT_FAILURE );
+			} // if
+		  if ( in.fail() ) break;
+			in.ignore( numeric_limits<int>::max(), '\n' ); // ignore remainder of line
+			numOfParm += 1;
+			parms[posn].used = true;
+			parms[posn].value = value;
+		} // for
+
+		if ( numOfParm != Parmnum ) {
+			cerr << "Error: file \"" << configFile << "\" is corrupt." << endl;
+			exit( EXIT_FAILURE );
+		} // if
+		if ( ! comments( in, name ) ) {					// ! eof ?
+			cerr << "Error: file \"" << configFile << "\" has extraneous data." << endl;
+			exit( EXIT_FAILURE );
+		} // if
+	} catch( uFile::Failure & ) {
+		cerr << "Error: could not open input file \"" << configFile << "\"" << endl;
+		exit( EXIT_FAILURE );
+	} // try
+
+	if (cparms.numStops < 2) {
+        cerr << "Error: file \"" << configFile << "\" parameter NumStops value "
+             << cparms.numStops << " must be at least 2." << endl;
+        exit( EXIT_FAILURE );
+	}
+    if (cparms.numStudents < 1) {
+        cerr << "Error: file \"" << configFile << "\" parameter NumStudents value "
+             << cparms.numStudents << " must be at least 1." << endl;
+        exit( EXIT_FAILURE );
+    }
+    if (cparms.numCouriers < 1) {
+        cerr << "Error: file \"" << configFile << "\" parameter NumCouriers value "
+             << cparms.numCouriers << " must be at least 1." << endl;
+        exit( EXIT_FAILURE );
+    }
+} // processConfigFile
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa parseconfig.cfa" //
+// End: //
Index: libcfa/src/parseconfig.hfa
===================================================================
--- libcfa/src/parseconfig.hfa	(revision 16f9aca2ea5ad835bf063489ba7b2cc2bf9ee79c)
+++ libcfa/src/parseconfig.hfa	(revision 16f9aca2ea5ad835bf063489ba7b2cc2bf9ee79c)
@@ -0,0 +1,22 @@
+#pragma once
+
+struct ConfigParms {
+	unsigned int stopCost;								// amount to charge per train stop
+	unsigned int numStudents;							// number of students to create
+	unsigned int numStops;								// number of train stops; minimum of 2
+	unsigned int maxNumStudents;						// maximum students each train can carry
+	unsigned int timerDelay;							// length of time between each tick of the timer
+	unsigned int maxStudentDelay;						// maximum random student delay between trips
+	unsigned int maxStudentTrips;						// maximum number of train trips each student takes
+	unsigned int groupoffDelay;							// length of time between initializing gift cards
+	unsigned int conductorDelay;						// length of time between checking on passenger POPs
+	unsigned int parentalDelay;							// length of time between cash deposits
+	unsigned int numCouriers;							// number of WATCard office couriers in the pool
+}; // ConfigParms
+
+void processConfigFile( const char * configFile, ConfigParms & cparms );
+
+// Local Variables: //
+// mode: c //
+// tab-width: 4 //
+// End: //
