Cell *sub(Node **a, int nnn) /* substitute command */ { char *sptr, *pb, *q; Cell *x, *y, *result; char *t, *buf; fa *pfa; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in sub"); x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ result = False; if (pmatch(pfa, t)) { sptr = t; adjbuf(&buf, &bufsz, 1+patbeg-sptr, recsize, 0, "sub"); pb = buf; while (sptr < patbeg) *pb++ = *sptr++; sptr = getsval(y); while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "sub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "sub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } *pb = '\0'; if (pb > buf + bufsz) FATAL("sub result1 %.30s too big; can't happen", buf); sptr = patbeg + patlen; if ((patlen == 0 && *patbeg) || (patlen && *(sptr-1))) { adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "sub"); while ((*pb++ = *sptr++) != 0) ; } if (pb > buf + bufsz) FATAL("sub result2 %.30s too big; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy */ result = True;; } tempfree(x); tempfree(y); free(buf); return result; }
Cell *gsub(Node **a, int nnn) /* global substitute */ { Cell *x, *y; char *rptr, *sptr, *t, *pb, *q; char *buf; fa *pfa; int mflag, tempstat, num; int bufsz = recsize; if ((buf = (char *) malloc(bufsz)) == NULL) FATAL("out of memory in gsub"); mflag = 0; /* if mflag == 0, can replace empty string */ num = 0; x = execute(a[3]); /* target string */ t = getsval(x); if (a[0] == 0) /* 0 => a[1] is already-compiled regexpr */ pfa = (fa *) a[1]; /* regular expression */ else { y = execute(a[1]); pfa = makedfa(getsval(y), 1); tempfree(y); } y = execute(a[2]); /* replacement string */ if (pmatch(pfa, t)) { tempstat = pfa->initstat; pfa->initstat = 2; pb = buf; rptr = getsval(y); do { if (patlen == 0 && *patbeg != 0) { /* matched empty string */ if (mflag == 0) { /* can replace empty */ num++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } } if (*t == 0) /* at end */ goto done; adjbuf(&buf, &bufsz, 2+pb-buf, recsize, &pb, "gsub"); *pb++ = *t++; if (pb > buf + bufsz) /* BUG: not sure of this test */ FATAL("gsub result0 %.30s too big; can't happen", buf); mflag = 0; } else { /* matched nonempty string */ num++; sptr = t; adjbuf(&buf, &bufsz, 1+(patbeg-sptr)+pb-buf, recsize, &pb, "gsub"); while (sptr < patbeg) *pb++ = *sptr++; sptr = rptr; while (*sptr != 0) { adjbuf(&buf, &bufsz, 5+pb-buf, recsize, &pb, "gsub"); if (*sptr == '\\') { backsub(&pb, &sptr); } else if (*sptr == '&') { sptr++; adjbuf(&buf, &bufsz, 1+patlen+pb-buf, recsize, &pb, "gsub"); for (q = patbeg; q < patbeg+patlen; ) *pb++ = *q++; } else *pb++ = *sptr++; } t = patbeg + patlen; if (patlen == 0 || *t == 0 || *(t-1) == 0) goto done; if (pb > buf + bufsz) FATAL("gsub result1 %.30s too big; can't happen", buf); mflag = 1; } } while (pmatch(pfa,t)); sptr = t; adjbuf(&buf, &bufsz, 1+strlen(sptr)+pb-buf, 0, &pb, "gsub"); while ((*pb++ = *sptr++) != 0) ; done: if (pb < buf + bufsz) *pb = '\0'; else if (*(pb-1) != '\0') FATAL("gsub result2 %.30s truncated; can't happen", buf); setsval(x, buf); /* BUG: should be able to avoid copy + free */ pfa->initstat = tempstat; } tempfree(x); tempfree(y); x = gettemp(); x->tval = NUM; x->fval = num; free(buf); return(x); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* ***************** */ /* Declare variables */ /* ***************** */ double *x, *b, *Pr, *pindex; /*mxGetPr, mxGetPr, mxGetPr, mxGetPr*/ mwSize n, i; /*0, 0*/ mwIndex *Ri, *Cj;/*mxGetIr, mxGetJc*/ mwSize j, jn; /*0, j */ mwSize m; /*mxGetN */ /* ********************************************** */ /* Determine input sizes and perform error checks */ /* ********************************************** */ if (nrhs<5 || nrhs>5) mexErrMsgTxt("Five arguments must be passed"); if (nlhs>1) mexErrMsgTxt("Only one output is produced by LUSolve"); for (n=0; n<nrhs; n++){ if (!(mxIsDouble(prhs[n]) || (mxIsSparse(prhs[n]) && n<2))) mexErrMsgTxt("Input arguments of inproper type"); if (mxIsComplex(prhs[n])) mexErrMsgTxt("Only real inputs are supported"); } n=mxGetM(prhs[0]); if (mxGetN(prhs[0])!=n) mexErrMsgTxt("First input must be square"); if (mxGetM(prhs[1])!=n || mxGetN(prhs[1])!=n) mexErrMsgTxt("Second input must be square"); if (mxGetM(prhs[4])!=n) mexErrMsgTxt("Inputs are not comformable"); m = mxGetN(prhs[4]); plhs[0]=mxDuplicateArray(prhs[4]); x=mxGetPr(plhs[0]); /* If a row permutation vector is passed, permute the RHS (b): x=b(rowindex) */ i=mxGetNumberOfElements(prhs[2]); if (i>0){ if (mxGetNumberOfElements(prhs[2])!=n) mexErrMsgTxt("Row permutation index is the wrong size"); b=mxGetPr(prhs[4]); pindex=mxGetPr(prhs[2]); for (j=0; j<m; j++){ jn=j*n; for (i=0; i<n; i++) x[i+jn]=b[(int)(pindex[i])-1+jn]; } } for (j=0; j<m;j++){ jn=j*n; /* Forward substitution using the L factor: x=L\x */ Pr=mxGetPr(prhs[0]); if (mxIsSparse(prhs[0])){ Ri=mxGetIr(prhs[0]); Cj=mxGetJc(prhs[0]); spforesub(x+jn,Pr,x+jn,Ri,Cj,n); } else foresub(x+jn,Pr,x+jn,n); /* Backward substitution using the U factor: x=U\x */ Pr=mxGetPr(prhs[1]); if (mxIsSparse(prhs[1])){ Ri=mxGetIr(prhs[1]); Cj=mxGetJc(prhs[1]); spbacksub(x+jn,Pr,x+jn,Ri,Cj,n); } else backsub(x+jn,Pr,x+jn,n); } /* If a column permutation vector is passed, permute the LHS: x(colindex)=x */ i=mxGetNumberOfElements(prhs[3]); if (i>0){ if (mxGetNumberOfElements(prhs[3])!=n) mexErrMsgTxt("Column permutation index is the wrong size"); b=mxCalloc(n,sizeof(double)); pindex=mxGetPr(prhs[3]); for (j=0; j<m; j++){ jn=j*n; for (i=0; i<n; i++) b[(int)(pindex[i])-1]=x[i+jn]; memcpy(x+jn,b,n*sizeof(double)); } mxFree(b); } }