00001
00008
00009
00010
00011
00012
00013
00014
00015 #include"mex.h"
00016 #include<vl/generic.h>
00017 #include<ctype.h>
00018 #include<stdio.h>
00019 #include<stdarg.h>
00020
00021 #ifdef VL_COMPILER_MSC
00022 #define snprintf _snprintf
00023 #define vsnprintf _vsnprintf
00024 #endif
00025
00026 #if !defined(MX_API_VER) | (MX_API_VER < 0x07030000)
00027 typedef int mwSize ;
00028 typedef int mwIndex ;
00029 #endif
00030
00038 #define VL_USE_MATLAB_ENV \
00039 vl_set_alloc_func (mxMalloc, mxRealloc, mxCalloc, mxFree) ; \
00040 vl_set_printf_func (mexPrintf) ;
00041
00057 static mxArray *
00058 uCreateNumericArray (mwSize ndim, const mwSize * dims,
00059 mxClassID classid, void * data)
00060 {
00061 mxArray *A ;
00062
00063 if (data) {
00064 mwSize dims_ [2] = {0, 0} ;
00065 A = mxCreateNumericArray (2, dims_, classid, mxREAL) ;
00066 mxSetData (A, data) ;
00067 mxSetDimensions (A, dims, ndim) ;
00068 } else {
00069 A = mxCreateNumericArray (ndim, dims, classid, mxREAL) ;
00070 }
00071
00072 return A ;
00073 }
00074
00090 static mxArray *
00091 uCreateNumericMatrix (int M, int N, mxClassID classid, void * data)
00092 {
00093 mxArray *A ;
00094
00095 if (data) {
00096 A = mxCreateNumericMatrix (0, 0, classid, mxREAL) ;
00097 mxSetData (A, data) ;
00098 mxSetM(A, M) ;
00099 mxSetN(A, N) ;
00100 } else {
00101 A = mxCreateNumericMatrix (M, N, classid, mxREAL) ;
00102 }
00103
00104 return A ;
00105 }
00106
00107
00120 static int
00121 uIsScalar(const mxArray* A)
00122 {
00123 return
00124 mxIsNumeric (A) && mxGetNumberOfElements(A) == 1 ;
00125 }
00126
00143 static int
00144 uIsMatrix (const mxArray* A, int M, int N)
00145 {
00146 return
00147 mxIsNumeric(A) &&
00148 mxGetNumberOfDimensions(A) == 2 &&
00149 (M < 0 || mxGetM(A) == M) &&
00150 (N < 0 || mxGetN(A) == N) ;
00151 }
00152
00167 static int
00168 uIsVector(const mxArray* A, int N)
00169 {
00170 return
00171 uIsMatrix(A, 1, N) || uIsMatrix(A, N, 1) ;
00172 }
00173
00186 static int
00187 uIsReal (const mxArray* A)
00188 {
00189 return
00190 mxIsDouble(A) &&
00191 !mxIsComplex(A) ;
00192 }
00193
00206 static int
00207 uIsRealScalar(const mxArray* A)
00208 {
00209 return
00210 uIsReal (A) && mxGetNumberOfElements(A) == 1 ;
00211 }
00212
00229 static int
00230 uIsRealMatrix(const mxArray* A, int M, int N)
00231 {
00232 return
00233 mxIsDouble(A) &&
00234 !mxIsComplex(A) &&
00235 mxGetNumberOfDimensions(A) == 2 &&
00236 (M < 0 || mxGetM(A) == M) &&
00237 (N < 0 || mxGetN(A) == N) ;
00238 }
00239
00254 static int
00255 uIsRealVector(const mxArray* A, int N)
00256 {
00257 return
00258 uIsRealMatrix(A, 1, N) || uIsRealMatrix(A, N, 1) ;
00259 }
00260
00277 static int
00278 uIsRealArray(const mxArray* A, int D, const int* dims)
00279 {
00280 if(!mxIsDouble(A) || mxIsComplex(A))
00281 return 0 ;
00282
00283 if(D >= 0) {
00284 int d ;
00285 const int* actual_dims = mxGetDimensions(A) ;
00286
00287 if(mxGetNumberOfDimensions(A) != D)
00288 return 0 ;
00289
00290 return 1 ;
00291
00292 if(dims != NULL) {
00293 for(d = 0 ; d < D ; ++d) {
00294 if(dims[d] >= 0 && dims[d] != actual_dims[d])
00295 return 0 ;
00296 }
00297 }
00298 }
00299 return 1 ;
00300 }
00301
00317 static int
00318 uIsString(const mxArray* A, int L)
00319 {
00320 int M = mxGetM(A) ;
00321 int N = mxGetN(A) ;
00322
00323 return
00324 mxIsChar(A) &&
00325 mxGetNumberOfDimensions(A) == 2 &&
00326 M == 1 &&
00327 (L < 0 || N == L) ;
00328 }
00329
00337 void
00338 uErrMsgTxt(char const * format, ...)
00339 {
00340 enum { buffLen = 1024 } ;
00341 char buffer [buffLen] ;
00342 va_list args;
00343 va_start (args, format) ;
00344 #ifdef VL_COMPILER_LCC
00345 vsprintf(buffer, format, args) ;
00346 #else
00347 vsnprintf (buffer, buffLen, format, args) ;
00348 #endif
00349 va_end (args) ;
00350 mexErrMsgTxt (buffer) ;
00351 }
00352
00353
00358 struct _uMexOption
00359 {
00360 const char *name ;
00361 int has_arg ;
00362 int val ;
00363 } ;
00364
00368 typedef struct _uMexOption uMexOption ;
00369
00380 static int
00381 uStrICmp(const char *s1, const char *s2)
00382 {
00383 while (tolower((unsigned char)*s1) ==
00384 tolower((unsigned char)*s2))
00385 {
00386 if (*s1 == 0)
00387 return 0;
00388 s1++;
00389 s2++;
00390 }
00391 return
00392 (int)tolower((unsigned char)*s1) -
00393 (int)tolower((unsigned char)*s2) ;
00394 }
00395
00420 static int uNextOption(mxArray const *args[], int nargs,
00421 uMexOption const *options,
00422 int *next,
00423 mxArray const **optarg)
00424 {
00425 char err_msg [1024] ;
00426 char name [1024] ;
00427 int opt = -1, i, len ;
00428
00429 if (*next >= nargs) {
00430 return opt ;
00431 }
00432
00433
00434 if (! uIsString (args [*next], -1)) {
00435 snprintf(err_msg, sizeof(err_msg),
00436 "The option name is not a string (argument number %d).",
00437 *next + 1) ;
00438 mexErrMsgTxt(err_msg) ;
00439 }
00440
00441
00442 len = mxGetNumberOfElements (args [*next]) ;
00443
00444 if (mxGetString (args [*next], name, sizeof(name))) {
00445 snprintf(err_msg, sizeof(err_msg),
00446 "The option name is too long (argument number %d).",
00447 *next + 1) ;
00448 mexErrMsgTxt(err_msg) ;
00449 }
00450
00451
00452 ++ (*next) ;
00453
00454
00455 for (i = 0 ; options[i].name != 0 ; ++i) {
00456 if (uStrICmp(name, options[i].name) == 0) {
00457 opt = options[i].val ;
00458 break ;
00459 }
00460 }
00461
00462
00463 if (opt < 0) {
00464 snprintf(err_msg, sizeof(err_msg),
00465 "Unknown option '%s'.", name) ;
00466 mexErrMsgTxt(err_msg) ;
00467 }
00468
00469
00470 if (! options [i].has_arg) {
00471 if (optarg) *optarg = 0 ;
00472 return opt ;
00473 }
00474
00475
00476 if (*next >= nargs) {
00477 snprintf(err_msg, sizeof(err_msg),
00478 "Option '%s' requires an argument.", options[i].name) ;
00479 mexErrMsgTxt(err_msg) ;
00480 }
00481
00482 if (optarg) *optarg = args [*next] ;
00483 ++ (*next) ;
00484 return opt ;
00485 }