int xlw::XlfOper4::ConvertToMatrix(MyMatrix& value) const { // deal with empty case first if (lpxloper_->xltype == xltypeMissing || lpxloper_->xltype == xltypeNil ) { MyMatrix tmp; value = tmp; return xlretSuccess; } CellMatrix tmp(1,1);// will be resized anyway int xlret = ConvertToCellMatrix(tmp); if (xlret != xlretSuccess) return xlret; value = MyMatrix(tmp.RowsInStructure(), tmp.ColumnsInStructure()); for (unsigned long i =0; i < tmp.RowsInStructure(); i++) for (unsigned long j =0; j < tmp.ColumnsInStructure(); j++) if (tmp(i,j).IsANumber()) ChangingElement(value,i,j) = tmp(i,j).NumericValue(); else return xlretFailed; return xlretSuccess; }
ArgumentList::ArgumentList(CellMatrix cells, std::string ErrorId) { CellValue empty; unsigned long rows = cells.RowsInStructure(); unsigned long columns = cells.ColumnsInStructure(); if (rows == 0) throw(std::string("Argument List requires non empty cell matix ")+ErrorId); if (!cells(0,0).IsAString()) throw(std::string("a structure name must be specified for argument list class ")+ErrorId); else { StructureName = cells(0,0).StringValueLowerCase(); cells(0,0) = empty; } {for (unsigned long i=1; i < columns; i++) if (!cells(0,i).IsEmpty() ) throw("An argument list should only have the structure name on the first line: "+StructureName+ " " + ErrorId); } ErrorId +=" "+StructureName; {for (unsigned long i=1; i < rows; i++) for (unsigned long j=0; j < columns; j++) if (cells(i,j).IsError()) GenerateThrow("Error Cell passed in ",i,j);} unsigned long row=1UL; while (row < rows) { unsigned long rowsDown=1; unsigned column = 0; while (column < columns) { if (cells(row,column).IsEmpty()) { // check nothing else in row while (column< columns) { if (!cells(row,column).IsEmpty()) GenerateThrow("data or value where unexpected.",row, column); ++column; } } else // we have data { if (!cells(row,column).IsAString()) GenerateThrow("data where name expected.", row, column); std::string thisName(cells(row,column).StringValueLowerCase()); if (thisName =="") GenerateThrow("empty name not permissible.", row, column); if (rows == row+1) GenerateThrow("No space where data expected below name", row, column); cells(row,column).clear(); // weird syntax to satisfy VC6 CellValue* belowPtr = &cells(row+1,column); CellValue& cellBelow = *belowPtr; if (cellBelow.IsEmpty()) GenerateThrow("Data expected below name", row, column); if (cellBelow.IsANumber()) { add(thisName, cellBelow.NumericValue()); column++; cellBelow=empty; } else if (cellBelow.IsBoolean()) { add(thisName, cellBelow.BooleanValue()); column++; cellBelow=empty; } else // ok its a string { std::string stringVal = cellBelow.StringValueLowerCase(); if ( (cellBelow.StringValueLowerCase() == "list") || (cellBelow.StringValueLowerCase() == "matrix") || (cellBelow.StringValueLowerCase() == "cells") ) { bool nonNumeric = false; CellMatrix extracted(ExtractCells(cells,row+2,column,ErrorId,thisName,nonNumeric)); if (cellBelow.StringValueLowerCase() == "list") { ArgumentList value(extracted,ErrorId+":"+thisName); addList(thisName, extracted); //note not value } if (cellBelow.StringValueLowerCase() == "cells") { add(thisName,extracted); } if (cellBelow.StringValueLowerCase() == "matrix") { if (nonNumeric) throw("Non numerical value in matrix argument :"+thisName+ " "+ErrorId); MJMatrix value(extracted.RowsInStructure(),extracted.ColumnsInStructure()); for (unsigned long i=0; i < extracted.RowsInStructure(); i++) for (unsigned long j=0; j < extracted.ColumnsInStructure(); j++) ChangingElement(value,i,j) = extracted(i,j); add(thisName,value); } cellBelow = empty; rowsDown = maxi(rowsDown,extracted.RowsInStructure()+2); column+= extracted.ColumnsInStructure(); } else // ok its an array or boring string { if (cellBelow.StringValueLowerCase() == "array" ||cellBelow.StringValueLowerCase() == "vector" ) { cellBelow.clear(); if (row+2>= rows) throw(ErrorId+" data expected below array "+thisName); unsigned long size = cells(row+2,column); cells(row+2,column).clear(); if (row+2+size>=rows) throw(ErrorId+" more data expected below array "+thisName); MyArray theArray(size); for (unsigned long i=0; i < size; i++) { theArray[i] = cells(row+3+i,column); cells(row+3+i,column).clear(); } add(thisName,theArray); rowsDown = maxi(rowsDown,size+2); column+=1; } else { std::string value = cellBelow.StringValueLowerCase(); add(thisName,value); column++; cellBelow=empty; } } } } } row+=rowsDown+1; } {for (unsigned long i=0; i < rows; i++) for (unsigned long j=0; j < columns; j++) if (!cells(i,j).IsEmpty()) { GenerateThrow("extraneous data "+ErrorId,i,j); }} }