pgnuplot stops function in Octave 3.0.1

View: New views
7 Messages — Rating Filter:   Alert me  

pgnuplot stops function in Octave 3.0.1

by gOS :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I can't isolate the error. I've tried several times, but the problem seems to randomly fix itself and then crop back up every 2 weeks or so. I'm looking for anyone with similar issues.

I'm running the windows version of Octave, the one that isn't cygwin. On a pentium 4 windows xp machine.

GNU plot crashes with messages like:

(gnuplot.exe:4580): Pango-WARNING **: couldn't load font "Helvetica Not-Rotated 200", falling back to "Sans Not-Rotated 200", expect ugly output.


Unfortunately, GNU plot stops working shortly after and I get the windows error report dialogue.

I usually recieve these errors when I call input inside of an Octave script where a user would traditionally input some value.

I've attempted to generate a bug report. Automatic sending doesn't work so I copied it and here it is:

#! /bin/sh -
#
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004,
#               2005, 2006 John W. Eaton
#
# This file is part of Octave.
#
# Octave is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# Octave is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with Octave; see the file COPYING.  If not, see
# <http://www.gnu.org/licenses/>.

# octave-bug - create a bug report and mail it to the bug-octave
# mailing list.
#
# Patterned after the bashbug script from bash 1.14.

# Configuration:  these variables are filled in when running make to
# compile Octave.

config_opts="'--build=i686-pc-msdosmsvc' '--prefix=/c/Software/VCLibs/local/octave-3.0.1' '--with-zlib=zlib' '--with-curl=libcurl' 'build_alias=i686-pc-msdosmsvc' 'CC=cc-msvc' 'CFLAGS=-O2' 'CXX=cc-msvc' 'CXXFLAGS=-O2' 'F77=fc-msvc' 'FFLAGS=-O2'"
VERSION="3.0.1"
SED="/usr/bin/sed"
MACHINE="i686-pc-msdosmsvc"
F77="fc-msvc"
FFLAGS="-O2"
FPICFLAG=""
FLIBS="-lhdf5 -lzlib -lf2c -lkernel32"
F2C="@F2C@"
F2CFLAGS="@F2CFLAGS@"
CPPFLAGS="-I.  -Ic:/Software/VCLibs/include"
INCFLAGS="-I. -I. -I./liboctave -I./src -I./libcruft/misc"
CC="cc-msvc"
CC_VERSION=""
CFLAGS="-O2 -MD"
CPICFLAG=""
CXX="cc-msvc"
CXX_VERSION=""
CXXFLAGS="-O2 -EHs -MD"
CXXPICFLAG=""
LD_CXX="cc-msvc"
LDFLAGS=""
LIBFLAGS="-L."
RLD_FLAG=""
LIBS="-lreadline  -lncurses -lhdf5 -lzlib  -lws2_32 -lkernel32"
BLAS_LIBS="-llapack -lblas"
FFTW_LIBS="-lfftw3"
LEXLIB=""
LIBGLOB="-lglob"
DEFS="-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DOCTAVE_SOURCE=1 -D_GNU_SOURCE=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_UNISTD_H=1 -DSEPCHAR=';' -DSEPCHAR_STR=\";\" -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1 -DCXX_ISO_COMPLIANT_LIBRARY=1 -DCXX_ABI=unknown -DHAVE_QHULL=1 -DHAVE_PCRE=1 -DHAVE_ZLIB_H=1 -DHAVE_ZLIB=1 -DHAVE_HDF5_H=1 -DHAVE_HDF5=1 -DHAVE_H5GGET_NUM_OBJS=1 -D_HDF5USEDLL_=1 -DHAVE_FFTW3=1 -DHAVE_GLPK_H=1 -DHAVE_GLPK=1 -DHAVE_CURL_CURL_H=1 -DHAVE_CURL=1 -DHAVE_IEEE754_DATA_FORMAT=1 -DF77_FUNC(name,NAME)=name ## _ -DF77_FUNC_(name,NAME)=name ## __ -DHAVE_BLAS=1 -DHAVE_SUITESPARSE_UMFPACK_H=1 -DHAVE_UMFPACK=1 -DUMFPACK_SEPARATE_SPLIT=1 -DHAVE_SUITESPARSE_COLAMD_H=1 -DHAVE_COLAMD=1 -DHAVE_SUITESPARSE_CCOLAMD_H=1 -DHAVE_CCOLAMD=1 -DHAVE_SUITESPARSE_CHOLMOD_H=1 -DHAVE_CHOLMOD=1 -DHAVE_SUITESPARSE_CS_H=1 -DHAVE_CXSPARSE=1 -Dmode_t=int -Dpid_t=int -Duid_t=int -Dgid_t=int -DHAVE_DEV_T=1 -DHAVE_INO_T=1 -DHAVE_LONG_LONG_INT=1 -DHAVE_UNSIGNED_LONG_LONG_INT=1 -DHAVE_SIG_ATOMIC_T=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DHAVE_ALLOCA=1 -DNPOS=std::string::npos -DHAVE_PLACEMENT_DELETE=1 -DSTDC_HEADERS=1 -DHAVE_ASSERT_H=1 -DHAVE_DIRECT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_FLOAT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_UTIME_H=1 -DHAVE_UNISTD_H=1 -DHAVE_VARARGS_H=1 -DHAVE_SSTREAM=1 -DHAVE_GLOB_H=1 -DHAVE_FNMATCH_H=1 -DHAVE_CONIO_H=1 -DHAVE_ATEXIT=1 -DHAVE_CHMOD=1 -DHAVE_DUP2=1 -DHAVE_EXECVP=1 -DHAVE_GETCWD=1 -DHAVE_GETPID=1 -DHAVE__KBHIT=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_PUTENV=1 -DHAVE_RAISE=1 -DHAVE_RENAME=1 -DHAVE_RMDIR=1 -DHAVE_SETLOCALE=1 -DHAVE_SETVBUF=1 -DHAVE_STAT=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRICMP=1 -DHAVE_STRNICMP=1 -DHAVE_TEMPNAM=1 -DHAVE_UMASK=1 -DHAVE_UNLINK=1 -DHAVE_UTIME=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1 -DHAVE_VSNPRINTF=1 -DHAVE__CHMOD=1 -DHAVE__SNPRINTF=1 -DHAVE__UTIME32=1 -DOCTAVE_HAVE_BROKEN_STRPTIME=1 -D_WIN32_WINNT=0x0403 -D_USE_MATH_DEFINES=1 -DHAVE_LOADLIBRARY_API=1 -DENABLE_DYNAMIC_LINKING=1 -DHAVE__FINITE=1 -DHAVE__ISNAN=1 -DHAVE__COPYSIGN=1 -DHAVE_DECL_SIGNBIT=0 -DHAVE_STRUCT_STAT_ST_RDEV=1 -DHAVE_DECL_TZNAME=1 -DHAVE_TZNAME=1 -DCLOSEDIR_VOID=1 -DMKDIR_TAKES_ONE_ARG=1 -DUSE_READLINE=1 -DRETSIGTYPE=void -DHAVE_DECL_SYS_SIGLIST=0 -DMUST_REINSTALL_SIGHANDLERS=1 -DRETSIGTYPE_IS_VOID=1 -DGNUPLOT_BINARY=\"pgnuplot\""

: ${USER=$LOGNAME}

CC_AND_VERSION=
if test -n "$CC_VERSION"; then
  CC_AND_VERSION="$CC, version $CC_VERSION"
fi

CXX_AND_VERSION=
if test -n "$CXX_VERSION"; then
  CXX_AND_VERSION="$CXX, version $CXX_VERSION"
fi

PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH
export PATH

TEMP=/tmp/octave-bug.$$

if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
  if [ -x /usr/bin/editor ]; then
    DEFEDITOR=editor
  elif [ -x /usr/local/bin/ce ]; then
    DEFEDITOR=ce
  elif [ -x /usr/local/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/contrib/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/bin/xemacs ]; then
    DEFEDITOR=xemacs
  elif [ -x /usr/contrib/bin/jove ]; then
    DEFEDITOR=jove
  elif [ -x /usr/local/bin/jove ]; then
    DEFEDITOR=jove
  elif [ -x /usr/bin/vi ]; then
    DEFEDITOR=vi
  else
    echo "octave-bug: No default editor found: attempting to use vi" >&2
    DEFEDITOR=vi
  fi
fi

: ${EDITOR=$DEFEDITOR}

if [ -z "$DEFPAGER" ] && [ -z "$PAGER" ]; then
  if [ -x /usr/bin/pager ]; then
    DEFPAGER=pager
  elif [ -x /usr/bin/less ]; then
    DEFPAGER=less
  elif [ -x /bin/less ]; then
    DEFPAGER=less
  elif [ -x /usr/local/bin/less ]; then
    DEFPAGER=less
  elif [ -x /usr/bin/more ]; then
    DEFPAGER=more
  elif [ -x /bin/more ]; then
    DEFPAGER=more
  elif [ -x /usr/bin/pg ]; then
    DEFPAGER=pg
  elif [ -x /bin/pg ]; then
    DEFPAGER=pg
  else
    echo "octave-bug: No default pager found: attempting to use more" >&2
    DEFPAGER=more
  fi
fi

: ${PAGER=$DEFPAGER}

trap 'rm -f $TEMP $TEMP.x; exit 1' 1 2 3 13 15
trap 'rm -f $TEMP $TEMP.x' 0

UN=
if (uname) > /dev/null 2>&1; then
  UN=`uname -a`
fi

HAVE_FMT=false
if (fmt < /dev/null) > /dev/null 2>&1; then
  HAVE_FMT=true
fi

# Check whether to use -n or \c to keep echo from printing a newline
# character.  Stolen from autoconf, which borrowed the idea from dist 3.0.

if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
  if (echo -n testing; echo 1,2,3) | $SED s/-n/xn/ | grep xn >/dev/null; then
    echo_n=
    echo_c='
'
  else
    echo_n=-n
    echo_c=
  fi
else
  echo_n=
  echo_c='\c'
fi

ss_p=`echo $VERSION | grep "^ss-"`
if test -n "$ss_p"; then
  BUGADDR="maintainers@octave.org"
else
  pretest_p=`echo $VERSION \
    | $SED 's,.*\.\([0-9]*\).*,\1,' \
    | grep -v '\.' \
    | grep '[0-9]'`

  if test -n "$pretest_p" && test "$pretest_p" -ge 90; then
    BUGADDR="maintainers@octave.org"
  else
    BUGADDR="bug@octave.org"
  fi
fi

SUBJECT="[50 character or so descriptive subject here (for reference)]"
if test $# -gt 0; then
  case "$1" in
    -s)
      shift
      if test $# -gt 0; then
        SUBJECT="$1"
        shift
      else
        echo "usage: octave-bug [-s subject]"
        exit 1
      fi
    ;;
  esac
fi

cat > $TEMP << EOF
To: $BUGADDR
EOF
if test -n "$USER"; then
cat >> $TEMP << EOF
Cc: $USER
EOF
fi
cat >> $TEMP << EOF
Subject: $SUBJECT
--------
Bug report for Octave $VERSION configured for $MACHINE

Description:
-----------

  * Octave stops recognizing packages and files in its path with out
    much warning. It may have to do with the error handling system,
    but I can't be sure.

    The main problem is that there appears to be no reliable way to
    cause this to happen, even with the same input. It happens between,
    1 out of 5 and 1 out of 10 times, depending on the day or hour.

    Windows XP machine. Pentium 4.

Repeat-By:
---------

  *

        1) Compile qpParseSum.c
        2) run testQpLoadAnalyzeData(true, true)
                This should cause an error no matter what on input.
                When it asks you to pick a column just pick UTC each time, case matters.
                Occasionally this causes Octave to stop recognizing files.

%%%%%%%%%%%%%%%%%%%%%%%
% You'll need to compile this as a mex file for octave
% qpParseSum.c
%%%%%%%%%%%%%%%%%%%%%%%

#include "mex.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

// Error Codes
#define NOERROR 0
#define CELLNOTSTRING 1
#define ELEMENTNOTSTRING 2
#define UNBALANCEDINPUTOUTPUT 3
#define MISSINGOUTPUT 4
#define UNDEFINEDCOLUMN 5
#define FILENOTFOUND 6
#define COLUMNNOTFOUND 7
#define BADSUMMARYFILE 8

//  Files to open
FILE *sumFile, *typeFile;
long lSize; // Storeing size of file

// Different stages of File parsing
char *typeBuffer, *sumBuffer, *noTrash, *line, *token, *errBuffer;
char *columnName, *fileLocation, *columnNameNoEndl;
char *char13;
char **argv, **lines;

size_t result;
int cell_dims[2];
int nlhs1, nrhs1;
int matlabSuccesful;
// Details for columns

mxArray *rhs[1], *lhs[1];int nlhs1, nrhs1;
mxArray *cellArr, *charArr;

long double dataCell; // for converting to numbers

double *pr;
int *neededColumns;
double *columnTypes;
long double *output;

int argc, len;
int k, ncell; // For Input
int numberOfRows, numberOfColumns; // Of Entire File
int i,j; // Iteration vars
int inComment, firstLine, found; // Control Vars (are we in a comment) (is this the first line?);
int index; // index for cell arrays

int justHead, errorStatus;

/*************************************************************************************
//  mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
//
// Opens a summary file and parses columns into double arrays for OCTAVE if it is a number and cell strings the column is a string
//
// ARGUMENTS:
// nlhs - The number of left hand side arguments that will be returned to the calling Octave code
// plhs[] - An array of pointers to the data being returned should have a size of nlhs
// nrhs - The number of right hand sides passed in for use by the calling Octave code
// prhs[] - An array of pointers to the data being passed in, having a size of nrhs. The data being pointed to is read only.
//
// A note on mxCalloc & mxMalloc: Matlab & Octave free these vars automatically when return to the prompt
// occurs. Still free them though, when you are done with them.
***********************************************************************************/

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  matlabSuccesful = 0;
 
  errorStatus = NOERROR;
  argc = 0;
  j = 0;
  justHead = 0;
 
  /*****************************************************
       *
       * Verify all data passed in is string data
       *
       *****************************************************/
 
  for(k=0; k<nrhs; k++)
  {
    if( mxIsCell( prhs[k] ) )
    {
      argc += ncell = mxGetNumberOfElements( prhs[k] );
      for( i=0; i<ncell; i++ ) {
        if( !mxIsChar( mxGetCell( prhs[k], i ) ) ) {
          errorStatus = CELLNOTSTRING;
          goto out;
        }
      }
    }
    else
    {
      argc++;
      if( !mxIsChar( prhs[k] ) ) {
        errorStatus = ELEMENTNOTSTRING;
        goto out;
      }
    }
  }  

  if(nlhs != argc - 1) {
    if(nlhs == 1 && argc == 1) {
      justHead = 1;  
    } else {
      errorStatus = UNBALANCEDINPUTOUTPUT;
      goto out;      
    }
  }
 
  if(nlhs == 0) {
    errorStatus = MISSINGOUTPUT;
    goto out;
  }
 
  argv = (char **) mxCalloc( argc, sizeof(char *) );  

  /***************************************************
       *
       *  Convert data stored in cells to strings
       *
       ***************************************************/
 
  for( k=0; k<nrhs; k++ )
  {
    if( mxIsCell( prhs[k] ) )
    {
        ncell = mxGetNumberOfElements( prhs[k] );
        for( i=0; i<ncell; i++ )
            argv[j++] = mxArrayToString( mxGetCell( prhs[k], i ));
    }
    else
    {
        argv[j++] = mxArrayToString( prhs[k] );
    }
  }
 
  /**************************************************************************************************
       *
       *  Octave has array types of cellstr and double. If a column is numeric want to store the data as numeric data.
       *  Call summaryColumnLookUpType to get the type of each column for later conversion.
       *  String is represented by 1, Numeric by 0.
       *
       **************************************************************************************************/

  columnTypes = (double*) mxMalloc (sizeof(double)*(argc-1)); // 0 = Number, 1 = String
 
  char13 = (char*)mxCalloc(2,sizeof(char));
  k = sprintf(char13, "%c", 13);
 
  for(k = 0; k < argc - 1; k++) {
    columnName = (char*)mxCalloc(strlen(argv[k+1])+10,sizeof(char));
   
    strcpy(columnName, argv[k+1]);  
   
    columnNameNoEndl = strtok(columnName,char13);    
    strcpy(argv[k+1], columnNameNoEndl);
   
    nrhs1 = 1;
    nlhs1 = 1;
    rhs[0] = mxCreateString(columnNameNoEndl);    
   
    /* Note: this call is represented the same way as mexFunction.*/
   
    mexSetTrapFlag(1);
    matlabSuccesful = mexCallMATLAB(nlhs1, lhs, nrhs1, rhs, "summaryColumnLookUpType");
    mexSetTrapFlag(0);
    if(matlabSuccesful) {
      errorStatus = UNDEFINEDCOLUMN;
      goto out;
    }    
   
   
    pr = mxGetPr(lhs[0]);
    columnTypes[k] = *pr;
    mxFree(pr);
    mxFree(columnName);
  }
  mxFree(char13);
 
  /*******************************************************************************
      *
      *   Read in and parse the summary file. Remove any element known that it won't be needed
      *   to return. (linefeed, comments...)
      *
      ******************************************************************************/

  sumFile = fopen(argv[0], "rb");
 
  if (sumFile==NULL) { errorStatus = FILENOTFOUND; goto out; }
 
  fseek(sumFile, -4, SEEK_END);
  lSize = ftell(sumFile);
  rewind(sumFile);

  // sumBuffer holds data directly from file
  sumBuffer = (char*) mxCalloc (lSize+1,sizeof(char));
  // noTrash will not have comments or extra linebreaks
  noTrash = (char*) mxCalloc (lSize+1,sizeof(char));
  result = fread (sumBuffer,1,lSize,sumFile); // read in the data
 
  fclose(sumFile);
 
  j = 0;
 
  inComment = 0; // Have we found a comment?
  firstLine = 0; // Is this the first line?
  numberOfRows = 0;
  numberOfColumns = 0;
  for(i = 0; i < lSize; i++) {
    if(inComment == 0) {
      if(sumBuffer[i] == '#') {
        inComment = 1;
       continue;
      }
      if(sumBuffer[i] == '\n') {
        numberOfRows++;
        if(firstLine == 1) {        
          firstLine = 2; // Can't be first line anymore
        }
      }
      if(sumBuffer[i] == 13) continue; // Don't add char(13) to noTrash
     
      if(firstLine == 0 && sumBuffer[i] == ',') {
        numberOfColumns++;
        firstLine = 1; // This is the first comma, so this is the first line of data
      }
      if(firstLine == 1 && sumBuffer[i] == ',') {
        numberOfColumns++;
      }
      noTrash[j] = sumBuffer[i]; // this byte wasn't trash
     
      j++; // Current position in noTrash updated
    } else {
     
      if(sumBuffer[i] == '\n') inComment = 0; //Comment must be over, found a new line.
    }
  }

  /******************************************************************************
      *   Split the file first into lines and then into cols, thereby storing each piece of data in a different cell of a cell matrix.
      *   This makes it simple to just grab the appropriate column of data and place it in nlhs[]. This block of code also locates
      *   the columns that were requested in the original data.
      *******************************************************************************/
 
  lines = (char**) mxCalloc(numberOfRows,sizeof(char*));
  lines[0] = (char *)strtok(noTrash,"\n");
  for(i = 1; i < numberOfRows; i++) {
   lines[i] = (char *)strtok(NULL,"\n");
  }

  cell_dims[0] = numberOfRows;
  cell_dims[1] = numberOfColumns;

  neededColumns = (int*) mxMalloc (sizeof(int)*(argc-1));
 
  for(k = 0; k < argc-1; k++) {
    neededColumns[k] = -1;
  }
 
  cellArr = mxCreateCellArray(2,cell_dims);

  for(i = 0; i < numberOfRows; i++) {
    line = lines[i];
    token = (char*)strtok(line," ,");
    for(j = 0; j < numberOfColumns; j++) {
      if(token == NULL) {
        errorStatus = BADSUMMARYFILE;
        goto out;
      }
      charArr = mxCreateString(token);
      // Cell arrays are indexed based column major order
      index = calcIndex(numberOfRows,i,j);
      mxSetCell(cellArr,index,charArr);
     
      if(i == 0) {
        //Looking at first row. Find columns requested by user
        for(k = 0; k < argc - 1; k++) {
          if(strcmp(argv[k+1],token) == 0) {
            neededColumns[k] = j;
          }
        }
      }
      if(j != numberOfColumns) { // If still looking, keep tokening
        token = (char *)strtok(NULL," ,");
      }
    }
  }
 
  for(k = 0; k < argc-1; k++) {
    if(neededColumns[k] == -1) {
      errorStatus = COLUMNNOTFOUND;
      goto out;
    }
  }
 
  /***************************************************************************************
       * Place Data into PLHS[], the return array.
       *  - Convert each column to the type discovered earlier.
       *  - Place each column in PLHS
       *
       *  Numbers are stored as Double arrays. Strings are stored Cellstr arrays.
       *  For an unknown reason, must convert back to string to store in a new cell array, otherwise data is corrupted.
       *  Use long doubles to grab all of the data, in C you lose information with just %f,e,g
       ***************************************************************************************/
 
  if(justHead) {
    cell_dims[0] = 1;
    cell_dims[1] = numberOfColumns;
   
    plhs[0] = mxCreateCellArray(2,cell_dims);
   
    for(k = 0; k < numberOfColumns; k++) {      
      charArr = mxGetCell(cellArr, calcIndex(numberOfRows,0,k));
      token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));      
      mxGetString(charArr, token, mxGetNumberOfElements(charArr)+1);
      charArr = mxCreateString(token);
      mxSetCell(plhs[0],calcIndex(1,0,k),charArr);      
    }  
  } else {
    cell_dims[0] = numberOfRows-1;
    cell_dims[1] = 1;
    for(k = 0; k < argc-1; k++) {
      if(!(columnTypes[k] > 0)) { // 0 means numeric
        plhs[k] = mxCreateDoubleMatrix(numberOfRows-1,1,mxREAL);
        for(i = 1; i < numberOfRows; i++) {
          charArr = mxGetCell(cellArr, calcIndex(numberOfRows,i,neededColumns[k]));
          token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));
          mxGetString(charArr, token,mxGetNumberOfElements(charArr)+1);
          sscanf(token,"%Lf",&dataCell);
          output = (long double*) mxGetPr(plhs[k]);
          mxFree(token);
          output[i-1] = dataCell;
        }
      } else { // 1 meant string
        plhs[k] = mxCreateCellArray(2,cell_dims);
        for(i = 1; i < numberOfRows; i++) {
          charArr = mxGetCell(cellArr, calcIndex(numberOfRows,i,neededColumns[k]));
          token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));
          mxGetString(charArr, token,mxGetNumberOfElements(charArr)+1);
          charArr = mxCreateString(token);
          mxSetCell(plhs[k],i-1,charArr);
          mxFree(token);
        }
      }
    }
  }

  // CLEAN  UP

out:
  switch(errorStatus) {
    case COLUMNNOTFOUND:
      len = strlen(argv[0]) + 130;
      errBuffer =(char*) mxCalloc(len, sizeof(char));            
      sprintf(errBuffer, "qpParseSum was unable to find requested column, '%s', in '%s'  Verify all requested columns exist in the summary file.",argv[k+1],argv[0]);      
    case BADSUMMARYFILE:
      mxFree(lines);
      mxFree(sumBuffer);
      mxFree(noTrash);
      mxFree(neededColumns);      
    case FILENOTFOUND:
      if(errorStatus == FILENOTFOUND) {
        len = strlen(argv[0])*2 + 200;
        errBuffer =(char*) mxCalloc(len, sizeof(char));            
        sprintf(errBuffer, "qpParseSum expects a file that exists, but %s does not exist in the path, and can not be opened. Check that %s is spelled correctly and that it exists in your current directory.", argv[0],argv[0]);
      }
    case UNDEFINEDCOLUMN:
      mxFree(columnTypes);
      if( argc ) {
        for( j=argc-1; j>=0; j-- )
          mxFree( argv[j] );
        mxFree( argv );
      }      
    case MISSINGOUTPUT:
    case UNBALANCEDINPUTOUTPUT:
    case ELEMENTNOTSTRING:
    case CELLNOTSTRING:
      break;
    case NOERROR:
    default:
      mxFree(lines);
      mxFree(sumBuffer);
      mxFree(noTrash);
      mxFree(neededColumns);
      mxFree(columnTypes);  
  }  
 

  switch(errorStatus) {
    case NOERROR:
      return;    
    case CELLNOTSTRING:      
      mexErrMsgIdAndTxt("qpMEX:FunctionCall:WrongTypeOfInput", "qpParseSum expects all input to be string data but recieved a cell input element that was not a string. Check input values for numeric data.");
      break;    
    case ELEMENTNOTSTRING:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:WrongTypeOfInput", "qpParseSum expects all input to be string data but recieved an input element that was not a string. Check input values for numeric data.  ");
      break;    
    case UNBALANCEDINPUTOUTPUT:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:InvalidCall","qpParseSum expects the number of output variables(%d) to be equivalent to the number of columns requested(%d). Check the number of arguments being passed in.  ",nlhs,(argc-1));
      break;    
    case MISSINGOUTPUT:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:InvalidCall","qpParseSum expects at least one output variable, but recieved none.");
      break;    
    case UNDEFINEDCOLUMN:      
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:DataNotFound","qpParseSum expected a defined column, but recieved '%s' which has not been defined in summaryColumnLookUpType.m",columnName);
      break;
    case FILENOTFOUND:
      mexErrMsgIdAndTxt("qpMEX:FileInteraction:FileNotFound",errBuffer);              
      break;    
    case COLUMNNOTFOUND:
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:DataNotFound",errBuffer);
      break;
    case BADSUMMARYFILE:  
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:EncounteredBadVersion","qpParseSum expected data to exist for each column, but one row was incomplete.");
      break;
    default:
      break;
  }
  return;
}

/*****************************************************************************
// calcIndex - Calculates the desired index for an array stored in column major order
//
//  ARGUMENTS:
//    rows - total number of rows in the table
//    row - row containing element e
//    col - column containing element e
//
//  RETURNS
//    An integer representing the index of a column major order entry of an array in memory
 *****************************************************************************/

int calcIndex(int rows, int row, int col) {
  return rows * col + row;
}

%%%%%%%%%%%%%%%%%%%%% testQpLoadAnalyzeData.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function success = testQpLoadAnalyzeData(verbose,cleanUp)
  more('off');
  if(~exist('verbose')) verbose = false; end;
  if(~exist('cleanUp')) cleanUp = false; end;

  for i = 1:7
      files{i} = sprintf('00_GEN_99_00000%d.sum',i);
  end
  setup(files);
 
  success = false;
  try
    if(verbose)
      for i = 5:7
        t = sprintf('qpLoadAnalyzeData: Bad Calls %d',i);
        fail = true;
        try
          [a b c] = qpLoadAnalyzeData(files{i});
        catch
          fail = false;
        end    
        if(fail)
          qpFailTest(t);
        end
        qpEndTest(t);
      end
    end
   
    try
      for i = 1:4
        t = sprintf('qpLoadAnalyzeData: Perfect Calls %d',i);
        [a b c] = qpLoadAnalyzeData(files{i});
        qpEndTest(t);
      end
    catch
      qpFailTest(t);
    end  
    teardown(files,cleanUp);
    success = true;
  catch    
    teardown(files,cleanUp);
    qpHandleError(mfilename);
    rethrow(lasterror);
  end
end

function setup(files)
  a = (1:100)';
  try
    writeSummaryFile(files{1},{'rangeReference' 'rangeAvg' 'rangeStd'},a,a,a);
    writeSummaryFile(files{2},{'rangeReference' 'phaseAvg' 'phaseStd'},a,a,a);
    writeSummaryFile(files{3},{'rangeReference' 'phaseHFAvg' 'phaseHFStd'},a,a,a);
    writeSummaryFile(files{4},{'rangeReference' 'phaseLFAvg' 'phaseLFStd'},a,a,a);
   
    writeSummaryFile(files{5},{'undefined' 'rangeAvg' 'rangeStd'},a,a,a);
    writeSummaryFile(files{6},{'rangeReference' 'rangeAvg' 'undefined'},a,a,a);
    writeSummaryFile(files{7},{'rangeReference' 'undefined' 'rangeStd'},a,a,a);
  catch
    qpHandleError([mfilename 'setup']);
    teardown(files,cleanUp);
    rethrow(lasterror);
  end
end

function teardown(files,cleanUp)
  if(cleanUp)
    for i = 1:length(files)
      delete(files{i});
    end
  end
end

%%%%%%%%%%%%%%%%%%%%%%%% qpLoadAnalyzeData.m %%%%%%%%%%%%%%%%%%%%%%%%%


function [rangeReference mean standard] = qpLoadAnalyzeData(sumFile)
  try
    header = qpParseSum(char(sumFile));

    if(sum(strcmp(header, 'rangeAvg')) == 1)
      mnStr ='rangeAvg';
      stStr ='rangeStd';
    elseif(sum(strcmp(header, 'phaseAvg')) == 1)
      mnStr = 'phaseAvg';
      stStr = 'phaseStd';
    elseif(sum(strcmp(header, 'phaseLFAvg')) == 1)
      mnStr = 'phaseLFAvg';
      stStr = 'phaseLFStd';
    elseif(sum(strcmp(header, 'phaseHFAvg')) == 1)
      mnStr = 'phaseHFAvg';
      stStr = 'phaseHFStd';
    else
      char(header)
      disp('Unable to find range/phase Mean and Standard Columns\n');
      mnStr = input('Please enter the name of the Mean column: ','s');
      stStr = input('Please enter the name of the Standard column: ','s')

      disp('\n');
      disp('Checking for existance... ');
      if(sum(strcmp(header, mnStr)) == 1)
        disp(sprintf('%s found ... ', mnStr));
      else
        suggestion = ['Check to see if ' sumFile ' is the right file.'];
        error('qp:SummaryFileInteraction:DataNotFound',sprintf('qpLoadAnalyzeData expected %s, but could not find it.', mnStr));
      end

      if(sum(strcmp(header, stStr)) == 1)
        disp(sprintf('%s found ... ', stStr));
      else
        error('qp:SummaryFileInteraction:DataNotFound',sprintf('qpLoadAnalyzeData expected %s, but could not find it.', stStr));
      end
    end

    if(sum(strcmp(header, 'rangeReference')) == 1)
      refStr = 'rangeReference';
    else
      char(header)
      disp('Unable to find reference range data');
      refStr = input('Please enter the name of the Reference column: ','s');

      if(sum(strcmp(header, refStr)) == 1)
        disp(sprintf('%s found ... ', refStr));
      else
        error('qp:SummaryFileInteraction:DataNotFound',sprintf('qpLoadAnalyzeData expected %s, but could not find it.', refStr));
      end
    end

    cols{1} = refStr;
    cols{2} = mnStr;
    cols{3} = stStr;

    [rangeReference mean standard] = qpParseSum(sumFile, refStr, mnStr, stStr);

    return
  catch
    if(exist('suggestion'))
      qpHandleError(mfilename,suggestion);
    else
      qpHandleError(mfilename);
    end

    rethrow(lasterror);
  end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qpEndTest.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% qpEndTest
%   Call to end a test case. Prints to the terminal that the test is
%   over and that it passed. Prints the time it took to run the test.
%
% ARGUMENTS
%   NONE
%
% RETURNS
%   NONE
%
% DEPENDENCIES
%   Call qpSetCurrentTest before this function is called.
%
%   Original Author: Brian Kirklin
%   $Id:  $
%   (c) Copyright Quantapoint Inc. All rights reserved.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function qpEndTest(name)
  fprintf(['> ' name]);
  for i = 1:66 - length(name)
    fprintf('.');
  end  
  disp(['<<<[ P ]>>>']);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qpFailTest.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function qpFailTest(name)

  lasterror
 
  fprintf(['> ' name]);
  for i = 1:66 - length(name)
    fprintf('.');
  end  
  disp(['<  ! F !  >']);
  error('qp:TestingSoftware:FailedTestCase',lasterror.message);  
end

%%%%%%%%%%%%%%%%%%%%%%%% writeSummaryFile.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [succeed] = writeSummaryFile(filename, header, varargin)

  try
    succeed = false;

    if(nargin < 3)
      error('qp:FunctionCall:InvalidCall',sprintf('writeSummaryFile expects at least 3 inputs and recieved %d', nargin));
    end

    if(nargout > 1)
      error('qp:FunctionCall:InvalidCall',sprintf('writeSummaryFile expects no more than one output variable and recieved %d', nargout));
    end

    if(~ischar(filename))
      suggestion = 'Check that first argument is a string. [ischar()]';
      error('qp:FunctionCall:WrongTypeOfInput','writeSummaryFile expects filename to be a string, but it was not a string');
    end

    % Check number of input arguments
    columns = max(size(header(1, :)));
    nvarargin = nargin-2;
    if (columns ~= nvarargin)
      error('qp:FunctionCall:InvalidCall',sprintf('writeSummaryFile expects the number of column names columns and number of columns of data to be the same, but recieved %d column name(s) and %d column(s) of data', columns, nvarargin));
    end


    % check vectors
    for it = 1:nvarargin
      sz = size(varargin{it});
      if(~isvector(varargin{it}) || sz(2) ~= 1)
        suggestion = 'Check that each array of data is a vector. [isvector()]';
        error('qp:FunctionCall:WrongTypeOfInput','writeSummaryFile expects each column of data to be a verticle vector, but at least one was not.')
      end
    end

    % combine data into 1 array
    data = varargin{1};
    data(:, 1) = 0;
    for col = 1:columns
      data(:, col+1) = varargin{col};
    end

    % Write file
    [fid msg] = fopen(filename, 'wb');

    if(fid == -1)
      if(isequal(msg,'Permision denied'))
        suggestion = ['Check that ' filename ' is not read only'];
        error('qp:FileInteraction:CouldNotWriteToFile',sprintf('writeSummaryFile expected %s to be writable, but it was protected.',filename));
      elseif(isequal(msg,'Invalid argument'))
        suggestion = ['Check that ' filename ' contains valid characters, is not protected, and is a legal name for a file on your operating sytem.'];
        error('qp:FileInteraction:UnableToOpen',sprintf('writeSummaryFile could not open %s because an argument was incorrect',filename));
      else
        suggestion = ['Check that ' filename ' contains valid characters, is not protected, and is a legal name for a file on your operating sytem.'];
        error('qp:FileInteraction:UnableToOpen',sprintf('writeSummaryFile expected to be able to open %s but could not for an unknown reason.',filename))
      end
    end

    % Write UTC and then rest of header
    fprintf(fid, '%s, ', 'UTC');
    for currentColumn = 1:columns
      if(currentColumn~=columns)
        fprintf(fid, '%s, ', char(header(1, currentColumn)));
      else
        fprintf(fid, '%s', char(header(1, currentColumn)));
      end
    end
    fprintf(fid, '%s\r\n', '');

    % Discover what format to write data
    format = '';
    for currentColumn = 1:columns+1
      if(isa(data(:, currentColumn), 'int32'))
        type = '%d';
      elseif(isa(data(:, currentColumn), 'float'))
        type = '%0.7e';
      elseif(isa(data(:, currentColumn), 'double'))
        type = '%0.7e';
      elseif(isa(data(:, curruntColumn), 'numeric'))
        type = '%0.7e';
      else
        type = '%s';
      end

      if(currentColumn~=columns+1)
        format =[format type ', '];
      else
        format =[format type '\r\n'];
      end
    end

    % Write the data
    fprintf(fid, format, data');

    % Close the file
    fclose(fid);

    % Does the file exist?
    if(exist(filename) ~= 2)
      return;
    end

    qpCrc32(filename,'w');
    if(~qpCrc32(filename,'c'))
      return;
    end

    succeed = true;
  catch

    if(exist('suggestion'))
      qpHandleError(mfilename, suggestion);
    else
      qpHandleError(mfilename);
    end

    if(exist('fid'))
      if(isequal(ferror(fid),''))
        fclose(fid);
      end
    end

    rethrow(lasterror);
  end
  return
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qpStandardErrorSuggestions.m %%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%55%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% qpStandardErrorSuggestions(id)
%   Gets a standard suggestion on how to fix an error, for a standard
%   Quantapoint error identifier
%  
%   ARGUMENTS:
%     id - a standard Quantapoint identifier of format 'qp:task:error'.
%
%   RETURNS:
%     sug - a standard suggestion for a standard error identifier.
%
%   ADDING NEW SUGGESTIONS:
%     Add the related identifier to the identifier list 'identifiers'
%     Add the related suggestion to the suggestion list 'suggestions'
%
%   MATLAB/Octave portability unconfirmed
%
% Original Author: Brian Kirklin
% $Id: $
% (c) Copyright Quantapoint Inc. All rights reserved.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function sug = qpStandardErrorSuggestions(id)
 
  n = nextNum;  
  identifiers{n} = 'qp:FileInteraction:UnableToOpen';
  suggestions{n} = 'Verify that the file is not protected, exists in the specified path, and contains no illigal characters in its name.';

  n = nextNum;  
  identifiers{n} = 'qp:FileInteraction:FileNotFound';
  suggestions{n} = 'Check your working directory for the file.';

  n = nextNum;  
  identifiers{n} = 'qp:FileInteractionCouldNotWriteToFile';
  suggestions{n} = 'Check file for protection, check working directory for file.';

  n = nextNum;  
  identifiers{n} = 'qp:FileInteraction:CouldNotReadFromFile';
  suggestions{n} = 'Check file for protection, check working directory for file.';  
 
  n = nextNum;  
  identifiers{n} = 'qp:FileInteraction:CouldNotCloseFile';
  suggestions{n} = 'Check for existance of file in working directory, free space on current device, etc.';  
 
  n = nextNum;  
  identifiers{n} = 'qp:SummaryFileInteraction:RequestedUndefinedColumn';
  suggestions{n} = 'Check that the right kind of file was passed in as the desired variable was not present.';
 
  n = nextNum;  
  identifiers{n} = 'qp:SummaryFileInteraction:RequestedAbsentColumn';
  suggestions{n} = 'Check that the right kind of file was passed in as the desired variable was not present.';
 
  n = nextNum;  
  identifiers{n} = 'qp:SummaryFileInteraction:EncounteredBlankLine';
  suggestions{n} = 'Check last opened summary file for a blank line. Blank lines are not allowed in summary files.';
 
  n = nextNum;  
  identifiers{n} = 'qp:SummaryFileInteraction:EncounteredBadVersion';
  suggestions{n} = 'Check the format of the last opened summary file to see if its the latest version of summary files.';  
 
  n = nextNum;  
  identifiers{n} = 'qp:SummaryFileInteraction:BadCRC';
  suggestions{n} = 'The data for the last opened summary file was corrupted and is unusable per quantapoint standards. Regenerate the data.';
 
  n = nextNum;  
  identifiers{n} = 'qp:LanguageSpecificTask:NeededOctave';
  suggestions{n} = 'Run this software under Octave.';  
 
  n = nextNum;  
  identifiers{n} = 'qp:LanguageSpecificTask:NeededMatlab';
  suggestions{n} = 'Run this software under Matlab.';
 
  n = nextNum;
  identifiers{n} = 'qp:LanguageSpecificTask:NeededGNUPlog';
  suggestions{n} = 'Turn off the jhandles package. Then, run this software again.';
 
  n = nextNum;
  identifiers{n} = 'qp:LanguageSpecificTask:NeededJhandles';
  suggestions{n} = 'Turn on the jhandles package. Then, run this software again.';
 
  n = nextNum;
  identifiers{n} = 'qp:TestingSoftware:TestCaseFailed';
  suggestions{n} = 'Check the code base for programmer errors.';
 
  clear('nextNum');
 
  idx = strmatch(id, identifiers);
  if(sum(idx) > 0)
    sug = suggestions{idx};
  else
    le = lasterror;
    if(sum(strfind(le.identifier,'qpMEX')))
      nm = strfind(le.message,':');
      sug = ['Review ''help ' le.message((nm(1)+2):(nm(2)-1)) ''''];
    else  
      sug = ['Review ''help ' le.stack.name ''''];
    end
  end
 
  return
end

function n = nextNum;
  persistent NUMCOUNTER;
  if(isempty(NUMCOUNTER))
    NUMCOUNTER = 1;
  else
    NUMCOUNTER = NUMCOUNTER + 1;
  end;
  n = NUMCOUNTER;
  return
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qpCrc32.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% result = qpCrc32(file, action)
%
% Takes in a file name, then computes the CRC of the chosen file, using
% the polynomial 0x04c11db7. If the result of the CRC math is 0, then
% the file is assumed to be unaltered since the creation of the original
% CRC.
%
% ARGUMENTS:
%   file    - the name of the file on which to compute the CRC, place in
%            single quotes
%   action  - 'c' --> check crc
%             'w' --> write crc
%
% RETURNS:
%   result - Returns 1 for an ok file.
%
% MATLAB/Octave portability confirmed.
%
% Original Author:
% $Id: qpCrc32.m 8998 2008-06-06 20:28:13Z bkirklin $
% (c) Copyright Quantapoint Inc. All rights reserved.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function result = qpCrc32(file, action)
  try
    if(nargin < 2)
      error('qp:FunctionCall:InvalidCall','qpCrc32 expects at least 2 input values and recieved less');
    elseif(nargin > 2)
      error('qp:FunctionCall:InvalidCall','qpCrc32 expects no more than 2 input values and recieved more');
    end

    if(~(strcmp(action,'c') || strcmp(action,'w')))
      error('qp:FunctionCall:WrongTypeOfInput','qpCrc32 expects an action equivalent to ''c'' or ''w'', but recieved some other value.');
    end

    if(exist(file,'file') ~= 2)
      error('qp:FileInteraction:FileNotFound',['qpCrc32 expected to find ' file ' in the working directory, but could not.']);
    end    

    % Polynomial for CRC generation:
    KEY = uint32(79764919); % Integer equivalent of 0x04c11db7
    % Generate Look Up Table
    % Start crc at the decimial equivalent to 0xFFFFFFFF

    key = KEY;
    CRCTABLE = bitshift(uint32(0:255), 24);
    for m = 0:7
      b2 = bitand(CRCTABLE, bitshift(1, 31));
      fn0 = find(b2>0);
      f0 = find(b2==0);
      CRCTABLE(fn0) = bitxor(uint32(bitshift(CRCTABLE(fn0), 1)), key);
      CRCTABLE(f0) = uint32(bitshift(CRCTABLE(f0), 1));
    end

    CRC = uint32(4294967295);

    % Read in file, byte by byte and generate CRC Byte by Byte


    fFile = fopen(file,'rb');
    if(fFile == -1)
      if(isequal(msg,'Permision denied'))
        suggestion = ['Check whether ' file ' is read/write protected'];
        error('qp:FileInteraction:CouldNotReadFromFile',['qpCrc32 expects to be able to read from ' file ', but it was protected.']);
      else
        suggestion = ['Check to see if ' file ' exists.'];
        error('qp:FileInteraction:UnableToOpen',['qpCrc32 expected to be able to open ' file ' but could not.'])
      end
    end

    bytes = fread(fFile);
    fclose(fFile);

    len = length(bytes);
    bytes = uint8(bytes);
    CRCTABLE = uint32(CRCTABLE);

    for i = 1:len
      CRC = bitxor(bitshift(CRC, -8), CRCTABLE(uint32(bitxor(uint8(bitand(CRC, 255)), bytes(i)))+1));
    end

    if(strcmp(action,'c'))
      result = (~CRC);
    elseif(strcmp(action,'w'))
      fOutId = fopen(file, 'ab');

    if(fOutId == -1)
      if(isequal(msg,'Permision denied'))
        suggestion = ['Check whether ' file ' is read/write protected'];
        error('qp:FileInteraction:CouldNotReadFromFile',['qpOldSum2v14 expects to be able to read from ' file ', but it was protected.']);
      else
        suggestion = ['Check to see if ' file ' exists.'];
        error('qp:FileInteraction:UnableToOpen',['qpOldSum2v14 expected to be able to open ' file ' but could not.'])
      end
    end

      fwrite(fOutId, CRC, 'uint32');
      fclose(fOutId);
    end
    return;
  catch
    if(exist('suggestion'))
      qpHandleError(mfilename, suggestion);
    else
      qpHandleError(mfilename);
    end

    rethrow(lasterror);
  end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% qpHandleError.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% qpHandleError(functionIdentifier)
%   called whenever an error is caught, this function is responsible for
% printing details to the terminal and controlling what information is printed
% based on what function called it.
%
% ARGUMENTS
%   functionIdentifier - An identifier for the function calling qpHandleError.
%                        If the function calling qpHandleError is a subfunction,
%                        or one of may functions inside of a single file, then
%                        functionIdentifier is equivalent to:
%                           [mfilename ':functionName']
%                        If the function calling qpHandleError is the first
%                        function in its file, then mfilename will suffice.
%
%   suggestions -        This field is optional and is used to define custom
%                        suggestions.
%
%                        A structure which contains all of the error
%                        identifiers and suggestions the calling script could
%                        have thrown. Suggestions should have the following
%                        fields:
%
%                         > ids - Stores all the identifiers
%                         > sug - Stores all of the suggestions
%
%                       ids and sug should be indexed so that matching pairs
%                       have the same index.
%
%   MATLAB/Octave portability unconfirmed.
%
%   Original Author: Brian Kirklin
%   $Id: $
%   (c) Copyright Quantapoint Inc. All rights reserved.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function qpHandleError(functionIdentifier, suggestion)
  if(nargin <1)
    return
  end
  if(nargin > 2)
    return
  end  
 
  global TESTING_IS_ACTIVE;
  if(isempty(TESTING_IS_ACTIVE))
    TESTING_IS_ACTIVE = false;
    errFileId = 1;
  elseif(TESTING_IS_ACTIVE)
    errFileId = fopen('ErrorLog.txt','a');
    if(errFileId == -1)
      error('omg wtf?');      
    end
  else
    errFileId = 1;
  end
   
  le = lasterror;
  mex = false;
 
  if(~isempty(le.identifier)) % Octave errors do not recieve identifiers      
    if(isequal(le.stack.name,functionIdentifier))    
      if(sum(strfind(le.identifier,'qpMEX')))  
        mex = true;
        idx = strfind(le.message,':');        
        fprintf(errFileId,['>>> An error occured in ' le.message((idx(1)+2):(idx(2)-1)) sprintf('\n')]);
        fprintf(errFileId,['    (' le.identifier ')' sprintf('\n')]);
        edisp(['Error occured because ' le.message((idx(2)+1):(length(le.message)-1)) sprintf('\n')],errFileId,'      ');
      else
        fprintf(errFileId, ['>>> An error occured in ' functionIdentifier sprintf('\n')]);
        fprintf(errFileId, ['    (' le.identifier ')' sprintf('\n')]);
        edisp(['Error occured because ' le.message(8:(length(le.message)-1))],errFileId,'      ');
      end

      expFound = false;
      if(nargin == 2)
        edisp('Suggestion: ',errFileId,'    ');
        edisp(suggestion,errFileId,'      ');
        expFound = true;
      end

      if(~expFound)
        edisp('Suggestion: ',errFileId,'    ');
        edisp(qpStandardErrorSuggestions(le.identifier),errFileId,'      ');
      end

      edisp([le.identifier ' caused failure in:'],errFileId,'    ');
      if(mex)
        fprintf(errFileId, ['      + ' le.message((idx(1)+2):(idx(2)-1)) sprintf('\n')]);
      end
      fprintf(errFileId, ['      + ' functionIdentifier sprintf('\n')]);
    else
      fprintf(errFileId, ['      + ' functionIdentifier sprintf('\n')]);
    end
  end
  if(TESTING_IS_ACTIVE)
    fclose(errFileId);
  end
end

function edisp(txt,errFileId,prepend)
  a = qpSplit(txt, ' ');
  for j = 1:length(a)
    b(j) = length(a{j});
  end
  msg = [prepend a{1}];
  for j = 2:length(a)
    if(length(msg) + b(j) <= 70)
      msg = [msg ' ' a{j}];
    else
      fprintf(errFileId, [msg sprintf('\n')]);
      msg = [prepend a{j}];
    end
  end
  fprintf(errFileId, [msg sprintf('\n')]);
end

Configuration (please do not edit this section):
-----------------------------------------------

uname output:     $UN
configure opts:   $config_opts
Fortran compiler: $F77
FFLAGS:           $FFLAGS
F2C:              $F2C
F2CFLAGS:         $F2CFLAGS
FLIBS:            $FLIBS
CPPFLAGS:         $CPPFLAGS
INCFLAGS:         $INCFLAGS
C compiler:       $CC_AND_VERSION
CFLAGS:           $CFLAGS
CPICFLAG:         $CPICFLAG
C++ compiler:     $CXX_AND_VERSION
CXXFLAGS:         $CXXFLAGS
CXXPICFLAG:       $CXXPICFLAG
LD_CXX:           $LD_CXX
LDFLAGS:          $LDFLAGS
LIBFLAGS:         $LIBFLAGS
RLD_FLAG:         $RLD_FLAG
BLAS_LIBS:        $BLAS_LIBS
FFTW_LIBS:        $FFTW_LIBS
LIBS:             $LIBS
LEXLIB:           $LEXLIB
LIBGLOB:          $LIBGLOB
SED:              $SED
DEFS:

EOF

if $HAVE_FMT; then
  echo $DEFS | fmt | $SED 's/^/  /' >> $TEMP
else
  echo $DEFS >> $TEMP
fi

if test $# -gt 0; then
  if test -f "$1"; then
    cat >> $TEMP << EOF

User-preferences (please do not edit this section):
--------------------------------------------------

EOF
    cat $1 >> $TEMP
  fi
fi

chmod u+w $TEMP
cp $TEMP $TEMP.x

status=0

editing=true

while $editing; do
  if $EDITOR $TEMP; then
    while $editing; do
      echo $echo_n "(a)bort, (e)dit, (l)ist, (s)end? $echo_c"
      read ans
      case "$ans" in
        a* | A*)
          status=1
          editing=false
        ;;
        e* | E*)
          break;
        ;;
        l* | L*)
          $PAGER $TEMP
        ;;
        s* | S*)
          editing=false
        ;;
      esac
    done
  else
    echo "problems with edit -- no bug report submitted"
    status=1
    editing=false
  fi
done

if test $status -eq 0; then
  if cmp -s $TEMP $TEMP.x; then
    echo "file not changed -- no bug report submitted"
    status=1
  elif test `wc $TEMP | awk '{print $1}'` -eq 0; then
    echo "empty bug report file -- not submitted"
    status=1
  else

# Try to extract the recipient address, in case the To: line in the
# message template has been changed.  Also get cc: lines.

    TO_ADDR=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^[Tt][Oo]://p'`
    CC_ADDR=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^[Cc][Cc]://p'`

    if test -z "$TO_ADDR"; then
      echo "no valid \`To:' field found in header -- using $BUGADDR instead"
    else
      BUGADDR="$TO_ADDR"      
    fi

    BUGADDR="$BUGADDR $CC_ADDR"

    TMP_SUB=`$SED -e '/^--------[ \t]*$/q' $TEMP | $SED -n -e 's/^Subject://p'`

    if test -n "$TMP_SUB"; then
      SUBJECT="$TMP_SUB"
    fi

# Delete the `--------' separator in the message.

# Don't pretty-print this.  Odd whitespace kills Ultrix AWK!

    awk 'BEGIN{in_header=1;} /^--------[ \t]*$/ {
      if (in_header) { in_header=0; print ""; next; }
    } { print $0; }' $TEMP > $TEMP.x

# Now try to mail it.

    # indicate that we have not yet sent email successfully
    status=11

    if test $status -ne 0; then
      ( mailx -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
      status=$?
      if test $status -ne 0; then
        ( Mail -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
        status=$?
        if test $status -ne 0; then
          ( /usr/ucb/mail -s "$SUBJECT" $BUGADDR < $TEMP.x ) > /dev/null 2>&1
          status=$?
          # make /bin/mail our last resort -- it ignores the subject line
          if test $status -ne 0; then
            ( /bin/mail $BUGADDR < $TEMP.x ) > /dev/null 2>&1
            status=$?
            if test $status -ne 0; then
              echo "unable to send mail..."
            fi
          fi
        fi
      fi
    fi
  fi
fi

if test $status -ne 0; then
  dead_bug_file=$HOME/dead-octave-bug
  looking_for_file=true;
  n=1
  while $looking_for_file; do
    if test -f "$dead_bug_file-$n"; then
      n=`expr $n + 1`
    else
      looking_for_file=false
      dead_bug_file=$dead_bug_file-$n
    fi
  done
  echo "saving message in $dead_bug_file";
  cat $TEMP >> $dead_bug_file;
  exit 1
else
  echo "bug report sent to: $TO_ADDR"
  echo "             cc to: $CC_ADDR"
fi

exit $status

Re: pgnuplot stops function in Octave 3.0.1

by gOS :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

No clue why, but this fixed the problem: set(0, 'defaulttextfontname', '*')
All the same, I'm not sure I like the fact that I had to put it in to my .octaverc to have octave function and not have it documented anywhere.


gOS wrote:
I can't isolate the error. I've tried several times, but the problem seems to randomly fix itself and then crop back up every 2 weeks or so. I'm looking for anyone with similar issues.

I'm running the windows version of Octave, the one that isn't cygwin. On a pentium 4 windows xp machine.

GNU plot crashes with messages like:

(gnuplot.exe:4580): Pango-WARNING **: couldn't load font "Helvetica Not-Rotated 200", falling back to "Sans Not-Rotated 200", expect ugly output.


Unfortunately, GNU plot stops working shortly after and I get the windows error report dialogue.

I usually recieve these errors when I call input inside of an Octave script where a user would traditionally input some value.

I've attempted to generate a bug report. Automatic sending doesn't work so I copied it and here it is:

#! /bin/sh -
#
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2004,
#               2005, 2006 John W. Eaton
#
# This file is part of Octave.
#
# Octave is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# Octave is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with Octave; see the file COPYING.  If not, see
# <http://www.gnu.org/licenses/>.

# octave-bug - create a bug report and mail it to the bug-octave
# mailing list.
#
# Patterned after the bashbug script from bash 1.14.

# Configuration:  these variables are filled in when running make to
# compile Octave.

config_opts="'--build=i686-pc-msdosmsvc' '--prefix=/c/Software/VCLibs/local/octave-3.0.1' '--with-zlib=zlib' '--with-curl=libcurl' 'build_alias=i686-pc-msdosmsvc' 'CC=cc-msvc' 'CFLAGS=-O2' 'CXX=cc-msvc' 'CXXFLAGS=-O2' 'F77=fc-msvc' 'FFLAGS=-O2'"
VERSION="3.0.1"
SED="/usr/bin/sed"
MACHINE="i686-pc-msdosmsvc"
F77="fc-msvc"
FFLAGS="-O2"
FPICFLAG=""
FLIBS="-lhdf5 -lzlib -lf2c -lkernel32"
F2C="@F2C@"
F2CFLAGS="@F2CFLAGS@"
CPPFLAGS="-I.  -Ic:/Software/VCLibs/include"
INCFLAGS="-I. -I. -I./liboctave -I./src -I./libcruft/misc"
CC="cc-msvc"
CC_VERSION=""
CFLAGS="-O2 -MD"
CPICFLAG=""
CXX="cc-msvc"
CXX_VERSION=""
CXXFLAGS="-O2 -EHs -MD"
CXXPICFLAG=""
LD_CXX="cc-msvc"
LDFLAGS=""
LIBFLAGS="-L."
RLD_FLAG=""
LIBS="-lreadline  -lncurses -lhdf5 -lzlib  -lws2_32 -lkernel32"
BLAS_LIBS="-llapack -lblas"
FFTW_LIBS="-lfftw3"
LEXLIB=""
LIBGLOB="-lglob"
DEFS="-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DOCTAVE_SOURCE=1 -D_GNU_SOURCE=1 -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_UNISTD_H=1 -DSEPCHAR=';' -DSEPCHAR_STR=\";\" -D__NO_MATH_INLINES=1 -DCXX_NEW_FRIEND_TEMPLATE_DECL=1 -DCXX_ISO_COMPLIANT_LIBRARY=1 -DCXX_ABI=unknown -DHAVE_QHULL=1 -DHAVE_PCRE=1 -DHAVE_ZLIB_H=1 -DHAVE_ZLIB=1 -DHAVE_HDF5_H=1 -DHAVE_HDF5=1 -DHAVE_H5GGET_NUM_OBJS=1 -D_HDF5USEDLL_=1 -DHAVE_FFTW3=1 -DHAVE_GLPK_H=1 -DHAVE_GLPK=1 -DHAVE_CURL_CURL_H=1 -DHAVE_CURL=1 -DHAVE_IEEE754_DATA_FORMAT=1 -DF77_FUNC(name,NAME)=name ## _ -DF77_FUNC_(name,NAME)=name ## __ -DHAVE_BLAS=1 -DHAVE_SUITESPARSE_UMFPACK_H=1 -DHAVE_UMFPACK=1 -DUMFPACK_SEPARATE_SPLIT=1 -DHAVE_SUITESPARSE_COLAMD_H=1 -DHAVE_COLAMD=1 -DHAVE_SUITESPARSE_CCOLAMD_H=1 -DHAVE_CCOLAMD=1 -DHAVE_SUITESPARSE_CHOLMOD_H=1 -DHAVE_CHOLMOD=1 -DHAVE_SUITESPARSE_CS_H=1 -DHAVE_CXSPARSE=1 -Dmode_t=int -Dpid_t=int -Duid_t=int -Dgid_t=int -DHAVE_DEV_T=1 -DHAVE_INO_T=1 -DHAVE_LONG_LONG_INT=1 -DHAVE_UNSIGNED_LONG_LONG_INT=1 -DHAVE_SIG_ATOMIC_T=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_LONG_LONG=8 -DHAVE_ALLOCA=1 -DNPOS=std::string::npos -DHAVE_PLACEMENT_DELETE=1 -DSTDC_HEADERS=1 -DHAVE_ASSERT_H=1 -DHAVE_DIRECT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_FLOAT_H=1 -DHAVE_LIMITS_H=1 -DHAVE_LOCALE_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_UTIME_H=1 -DHAVE_UNISTD_H=1 -DHAVE_VARARGS_H=1 -DHAVE_SSTREAM=1 -DHAVE_GLOB_H=1 -DHAVE_FNMATCH_H=1 -DHAVE_CONIO_H=1 -DHAVE_ATEXIT=1 -DHAVE_CHMOD=1 -DHAVE_DUP2=1 -DHAVE_EXECVP=1 -DHAVE_GETCWD=1 -DHAVE_GETPID=1 -DHAVE__KBHIT=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_PUTENV=1 -DHAVE_RAISE=1 -DHAVE_RENAME=1 -DHAVE_RMDIR=1 -DHAVE_SETLOCALE=1 -DHAVE_SETVBUF=1 -DHAVE_STAT=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRICMP=1 -DHAVE_STRNICMP=1 -DHAVE_TEMPNAM=1 -DHAVE_UMASK=1 -DHAVE_UNLINK=1 -DHAVE_UTIME=1 -DHAVE_VFPRINTF=1 -DHAVE_VSPRINTF=1 -DHAVE_VSNPRINTF=1 -DHAVE__CHMOD=1 -DHAVE__SNPRINTF=1 -DHAVE__UTIME32=1 -DOCTAVE_HAVE_BROKEN_STRPTIME=1 -D_WIN32_WINNT=0x0403 -D_USE_MATH_DEFINES=1 -DHAVE_LOADLIBRARY_API=1 -DENABLE_DYNAMIC_LINKING=1 -DHAVE__FINITE=1 -DHAVE__ISNAN=1 -DHAVE__COPYSIGN=1 -DHAVE_DECL_SIGNBIT=0 -DHAVE_STRUCT_STAT_ST_RDEV=1 -DHAVE_DECL_TZNAME=1 -DHAVE_TZNAME=1 -DCLOSEDIR_VOID=1 -DMKDIR_TAKES_ONE_ARG=1 -DUSE_READLINE=1 -DRETSIGTYPE=void -DHAVE_DECL_SYS_SIGLIST=0 -DMUST_REINSTALL_SIGHANDLERS=1 -DRETSIGTYPE_IS_VOID=1 -DGNUPLOT_BINARY=\"pgnuplot\""

: ${USER=$LOGNAME}

CC_AND_VERSION=
if test -n "$CC_VERSION"; then
  CC_AND_VERSION="$CC, version $CC_VERSION"
fi

CXX_AND_VERSION=
if test -n "$CXX_VERSION"; then
  CXX_AND_VERSION="$CXX, version $CXX_VERSION"
fi

PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH
export PATH

TEMP=/tmp/octave-bug.$$

if [ -z "$DEFEDITOR" ] && [ -z "$EDITOR" ]; then
  if [ -x /usr/bin/editor ]; then
    DEFEDITOR=editor
  elif [ -x /usr/local/bin/ce ]; then
    DEFEDITOR=ce
  elif [ -x /usr/local/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/contrib/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/bin/emacs ]; then
    DEFEDITOR=emacs
  elif [ -x /usr/bin/xemacs ]; then
    DEFEDITOR=xemacs
  elif [ -x /usr/contrib/bin/jove ]; then
    DEFEDITOR=jove
  elif [ -x /usr/local/bin/jove ]; then
    DEFEDITOR=jove
  elif [ -x /usr/bin/vi ]; then
    DEFEDITOR=vi
  else
    echo "octave-bug: No default editor found: attempting to use vi" >&2
    DEFEDITOR=vi
  fi
fi

: ${EDITOR=$DEFEDITOR}

if [ -z "$DEFPAGER" ] && [ -z "$PAGER" ]; then
  if [ -x /usr/bin/pager ]; then
    DEFPAGER=pager
  elif [ -x /usr/bin/less ]; then
    DEFPAGER=less
  elif [ -x /bin/less ]; then
    DEFPAGER=less
  elif [ -x /usr/local/bin/less ]; then
    DEFPAGER=less
  elif [ -x /usr/bin/more ]; then
    DEFPAGER=more
  elif [ -x /bin/more ]; then
    DEFPAGER=more
  elif [ -x /usr/bin/pg ]; then
    DEFPAGER=pg
  elif [ -x /bin/pg ]; then
    DEFPAGER=pg
  else
    echo "octave-bug: No default pager found: attempting to use more" >&2
    DEFPAGER=more
  fi
fi

: ${PAGER=$DEFPAGER}

trap 'rm -f $TEMP $TEMP.x; exit 1' 1 2 3 13 15
trap 'rm -f $TEMP $TEMP.x' 0

UN=
if (uname) > /dev/null 2>&1; then
  UN=`uname -a`
fi

HAVE_FMT=false
if (fmt < /dev/null) > /dev/null 2>&1; then
  HAVE_FMT=true
fi

# Check whether to use -n or \c to keep echo from printing a newline
# character.  Stolen from autoconf, which borrowed the idea from dist 3.0.

if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
  if (echo -n testing; echo 1,2,3) | $SED s/-n/xn/ | grep xn >/dev/null; then
    echo_n=
    echo_c='
'
  else
    echo_n=-n
    echo_c=
  fi
else
  echo_n=
  echo_c='\c'
fi

ss_p=`echo $VERSION | grep "^ss-"`
if test -n "$ss_p"; then
  BUGADDR="maintainers@octave.org"
else
  pretest_p=`echo $VERSION \
    | $SED 's,.*\.\([0-9]*\).*,\1,' \
    | grep -v '\.' \
    | grep '[0-9]'`

  if test -n "$pretest_p" && test "$pretest_p" -ge 90; then
    BUGADDR="maintainers@octave.org"
  else
    BUGADDR="bug@octave.org"
  fi
fi

SUBJECT="[50 character or so descriptive subject here (for reference)]"
if test $# -gt 0; then
  case "$1" in
    -s)
      shift
      if test $# -gt 0; then
        SUBJECT="$1"
        shift
      else
        echo "usage: octave-bug [-s subject]"
        exit 1
      fi
    ;;
  esac
fi

cat > $TEMP << EOF
To: $BUGADDR
EOF
if test -n "$USER"; then
cat >> $TEMP << EOF
Cc: $USER
EOF
fi
cat >> $TEMP << EOF
Subject: $SUBJECT
--------
Bug report for Octave $VERSION configured for $MACHINE

Description:
-----------

  * Octave stops recognizing packages and files in its path with out
    much warning. It may have to do with the error handling system,
    but I can't be sure.

    The main problem is that there appears to be no reliable way to
    cause this to happen, even with the same input. It happens between,
    1 out of 5 and 1 out of 10 times, depending on the day or hour.

    Windows XP machine. Pentium 4.

Repeat-By:
---------

  *

        1) Compile qpParseSum.c
        2) run testQpLoadAnalyzeData(true, true)
                This should cause an error no matter what on input.
                When it asks you to pick a column just pick UTC each time, case matters.
                Occasionally this causes Octave to stop recognizing files.

%%%%%%%%%%%%%%%%%%%%%%%
% You'll need to compile this as a mex file for octave
% qpParseSum.c
%%%%%%%%%%%%%%%%%%%%%%%

#include "mex.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

// Error Codes
#define NOERROR 0
#define CELLNOTSTRING 1
#define ELEMENTNOTSTRING 2
#define UNBALANCEDINPUTOUTPUT 3
#define MISSINGOUTPUT 4
#define UNDEFINEDCOLUMN 5
#define FILENOTFOUND 6
#define COLUMNNOTFOUND 7
#define BADSUMMARYFILE 8

//  Files to open
FILE *sumFile, *typeFile;
long lSize; // Storeing size of file

// Different stages of File parsing
char *typeBuffer, *sumBuffer, *noTrash, *line, *token, *errBuffer;
char *columnName, *fileLocation, *columnNameNoEndl;
char *char13;
char **argv, **lines;

size_t result;
int cell_dims[2];
int nlhs1, nrhs1;
int matlabSuccesful;
// Details for columns

mxArray *rhs[1], *lhs[1];int nlhs1, nrhs1;
mxArray *cellArr, *charArr;

long double dataCell; // for converting to numbers

double *pr;
int *neededColumns;
double *columnTypes;
long double *output;

int argc, len;
int k, ncell; // For Input
int numberOfRows, numberOfColumns; // Of Entire File
int i,j; // Iteration vars
int inComment, firstLine, found; // Control Vars (are we in a comment) (is this the first line?);
int index; // index for cell arrays

int justHead, errorStatus;

/*************************************************************************************
//  mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
//
// Opens a summary file and parses columns into double arrays for OCTAVE if it is a number and cell strings the column is a string
//
// ARGUMENTS:
// nlhs - The number of left hand side arguments that will be returned to the calling Octave code
// plhs[] - An array of pointers to the data being returned should have a size of nlhs
// nrhs - The number of right hand sides passed in for use by the calling Octave code
// prhs[] - An array of pointers to the data being passed in, having a size of nrhs. The data being pointed to is read only.
//
// A note on mxCalloc & mxMalloc: Matlab & Octave free these vars automatically when return to the prompt
// occurs. Still free them though, when you are done with them.
***********************************************************************************/

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  matlabSuccesful = 0;
 
  errorStatus = NOERROR;
  argc = 0;
  j = 0;
  justHead = 0;
 
  /*****************************************************
       *
       * Verify all data passed in is string data
       *
       *****************************************************/
 
  for(k=0; k<nrhs; k++)
  {
    if( mxIsCell( prhs[k] ) )
    {
      argc += ncell = mxGetNumberOfElements( prhs[k] );
      for( i=0; i<ncell; i++ ) {
        if( !mxIsChar( mxGetCell( prhs[k], i ) ) ) {
          errorStatus = CELLNOTSTRING;
          goto out;
        }
      }
    }
    else
    {
      argc++;
      if( !mxIsChar( prhs[k] ) ) {
        errorStatus = ELEMENTNOTSTRING;
        goto out;
      }
    }
  }  

  if(nlhs != argc - 1) {
    if(nlhs == 1 && argc == 1) {
      justHead = 1;  
    } else {
      errorStatus = UNBALANCEDINPUTOUTPUT;
      goto out;      
    }
  }
 
  if(nlhs == 0) {
    errorStatus = MISSINGOUTPUT;
    goto out;
  }
 
  argv = (char **) mxCalloc( argc, sizeof(char *) );  

  /***************************************************
       *
       *  Convert data stored in cells to strings
       *
       ***************************************************/
 
  for( k=0; k<nrhs; k++ )
  {
    if( mxIsCell( prhs[k] ) )
    {
        ncell = mxGetNumberOfElements( prhs[k] );
        for( i=0; i<ncell; i++ )
            argv[j++] = mxArrayToString( mxGetCell( prhs[k], i ));
    }
    else
    {
        argv[j++] = mxArrayToString( prhs[k] );
    }
  }
 
  /**************************************************************************************************
       *
       *  Octave has array types of cellstr and double. If a column is numeric want to store the data as numeric data.
       *  Call summaryColumnLookUpType to get the type of each column for later conversion.
       *  String is represented by 1, Numeric by 0.
       *
       **************************************************************************************************/

  columnTypes = (double*) mxMalloc (sizeof(double)*(argc-1)); // 0 = Number, 1 = String
 
  char13 = (char*)mxCalloc(2,sizeof(char));
  k = sprintf(char13, "%c", 13);
 
  for(k = 0; k < argc - 1; k++) {
    columnName = (char*)mxCalloc(strlen(argv[k+1])+10,sizeof(char));
   
    strcpy(columnName, argv[k+1]);  
   
    columnNameNoEndl = strtok(columnName,char13);    
    strcpy(argv[k+1], columnNameNoEndl);
   
    nrhs1 = 1;
    nlhs1 = 1;
    rhs[0] = mxCreateString(columnNameNoEndl);    
   
    /* Note: this call is represented the same way as mexFunction.*/
   
    mexSetTrapFlag(1);
    matlabSuccesful = mexCallMATLAB(nlhs1, lhs, nrhs1, rhs, "summaryColumnLookUpType");
    mexSetTrapFlag(0);
    if(matlabSuccesful) {
      errorStatus = UNDEFINEDCOLUMN;
      goto out;
    }    
   
   
    pr = mxGetPr(lhs[0]);
    columnTypes[k] = *pr;
    mxFree(pr);
    mxFree(columnName);
  }
  mxFree(char13);
 
  /*******************************************************************************
      *
      *   Read in and parse the summary file. Remove any element known that it won't be needed
      *   to return. (linefeed, comments...)
      *
      ******************************************************************************/

  sumFile = fopen(argv[0], "rb");
 
  if (sumFile==NULL) { errorStatus = FILENOTFOUND; goto out; }
 
  fseek(sumFile, -4, SEEK_END);
  lSize = ftell(sumFile);
  rewind(sumFile);

  // sumBuffer holds data directly from file
  sumBuffer = (char*) mxCalloc (lSize+1,sizeof(char));
  // noTrash will not have comments or extra linebreaks
  noTrash = (char*) mxCalloc (lSize+1,sizeof(char));
  result = fread (sumBuffer,1,lSize,sumFile); // read in the data
 
  fclose(sumFile);
 
  j = 0;
 
  inComment = 0; // Have we found a comment?
  firstLine = 0; // Is this the first line?
  numberOfRows = 0;
  numberOfColumns = 0;
  for(i = 0; i < lSize; i++) {
    if(inComment == 0) {
      if(sumBuffer[i] == '#') {
        inComment = 1;
       continue;
      }
      if(sumBuffer[i] == '\n') {
        numberOfRows++;
        if(firstLine == 1) {        
          firstLine = 2; // Can't be first line anymore
        }
      }
      if(sumBuffer[i] == 13) continue; // Don't add char(13) to noTrash
     
      if(firstLine == 0 && sumBuffer[i] == ',') {
        numberOfColumns++;
        firstLine = 1; // This is the first comma, so this is the first line of data
      }
      if(firstLine == 1 && sumBuffer[i] == ',') {
        numberOfColumns++;
      }
      noTrash[j] = sumBuffer[i]; // this byte wasn't trash
     
      j++; // Current position in noTrash updated
    } else {
     
      if(sumBuffer[i] == '\n') inComment = 0; //Comment must be over, found a new line.
    }
  }

  /******************************************************************************
      *   Split the file first into lines and then into cols, thereby storing each piece of data in a different cell of a cell matrix.
      *   This makes it simple to just grab the appropriate column of data and place it in nlhs[]. This block of code also locates
      *   the columns that were requested in the original data.
      *******************************************************************************/
 
  lines = (char**) mxCalloc(numberOfRows,sizeof(char*));
  lines[0] = (char *)strtok(noTrash,"\n");
  for(i = 1; i < numberOfRows; i++) {
   lines[i] = (char *)strtok(NULL,"\n");
  }

  cell_dims[0] = numberOfRows;
  cell_dims[1] = numberOfColumns;

  neededColumns = (int*) mxMalloc (sizeof(int)*(argc-1));
 
  for(k = 0; k < argc-1; k++) {
    neededColumns[k] = -1;
  }
 
  cellArr = mxCreateCellArray(2,cell_dims);

  for(i = 0; i < numberOfRows; i++) {
    line = lines[i];
    token = (char*)strtok(line," ,");
    for(j = 0; j < numberOfColumns; j++) {
      if(token == NULL) {
        errorStatus = BADSUMMARYFILE;
        goto out;
      }
      charArr = mxCreateString(token);
      // Cell arrays are indexed based column major order
      index = calcIndex(numberOfRows,i,j);
      mxSetCell(cellArr,index,charArr);
     
      if(i == 0) {
        //Looking at first row. Find columns requested by user
        for(k = 0; k < argc - 1; k++) {
          if(strcmp(argv[k+1],token) == 0) {
            neededColumns[k] = j;
          }
        }
      }
      if(j != numberOfColumns) { // If still looking, keep tokening
        token = (char *)strtok(NULL," ,");
      }
    }
  }
 
  for(k = 0; k < argc-1; k++) {
    if(neededColumns[k] == -1) {
      errorStatus = COLUMNNOTFOUND;
      goto out;
    }
  }
 
  /***************************************************************************************
       * Place Data into PLHS[], the return array.
       *  - Convert each column to the type discovered earlier.
       *  - Place each column in PLHS
       *
       *  Numbers are stored as Double arrays. Strings are stored Cellstr arrays.
       *  For an unknown reason, must convert back to string to store in a new cell array, otherwise data is corrupted.
       *  Use long doubles to grab all of the data, in C you lose information with just %f,e,g
       ***************************************************************************************/
 
  if(justHead) {
    cell_dims[0] = 1;
    cell_dims[1] = numberOfColumns;
   
    plhs[0] = mxCreateCellArray(2,cell_dims);
   
    for(k = 0; k < numberOfColumns; k++) {      
      charArr = mxGetCell(cellArr, calcIndex(numberOfRows,0,k));
      token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));      
      mxGetString(charArr, token, mxGetNumberOfElements(charArr)+1);
      charArr = mxCreateString(token);
      mxSetCell(plhs[0],calcIndex(1,0,k),charArr);      
    }  
  } else {
    cell_dims[0] = numberOfRows-1;
    cell_dims[1] = 1;
    for(k = 0; k < argc-1; k++) {
      if(!(columnTypes[k] > 0)) { // 0 means numeric
        plhs[k] = mxCreateDoubleMatrix(numberOfRows-1,1,mxREAL);
        for(i = 1; i < numberOfRows; i++) {
          charArr = mxGetCell(cellArr, calcIndex(numberOfRows,i,neededColumns[k]));
          token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));
          mxGetString(charArr, token,mxGetNumberOfElements(charArr)+1);
          sscanf(token,"%Lf",&dataCell);
          output = (long double*) mxGetPr(plhs[k]);
          mxFree(token);
          output[i-1] = dataCell;
        }
      } else { // 1 meant string
        plhs[k] = mxCreateCellArray(2,cell_dims);
        for(i = 1; i < numberOfRows; i++) {
          charArr = mxGetCell(cellArr, calcIndex(numberOfRows,i,neededColumns[k]));
          token = (char*)mxCalloc(mxGetNumberOfElements(charArr)+1,sizeof(char));
          mxGetString(charArr, token,mxGetNumberOfElements(charArr)+1);
          charArr = mxCreateString(token);
          mxSetCell(plhs[k],i-1,charArr);
          mxFree(token);
        }
      }
    }
  }

  // CLEAN  UP

out:
  switch(errorStatus) {
    case COLUMNNOTFOUND:
      len = strlen(argv[0]) + 130;
      errBuffer =(char*) mxCalloc(len, sizeof(char));            
      sprintf(errBuffer, "qpParseSum was unable to find requested column, '%s', in '%s'  Verify all requested columns exist in the summary file.",argv[k+1],argv[0]);      
    case BADSUMMARYFILE:
      mxFree(lines);
      mxFree(sumBuffer);
      mxFree(noTrash);
      mxFree(neededColumns);      
    case FILENOTFOUND:
      if(errorStatus == FILENOTFOUND) {
        len = strlen(argv[0])*2 + 200;
        errBuffer =(char*) mxCalloc(len, sizeof(char));            
        sprintf(errBuffer, "qpParseSum expects a file that exists, but %s does not exist in the path, and can not be opened. Check that %s is spelled correctly and that it exists in your current directory.", argv[0],argv[0]);
      }
    case UNDEFINEDCOLUMN:
      mxFree(columnTypes);
      if( argc ) {
        for( j=argc-1; j>=0; j-- )
          mxFree( argv[j] );
        mxFree( argv );
      }      
    case MISSINGOUTPUT:
    case UNBALANCEDINPUTOUTPUT:
    case ELEMENTNOTSTRING:
    case CELLNOTSTRING:
      break;
    case NOERROR:
    default:
      mxFree(lines);
      mxFree(sumBuffer);
      mxFree(noTrash);
      mxFree(neededColumns);
      mxFree(columnTypes);  
  }  
 

  switch(errorStatus) {
    case NOERROR:
      return;    
    case CELLNOTSTRING:      
      mexErrMsgIdAndTxt("qpMEX:FunctionCall:WrongTypeOfInput", "qpParseSum expects all input to be string data but recieved a cell input element that was not a string. Check input values for numeric data.");
      break;    
    case ELEMENTNOTSTRING:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:WrongTypeOfInput", "qpParseSum expects all input to be string data but recieved an input element that was not a string. Check input values for numeric data.  ");
      break;    
    case UNBALANCEDINPUTOUTPUT:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:InvalidCall","qpParseSum expects the number of output variables(%d) to be equivalent to the number of columns requested(%d). Check the number of arguments being passed in.  ",nlhs,(argc-1));
      break;    
    case MISSINGOUTPUT:
        mexErrMsgIdAndTxt("qpMEX:FunctionCall:InvalidCall","qpParseSum expects at least one output variable, but recieved none.");
      break;    
    case UNDEFINEDCOLUMN:      
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:DataNotFound","qpParseSum expected a defined column, but recieved '%s' which has not been defined in summaryColumnLookUpType.m",columnName);
      break;
    case FILENOTFOUND:
      mexErrMsgIdAndTxt("qpMEX:FileInteraction:FileNotFound",errBuffer);              
      break;    
    case COLUMNNOTFOUND:
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:DataNotFound",errBuffer);
      break;
    case BADSUMMARYFILE:  
      mexErrMsgIdAndTxt("qpMEX:SummaryFileInteraction:EncounteredBadVersion","qpParseSum expected data to exist for each column, but one row was incomplete.");
      break;
    default:
      break;
  }
  return;
}

/*****************************************************************************
// calcIndex - Calculates the desired index for an array stored in column major order
//
//  ARGUMENTS:
//    rows - total number of rows in the table
//    row - row containing element e
//    col - column containing element e
//
//  RETURNS
//    An integer representing the index of a column major order entry of an array in memory
 *****************************************************************************/

int calcIndex(int rows, int row, int col) {
  return rows * col + row;
}

%%%%%%%%%%%%%%%%%%%%% testQpLoadAnalyzeData.m %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function success = testQpLoadAnalyzeData(verbose,cleanUp)
  more('off');
  if(~exist('verbose')) verbose = false; end;
  if(~exist('cleanUp')) cleanUp = false; end;

  for i = 1:7
      files{i} = sprintf('00_GEN_99_00000%d.sum',i);
  end
  setup(files);
 
  success = false;
  try
    if(verbose)
      for i = 5:7
        t = sprintf('qpLoadAnalyzeData: Bad Calls %d',i);
        fail = true;
        try
          [a b c] = qpLoadAnalyzeData(files{i});
        catch
          fail = false;
        end    
        if(fail)
          qpFailTest(t);
        end
        qpEndTest(t);
      end
    end
   
    try
      for i = 1:4
        t = sprintf('qpLoadAnalyzeData: Perfect Calls %d',i);
        [a b c] = qpLoadAnalyzeData(files{i});
        qpEndTest(t);
      end
    catch
      qpFailTest(t);
    end  
    teardown(files,cleanUp);
    success = true;
  catch    
    teardown(files,cleanUp);
    qpHandleError(mfilename);
    rethrow(lasterror);
  end
end

function setup(files)
  a = (1:100)';
  try
    writeSummaryFile(files{1},{'rangeReference' 'rangeAvg' 'rangeStd'},a,a,a);
    writeSummaryFile(files{2},{'rangeReference' 'phaseAvg' 'phaseStd'},a,a,a);
    writeSummaryFile(files{3},{'rangeReference' 'phaseHFAvg' 'phaseHFStd'},a,a,a);
    writeSummaryFile(files{4},{'rangeReference' 'phaseLFAvg' 'phaseLFStd'},a,a,a);
   
    writeSummaryFile(files{5},{'undefined' 'rangeAvg' 'rangeStd'},a,a,a);
    writeSummaryFile(files{6},{'rangeReference' 'rangeAvg' 'undefined'},a,a,a);
    writeSummaryFile(files{7},{'rangeReference' 'undefined' 'rangeStd'},a,a,a);
  catch
    qpHandleError([mfilename 'setup']);
    teardown(files,cleanUp);
    rethrow(lasterror);
  end
end

function teardown(files,cleanUp)
  if(cleanUp)
    for i = 1:length(files)
      delete(files{i});
    end
  end
end

%%%%%%%%%%%%%%%%%%%%%%%% qpLoadAnalyzeData.m %%%%%%%%%%%%%%%%%%%%%%%%%


function [rangeReference mean standard] = qpLoadAnalyzeData(sumFile)
  try
    header = qpParseSum(char(sumFile));

    if(sum(strcmp(header, 'rangeAvg')) == 1)
      mnStr ='rangeAvg';
      stStr ='rangeStd';
    elseif(sum(strcmp(header, 'phaseAvg')) == 1)
      mnStr = 'phaseAvg';
      stStr = 'phaseStd';
    elseif(sum(strcmp(header, 'phaseLFAvg')) == 1)
      mnStr = 'phaseLFAvg';
      stStr = 'phaseLFStd';
    elseif(sum(strcmp(header, 'phaseHFAvg')) == 1)
      mnStr = 'phaseHFAvg';
      stStr = 'pha