# MATLAB: Recursive MEX function, structures within structure

mexstructures

I'm trying to make a MEX function that takes a structure (STRUCT0) and a number of strings (STRING1, STRING2, …) as input arguments. The function should test whether STRUCT0.STRING1.STRING2 is a valid field. The function "checkForFields" below will verify that STRUCT0 is a structure, that STRING1 is a valid field and that STRUCT0.STRING1 is itself a structure. It should then recursively call itself, to check whether STRING2 is a field of STRUCT0.STRING1. However, that's where it goes wrong. When the function recursively calls itself, STRUCT0.STRING1 is no longer recognised as a structure. How should I define the input arguments for the recursive function call?
Many thanks, Dries
#include "mex.h"#include "matrix.h"void checkForFields(mxArray *output[], int nInputArguments, const mxArray *inputArguments[]);void mexFunction(        int nlhs, mxArray *plhs[],        int nrhs, const mxArray *prhs[]) {      // define a boolean output argument, initialised to false      plhs[0] = mxCreateLogicalScalar(0);      // check number of input arguments:      if(nrhs<2) {          mexErrMsgIdAndTxt("driesMex:fieldExists:nrhs1",                  "Function requires a structure and at least one field.");      }      // check number of output arguments:      if(nlhs>1) {          mexErrMsgIdAndTxt("driesMex:fieldExists:nlhs",                  "Function supports maximum one output.");      }      // if first argument is a struct      if (mxIsStruct(prhs[0])) {          // call a subroutine that will recursively call itself          checkForFields(plhs, nrhs, prhs);      } else {          // first argument is not a struct, issue a warning:          mexWarnMsgIdAndTxt("driesMex:fieldExists:firstArg", "First argument is not a structure.");      }  }void checkForFields(mxArray *output[], int nInputArguments, const mxArray *inputArguments[]){    // *output[]:       pointer to output mxArray    // nInputArguments: number of input arguments    // *inputArguments: pointer to input mxArray,    //                  first argument must be struct, rest are fields to be tested      // initialise output to false      output[0] = mxCreateLogicalScalar(0);      // if first argument is not a struct      if (!mxIsStruct(inputArguments[0])) {          // issue a warning:                  mexWarnMsgIdAndTxt("driesMex:fieldExists:checkForFields:firstArg", "CheckForFields: First argument is not a structure.");      }      // if second argument is a string      if (mxIsChar(inputArguments[1])) {          // if second argument is a field          if (mxGetFieldNumber(inputArguments[0], mxArrayToString(inputArguments[1]))+1) {              // output argument should be set to true              output[0] = mxCreateLogicalScalar(1);              // check if there are more than 2 input arguments              if (nInputArguments>2) {                                  // check if second argument is also struct                  if (mxIsStruct(mxGetField(inputArguments[0], 0, mxArrayToString(inputArguments[1])))){                      // recursively call this subroutine                      checkForFields(output, nInputArguments-1, &inputArguments[1]);                      // output argument may be overwritten if subsequent field  was not a field                  }              }          }          // else second argument is not a field          // output argument was already initialised to false      } else {          // second argument is not a string, throw error          mexErrMsgIdAndTxt("driesMex:fieldExists:nrhs2",                  "Function requires field argument(s) to be a string.");      }  }

#include "mex.h"   // Includes matrix.h alreadyvoid mexFunction(      int nlhs, mxArray *plhs[],      int nrhs, const mxArray *prhs[]){  mwSize i;  char Field[mxMAXNAM];  S = prhs[0];  if (!mxIsStruct(S)) {    mexErrMsgIdAndTxt(...);  }  for (i = 1; i < nrhs; i++) {    // mxGetString replies 1 if the input is not a string    // or too long:    if (mxGetString(prhs[i], Field, mxMAXNAM)) {      // Check for: prhs[i] is not a string, or too long      mexErrMsgIdAndTxt(...);    }       // mxGetFields replies NULL, if S is not a struct or doe not    // have the wanted field:    S = mxGetField(S, 0, Field);    if (S == NULL) {  // Field not found:      plhs[0] = mxCreateLogicalScalar(0);      return;    }  }   // All subfields have been found:   plhs[0] = mxCreateLogicalScalar(1);  return;}