Index: /issm/trunk/src/c/io/OptionsParse.cpp
===================================================================
--- /issm/trunk/src/c/io/OptionsParse.cpp	(revision 7732)
+++ /issm/trunk/src/c/io/OptionsParse.cpp	(revision 7732)
@@ -0,0 +1,320 @@
+/*\file OptionsParse.c
+ *\brief: functions to parse the mex options.
+ */
+#ifdef HAVE_CONFIG_H
+    #include "config.h"
+#else
+#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
+#endif
+
+#include "./io.h"
+#include "../shared/shared.h"
+#include "../include/include.h"
+
+#ifdef _SERIAL_
+#include <mex.h>
+
+DataSet* OptionsParse( int istart, int nrhs, const mxArray* prhs[]){
+
+	int   i;
+	char* name=NULL;
+	DataSet* options=NULL;
+	OptionsObject* oobject=NULL;
+
+	options=new DataSet;
+
+/*  loop over each name and value  */
+
+	for (i=istart; i<nrhs; i=i+2) {
+		if (!mxIsChar(prhs[i]))
+			_error_("Argument %d must be name of option.",i+1);
+
+		FetchData(&name,prhs[i]);
+		if (i+1 == nrhs) {
+			_error_("Argument %d must exist and be value of option \"%s\".",i+2,name);
+		}
+
+		_printf_(true,"  Processing option \"%s\" of class \"%s\".\n",
+				 name,mxGetClassName(prhs[i+1]));
+		oobject=(OptionsObject*)OptionsObjectParse(name,&prhs[i+1]);
+		options->AddObject((Object*)oobject);
+		oobject=NULL;
+	}
+
+/*  echo the dataset  */
+
+	if (options->Size())
+		for (i=0; i<options->Size(); i++)
+			((OptionsObject *)options->GetObjectByOffset(i))->Echo();
+
+	return(options);
+}
+
+
+OptionsObject* OptionsObjectParse( char* name, const mxArray* prhs[]){
+
+	OptionsObject* oobject=NULL;
+	mxArray* lhs[1];
+
+/*  parse the value according to the matlab data type  */
+
+	if      (mxIsDouble(prhs[0]))
+		oobject=(OptionsObject*)OptionsDoubleParse(name,prhs);
+	else if (mxIsLogical(prhs[0]))
+		oobject=(OptionsObject*)OptionsLogicalParse(name,prhs);
+	else if (mxIsChar(prhs[0]))
+		oobject=(OptionsObject*)OptionsCharParse(name,prhs);
+	else if (mxIsStruct(prhs[0]))
+		oobject=(OptionsObject*)OptionsStructParse(name,prhs);
+	else if (mxIsCell(prhs[0]))
+		oobject=(OptionsObject*)OptionsCellParse(name,prhs);
+	else {
+		_printf_(true,"  Converting value of option \"%s\" from unrecognized class \"%s\" to class \"%s\".\n",
+				 name,mxGetClassName(prhs[0]),"struct");
+		if (!mexCallMATLAB(1,lhs,1,(mxArray**)prhs,"struct")) {
+			oobject=(OptionsObject*)OptionsStructParse(name,(const mxArray**)lhs);
+			mxDestroyArray(lhs[0]);
+		}
+		else
+			_error_("Second argument value of option \"%s\" is of unrecognized class \"%s\".",
+					name,mxGetClassName(prhs[0]));
+	}
+
+	return(oobject);
+}
+
+
+OptionsDouble* OptionsDoubleParse( char* name, const mxArray* prhs[]){
+
+	int   i;
+	OptionsDouble* odouble=NULL;
+	const mwSize* ipt=NULL;
+
+/*  check and parse the name  */
+
+	odouble=new OptionsDouble;
+	odouble->name =(char *) xmalloc((strlen(name)+1)*sizeof(char));
+	strcpy(odouble->name,name);
+
+/*  check and parse the value  */
+
+	if (!mxIsDouble(prhs[0]))
+		_error_("Value of option \"%s\" must be class \"%s\", not class \"%s\".",
+				odouble->name,"double",odouble->name,mxGetClassName(prhs[0]));
+
+	odouble->numel=mxGetNumberOfElements(prhs[0]);
+	odouble->ndims=mxGetNumberOfDimensions(prhs[0]);
+	ipt           =mxGetDimensions(prhs[0]);
+	odouble->size =(int *) xmalloc(odouble->ndims*sizeof(int));
+	for (i=0; i<odouble->ndims; i++)
+		odouble->size[i]=(int)ipt[i];
+
+//  note that FetchData does not correctly handle ndims >= 3
+	if (odouble->ndims > 2) {
+		_printf_(true,"WARNING -- option \"%s\" of class \"%s\" has ndims=%d and will be skipped.\n",
+				 odouble->name,mxGetClassName(prhs[0]),odouble->ndims);
+	}
+	else
+		FetchData(&odouble->values,NULL,NULL,prhs[0]);
+
+	odouble->DeepEcho();
+
+	return(odouble);
+}
+
+
+OptionsLogical* OptionsLogicalParse( char* name, const mxArray* prhs[]){
+
+	int   i;
+	OptionsLogical* ological=NULL;
+	const mwSize* ipt=NULL;
+	bool  btemp;
+
+/*  check and parse the name  */
+
+	ological=new OptionsLogical;
+	ological->name =(char *) xmalloc((strlen(name)+1)*sizeof(char));
+	strcpy(ological->name,name);
+
+/*  check and parse the value  */
+
+	if (!mxIsLogical(prhs[0]))
+		_error_("Value of option \"%s\" must be class \"%s\", not class \"%s\".",
+				ological->name,"logical",ological->name,mxGetClassName(prhs[0]));
+
+	ological->numel=mxGetNumberOfElements(prhs[0]);
+	ological->ndims=mxGetNumberOfDimensions(prhs[0]);
+	ipt            =mxGetDimensions(prhs[0]);
+	ological->size =(int *) xmalloc(ological->ndims*sizeof(int));
+	for (i=0; i<ological->ndims; i++)
+		ological->size[i]=(int)ipt[i];
+
+//  note that FetchData does not correctly handle non-scalar logicals
+	if (ological->ndims > 2 || ological->size[0] > 1 || ological->size[1] > 1) {
+		_printf_(true,"WARNING -- option \"%s\" of class \"%s\" is more than [1x1] and will be skipped.\n",
+				 ological->name,mxGetClassName(prhs[0]));
+	}
+	else {
+//		FetchData(&ological->values,prhs[0]);
+//  could be memory leak until FetchData handles logical arrays
+		ological->values=(bool *) xmalloc(sizeof(bool));
+		FetchData(ological->values,prhs[0]);
+	}
+
+	ological->DeepEcho();
+
+	return(ological);
+}
+
+
+OptionsChar* OptionsCharParse( char* name, const mxArray* prhs[]){
+
+	int   i;
+	OptionsChar* ochar=NULL;
+	const mwSize* ipt=NULL;
+
+/*  check and parse the name  */
+
+	ochar=new OptionsChar;
+	ochar->name =(char *) xmalloc((strlen(name)+1)*sizeof(char));
+	strcpy(ochar->name,name);
+
+/*  check and parse the value  */
+
+	if (!mxIsChar(prhs[0]))
+		_error_("Value of option \"%s\" must be class \"%s\", not class \"%s\".",
+				ochar->name,"char",ochar->name,mxGetClassName(prhs[0]));
+
+	ochar->numel=mxGetNumberOfElements(prhs[0]);
+	ochar->ndims=mxGetNumberOfDimensions(prhs[0]);
+	ipt         =mxGetDimensions(prhs[0]);
+	ochar->size =(int *) xmalloc(ochar->ndims*sizeof(int));
+	for (i=0; i<ochar->ndims; i++)
+		ochar->size[i]=(int)ipt[i];
+
+//  note that FetchData does not correctly handle ndims >= 2 or multiple rows
+	if (ochar->ndims > 2 || ochar->size[0] > 1) {
+		_printf_(true,"WARNING -- option \"%s\" of class \"%s\" is more than [1xn] and will be skipped.\n",
+				 ochar->name,mxGetClassName(prhs[0]));
+	}
+	else
+		FetchData(&ochar->values,prhs[0]);
+
+	ochar->DeepEcho();
+
+	return(ochar);
+}
+
+
+OptionsStruct* OptionsStructParse( char* name, const mxArray* prhs[]){
+
+	int   i;
+	char  namei[161];
+	OptionsStruct* ostruct=NULL;
+	OptionsObject* oobject=NULL;
+	const mwSize*  ipt=NULL;
+	const mxArray* structi;
+	mwIndex        sindex;
+
+/*  check and parse the name  */
+
+	ostruct=new OptionsStruct;
+	ostruct->name =(char *) xmalloc((strlen(name)+1)*sizeof(char));
+	strcpy(ostruct->name,name);
+
+/*  check and parse the value  */
+
+	if (!mxIsStruct(prhs[0]))
+		_error_("Value of option \"%s\" must be class \"%s\", not class \"%s\".",
+				ostruct->name,"struct",ostruct->name,mxGetClassName(prhs[0]));
+
+	ostruct->numel=mxGetNumberOfElements(prhs[0]);
+	ostruct->ndims=mxGetNumberOfDimensions(prhs[0]);
+	ipt           =mxGetDimensions(prhs[0]);
+	ostruct->size =(int *) xmalloc(ostruct->ndims*sizeof(int));
+	for (i=0; i<ostruct->ndims; i++)
+		ostruct->size[i]=(int)ipt[i];
+	if (ostruct->numel)
+		ostruct->values=(DataSet **) xmalloc(ostruct->numel*sizeof(DataSet *));
+
+/*  loop through and process each element of the struct array  */
+
+	for (sindex=0; sindex<ostruct->numel; sindex++) {
+		ostruct->values[sindex]=new DataSet;
+
+/*  loop through and process each field for the element  */
+
+		for (i=0; i<mxGetNumberOfFields(prhs[0]); i++) {
+			sprintf(namei,"%s.%s",name,mxGetFieldNameByNumber(prhs[0],i));
+			structi=mxGetFieldByNumber(prhs[0],sindex,i);
+
+			oobject=(OptionsObject*)OptionsObjectParse(namei,&structi);
+			ostruct->values[sindex]->AddObject((Object*)oobject);
+			oobject=NULL;
+		}
+	}
+
+	ostruct->DeepEcho();
+
+	return(ostruct);
+}
+
+
+OptionsCell* OptionsCellParse( char* name, const mxArray* prhs[]){
+
+	int   i;
+	int*  dims;
+	char  namei[161];
+	char  cstr[81];
+	OptionsCell*   ocell=NULL;
+	OptionsObject* oobject=NULL;
+	const mwSize*  ipt=NULL;
+	const mxArray* celli;
+	mwIndex        cindex;
+
+/*  check and parse the name  */
+
+	ocell=new OptionsCell;
+	ocell->name =(char *) xmalloc((strlen(name)+1)*sizeof(char));
+	strcpy(ocell->name,name);
+
+/*  check and parse the value  */
+
+	if (!mxIsCell(prhs[0]))
+		_error_("Value of option \"%s\" must be class \"%s\", not class \"%s\".",
+				ocell->name,"cell",ocell->name,mxGetClassName(prhs[0]));
+
+	ocell->numel=mxGetNumberOfElements(prhs[0]);
+	ocell->ndims=mxGetNumberOfDimensions(prhs[0]);
+	ipt         =mxGetDimensions(prhs[0]);
+	ocell->size =(int *) xmalloc(ocell->ndims*sizeof(int));
+	for (i=0; i<ocell->ndims; i++)
+		ocell->size[i]=(int)ipt[i];
+	ocell->values=new DataSet;
+
+/*  loop through and process each element of the cell array  */
+
+	dims=(int *) xmalloc(ocell->ndims*sizeof(int));
+	for (cindex=0; cindex<ocell->numel; cindex++) {
+		ColumnWiseDimsFromIndex(dims,
+								(int)cindex,
+								ocell->size,
+								ocell->ndims);
+		StringFromDims(cstr,
+					   dims,
+					   ocell->ndims);
+		sprintf(namei,"%s%s",name,cstr);
+		celli=mxGetCell(prhs[0],cindex);
+
+		oobject=(OptionsObject*)OptionsObjectParse(namei,&celli);
+		ocell->values->AddObject((Object*)oobject);
+		oobject=NULL;
+	}
+	xfree((void**)&dims);
+
+	ocell->DeepEcho();
+
+	return(ocell);
+}
+
+#endif
Index: /issm/trunk/src/c/io/io.h
===================================================================
--- /issm/trunk/src/c/io/io.h	(revision 7731)
+++ /issm/trunk/src/c/io/io.h	(revision 7732)
@@ -58,4 +58,12 @@
 void FetchParams(Parameters** pparameters, DataHandle dataref);
 
+DataSet* OptionsParse( int istart, int nrhs, const mxArray* prhs[]);
+OptionsObject* OptionsObjectParse( char* name, const mxArray* prhs[]);
+OptionsDouble* OptionsDoubleParse( char* name, const mxArray* prhs[]);
+OptionsLogical* OptionsLogicalParse( char* name, const mxArray* prhs[]);
+OptionsChar* OptionsCharParse( char* name, const mxArray* prhs[]);
+OptionsStruct* OptionsStructParse( char* name, const mxArray* prhs[]);
+OptionsCell* OptionsCellParse( char* name, const mxArray* prhs[]);
+
 #endif
 
