00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <math.h>
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <stdarg.h>
00023 #include <string.h>
00024 #include <sys/types.h>
00025
00026 #include "mex.h"
00027 #include "mexhead.h"
00028
00029
00030 extern char *mex2c_progname;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 void
00042 mex2c_unimplemented(char *fn) {
00043 char msg[256];
00044
00045 snprintf(msg, sizeof(msg),
00046 "%s: error: mex2c does not yet implement %s",
00047 mex2c_progname, fn);
00048 mexErrMsgTxt(msg);
00049 }
00050
00051 #include "mex_stubs_api.c"
00052 #include "mex_stubs_unimp.c"
00053
00054
00055
00056
00057
00058
00059
00060
00061 void *mxMalloc(size_t n) { return malloc(n); }
00062 void *mxCalloc(size_t n, size_t size) { return calloc(n, size); }
00063 void mxFree(void *ptr) { free(ptr); }
00064 void *mxRealloc(void *ptr, size_t size) { return realloc(ptr, size); }
00065
00066
00067
00068
00069
00070
00071
00072 mxArray *
00073 mxCreateNumericArray(mwSize n, const mwSize *dims, mxClassID id, mxComplexity cflag)
00074 {
00075 mxArray *pm;
00076
00077
00078 if ((pm = (mxArray *) malloc(sizeof(mxArray))) == NULL)
00079 return NULL;
00080
00081 pm->tag = id;
00082 pm->sparse = 0;
00083
00084 if (mxSetDimensions(pm, dims, n)) {
00085
00086 free(pm);
00087 return NULL;
00088 }
00089
00090 pm->datamin = mxt_getnand();
00091 pm->datamax = mxt_getnand();
00092
00093 pm->data.numA.pr = (void *)
00094 calloc((size_t) mxGetNumberOfElements(pm), mxGetElementSize(pm));
00095 if (pm->data.numA.pr == NULL) {
00096 free(pm->dims);
00097 free(pm);
00098 return NULL;
00099 }
00100
00101 if (cflag == mxCOMPLEX) {
00102 pm->data.numA.pi = (void *)
00103 calloc((size_t) mxGetNumberOfElements(pm), mxGetElementSize(pm));
00104 if (pm->data.numA.pi == NULL) {
00105 free(pm->data.numA.pr);
00106 free(pm->dims);
00107 free(pm);
00108 return NULL;
00109 }
00110 } else {
00111 pm->data.numA.pi = NULL;
00112 }
00113 return pm;
00114 }
00115
00116 mxArray *
00117 mxCreateNumericMatrix(mwSize m, mwSize n, mxClassID classid, mxComplexity cflag)
00118 {
00119 mwSize dims[2];
00120
00121 dims[0] = m; dims[1] = n;
00122 return mxCreateNumericArray((mwSize) 2, dims, classid, cflag);
00123 }
00124
00125 mxArray *
00126 mxCreateDoubleMatrix(mwSize m, mwSize n, mxComplexity cflag)
00127 {
00128 mxArray *pm;
00129 mwSize dims[2];
00130
00131
00132 if ((pm = (mxArray *) malloc(sizeof(mxArray))) == NULL)
00133 return(NULL);
00134
00135 pm->tag = mxDOUBLE_CLASS;
00136 pm->sparse = 0;
00137
00138 dims[0] = m; dims[1] = n;
00139 if (mxSetDimensions(pm, dims, (mwSize) 2)) {
00140
00141 free(pm);
00142 return NULL;
00143 }
00144
00145 pm->datamin = mxt_getnand();
00146 pm->datamax = mxt_getnand();
00147
00148 pm->data.numA.pr = (void *) calloc((size_t) (m*n), sizeof(double));
00149 if (pm->data.numA.pr == NULL) {
00150 free(pm->dims);
00151 free(pm);
00152 return NULL;
00153 }
00154
00155 if (cflag == mxCOMPLEX) {
00156 pm->data.numA.pi = (void *) calloc((size_t) (m*n), sizeof(double));
00157 if (pm->data.numA.pi == NULL) {
00158 free(pm->data.numA.pr);
00159 free(pm->dims);
00160 free(pm);
00161 return NULL;
00162 }
00163 } else {
00164 pm->data.numA.pi = NULL;
00165 }
00166 return pm;
00167 }
00168
00169
00170
00171
00172 mxArray *
00173 mxCreateDoubleScalar(double value)
00174 {
00175 mxArray *pm;
00176
00177 if ((pm = mxCreateDoubleMatrix((mwSize) 1, (mwSize) 1, mxREAL))) {
00178 (mxGetPr(pm))[0] = value;
00179 pm->datamin = pm->datamax = value;
00180 }
00181 return pm;
00182 }
00183
00184
00185
00186
00187
00188 mxArray *
00189 mxCreateLogicalArray(mwSize n, const mwSize *dims)
00190 {
00191 mxArray *pm;
00192
00193
00194 if ((pm = (mxArray *) malloc(sizeof(mxArray))) == NULL)
00195 return NULL;
00196
00197 pm->tag = mxLOGICAL_CLASS;
00198 pm->sparse = 0;
00199
00200 if (mxSetDimensions(pm, dims, n)) {
00201
00202 free(pm);
00203 return NULL;
00204 }
00205
00206 pm->datamin = 0;
00207 pm->datamax = 1;
00208
00209 pm->data.logA.pl = (mxLogical *)
00210 calloc((size_t) mxGetNumberOfElements(pm), sizeof(mxLogical));
00211 if (pm->data.logA.pl == NULL) {
00212 free(pm);
00213 return NULL;
00214 }
00215 return pm;
00216 }
00217
00218 mxArray *
00219 mxCreateLogicalMatrix(mwSize m, mwSize n)
00220 {
00221 mxArray *pm;
00222 mwSize dims[2];
00223
00224
00225 if ((pm = (mxArray *) malloc(sizeof(mxArray))) == NULL)
00226 return NULL;
00227
00228 pm->tag = mxLOGICAL_CLASS;
00229 pm->sparse = 0;
00230
00231 dims[0] = m; dims[1] = n;
00232 if (mxSetDimensions(pm, dims, (mwSize) 2)) {
00233
00234 free(pm);
00235 return NULL;
00236 }
00237
00238 pm->datamin = 0;
00239 pm->datamax = 1;
00240
00241 pm->data.logA.pl = (mxLogical *) calloc((size_t) (m*n), sizeof(mxLogical));
00242 if (pm->data.logA.pl == NULL) {
00243 free(pm);
00244 return NULL;
00245 }
00246 return pm;
00247 }
00248
00249 mxArray *mxCreateLogicalScalar(bool value) {
00250 mxArray *pm;
00251
00252 if ((pm = mxCreateLogicalMatrix((mwSize) 1, (mwSize) 1))) {
00253 (mxGetLogicals(pm))[0] = value;
00254 }
00255 return(pm);
00256 }
00257
00258
00259
00260
00261
00262
00263
00264 void
00265 mxDestroyArray(mxArray *pm) {
00266 mwSize i;
00267
00268 if (pm == NULL)
00269 return;
00270 switch (mxGetClassID(pm)) {
00271 case mxDOUBLE_CLASS:
00272 case mxSINGLE_CLASS:
00273 case mxINT8_CLASS:
00274 case mxUINT8_CLASS:
00275 case mxINT16_CLASS:
00276 case mxUINT16_CLASS:
00277 case mxINT32_CLASS:
00278 case mxUINT32_CLASS:
00279 case mxINT64_CLASS:
00280 case mxUINT64_CLASS:
00281 free((void *) pm->data.numA.pr);
00282 free((void *) pm->data.numA.pi);
00283 break;
00284 case mxCHAR_CLASS:
00285 free((void *) pm->data.charA.pc);
00286 break;
00287 case mxLOGICAL_CLASS:
00288 free((void *) pm->data.logA.pl);
00289 break;
00290 case mxCELL_CLASS:
00291 for (i = 0; i < pm->Nelem; i++)
00292 mxDestroyArray(pm->data.cellA.pc[i]);
00293 free((void *) pm->data.cellA.pc);
00294 break;
00295 case mxSTRUCT_CLASS:
00296
00297 for (i = 0; i < pm->Nelem; i++)
00298 mxDestroyArray(pm->data.structA.ps[i]);
00299 free((void *) pm->data.structA.ps);
00300 for (i = 0; i < pm->data.structA.nfield; i++)
00301 free((void *) pm->data.structA.fname[i]);
00302 free((void *) pm->data.structA.fname);
00303 break;
00304 case mxFUNCTION_CLASS:
00305 case mxOPAQUE_CLASS:
00306 case mxOBJECT_CLASS:
00307 default:
00308 break;
00309 }
00310 mxFree(pm->dims);
00311 mxFree(pm);
00312 }
00313
00314
00315
00316
00317
00318 mxArray *
00319 mxDuplicateArray(const mxArray *pm) {
00320 mxArray *out;
00321 size_t length;
00322 mwSize i;
00323
00324 if (pm == NULL) return(NULL);
00325
00326 if ((out = malloc(sizeof(mxArray))) == NULL) return(NULL);
00327 memcpy((void *) out, (void *) pm, sizeof(mxArray));
00328
00329
00330 if (mxSetDimensions(out, mxGetDimensions(pm), mxGetNumberOfDimensions(pm)))
00331 return(NULL);
00332
00333 length = mxGetNumberOfElements(pm) * mxGetElementSize(pm);
00334 switch (mxGetClassID(pm)) {
00335 case mxDOUBLE_CLASS:
00336 case mxSINGLE_CLASS:
00337 case mxINT8_CLASS:
00338 case mxUINT8_CLASS:
00339 case mxINT16_CLASS:
00340 case mxUINT16_CLASS:
00341 case mxINT32_CLASS:
00342 case mxUINT32_CLASS:
00343 case mxINT64_CLASS:
00344 case mxUINT64_CLASS:
00345
00346 mxSetData(out, calloc(length, (size_t) 1));
00347 if (mxGetData(out) == NULL) return (NULL);
00348 memcpy(mxGetData(out), mxGetData(pm), length);
00349
00350 if (mxIsComplex(pm)) {
00351 mxSetImagData(out, calloc(length, (size_t) 1));
00352 if (mxGetImagData(out) == NULL) return (NULL);
00353 memcpy(mxGetImagData(out), mxGetImagData(pm), length);
00354 }
00355 break;
00356 case mxCHAR_CLASS:
00357 out->data.charA.pc = (mxChar *) calloc(length, (size_t) 1);
00358 if (out->data.charA.pc == NULL) return (NULL);
00359 memcpy((mxChar *) out->data.charA.pc,
00360 (mxChar *) pm->data.charA.pc, length);
00361 break;
00362 case mxCELL_CLASS:
00363
00364 out->data.cellA.pc = (mxArray **) calloc(length, (size_t) 1);
00365 if (out->data.cellA.pc == NULL) return (NULL);
00366 for (i = 0; i < pm->Nelem; i++)
00367 if (( out->data.cellA.pc[i] =
00368 mxDuplicateArray(pm->data.cellA.pc[i])) == NULL)
00369 return(NULL);
00370 break;
00371 case mxSTRUCT_CLASS:
00372
00373
00374 out->data.structA.ps = (mxArray **) calloc(length, (size_t) 1);
00375 if (out->data.structA.ps == NULL) return (NULL);
00376 for (i = 0; i < pm->Nelem; i++)
00377 if (( out->data.structA.ps[i] =
00378 mxDuplicateArray(pm->data.structA.ps[i])) == NULL)
00379 return(NULL);
00380
00381 out->data.structA.fname = (char **)
00382 calloc(out->data.structA.nfield, sizeof(char *));
00383 if (out->data.structA.fname == NULL) return (NULL);
00384
00385 for (i = 0; i < out->data.structA.nfield; i++)
00386 if ((out->data.structA.fname[i] =
00387 strdup(pm->data.structA.fname[i])) == NULL)
00388 return(NULL);
00389 break;
00390 case mxFUNCTION_CLASS:
00391 case mxOPAQUE_CLASS:
00392 case mxOBJECT_CLASS:
00393 default:
00394 break;
00395 }
00396 return(out);
00397 }
00398
00399 mxArray *
00400 mxCreateString(const char *str)
00401 {
00402 const char *sptr[1];
00403
00404 sptr[0] = str;
00405 return mxCreateCharMatrixFromStrings((mwSize) 1, sptr);
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 mxArray *
00415 mxCreateCharMatrixFromStrings(mwSize m, const char **str)
00416 {
00417 mxArray *pm;
00418 mxChar *dst;
00419 mwSize dims[2];
00420 size_t strlen_one, strlen_max;
00421 mwSize m_ct;
00422 mwSize n_ct;
00423 int blankwrite;
00424
00425
00426
00427 for (strlen_max = 0, m_ct = 0; m_ct < m; m_ct++) {
00428 strlen_one = strlen(str[m_ct]);
00429 if (strlen_one > strlen_max) strlen_max = strlen_one;
00430 }
00431 dims[0] = m;
00432 dims[1] = strlen_max;
00433 pm = mxCreateCharArray((mwSize) 2, dims);
00434 if (pm == NULL) return(pm);
00435
00436 dst = pm->data.charA.pc;
00437 for (m_ct = 0; m_ct < m; m_ct++) {
00438 for (blankwrite = 0, n_ct = 0; n_ct < strlen_max; n_ct++) {
00439
00440 blankwrite |= (str[m_ct][n_ct] == '\0');
00441
00442 if (blankwrite)
00443 dst[m_ct + n_ct * m] = (mxChar) ' ';
00444 else
00445 dst[m_ct + n_ct * m] = (mxChar) str[m_ct][n_ct];
00446 }
00447 }
00448
00449 return(pm);
00450 }
00451
00452
00453 mxArray *
00454 mxCreateCharArray(mwSize n, const mwSize *dims)
00455 {
00456 mxArray *pm;
00457
00458
00459 if ((pm = (mxArray *) malloc(sizeof(mxArray))) == NULL)
00460 return(NULL);
00461
00462 pm->tag = mxCHAR_CLASS;
00463
00464 if (mxSetDimensions(pm, dims, n)) {
00465
00466 free(pm);
00467 return NULL;
00468 }
00469
00470 pm->datamin = (double) 0;
00471 pm->datamax = (double) 65535;
00472
00473 pm->data.charA.pc = (mxChar *)
00474 calloc((size_t) mxGetNumberOfElements(pm),
00475 (size_t) mxGetElementSize(pm));
00476 if (pm->data.charA.pc == NULL) {
00477 free(pm);
00478 return NULL;
00479 }
00480 return pm;
00481 }
00482
00483 int
00484 mxGetString(const mxArray *pm, char *buf, mwSize buflen)
00485 {
00486 mxChar *src;
00487 mwSize n, nxfer;
00488
00489 if (!mxIsChar(pm))
00490 return 1;
00491
00492 if (buflen == 0)
00493 return 1;
00494
00495 nxfer = mxGetNumberOfElements(pm);
00496 if (nxfer > (buflen-1))
00497 nxfer = buflen-1;
00498
00499 src = pm->data.charA.pc;
00500 for (n = 0; n < nxfer; n++)
00501 *buf++ = (char) *src++;
00502 *buf = '\0';
00503
00504 if (mxGetNumberOfElements(pm) > (buflen-1))
00505 return 1;
00506 return 0;
00507 }
00508
00509 char *
00510 mxArrayToString(const mxArray *pm)
00511 {
00512 mxChar *src;
00513 char *dst;
00514 mwSize n, nxfer;
00515
00516 if (!mxIsChar(pm))
00517 return(NULL);
00518 nxfer = mxGetNumberOfElements(pm);
00519
00520 dst = (char *) malloc((size_t) nxfer + 1);
00521 if (dst == NULL) return NULL;
00522
00523 src = pm->data.charA.pc;
00524 for (n = 0; n < nxfer; n++)
00525 dst[n] = (char) src[n];
00526 dst[nxfer] = '\0';
00527 return dst;
00528 }
00529
00530
00531
00532
00533
00534
00535
00536
00537 mxClassID mxGetClassID(const mxArray *pa) {return(pa->tag);}
00538
00539
00540 size_t mxGetM(const mxArray *pm) {return (size_t) pm->M;}
00541 size_t mxGetN(const mxArray *pm) {return (size_t) pm->N;}
00542
00543
00544
00545
00546 void
00547 mxSetM(mxArray *pm, mwSize m) {
00548 mwSize i;
00549 pm->dims[0] = pm->M = m;
00550 for (pm->Nelem = pm->M, pm->N = 1, i = 1; i < pm->ndim; i++) {
00551 pm->Nelem *= pm->dims[i];
00552 pm->N *= pm->dims[i];
00553 }
00554 }
00555
00556 void
00557 mxSetN(mxArray *pm, mwSize n) {
00558 mwSize i;
00559 pm->dims[1] = n;
00560 for (pm->Nelem = pm->M, pm->N = 1, i = 1; i < pm->ndim; i++) {
00561 pm->Nelem *= pm->dims[i];
00562 pm->N *= pm->dims[i];
00563 }
00564 }
00565
00566
00567 mwSize mxGetNumberOfDimensions(const mxArray *pa) {return (mwSize) pa->ndim; }
00568
00569
00570 const mwSize *
00571 mxGetDimensions(const mxArray *pa) {
00572 return (const mwSize *) pa->dims;
00573 }
00574
00575
00576 size_t mxGetNumberOfElements(const mxArray *pa) { return (size_t) pa->Nelem;}
00577
00578
00579 int
00580 mxSetDimensions(mxArray *pa, const mwSize *size, mwSize ndims) {
00581 mwSize *size2;
00582 mwSize i;
00583
00584 if (ndims < (mwSize) 2)
00585 return 1;
00586 if ((size2 = mxCalloc((size_t) ndims, sizeof(mwSize))) == NULL)
00587 return 1;
00588 memcpy((void *) size2, (void *) size, ndims*sizeof(mwSize));
00589 pa->dims = size2;
00590 pa->ndim = ndims;
00591
00592 pa->M = size[0];
00593 for (i = 1, pa->Nelem = pa->M, pa->N = 1; i < ndims; i++) {
00594 pa->Nelem *= size[i];
00595 pa->N *= size[i];
00596 }
00597 return 0;
00598 }
00599
00600 mwIndex
00601 mxCalcSingleSubscript(const mxArray *pa, mwSize n, const mwSize *subs) {
00602 mwSignedIndex k;
00603 mwIndex index;
00604
00605 if (n == 0) return 0;
00606
00607 for (index = subs[n-1], k = n-2; k >= 0; k--)
00608 index = subs[k] + pa->dims[k] * index;
00609 return index;
00610 }
00611
00612
00613 void *
00614 mxGetImagData(const mxArray *pm) {
00615 return (mxIsNumeric(pm) ? (void *) pm->data.numA.pi : NULL);
00616 }
00617
00618 void *
00619 mxGetData(const mxArray *pm) {
00620 return (mxIsNumeric(pm) ? (void *) pm->data.numA.pr : NULL);
00621 }
00622
00623 mxChar *
00624 mxGetChars(const mxArray *pm) {
00625 return (mxIsChar(pm) ? (void *) pm->data.charA.pc : NULL);
00626 }
00627
00628 mxLogical *
00629 mxGetLogicals(const mxArray *pm){
00630 return (mxIsLogical(pm) ? (void *) pm->data.logA.pl : NULL);
00631 }
00632
00633 void mxSetImagData(mxArray *pm, void *newdata) {pm->data.numA.pi = newdata;}
00634 void mxSetData( mxArray *pm, void *newdata) {pm->data.numA.pr = newdata;}
00635
00636 double *
00637 mxGetPi(const mxArray *pm) {
00638 return (mxGetClassID(pm) == mxDOUBLE_CLASS ?
00639 (double *) pm->data.numA.pi : NULL);
00640 }
00641
00642 double *
00643 mxGetPr(const mxArray *pm) {
00644 return (mxGetClassID(pm) == mxDOUBLE_CLASS ?
00645 (double *) pm->data.numA.pr : NULL);
00646 }
00647
00648 void mxSetPi(mxArray *pm, double *pi) {pm->data.numA.pi = (void *) pi;}
00649 void mxSetPr(mxArray *pm, double *pr) {pm->data.numA.pr = (void *) pr;}
00650
00651 double
00652 mxGetScalar(const mxArray *pm) {
00653 if (mxGetClassID(pm) == mxDOUBLE_CLASS) {
00654 double *p_real = (double *) pm->data.numA.pr;
00655 return p_real[0];
00656 }
00657 else
00658 return mxt_getnand();
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668 bool
00669 mxIsComplex(const mxArray *pm)
00670 {
00671 if (mxGetClassID(pm) == mxDOUBLE_CLASS)
00672 return (pm->data.numA.pi != NULL);
00673 else
00674 return 0;
00675 }
00676
00677 bool
00678 mxIsSparse(const mxArray *pm)
00679 {
00680
00681 return (pm->sparse);
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 void mxt_ErrHandler(const char *);
00697
00698 void
00699 mexErrMsgTxt(const char *error_msg)
00700 {
00701 fprintf(stderr, "%s\n", error_msg);
00702 mxt_ErrHandler(error_msg);
00703 }
00704
00705 void
00706 mexWarnMsgTxt(const char *error_msg)
00707 {
00708 fprintf(stderr, "%s\n", error_msg);
00709 }
00710
00711 void
00712 mexErrMsgIdAndTxt(const char *id, const char *error_msg, ... )
00713 {
00714 va_list args;
00715
00716 va_start(args, error_msg);
00717 fprintf(stderr, "%s\n", id);
00718 vfprintf(stderr, error_msg, args);
00719 fprintf(stderr, "\n");
00720 va_end(args);
00721 mxt_ErrHandler(id);
00722 }
00723
00724 void
00725 mexWarnMsgIdAndTxt(const char *id, const char *warn_msg, ... )
00726 {
00727 va_list args;
00728
00729 va_start(args, warn_msg);
00730 fprintf(stderr, "%s\n", id);
00731 vfprintf(stderr, warn_msg, args);
00732 fprintf(stderr, "\n");
00733 va_end(args);
00734 }
00735
00736
00737
00738 const char *
00739 mexFunctionName(void)
00740 {
00741 return(strdup(mex2c_progname));
00742 }
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 void
00754 getrange(const mxArray *pm, double *datamin, double *datamax)
00755 {
00756 *datamin = pm->datamin;
00757 *datamax = pm->datamax;
00758 }
00759
00760 void
00761 setrange(mxArray *pm, double datamin, double datamax)
00762 {
00763 pm->datamin = datamin;
00764 pm->datamax = datamax;
00765 }
00766