00001
00008
00009
00010 #include"mex.h"
00011 #include<ctype.h>
00012
00013 #ifdef __VISUALC__
00014 #define snprintf _snprintf
00015 #endif
00016
00017 #if (MX_API_VER < 0x07030000)
00018 typedef int mwSize ;
00019 typedef int mwIndex ;
00020 #endif
00021
00029 #define VL_USE_MATLAB_ENV \
00030 vl_set_alloc_func (mxMalloc, mxRealloc, mxCalloc, mxFree) ; \
00031 vl_set_printf_func (mexPrintf) ;
00032
00048 static mxArray *
00049 uCreateNumericArray (mwSize ndim, const mwSize * dims,
00050 mxClassID classid, void * data)
00051 {
00052 mxArray *A ;
00053
00054 if (data) {
00055 mwSize dims_ [2] = {0, 0} ;
00056 A = mxCreateNumericArray (2, dims_, classid, mxREAL) ;
00057 mxSetData (A, data) ;
00058 mxSetDimensions (A, dims, ndim) ;
00059 } else {
00060 A = mxCreateNumericArray (ndim, dims, classid, mxREAL) ;
00061 }
00062
00063 return A ;
00064 }
00065
00081 static mxArray *
00082 uCreateNumericMatrix (int M, int N, mxClassID classid, void * data)
00083 {
00084 mxArray *A ;
00085
00086 if (data) {
00087 A = mxCreateNumericMatrix (0, 0, classid, mxREAL) ;
00088 mxSetData (A, data) ;
00089 mxSetM(A, M) ;
00090 mxSetN(A, N) ;
00091 } else {
00092 A = mxCreateNumericMatrix (M, N, classid, mxREAL) ;
00093 }
00094
00095 return A ;
00096 }
00097
00098
00111 static int
00112 uIsScalar(const mxArray* A)
00113 {
00114 return
00115 mxIsNumeric (A) && mxGetNumberOfElements(A) == 1 ;
00116 }
00117
00134 static int
00135 uIsMatrix (const mxArray* A, int M, int N)
00136 {
00137 return
00138 mxIsNumeric(A) &&
00139 mxGetNumberOfDimensions(A) == 2 &&
00140 (M < 0 || mxGetM(A) == M) &&
00141 (N < 0 || mxGetN(A) == N) ;
00142 }
00143
00158 static int
00159 uIsVector(const mxArray* A, int N)
00160 {
00161 return
00162 uIsMatrix(A, 1, N) || uIsMatrix(A, N, 1) ;
00163 }
00164
00177 static int
00178 uIsReal (const mxArray* A)
00179 {
00180 return
00181 mxIsDouble(A) &&
00182 !mxIsComplex(A) ;
00183 }
00184
00197 static int
00198 uIsRealScalar(const mxArray* A)
00199 {
00200 return
00201 uIsReal (A) && mxGetNumberOfElements(A) == 1 ;
00202 }
00203
00220 static int
00221 uIsRealMatrix(const mxArray* A, int M, int N)
00222 {
00223 return
00224 mxIsDouble(A) &&
00225 !mxIsComplex(A) &&
00226 mxGetNumberOfDimensions(A) == 2 &&
00227 (M < 0 || mxGetM(A) == M) &&
00228 (N < 0 || mxGetN(A) == N) ;
00229 }
00230
00245 static int
00246 uIsRealVector(const mxArray* A, int N)
00247 {
00248 return
00249 uIsRealMatrix(A, 1, N) || uIsRealMatrix(A, N, 1) ;
00250 }
00251
00252
00269 static int
00270 uIsRealArray(const mxArray* A, int D, const int* dims)
00271 {
00272 if(!mxIsDouble(A) || mxIsComplex(A))
00273 return false ;
00274
00275 if(D >= 0) {
00276 int d ;
00277 const int* actual_dims = mxGetDimensions(A) ;
00278
00279 if(mxGetNumberOfDimensions(A) != D)
00280 return false ;
00281
00282 return true ;
00283
00284 if(dims != NULL) {
00285 for(d = 0 ; d < D ; ++d) {
00286 if(dims[d] >= 0 && dims[d] != actual_dims[d])
00287 return false ;
00288 }
00289 }
00290 }
00291 return true ;
00292 }
00293
00309 static int
00310 uIsString(const mxArray* A, int L)
00311 {
00312 int M = mxGetM(A) ;
00313 int N = mxGetN(A) ;
00314
00315 return
00316 mxIsChar(A) &&
00317 mxGetNumberOfDimensions(A) == 2 &&
00318 M == 1 &&
00319 (L < 0 || N == L) ;
00320 }
00321
00322
00327 struct _uMexOption
00328 {
00329 const char *name ;
00330 int has_arg ;
00331 int val ;
00332 } ;
00333
00337 typedef struct _uMexOption uMexOption ;
00338
00349 static int
00350 uStrICmp(const char *s1, const char *s2)
00351 {
00352 while (tolower((unsigned char)*s1) ==
00353 tolower((unsigned char)*s2))
00354 {
00355 if (*s1 == 0)
00356 return 0;
00357 s1++;
00358 s2++;
00359 }
00360 return
00361 (int)tolower((unsigned char)*s1) -
00362 (int)tolower((unsigned char)*s2) ;
00363 }
00364
00389 static int uNextOption(mxArray const *args[], int nargs,
00390 uMexOption const *options,
00391 int *next,
00392 mxArray const **optarg)
00393 {
00394 char err_msg [1024] ;
00395 char name [1024] ;
00396 int opt = -1, i, len ;
00397
00398 if (*next >= nargs) {
00399 return opt ;
00400 }
00401
00402
00403 if (! uIsString (args [*next], -1)) {
00404 snprintf(err_msg, sizeof(err_msg),
00405 "The option name is not a string (argument number %d).",
00406 *next + 1) ;
00407 mexErrMsgTxt(err_msg) ;
00408 }
00409
00410
00411 len = mxGetNumberOfElements (args [*next]) ;
00412
00413 if (mxGetString (args [*next], name, sizeof(name))) {
00414 snprintf(err_msg, sizeof(err_msg),
00415 "The option name is too long (argument number %d).",
00416 *next + 1) ;
00417 mexErrMsgTxt(err_msg) ;
00418 }
00419
00420
00421 ++ (*next) ;
00422
00423
00424 for (i = 0 ; options[i].name != 0 ; ++i) {
00425 if (uStrICmp(name, options[i].name) == 0) {
00426 opt = options[i].val ;
00427 break ;
00428 }
00429 }
00430
00431
00432 if (opt < 0) {
00433 snprintf(err_msg, sizeof(err_msg),
00434 "Unkown option '%s'.", name) ;
00435 mexErrMsgTxt(err_msg) ;
00436 }
00437
00438
00439 if (! options [i].has_arg) {
00440 if (optarg) *optarg = 0 ;
00441 return opt ;
00442 }
00443
00444
00445 if (*next >= nargs) {
00446 snprintf(err_msg, sizeof(err_msg),
00447 "Option '%s' requires an argument.", options[i].name) ;
00448 mexErrMsgTxt(err_msg) ;
00449 }
00450
00451 if (optarg) *optarg = args [*next] ;
00452 ++ (*next) ;
00453 return opt ;
00454 }