问:
Mex type C file to normal C file
I have a c file written using mex functions, run by Matlab using mex compiler Now I want to run those mex type .c files without Matlab environment. So, is there any way to convert mex type .c file to normal .c file ? Or any other options available for the above mentioned concern.
Thanks in advance....!

Here is the one mex type .c file for sample.

```<code>#include <stdlib.h>
#include "mex.h"
#include "matrix.h"
#include "distances.h"
#include "ltl2tree.h"
#include "param.h"

#define BUFF_LEN 4096

char * emalloc(size_t n)
{
    char *tmp;

    if (!(tmp = (char *) mxMalloc(n)))
        mexErrMsgTxt("mx_dp_taliro: not enough memory!");
    memset(tmp, 0, n);
    return tmp;
}

int tl_Getchar(int *cnt, size_t hasuform, char *uform)
{
    if (*cnt < hasuform)
        return uform[(*cnt)++];
    (*cnt)++;
    return -1;
}

void tl_UnGetchar(int *cnt)
{
    if (*cnt > 0) (*cnt)--;
}

#define Binop(a)        \
        fprintf(miscell->tl_out, "(");  \
        dump(n->lft, miscell);      \
        fprintf(miscell->tl_out, a);    \
        dump(n->rgt, miscell);      \
        fprintf(miscell->tl_out, ")")

static void sdump(Node *n, char *dumpbuf)
{
    switch (n->ntyp) {
    case PREDICATE: strcat(dumpbuf, n->sym->name);
            break;
    case U_OPER:    strcat(dumpbuf, "U");
            goto common2;
    case V_OPER:    strcat(dumpbuf, "V");
            goto common2;
    case OR:    strcat(dumpbuf, "|");
            goto common2;
    case AND:   strcat(dumpbuf, "&");
common2:        sdump(n->rgt,dumpbuf);
common1:        sdump(n->lft,dumpbuf);
            break;
    case NEXT:  strcat(dumpbuf, "X");
            goto common1;
    case NOT:   strcat(dumpbuf, "!");
            goto common1;
    case TRUE:  strcat(dumpbuf, "T");
            break;
    case FALSE: strcat(dumpbuf, "F");
            break;
    default:    strcat(dumpbuf, "?");
            break;
    }
}

Symbol *DoDump(Node *n, char *dumpbuf, Miscellaneous *miscell)
{
    if (!n) return ZS;

    if (n->ntyp == PREDICATE)
        return n->sym;

    dumpbuf[0] = '\0';
    sdump(n,dumpbuf);
    return tl_lookup(dumpbuf, miscell);
}

void dump(Node *n, Miscellaneous *miscell)
{
    if (!n) return;

    switch(n->ntyp) {
    case OR:    Binop(" || "); break;
    case AND:   Binop(" && "); break;
    case U_OPER:    Binop(" U ");  break;
    case V_OPER:    Binop(" V ");  break;
    case NEXT:
        fprintf(miscell->tl_out, "X");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case NOT:
        fprintf(miscell->tl_out, "!");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case FALSE:
        fprintf(miscell->tl_out, "false");
        break;
    case TRUE:
        fprintf(miscell->tl_out, "true");
        break;
    case PREDICATE:
        fprintf(miscell->tl_out, "(%s)", n->sym->name);
        break;
    case -1:
        fprintf(miscell->tl_out, " D ");
        break;
    default:
        printf("Unknown token: ");
        tl_explain(n->ntyp);
        break;
    }
}

void tl_explain(int n)
{
    switch (n) {
    case ALWAYS:    printf("[]"); break;
    case EVENTUALLY: printf("<>"); break;
    case IMPLIES:   printf("->"); break;
    case EQUIV: printf("<->"); break;
    case PREDICATE: printf("predicate"); break;
    case OR:    printf("||"); break;
    case AND:   printf("&&"); break;
    case NOT:   printf("!"); break;
    case U_OPER:    printf("U"); break;
    case V_OPER:    printf("V"); break;
    case NEXT:  printf("X"); break;
    case TRUE:  printf("true"); break;
    case FALSE: printf("false"); break;
    case ';':   printf("end of formula"); break;
    default:    printf("%c", n); break;
    }
}

static void non_fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    int i;

    printf("TaLiRo: ");
    if (s2)
        printf(s1, s2);
    else
        printf(s1);
    if ((*tl_yychar) != -1 && (*tl_yychar) != 0)
    {   printf(", saw '");
        tl_explain((*tl_yychar));
        printf("'");
    }
    printf("\nTaLiRo: %s\n---------", uform);
    for (i = 0; i < (*cnt); i++)
        printf("-");
    printf("^\n");
    fflush(stdout);
    (miscell->tl_errs)++;
}

void
tl_yyerror(char *s1, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    Fatal(s1, (char *) 0, cnt, uform, tl_yychar, miscell);
}

void
Fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
  non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
  tl_exit(0);
}

void fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
        non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
        tl_exit(0);
}

void put_uform(char *uform, Miscellaneous *miscell)
{
    fprintf(miscell->tl_out, "%s", uform);
}

void tl_exit(int i)
{
    mexErrMsgTxt("mx_dp_taliro: unexpected error, tl_exit executed.");
}

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    /* Variables needed to process the input */
    int status, pstatus;
    mwSize buflen, pbuflen;
    size_t NElems,NCells;
    mwSize ndimA, ndimb, ndimG, ndim, pdim,ndimP;
    const mwSize *dimsA, *dimsb, *dimsG, *dims, *pardims,*dimsP;
    mwIndex jstruct, iii, jjj, i1, j1, idx_j;
    mxArray *tmp,*tmp1,*tmp_cell;
    /* Variables needed for monitor */
    Node *node;
    double *XTrace, *TStamps, *LTrace;
    DistCompData distData;
    PMap *predMap;
    int ii,jj,kk,ll,objs,tempI;
    bool par_on;
    bool is_Multi_HA;
    bool initial_of_par;
    int npred, npar;

    static char uform[BUFF_LEN];
    static size_t hasuform=0;
    static int *cnt;
    int temp = 0;
    Miscellaneous *miscell = (Miscellaneous *) emalloc(sizeof(Miscellaneous));
    int *tl_yychar = (int *) emalloc(sizeof(int));
    miscell->dp_taliro_param.LTL = 1;
    miscell->dp_taliro_param.ConOnSamples = 0;
    miscell->dp_taliro_param.SysDim = 0;
    miscell->dp_taliro_param.nSamp = 0;
    miscell->dp_taliro_param.nPred = 0;
    miscell->dp_taliro_param.true_nPred = 0;
    miscell->dp_taliro_param.tnLoc = 0;
    miscell->dp_taliro_param.nInp = 0;
    miscell->dp_taliro_param.nCLG = 0;
    miscell->tl_errs = 0;
    miscell->type_temp = 0;

    /* Reset cnt to 0:
        cnt is the counter that points to the next symbol in the formula
        to be processed. This is a static variable and it retains its
        value between Matlab calls to mx_dp_taliro. */
    cnt = &temp;

    /* Other initializations */
    miscell->dp_taliro_param.nInp = nrhs;
    par_on = false;
    initial_of_par = false;
    npred = 0;
    npar= 0;

    /* Make sure the I/O are in the right form */
    if(nrhs < 3)
        mexErrMsgTxt("mx_dp_taliro: At least 3 inputs are required.");
    else if(nlhs > 1)
      mexErrMsgTxt("mx_dp_taliro: Too many output arguments.");
    else if(nrhs > 8)
      mexErrMsgTxt("mx_dp_taliro: Too many input arguments.");
    else if(!mxIsChar(prhs[0]))
      mexErrMsgTxt("mx_dp_taliro: 1st input must be a string with TL formula.");
    else if(!mxIsStruct(prhs[1]))
      mexErrMsgTxt("mx_dp_taliro: 2nd input must be a structure (predicate map).");
    else if(!mxIsDouble(prhs[2]))
      mexErrMsgTxt("mx_dp_taliro: 3rd input must be a numerical array (State trace).");
    else if(nrhs>3 && !mxIsDouble(prhs[3]))
      mexErrMsgTxt("mx_dp_taliro: 4th input must be a numerical array (Time stamps).");
    else if(nrhs>5 && !mxIsDouble(prhs[4]))
      mexErrMsgTxt("mx_dp_taliro: 5th input must be a numerical array (Location trace).");
    else if(nrhs>5 && !(mxIsDouble(prhs[5])||mxIsCell(prhs[5])))
      mexErrMsgTxt("mx_dp_taliro: 6th input must be a numerical array \n (Minimum path distance to each control location for each predicate).");
    else if(nrhs>7 && !(mxIsCell(prhs[6])))
      mexErrMsgTxt("mx_dp_taliro: 7th input must be a cell array (Adjacency list).");
    else if(nrhs>7 && !(mxIsStruct(prhs[7])||mxIsCell(prhs[7])))
      mexErrMsgTxt("mx_dp_taliro: 8th input must be a structure (guard map).");

    if(nlhs > 1)
        mexErrMsgTxt("Too many output arguments.");
    plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);

    /* Process inputs */

    /* Get the formula */
    ndim = mxGetNumberOfDimensions(prhs[0]);
    dims = mxGetDimensions(prhs[0]);
    buflen = dims[1]*sizeof(mxChar)+1;
    if (buflen >= BUFF_LEN)
    {
      mexPrintf("%s%d%s\n", "The formula must be less than ", BUFF_LEN," characters.");
      mexErrMsgTxt("mx_dp_taliro: Formula too long.");
    }
    status = mxGetString(prhs[0], uform, buflen);
    hasuform = strlen(uform);
    for (iii=0; iii<hasuform; iii++)
    {
        if (uform[iii] == '\t' || uform[iii] == '\"' || uform[iii] == '\n')
            uform[iii] = ' ';
    }

    /* Get state trace */
    ndim = mxGetNumberOfDimensions(prhs[2]);
    if (ndim>2)
        mexErrMsgTxt("mx_dp_taliro: The state trace is not in proper form!");
    dims = mxGetDimensions(prhs[2]);
    miscell->dp_taliro_param.nSamp = dims[0];
    miscell->dp_taliro_param.SysDim = dims[1];
    XTrace = mxGetPr(prhs[2]);

    /* Get time stamps */
    if (nrhs>3)
    {
        ndim = mxGetNumberOfDimensions(prhs[3]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The time stamp sequence is not in proper form!");
        dims = mxGetDimensions(prhs[3]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the time stamp sequence and the state trace do not match!");
        TStamps = mxGetPr(prhs[3]);
    }

    /* Get location trace and location graph */
    if (nrhs>4)
    {
        ndim = mxGetNumberOfDimensions(prhs[4]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The location trace is not in proper form!");
        dims = mxGetDimensions(prhs[4]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the location trace and the state trace do not match!");
        LTrace = mxGetPr(prhs[4]);

        /* For Multiple H.A.s is added  */
        if(nrhs>5 && (mxIsCell(prhs[5]))){/*  For Multiple H.A.s */
            is_Multi_HA=1;
        miscell->dp_taliro_param.nCLG = dims[1];
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
            {
                mexErrMsgTxt("mx_dp_taliro.c: !");
            }
            dims = mxGetDimensions(prhs[5]);
            if (dims[0]!=1)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be a column vector cell!");
            }
            if (dims[1]!=miscell->dp_taliro_param.nCLG)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be of the size of nCLG!");
            }
            distData.LDistNCLG = (double **)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(double*));
            miscell->dp_taliro_param.tnLocNCLG = (mwSize*)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(mwSize));
            for(kk=0; kk<miscell->dp_taliro_param.nCLG; kk++){
                tmp = mxGetCell(prhs[5],kk);
                dims = mxGetDimensions(tmp);
                miscell->dp_taliro_param.tnLocNCLG[kk] = dims[0];
                distData.LDistNCLG[kk]=mxGetPr(tmp);
            }
        }
        else if(nrhs>5) {/*  For Single H.A. */
            is_Multi_HA=0;
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
                mexErrMsgTxt("mx_dp_taliro: The minimum distance array is not in proper form!");
            dims = mxGetDimensions(prhs[5]);
            miscell->dp_taliro_param.tnLoc = dims[0];
            distData.LDist = mxGetPr(prhs[5]);
        }

    }

}
</code>```

答:
In your code, you are using a lot of functions and data types, provided by the MEX API. Therefore, if you want to produce "normal" C-Code you will have to completly refactor your code.

But one possible solution might be to compile your source code outside MATLAB IDE, by gcc or any other compiler. In this case you will have to include all necessary header files and link against all libraries you need.
Follwo the link to find a pretty good documentation from Mathworks:

https://de.mathworks.com/matlabcentral/answers/377799-compiling-mex-files-without-the-mex-command

Another way for creating C Code from Matlab Scipts/Functions is to use MATLAB Coder:

https://de.mathworks.com/products/matlab-coder.html

Hope this is helpful.

Title: Mex type C file to normal C file

Body:
I have a c file written using mex functions, run by Matlab using mex compiler Now I want to run those mex type .c files without Matlab environment. So, is there any way to convert mex type .c file to normal .c file ? Or any other options available for the above mentioned concern.
Thanks in advance....!

Here is the one mex type .c file for sample.

#include <stdlib.h>
#include "mex.h"
#include "matrix.h"
#include "distances.h"
#include "ltl2tree.h"
#include "param.h"

#define BUFF_LEN 4096

char * emalloc(size_t n)
{
    char *tmp;

    if (!(tmp = (char *) mxMalloc(n)))
        mexErrMsgTxt("mx_dp_taliro: not enough memory!");
    memset(tmp, 0, n);
    return tmp;
}

int tl_Getchar(int *cnt, size_t hasuform, char *uform)
{
    if (*cnt < hasuform)
        return uform[(*cnt)++];
    (*cnt)++;
    return -1;
}

void tl_UnGetchar(int *cnt)
{
    if (*cnt > 0) (*cnt)--;
}

#define Binop(a)        \
        fprintf(miscell->tl_out, "(");  \
        dump(n->lft, miscell);      \
        fprintf(miscell->tl_out, a);    \
        dump(n->rgt, miscell);      \
        fprintf(miscell->tl_out, ")")

static void sdump(Node *n, char *dumpbuf)
{
    switch (n->ntyp) {
    case PREDICATE: strcat(dumpbuf, n->sym->name);
            break;
    case U_OPER:    strcat(dumpbuf, "U");
            goto common2;
    case V_OPER:    strcat(dumpbuf, "V");
            goto common2;
    case OR:    strcat(dumpbuf, "|");
            goto common2;
    case AND:   strcat(dumpbuf, "&");
common2:        sdump(n->rgt,dumpbuf);
common1:        sdump(n->lft,dumpbuf);
            break;
    case NEXT:  strcat(dumpbuf, "X");
            goto common1;
    case NOT:   strcat(dumpbuf, "!");
            goto common1;
    case TRUE:  strcat(dumpbuf, "T");
            break;
    case FALSE: strcat(dumpbuf, "F");
            break;
    default:    strcat(dumpbuf, "?");
            break;
    }
}

Symbol *DoDump(Node *n, char *dumpbuf, Miscellaneous *miscell)
{
    if (!n) return ZS;

    if (n->ntyp == PREDICATE)
        return n->sym;

    dumpbuf[0] = '\0';
    sdump(n,dumpbuf);
    return tl_lookup(dumpbuf, miscell);
}

void dump(Node *n, Miscellaneous *miscell)
{
    if (!n) return;

    switch(n->ntyp) {
    case OR:    Binop(" || "); break;
    case AND:   Binop(" && "); break;
    case U_OPER:    Binop(" U ");  break;
    case V_OPER:    Binop(" V ");  break;
    case NEXT:
        fprintf(miscell->tl_out, "X");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case NOT:
        fprintf(miscell->tl_out, "!");
        fprintf(miscell->tl_out, " (");
        dump(n->lft, miscell);
        fprintf(miscell->tl_out, ")");
        break;
    case FALSE:
        fprintf(miscell->tl_out, "false");
        break;
    case TRUE:
        fprintf(miscell->tl_out, "true");
        break;
    case PREDICATE:
        fprintf(miscell->tl_out, "(%s)", n->sym->name);
        break;
    case -1:
        fprintf(miscell->tl_out, " D ");
        break;
    default:
        printf("Unknown token: ");
        tl_explain(n->ntyp);
        break;
    }
}

void tl_explain(int n)
{
    switch (n) {
    case ALWAYS:    printf("[]"); break;
    case EVENTUALLY: printf("<>"); break;
    case IMPLIES:   printf("->"); break;
    case EQUIV: printf("<->"); break;
    case PREDICATE: printf("predicate"); break;
    case OR:    printf("||"); break;
    case AND:   printf("&&"); break;
    case NOT:   printf("!"); break;
    case U_OPER:    printf("U"); break;
    case V_OPER:    printf("V"); break;
    case NEXT:  printf("X"); break;
    case TRUE:  printf("true"); break;
    case FALSE: printf("false"); break;
    case ';':   printf("end of formula"); break;
    default:    printf("%c", n); break;
    }
}

static void non_fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    int i;

    printf("TaLiRo: ");
    if (s2)
        printf(s1, s2);
    else
        printf(s1);
    if ((*tl_yychar) != -1 && (*tl_yychar) != 0)
    {   printf(", saw '");
        tl_explain((*tl_yychar));
        printf("'");
    }
    printf("\nTaLiRo: %s\n---------", uform);
    for (i = 0; i < (*cnt); i++)
        printf("-");
    printf("^\n");
    fflush(stdout);
    (miscell->tl_errs)++;
}

void
tl_yyerror(char *s1, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
    Fatal(s1, (char *) 0, cnt, uform, tl_yychar, miscell);
}

void
Fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
  non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
  tl_exit(0);
}

void fatal(char *s1, char *s2, int *cnt, char *uform, int *tl_yychar, Miscellaneous *miscell)
{
        non_fatal(s1, s2, cnt, uform, tl_yychar, miscell);
        tl_exit(0);
}

void put_uform(char *uform, Miscellaneous *miscell)
{
    fprintf(miscell->tl_out, "%s", uform);
}

void tl_exit(int i)
{
    mexErrMsgTxt("mx_dp_taliro: unexpected error, tl_exit executed.");
}

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    /* Variables needed to process the input */
    int status, pstatus;
    mwSize buflen, pbuflen;
    size_t NElems,NCells;
    mwSize ndimA, ndimb, ndimG, ndim, pdim,ndimP;
    const mwSize *dimsA, *dimsb, *dimsG, *dims, *pardims,*dimsP;
    mwIndex jstruct, iii, jjj, i1, j1, idx_j;
    mxArray *tmp,*tmp1,*tmp_cell;
    /* Variables needed for monitor */
    Node *node;
    double *XTrace, *TStamps, *LTrace;
    DistCompData distData;
    PMap *predMap;
    int ii,jj,kk,ll,objs,tempI;
    bool par_on;
    bool is_Multi_HA;
    bool initial_of_par;
    int npred, npar;

    static char uform[BUFF_LEN];
    static size_t hasuform=0;
    static int *cnt;
    int temp = 0;
    Miscellaneous *miscell = (Miscellaneous *) emalloc(sizeof(Miscellaneous));
    int *tl_yychar = (int *) emalloc(sizeof(int));
    miscell->dp_taliro_param.LTL = 1;
    miscell->dp_taliro_param.ConOnSamples = 0;
    miscell->dp_taliro_param.SysDim = 0;
    miscell->dp_taliro_param.nSamp = 0;
    miscell->dp_taliro_param.nPred = 0;
    miscell->dp_taliro_param.true_nPred = 0;
    miscell->dp_taliro_param.tnLoc = 0;
    miscell->dp_taliro_param.nInp = 0;
    miscell->dp_taliro_param.nCLG = 0;
    miscell->tl_errs = 0;
    miscell->type_temp = 0;

    /* Reset cnt to 0:
        cnt is the counter that points to the next symbol in the formula
        to be processed. This is a static variable and it retains its
        value between Matlab calls to mx_dp_taliro. */
    cnt = &temp;

    /* Other initializations */
    miscell->dp_taliro_param.nInp = nrhs;
    par_on = false;
    initial_of_par = false;
    npred = 0;
    npar= 0;

    /* Make sure the I/O are in the right form */
    if(nrhs < 3)
        mexErrMsgTxt("mx_dp_taliro: At least 3 inputs are required.");
    else if(nlhs > 1)
      mexErrMsgTxt("mx_dp_taliro: Too many output arguments.");
    else if(nrhs > 8)
      mexErrMsgTxt("mx_dp_taliro: Too many input arguments.");
    else if(!mxIsChar(prhs[0]))
      mexErrMsgTxt("mx_dp_taliro: 1st input must be a string with TL formula.");
    else if(!mxIsStruct(prhs[1]))
      mexErrMsgTxt("mx_dp_taliro: 2nd input must be a structure (predicate map).");
    else if(!mxIsDouble(prhs[2]))
      mexErrMsgTxt("mx_dp_taliro: 3rd input must be a numerical array (State trace).");
    else if(nrhs>3 && !mxIsDouble(prhs[3]))
      mexErrMsgTxt("mx_dp_taliro: 4th input must be a numerical array (Time stamps).");
    else if(nrhs>5 && !mxIsDouble(prhs[4]))
      mexErrMsgTxt("mx_dp_taliro: 5th input must be a numerical array (Location trace).");
    else if(nrhs>5 && !(mxIsDouble(prhs[5])||mxIsCell(prhs[5])))
      mexErrMsgTxt("mx_dp_taliro: 6th input must be a numerical array \n (Minimum path distance to each control location for each predicate).");
    else if(nrhs>7 && !(mxIsCell(prhs[6])))
      mexErrMsgTxt("mx_dp_taliro: 7th input must be a cell array (Adjacency list).");
    else if(nrhs>7 && !(mxIsStruct(prhs[7])||mxIsCell(prhs[7])))
      mexErrMsgTxt("mx_dp_taliro: 8th input must be a structure (guard map).");

    if(nlhs > 1)
        mexErrMsgTxt("Too many output arguments.");
    plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);

    /* Process inputs */

    /* Get the formula */
    ndim = mxGetNumberOfDimensions(prhs[0]);
    dims = mxGetDimensions(prhs[0]);
    buflen = dims[1]*sizeof(mxChar)+1;
    if (buflen >= BUFF_LEN)
    {
      mexPrintf("%s%d%s\n", "The formula must be less than ", BUFF_LEN," characters.");
      mexErrMsgTxt("mx_dp_taliro: Formula too long.");
    }
    status = mxGetString(prhs[0], uform, buflen);
    hasuform = strlen(uform);
    for (iii=0; iii<hasuform; iii++)
    {
        if (uform[iii] == '\t' || uform[iii] == '\"' || uform[iii] == '\n')
            uform[iii] = ' ';
    }

    /* Get state trace */
    ndim = mxGetNumberOfDimensions(prhs[2]);
    if (ndim>2)
        mexErrMsgTxt("mx_dp_taliro: The state trace is not in proper form!");
    dims = mxGetDimensions(prhs[2]);
    miscell->dp_taliro_param.nSamp = dims[0];
    miscell->dp_taliro_param.SysDim = dims[1];
    XTrace = mxGetPr(prhs[2]);

    /* Get time stamps */
    if (nrhs>3)
    {
        ndim = mxGetNumberOfDimensions(prhs[3]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The time stamp sequence is not in proper form!");
        dims = mxGetDimensions(prhs[3]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the time stamp sequence and the state trace do not match!");
        TStamps = mxGetPr(prhs[3]);
    }

    /* Get location trace and location graph */
    if (nrhs>4)
    {
        ndim = mxGetNumberOfDimensions(prhs[4]);
        if (ndim>2)
            mexErrMsgTxt("mx_dp_taliro: The location trace is not in proper form!");
        dims = mxGetDimensions(prhs[4]);
        if (miscell->dp_taliro_param.nSamp != dims[0])
            mexErrMsgTxt("mx_dp_taliro: The lengths of the location trace and the state trace do not match!");
        LTrace = mxGetPr(prhs[4]);

        /* For Multiple H.A.s is added  */
        if(nrhs>5 && (mxIsCell(prhs[5]))){/*  For Multiple H.A.s */
            is_Multi_HA=1;
        miscell->dp_taliro_param.nCLG = dims[1];
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
            {
                mexErrMsgTxt("mx_dp_taliro.c: !");
            }
            dims = mxGetDimensions(prhs[5]);
            if (dims[0]!=1)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be a column vector cell!");
            }
            if (dims[1]!=miscell->dp_taliro_param.nCLG)
            {
                mexErrMsgTxt("mx_dp_taliro: DMin is a cell, it must be of the size of nCLG!");
            }
            distData.LDistNCLG = (double **)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(double*));
            miscell->dp_taliro_param.tnLocNCLG = (mwSize*)emalloc((miscell->dp_taliro_param.nCLG)*sizeof(mwSize));
            for(kk=0; kk<miscell->dp_taliro_param.nCLG; kk++){
                tmp = mxGetCell(prhs[5],kk);
                dims = mxGetDimensions(tmp);
                miscell->dp_taliro_param.tnLocNCLG[kk] = dims[0];
                distData.LDistNCLG[kk]=mxGetPr(tmp);
            }
        }
        else if(nrhs>5) {/*  For Single H.A. */
            is_Multi_HA=0;
            ndim = mxGetNumberOfDimensions(prhs[5]);
            if (ndim>2)
                mexErrMsgTxt("mx_dp_taliro: The minimum distance array is not in proper form!");
            dims = mxGetDimensions(prhs[5]);
            miscell->dp_taliro_param.tnLoc = dims[0];
            distData.LDist = mxGetPr(prhs[5]);
        }

    }

}


来源: stackexchange

问:
Iteration Problem Facebook Bot / Transforming text file lines into an array
I'm trying to make a bot for Facebook. I have to log in to facebook with a username and password (found in identifiants.txt). After, I do actions on facebook, I log out and I have to log in again with other username and password.
Each line corresponds to a username and the next line corresponds to a password. So the next line is still a username. What I've tried to do is to transform the text file into a table of usernames. So the usernames have an odd box and the passwords have an even box. So here's what I tried to do:

```<code>nombre_listeux = 2

class Facebook(scrapy.Spider):

def __init__(self):
    self.driver = webdriver
    self.url = 'https://www.facebook.com/'
    webdriver.maximize_window()

def login(self,nombre_listeux):

    f=open("/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/identifiants.txt","r")

    for i in range(0,nombre_listeux):
        self.driver.get(self.url)
        lines=f.readlines()
        print(i)
        username=lines[2*i]
        password=lines[2*i+1]
        print(username)
        print(password)
        user = self.driver.find_element_by_xpath("//input[@name=\"email\"]")
        user.send_keys(username)
        pwd = self.driver.find_element_by_xpath("//input[@name=\"pass\"]")
        pwd.send_keys(password)
        sleep(medium_time)
        Facebook_Bot.change_pic(nombre_listeux)
        Facebook_Bot.log_out()

    f.close()
</code>```

The program works for the first pair of identifiers and for i=0, but when i=1, this is what the program returns:

```<code>Traceback (most recent call last):
File "/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/facebook.py", line 68, in <module>
Facebook_Bot.login(nombre_listeux)
File "/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/facebook.py", line 29, in login
username=lines[2*i]
IndexError: list index out of range
</code>```

Identifiants.txt is also like that :

```<code>dermacareprofr@gmail.com
password1
legrandpatrick410@gmail.com
password2
</code>```

It would be awesome if you could help me, thanks !

答:
try this to get data from your text file</p>

```<code>nombre_listeux = 2
with open('/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/identifiants.txt', 'r') as f:
    lines = f.readlines()

for i in range(0, nombre_listeux):
    username = lines[2 * i].strip()
    password = lines[2 * i + 1].strip()
    print(username)
    print(password)
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to make a bot for Facebook. I have to log in to facebook with a username and password (found in identifiants.txt). After, I do actions on facebook, I log out and I have to log in again with other username and password.
Each line corresponds to a username and the next line corresponds to a password. So the next line is still a username. What I've tried to do is to transform the text file into a table of usernames. So the usernames have an odd box and the passwords have an even box. So here's what I tried to do:

nombre_listeux = 2

class Facebook(scrapy.Spider):

def __init__(self):
    self.driver = webdriver
    self.url = 'https://www.facebook.com/'
    webdriver.maximize_window()

def login(self,nombre_listeux):

    f=open("/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/identifiants.txt","r")

    for i in range(0,nombre_listeux):
        self.driver.get(self.url)
        lines=f.readlines()
        print(i)
        username=lines[2*i]
        password=lines[2*i+1]
        print(username)
        print(password)
        user = self.driver.find_element_by_xpath("//input[@name=\"email\"]")
        user.send_keys(username)
        pwd = self.driver.find_element_by_xpath("//input[@name=\"pass\"]")
        pwd.send_keys(password)
        sleep(medium_time)
        Facebook_Bot.change_pic(nombre_listeux)
        Facebook_Bot.log_out()

    f.close()

The program works for the first pair of identifiers and for i=0, but when i=1, this is what the program returns:

Traceback (most recent call last):
File "/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/facebook.py", line 68, in <module>
Facebook_Bot.login(nombre_listeux)
File "/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/facebook.py", line 29, in login
username=lines[2*i]
IndexError: list index out of range

Identifiants.txt is also like that :

dermacareprofr@gmail.com
password1
legrandpatrick410@gmail.com
password2

It would be awesome if you could help me, thanks !

Body:
try this to get data from your text file

nombre_listeux = 2
with open('/Users/anthonyjacquelin/Desktop/Dev Projects/Bot Insta /Facebook Bot/identifiants.txt', 'r') as f:
    lines = f.readlines()

for i in range(0, nombre_listeux):
    username = lines[2 * i].strip()
    password = lines[2 * i + 1].strip()
    print(username)
    print(password)


问:
Showing trailing spaces in vim
I've set the following options in .vimrc

```<code>set listchars=tab:▸\ ,trail:·
set list
</code>```

And expected to see dots in those places where spaces are used for tabulation in the code (I use spaces, not tabs).
However, the result is different:

Could you please recommend how to reach the desired result? Thanks!

答:
To highlight trailing whitespace characters:

:set hlsearch, then

/\s\+$

ContentLicense: CC BY-SA 3.0

Title: Showing trailing spaces in vim

Body:
I've set the following options in .vimrc

set listchars=tab:▸\ ,trail:·
set list

And expected to see dots in those places where spaces are used for tabulation in the code (I use spaces, not tabs).
However, the result is different:

Could you please recommend how to reach the desired result? Thanks!


问:
Multi-Factor Authentication with Spring Boot 2 and Spring Security 5
I want to add multi-factor authentication with TOTP soft tokens to an Angular & Spring application, while keeping everything as close as possible to the defaults of Spring Boot Security Starter.

The token-validation happens locally (with the aerogear-otp-java library), no third party API provider.

Setting up tokens for a user works, but validating them by leveraging Spring Security Authentication Manager/Providers does not.

TL;DR

What is the official way to integrate an additional AuthenticationProvider into a Spring Boot Security Starter configured system?

What are recommended ways to prevent replay attacks?

Long Version

The API has an endpoint /auth/token from which the frontend can get a JWT token by providing username and password. The response also includes an authentication-status, which can be either AUTHENTICATED or PRE_AUTHENTICATED_MFA_REQUIRED.

If the user requires MFA, the token is issued with a single granted authority of PRE_AUTHENTICATED_MFA_REQUIRED and an expiration-time of 5 minutes. This allows the user to access the endpoint /auth/mfa-token where they can provide the TOTP code from their Authenticator app and get the fully authenticated token to access the site.

Provider and Token

I have created my custom MfaAuthenticationProvider which implements AuthenticationProvider:

```<code>    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // validate the OTP code
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return OneTimePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }
</code>```

And a OneTimePasswordAuthenticationToken which extends AbstractAuthenticationToken to hold the username (taken from the signed JWT) and the OTP code.

Config

I have my custom WebSecurityConfigurerAdapter, where I add my custom AuthenticationProvider via http.authenticationProvider(). Accoring to the JavaDoc, this seems to be the right place:

Allows adding an additional AuthenticationProvider to be used

The relevant parts of my SecurityConfig looks like this.

```<code>    @Configuration
    @EnableWebSecurity
    @EnableJpaAuditing(auditorAwareRef = "appSecurityAuditorAware")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        private final TokenProvider tokenProvider;

        public SecurityConfig(TokenProvider tokenProvider) {
            this.tokenProvider = tokenProvider;
        }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authenticationProvider(new MfaAuthenticationProvider());

        http.authorizeRequests()
            // Public endpoints, HTML, Assets, Error Pages and Login
            .antMatchers("/", "favicon.ico", "/asset/**", "/pages/**", "/api/auth/token").permitAll()

            // MFA auth endpoint
            .antMatchers("/api/auth/mfa-token").hasAuthority(ROLE_PRE_AUTH_MFA_REQUIRED)

            // much more config
</code>```

Controller

The AuthController has the AuthenticationManagerBuilder injected and is pulling it all together.

```<code>@RestController
@RequestMapping(AUTH)
public class AuthController {
    private final TokenProvider tokenProvider;
    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    public AuthController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
        this.tokenProvider = tokenProvider;
        this.authenticationManagerBuilder = authenticationManagerBuilder;
    }

    @PostMapping("/mfa-token")
    public ResponseEntity<Token> mfaToken(@Valid @RequestBody OneTimePassword oneTimePassword) {
        var username = SecurityUtils.getCurrentUserLogin().orElse("");
        var authenticationToken = new OneTimePasswordAuthenticationToken(username, oneTimePassword.getCode());
        var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);

        // rest of class
</code>```

However, posting against /auth/mfa-token leads to this error:

```<code>"error": "Forbidden",
"message": "Access Denied",
"trace": "org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for de.....OneTimePasswordAuthenticationToken
</code>```

Why does Spring Security not pick up my Authentication Provider? Debugging the controller shows me that DaoAuthenticationProvider is the only Authentication Provider in AuthenticationProviderManager.

If I expose my MfaAuthenticationProvider as bean, it is the only Provider that is registered, so I get the opposite:

```<code>No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken.
</code>```

So, how do I get both?

My Question

What is the recommended way to integrate an additional AuthenticationProvider into a Spring Boot Security Starter configured system, so that I get both, the DaoAuthenticationProvider and my own custom MfaAuthenticationProvider? I want to keep the defaults of Spring Boot Scurity Starter and have my own Provider additionally.

Prevention of Replay Attack

I know that the OTP algorithm does not by itself protect against replay attacks within the time slice in which the code is valid; RFC 6238 makes this clear

The verifier MUST NOT accept the second attempt of the OTP after the successful validation has been issued for the first OTP, which ensures one-time only use of an OTP.

I was wondering if there is a recommended way to implement protection. Since the OTP tokens are time based I am thinking of storing the last successful login on the user's model and making sure there is only one successful login per 30 seconds time slice. This of course means synchronization on the user model. Any better approaches?

Thank you.

--

PS: since this is a question about security I am looking for an answer drawing from credible and/or official sources. Thank you.

答:
To answer my own question, this is how I implemented it, after further research.

I have a provider as a pojo that implements AuthenticationProvider. It's deliberately not a Bean/Component. Otherwise Spring would register it as the only Provider.

```<code>public class MfaAuthenticationProvider implements AuthenticationProvider {
    private final AccountService accountService;

    @Override
    public Authentication authenticate(Authentication authentication) {
        // here be code
        }
</code>```

In my SecurityConfig, I let Spring autowire the AuthenticationManagerBuilder and manually inject my MfaAuthenticationProvider

```<code>@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
       private final AuthenticationManagerBuilder authenticationManagerBuilder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // other code
        authenticationManagerBuilder.authenticationProvider(getMfaAuthenticationProvider());
        // more code
}

// package private for testing purposes.
MfaAuthenticationProvider getMfaAuthenticationProvider() {
    return new MfaAuthenticationProvider(accountService);
}
</code>```

After standard authentication, if the user has MFA enabled, they are pre authenticated with a granted authority of PRE_AUTHENTICATED_MFA_REQUIRED. This allows them to access a single endpoint, /auth/mfa-token.
This endpoint takes the username from the valid JWT and the provided TOTP and sends it to the authenticate() method of the authenticationManagerBuilder, which chooses the MfaAuthenticationProvider as it can handle OneTimePasswordAuthenticationToken.

```<code>    var authenticationToken = new OneTimePasswordAuthenticationToken(usernameFromJwt, providedOtp);
    var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
</code>```

Body:
I want to add multi-factor authentication with TOTP soft tokens to an Angular & Spring application, while keeping everything as close as possible to the defaults of Spring Boot Security Starter.

The token-validation happens locally (with the aerogear-otp-java library), no third party API provider.

Setting up tokens for a user works, but validating them by leveraging Spring Security Authentication Manager/Providers does not.

TL;DR

What is the official way to integrate an additional AuthenticationProvider into a Spring Boot Security Starter configured system?

What are recommended ways to prevent replay attacks?

Long Version

The API has an endpoint /auth/token from which the frontend can get a JWT token by providing username and password. The response also includes an authentication-status, which can be either AUTHENTICATED or PRE_AUTHENTICATED_MFA_REQUIRED.

If the user requires MFA, the token is issued with a single granted authority of PRE_AUTHENTICATED_MFA_REQUIRED and an expiration-time of 5 minutes. This allows the user to access the endpoint /auth/mfa-token where they can provide the TOTP code from their Authenticator app and get the fully authenticated token to access the site.

Provider and Token

I have created my custom MfaAuthenticationProvider which implements AuthenticationProvider:

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // validate the OTP code
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return OneTimePasswordAuthenticationToken.class.isAssignableFrom(authentication);
    }

And a OneTimePasswordAuthenticationToken which extends AbstractAuthenticationToken to hold the username (taken from the signed JWT) and the OTP code.

Config

I have my custom WebSecurityConfigurerAdapter, where I add my custom AuthenticationProvider via http.authenticationProvider(). Accoring to the JavaDoc, this seems to be the right place:

Allows adding an additional AuthenticationProvider to be used

The relevant parts of my SecurityConfig looks like this.

    @Configuration
    @EnableWebSecurity
    @EnableJpaAuditing(auditorAwareRef = "appSecurityAuditorAware")
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        private final TokenProvider tokenProvider;

        public SecurityConfig(TokenProvider tokenProvider) {
            this.tokenProvider = tokenProvider;
        }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authenticationProvider(new MfaAuthenticationProvider());

        http.authorizeRequests()
            // Public endpoints, HTML, Assets, Error Pages and Login
            .antMatchers("/", "favicon.ico", "/asset/**", "/pages/**", "/api/auth/token").permitAll()

            // MFA auth endpoint
            .antMatchers("/api/auth/mfa-token").hasAuthority(ROLE_PRE_AUTH_MFA_REQUIRED)

            // much more config

Controller

The AuthController has the AuthenticationManagerBuilder injected and is pulling it all together.

@RestController
@RequestMapping(AUTH)
public class AuthController {
    private final TokenProvider tokenProvider;
    private final AuthenticationManagerBuilder authenticationManagerBuilder;

    public AuthController(TokenProvider tokenProvider, AuthenticationManagerBuilder authenticationManagerBuilder) {
        this.tokenProvider = tokenProvider;
        this.authenticationManagerBuilder = authenticationManagerBuilder;
    }

    @PostMapping("/mfa-token")
    public ResponseEntity<Token> mfaToken(@Valid @RequestBody OneTimePassword oneTimePassword) {
        var username = SecurityUtils.getCurrentUserLogin().orElse("");
        var authenticationToken = new OneTimePasswordAuthenticationToken(username, oneTimePassword.getCode());
        var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);

        // rest of class

However, posting against /auth/mfa-token leads to this error:

"error": "Forbidden",
"message": "Access Denied",
"trace": "org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for de.....OneTimePasswordAuthenticationToken

Why does Spring Security not pick up my Authentication Provider? Debugging the controller shows me that DaoAuthenticationProvider is the only Authentication Provider in AuthenticationProviderManager.

If I expose my MfaAuthenticationProvider as bean, it is the only Provider that is registered, so I get the opposite:

No AuthenticationProvider found for org.springframework.security.authentication.UsernamePasswordAuthenticationToken.

So, how do I get both?

My Question

What is the recommended way to integrate an additional AuthenticationProvider into a Spring Boot Security Starter configured system, so that I get both, the DaoAuthenticationProvider and my own custom MfaAuthenticationProvider? I want to keep the defaults of Spring Boot Scurity Starter and have my own Provider additionally.

Prevention of Replay Attack

I know that the OTP algorithm does not by itself protect against replay attacks within the time slice in which the code is valid; RFC 6238 makes this clear

The verifier MUST NOT accept the second attempt of the OTP after the successful validation has been issued for the first OTP, which ensures one-time only use of an OTP.

I was wondering if there is a recommended way to implement protection. Since the OTP tokens are time based I am thinking of storing the last successful login on the user's model and making sure there is only one successful login per 30 seconds time slice. This of course means synchronization on the user model. Any better approaches?

Thank you.

--

PS: since this is a question about security I am looking for an answer drawing from credible and/or official sources. Thank you.

Body:
To answer my own question, this is how I implemented it, after further research.

I have a provider as a pojo that implements AuthenticationProvider. It's deliberately not a Bean/Component. Otherwise Spring would register it as the only Provider.

public class MfaAuthenticationProvider implements AuthenticationProvider {
    private final AccountService accountService;

    @Override
    public Authentication authenticate(Authentication authentication) {
        // here be code
        }

In my SecurityConfig, I let Spring autowire the AuthenticationManagerBuilder and manually inject my MfaAuthenticationProvider

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
       private final AuthenticationManagerBuilder authenticationManagerBuilder;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // other code
        authenticationManagerBuilder.authenticationProvider(getMfaAuthenticationProvider());
        // more code
}

// package private for testing purposes.
MfaAuthenticationProvider getMfaAuthenticationProvider() {
    return new MfaAuthenticationProvider(accountService);
}

After standard authentication, if the user has MFA enabled, they are pre authenticated with a granted authority of PRE_AUTHENTICATED_MFA_REQUIRED. This allows them to access a single endpoint, /auth/mfa-token.
This endpoint takes the username from the valid JWT and the provided TOTP and sends it to the authenticate() method of the authenticationManagerBuilder, which chooses the MfaAuthenticationProvider as it can handle OneTimePasswordAuthenticationToken.

    var authenticationToken = new OneTimePasswordAuthenticationToken(usernameFromJwt, providedOtp);
    var authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);


问:
How do I dismiss an autocomplete suggestion in Atom?
When I'm writing Docstrings in Python3, I'm ending all of my sentences with periods and I see an autocomplete suggestion like this:

In this case it wants to replace the string "wager." with "wagerself."

If I press Enter or Tab the string replaces. I've messed around with all the logical buttons (Including adding an extra space which doesn't work), and nothing will allow me on my merry way to a newline.

This problem occurs both with and without the autocomplete-python package installed.

I do want to use auto-complete when I type a dot after an object, just not in the comments.

Is there a way to either:

Dismiss the autocomplete suggestion as they come up.

-- or --

Change the autocomplete to be aware of the context, i.e. not autocomplete dots when I'm in a string/comment.

答: I'm using Atom 1.44.0 on Windows and have found that shift + enter works to dismiss an autocomplete suggestion. No luck with tab on this platform though.


问:
Store file to MinIO from browser form (Angular2)
I'm doing a prototype of an Angular8 app that can upload files from a form to MinIO.
Here is the form :

upload-form.component.html :

```<code><input class="form-control" type="file" (change)="onFileChanged($event)" required />
<button mat-flat-button color="primary" class="flex__item--middle u-1/3 u-mt+" type="sumbit">
    Upload
</button>
</code>```

Here is the ts :

upload-form.component.ts

onFileChanged(event) {
    let reader = new FileReader();
    if(event.target.files && event.target.files.length) {
      const [file] = event.target.files;

      this.uploadForm.patchValue({
        fileName: file.name,
        fileSize: file.size
      });

      reader.onload = () => {
        this.uploadForm.patchValue({
          fileStream: reader.result
        });
        reader.readAsDataURL(file);
      };
    }
  }

  // ... here is the service call
  // this.uploadService.sendMinIO(form_values).then(...```

and here is the API call to MinIO putObject function :

minioClient.putObject(bucketName, fileName, fileStream, fileSize, function (err, etag).

The Angular service is not relevant since it just pass the data unchanged.

With this method, the file is created and stored but the content is the base64 encoded string I got from the FileReader. I tried several method in order to get the file content.

MinIO wait for a "stream" (Readable Stream) so i tried to use Buffer (new Buffer(string, "base64")...., or streamifier and other tricks but I think there is something basic I don't understand here.

What do I have to do to store the data coming from Angular into the initial file in MinIO ?

答:
You should remove the headers added in the base64 encoded string by readAsDataURL (check the note in the API docs) in the server. For example:

```<code>const { file } = req.body; // the base64 encoded string
const buffer = Buffer.from(file.replace(/^data:image\/\w+;base64,/, ""),'base64');
</code>```

if the file is an image (png, jpeg) or:

```<code>const buffer = Buffer.from(file.replace(/^data:application\/pdf;base64,/, ""),'base64');
</code>```

if the file is a pdf document and then add it in the bucket:

```<code>minioClient.putObject('bucket', 'filename', buffer)
</code>```

Body:
I'm doing a prototype of an Angular8 app that can upload files from a form to MinIO.
Here is the form :

upload-form.component.html :

<input class="form-control" type="file" (change)="onFileChanged($event)" required />
<button mat-flat-button color="primary" class="flex__item--middle u-1/3 u-mt+" type="sumbit">
    Upload
</button>

Here is the ts :

upload-form.component.ts

onFileChanged(event) {
    let reader = new FileReader();
    if(event.target.files && event.target.files.length) {
      const [file] = event.target.files;

      this.uploadForm.patchValue({
        fileName: file.name,
        fileSize: file.size
      });

      reader.onload = () => {
        this.uploadForm.patchValue({
          fileStream: reader.result
        });
        reader.readAsDataURL(file);
      };
    }
  }

  // ... here is the service call
  // this.uploadService.sendMinIO(form_values).then(...

and here is the API call to MinIO putObject function :

minioClient.putObject(bucketName, fileName, fileStream, fileSize, function (err, etag).

The Angular service is not relevant since it just pass the data unchanged.

With this method, the file is created and stored but the content is the base64 encoded string I got from the FileReader. I tried several method in order to get the file content.

MinIO wait for a "stream" (Readable Stream) so i tried to use Buffer (new Buffer(string, "base64")...., or streamifier and other tricks but I think there is something basic I don't understand here.

What do I have to do to store the data coming from Angular into the initial file in MinIO ?

Body:
You should remove the headers added in the base64 encoded string by readAsDataURL (check the note in the API docs) in the server. For example:

const { file } = req.body; // the base64 encoded string
const buffer = Buffer.from(file.replace(/^data:image\/\w+;base64,/, ""),'base64');

if the file is an image (png, jpeg) or:

const buffer = Buffer.from(file.replace(/^data:application\/pdf;base64,/, ""),'base64');

if the file is a pdf document and then add it in the bucket:

minioClient.putObject('bucket', 'filename', buffer)


问:
Rendered.enabled : NullReferenceException: Object reference not set to an instance of an object
So I am trying to see when my Renderer is deactivated so it activates so it ends the game, but the error in the title appears. Would appreciate some help! The error appears in the if statement if (Rendere.enabled==true) PS.(i know I can take the ==true out but it was to make sure).</p>

```<code>private bool lost;
private MeshRenderer Rendere;

Void Start(){
    Rendere = gameObject.GetComponent<MeshRenderer>();
    lost = false;
    Rendere.enabled = true;
}

void Update()
    {
        if (timer < Time.time)
        {
            if (Rendere.enabled == true){
                Debug.Log("You lost");
                lost = true;
            }
    }
     }

   private void OnMouseDown()
    {
        Rendere.enabled = false;
    }
</code>```

答: Found the error. It seems that only some of my cube objects were following the prefab. If you get this error make sure that they are following the main prefab or do it like me and delete all the same objects in the game and put them from the prefab again. Thanks for all the suggestions! </p>

Body:
So I am trying to see when my Renderer is deactivated so it activates so it ends the game, but the error in the title appears. Would appreciate some help! The error appears in the if statement if (Rendere.enabled==true) PS.(i know I can take the ==true out but it was to make sure).

private bool lost;
private MeshRenderer Rendere;

Void Start(){
    Rendere = gameObject.GetComponent<MeshRenderer>();
    lost = false;
    Rendere.enabled = true;
}

void Update()
    {
        if (timer < Time.time)
        {
            if (Rendere.enabled == true){
                Debug.Log("You lost");
                lost = true;
            }
    }
     }

   private void OnMouseDown()
    {
        Rendere.enabled = false;
    }


问:
How do I divide a record according to the different types?
I have this query

```<code>Declare @TotalThreats int;
Declare @TotalThreats_M int;
Declare @TotalThreats_H int;
Declare @TotalThreats_L int;
(Select count(E.EnggDataID) as 'Total Threats', E.Area from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID  group by E.Area)
(Select count(E.EnggDataID) as 'Total Threats M',E.Area from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='M' group by E.Area)
(Select count(E.EnggDataID) as 'Total Threats H',E.Area  from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='H' group by E.Area )
(Select count(E.EnggDataID) as 'Total Threats L',E.Area  from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='L' group by E.Area)

--Select @TotalThreats,@TotalThreats_M,@TotalThreats_H,@TotalThreats_L
</code>```

It shows Total Threats for each area.

But each area has 3 types of overall risk i.e. H, M, L, MH. (Name of the columns is RiskOverall)

Now my query is ok to show TotalThreats according to Area but i also want to see different total H,M,L, MH.

For Example. Output should be like this

```<code>TotalThreats     Area   H   M   L   MH

   10             A     1   5   3   1
</code>```

答:
Use conditional aggregation:</p>

```<code>select E.Area, count(*) as TotalThreats,
       sum(case when R.RiskOverall = 'H' then 1 else 0 end) as risk_h,
       sum(case when R.RiskOverall = 'M' then 1 else 0 end) as risk_m,
       sum(case when R.RiskOverall = 'L' then 1 else 0 end) as risk_l,
       sum(case when R.RiskOverall in ('H', 'M', 'L') then 1 else 0 end) as risk_all
from EngineeringData E join
     RBIResults R
     on R.EnggDataID = E.EnggDataID
group by E.Area;
</code>```

Body:
I have this query

Declare @TotalThreats int;
Declare @TotalThreats_M int;
Declare @TotalThreats_H int;
Declare @TotalThreats_L int;
(Select count(E.EnggDataID) as 'Total Threats', E.Area from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID  group by E.Area)
(Select count(E.EnggDataID) as 'Total Threats M',E.Area from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='M' group by E.Area)
(Select count(E.EnggDataID) as 'Total Threats H',E.Area  from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='H' group by E.Area )
(Select count(E.EnggDataID) as 'Total Threats L',E.Area  from EngineeringData E inner join RBIResults R on R.EnggDataID=E.EnggDataID where R.RiskOverall='L' group by E.Area)

--Select @TotalThreats,@TotalThreats_M,@TotalThreats_H,@TotalThreats_L

It shows Total Threats for each area.

But each area has 3 types of overall risk i.e. H, M, L, MH. (Name of the columns is RiskOverall)

Now my query is ok to show TotalThreats according to Area but i also want to see different total H,M,L, MH.

For Example. Output should be like this

TotalThreats     Area   H   M   L   MH

   10             A     1   5   3   1

Body:
Use conditional aggregation:

select E.Area, count(*) as TotalThreats,
       sum(case when R.RiskOverall = 'H' then 1 else 0 end) as risk_h,
       sum(case when R.RiskOverall = 'M' then 1 else 0 end) as risk_m,
       sum(case when R.RiskOverall = 'L' then 1 else 0 end) as risk_l,
       sum(case when R.RiskOverall in ('H', 'M', 'L') then 1 else 0 end) as risk_all
from EngineeringData E join
     RBIResults R
     on R.EnggDataID = E.EnggDataID
group by E.Area;


问:
What is the swift way of converting this string into PGN notation?
I have the following string

```<code>let a:String = "r0bqkb0r/pppppppp/00n00n00/00000000/000P0000/0000B000/PPP0PPPP/RN0QKBNR/"
</code>```

and want to convert this to PGN notation so the final result should be

```<code>result = "r1bqkb1r/pppppppp/2n2n2/8/3P4/4B3/PPP1PPPP/RN1QKBNR/"
</code>```

The PGN notation converts the zeros to counts found.  Normally in python, I would just use

import chess.pgn

Before deep diving into python library, is there is a succinct and 'Swift' way to do this?

答:
There doesn't exist any direct method to get the pgn notation String. You can use a forEach(_:) instead, i.e.

```<code>let a = "r0bqkb0r/pppppppp/00n00n00/00000000/000P0000/0000B000/PPP0PPPP/RN0QKBNR/"
var result = ""
var count = 0
a.forEach {
    if $0 == "0" {
        count += 1
    } else {
        if count != 0 {
            result.append("\(count)")
            count = 0
        }
        result.append($0)
    }
}
print(result) //r1bqkb1r/pppppppp/2n2n2/8/3P4/4B3/PPP1PPPP/RN1QKBNR/
</code>```

Body:
I have the following string

let a:String = "r0bqkb0r/pppppppp/00n00n00/00000000/000P0000/0000B000/PPP0PPPP/RN0QKBNR/"

and want to convert this to PGN notation so the final result should be

result = "r1bqkb1r/pppppppp/2n2n2/8/3P4/4B3/PPP1PPPP/RN1QKBNR/"

The PGN notation converts the zeros to counts found.  Normally in python, I would just use

import chess.pgn

Before deep diving into python library, is there is a succinct and 'Swift' way to do this?

Body:
There doesn't exist any direct method to get the pgn notation String. You can use a forEach(_:) instead, i.e.

let a = "r0bqkb0r/pppppppp/00n00n00/00000000/000P0000/0000B000/PPP0PPPP/RN0QKBNR/"
var result = ""
var count = 0
a.forEach {
    if $0 == "0" {
        count += 1
    } else {
        if count != 0 {
            result.append("\(count)")
            count = 0
        }
        result.append($0)
    }
}
print(result) //r1bqkb1r/pppppppp/2n2n2/8/3P4/4B3/PPP1PPPP/RN1QKBNR/


问:
How can I check what value is assigned to what label while using sklearns' LabelEncoder()?
I am transforming categorical data to numeric values for machine learning purposes.

To give an example, the buying price (= "buying" variable) of a car is categorized in: "vhigh, high, med, low".
To transform it into numeric values, I used:

```<code>le = preprocessing.LabelEncoder()
buying = le.fit_transform(list(data["buying"]))
</code>```

Is there a way to check how exactly Python transformed each of those labels into numeric value since this is done randomly (e.g. vhigh = 0, high = 2)?

答:
You can create an extra column in your dataframe to map the values:

```<code>mapping_df = data[['buying']].copy() #Create an extra dataframe which will be used to address only the encoded values
mapping_df['buying_encoded'] = le.fit_transform(data['buying'].values) #Using values is faster than using list
</code>```

Here's a full working example:

```<code>import pandas as pd
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
data = pd.DataFrame({'index':[0,1,2,3,4,5,6],
        'buying':['Luffy','Nami','Luffy','Franky','Sanji','Zoro','Luffy']})
data['buying_encoded'] = le.fit_transform(data['buying'].values)
data = data.drop_duplicates('buying').set_index('index')
print(data)
</code>```

Output:

```<code>       buying  buying_encoded
index
0       Luffy               1
1        Nami               2
3      Franky               0
4       Sanji               3
5        Zoro               4
</code>```

Body:
I am transforming categorical data to numeric values for machine learning purposes.

To give an example, the buying price (= "buying" variable) of a car is categorized in: "vhigh, high, med, low".
To transform it into numeric values, I used:

le = preprocessing.LabelEncoder()
buying = le.fit_transform(list(data["buying"]))

Is there a way to check how exactly Python transformed each of those labels into numeric value since this is done randomly (e.g. vhigh = 0, high = 2)?

Body:
You can create an extra column in your dataframe to map the values:

mapping_df = data[['buying']].copy() #Create an extra dataframe which will be used to address only the encoded values
mapping_df['buying_encoded'] = le.fit_transform(data['buying'].values) #Using values is faster than using list

Here's a full working example:

import pandas as pd
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
data = pd.DataFrame({'index':[0,1,2,3,4,5,6],
        'buying':['Luffy','Nami','Luffy','Franky','Sanji','Zoro','Luffy']})
data['buying_encoded'] = le.fit_transform(data['buying'].values)
data = data.drop_duplicates('buying').set_index('index')
print(data)

Output:

       buying  buying_encoded
index
0       Luffy               1
1        Nami               2
3      Franky               0
4       Sanji               3
5        Zoro               4


问:
WCF RIA Services simple question
I'm new to all this stuff, so a question is dumb. If I'll use WCF RIA Services in my app, does a user well need to install something special to launch my app?

Thank you in advance!

答:
RIA Services will be installed at the Server end.

For Silverlight clients, the user is required to install the Silverlight plugin.

A guide to deploy RIA Services is provided here

Hope that helps!

Title: WCF RIA Services simple question


问:
c++ move semantics when using pointers
How do I use the move assignment operator when working with raw pointers.

Is there any other way than doing something like:

```<code>void Function(T* dest)
{
    T* src = LoadT();
    (*dest) = std::move(*src);
    delete src;
}
</code>```

答:
Your move is fine. The object pointed to by src will be moved into the object pointed to by dest.

About your updated code example, the version with Function:

If your LoadT() returns a raw pointer to an object allocated with new, that does not get stored somewhere else and later deleted, you will have a memory leak.

When you std::move something, you move the contents of that object, the object itself remains alive, only "empty"/in whatever state you leave it after moving.

If you return a pointer to an object that is owned by someone else and will be cleaned up somehow beyond the code that's seen here, you could make that explicit by changing your pointers to references - that way you will explicitly specify that: a) the pointers are guaranteed to not be null; b) that there should be no worries about deleting the object you get from LoadT, since a reference can't have ownership of that object.

Title: c++ move semantics when using pointers

Body:
How do I use the move assignment operator when working with raw pointers.

Is there any other way than doing something like:

void Function(T* dest)
{
    T* src = LoadT();
    (*dest) = std::move(*src);
    delete src;
}


问:
Null or default comparison of generic argument in C#
I have a generic method defined like this:

```<code>public void MyMethod<T>(T myArgument)
</code>```

The first thing I want to do is check if the value of myArgument is the default value for that type, something like this:

```<code>if (myArgument == default(T))
</code>```

But this doesn't compile because I haven't guaranteed that T will implement the == operator.  So I switched the code to this:

```<code>if (myArgument.Equals(default(T)))
</code>```

Now this compiles, but will fail if myArgument is null, which is part of what I'm testing for.  I can add an explicit null check like this:

```<code>if (myArgument == null || myArgument.Equals(default(T)))
</code>```

Now this feels redundant to me.  ReSharper is even suggesting that I change the myArgument == null part into myArgument == default(T) which is where I started.  Is there a better way to solve this problem?

I need to support both references types and value types.

答:
Extension method based on accepted answer.

```<code>   public static bool IsDefault<T>(this T inObj)
   {
       return EqualityComparer<T>.Default.Equals(inObj, default);
   }
</code>```

Usage:

```<code>   private bool SomeMethod(){
       var tValue = GetMyObject<MyObjectType>();
       if (tValue == null || tValue.IsDefault()) return false;
   }
</code>```

Alternate with null to simplify:

```<code>   public static bool IsNullOrDefault<T>(this T inObj)
   {
       if (inObj == null) return true;
       return EqualityComparer<T>.Default.Equals(inObj, default);
   }
</code>```

Usage:

```<code>   private bool SomeMethod(){
       var tValue = GetMyObject<MyObjectType>();
       if (tValue.IsNullOrDefault()) return false;
   }
</code>```

OwnerDisplayName: Stefan Moser

Body:
I have a generic method defined like this:

public void MyMethod<T>(T myArgument)

The first thing I want to do is check if the value of myArgument is the default value for that type, something like this:

if (myArgument == default(T))

But this doesn't compile because I haven't guaranteed that T will implement the == operator.  So I switched the code to this:

if (myArgument.Equals(default(T)))

Now this compiles, but will fail if myArgument is null, which is part of what I'm testing for.  I can add an explicit null check like this:

if (myArgument == null || myArgument.Equals(default(T)))

Now this feels redundant to me.  ReSharper is even suggesting that I change the myArgument == null part into myArgument == default(T) which is where I started.  Is there a better way to solve this problem?

I need to support both references types and value types.

LastEditorDisplayName: Stefan Moser

Body:
Extension method based on accepted answer.

   public static bool IsDefault<T>(this T inObj)
   {
       return EqualityComparer<T>.Default.Equals(inObj, default);
   }

Usage:

   private bool SomeMethod(){
       var tValue = GetMyObject<MyObjectType>();
       if (tValue == null || tValue.IsDefault()) return false;
   }

Alternate with null to simplify:

   public static bool IsNullOrDefault<T>(this T inObj)
   {
       if (inObj == null) return true;
       return EqualityComparer<T>.Default.Equals(inObj, default);
   }

Usage:

   private bool SomeMethod(){
       var tValue = GetMyObject<MyObjectType>();
       if (tValue.IsNullOrDefault()) return false;
   }


问:
XY chart labels are exceeding the chart boundry
When I have some values in the XY chart, some column label locations' are exceeding the boundary of the chart, like in the image, how can I suppress that?

答: You can solve this by either increasing paddingRight of the whole chart or by setting axis.maxLabelPosition = 0.98 which would result last label to be hidden.


问:
How to create a preloader within a html select box using JQuery?
I have a select box with id Provice, whenever a Province is selected within this select box, the city select box populates with the cities within the selected provinces. Now that works, what I need to know is how to add a pre-loader in the city select box while it loads the appropriate cities using JQuery

My code looks as below

```<code> $('#Province').change(function() {
          $("#cities").load('cities.php');
        });
</code>```

答:
You can do something like this,assuming that you want to add a loader to the select .       </p>

```<code>  $('#Province').change(function() {
             $(this).parent().append('<img  class="loading" src="/css/images/loading1.gif"/>')
              $("#cities").load('cities.php');
              $('.loading').remove();

            });
</code>```

Body:
I have a select box with id Provice, whenever a Province is selected within this select box, the city select box populates with the cities within the selected provinces. Now that works, what I need to know is how to add a pre-loader in the city select box while it loads the appropriate cities using JQuery

My code looks as below

 $('#Province').change(function() {
          $("#cities").load('cities.php');
        });

Body:
You can do something like this,assuming that you want to add a loader to the select .

  $('#Province').change(function() {
             $(this).parent().append('<img  class="loading" src="/css/images/loading1.gif"/>')
              $("#cities").load('cities.php');
              $('.loading').remove();

            });


问:
Hapijs content-type has application/jwt giving 415 unsupported media type
Hi I am using hapijs version 17 for REST API development, when we are using Content-Type as application/jwt, we are getting 415 http error code Unsupported Media Type .. details below ..

Could someone recommend how to set the Content-type header to application/jwt?

```<code>server.route({
            method: 'POST',
            path: '/hello',
            config: {
                payload: {
                  allow: 'application/jwt'
                }
              },
            handler: (request, h) => {
                console.log("req------------->",request)
                return "hello";
            }
        });
</code>```

we get the following error in response:

```<code>{
    "statusCode": 415,
    "error": "Unsupported Media Type",
    "message": "Unsupported Media Type"
}
</code>```

答:
You need to set parse: false to use these content types. Something like this

```<code>payload: {
              "parse": false,
              allow: 'application/jwt'
            }
</code>```

Body:
Hi I am using hapijs version 17 for REST API development, when we are using Content-Type as application/jwt, we are getting 415 http error code Unsupported Media Type .. details below ..

Could someone recommend how to set the Content-type header to application/jwt?

server.route({
            method: 'POST',
            path: '/hello',
            config: {
                payload: {
                  allow: 'application/jwt'
                }
              },
            handler: (request, h) => {
                console.log("req------------->",request)
                return "hello";
            }
        });

we get the following error in response:

{
    "statusCode": 415,
    "error": "Unsupported Media Type",
    "message": "Unsupported Media Type"
}

Body:
You need to set parse: false to use these content types. Something like this

payload: {
              "parse": false,
              allow: 'application/jwt'
            }


问:
SIM900 - Send SMS over 160 characters using Gammu
I am using raspberry
 Pi 3 for sending SMS using SIM900A. I configured Gammu to send SMS via SIM900A and it worked fine. But I was able to send only 156 characters(Max). I need to send more than 200 characters.

Command I used : " echo 'MESSAGE' | sudo gammu sendsms TEXT +91XXXXXXXXXX"

Is there any way to do that? I am open for both AT commands and Gammu way.

Thanks in advance...

P.S : I would prefer TEXT format than PDU

答:
This works for me.

Please try this.

```<code>echo 'MESSAGE' | sudo gammu sendsms TEXT +91XXXXXXXXXX" -len 400
</code>```

Internally gammu sends more than one message if it is greater than 156 characters, but that is transparent to you. You only send a message with that command of up to 400 characters, and the phone receives 1 SMS only.

Body:
This works for me.

Please try this.

echo 'MESSAGE' | sudo gammu sendsms TEXT +91XXXXXXXXXX" -len 400

Internally gammu sends more than one message if it is greater than 156 characters, but that is transparent to you. You only send a message with that command of up to 400 characters, and the phone receives 1 SMS only.


问:
How to reliably determine last commit date in remote repository?
I have seen this answer and it is almost exactly what I need.

Difference is that will print date for human eyes, while I need to check it in a Makefile.

In particular I need to rebuild a certain file IFF something changed in repo after its creation.

I might not have a local copy of repo, so I might need a full "git clone" (possibly shallow), but I cannot directly use file dates because git does not preserve them.

I need something like:
   if myfile is_older $(git log -1 --format=%cd origin/master); then ... or, in Makefile:

```<code>myfile: $(somefunc $(shell git log -1 --format=%cd origin/master))
        commands to rebuild myfile
</code>```

but I don't know how to write it.

答:
As pointed out by @Slavomir, a key ingredient will be the --date option, but not with the raw value but rather the unix value (in order to only get the number of seconds from the epoch in UTC, without the timezone).

```<code>$ git log -1 --format=%cd --date=unix
1582030040
</code>```

(cf. doc).

Then, you'll be able to use the date +%s -r myfile shell command to get the timestamp of myfile.

(cf. man page).

Finally, you can devise a Makefile function to ease the comparison, which leads to a minimal working example like the following one:

Makefile

```<code># Return 'true' if $(1) does not exist or is older than branch $(2)
check_repo_change = $(shell if [ ! -e $(1) ] || [ $$(date +%s -r $(1)) -lt \
  $$(git log -1 --format=%cd --date=unix $(2)) ]; then echo true; fi)

# Note that you'll probably need to run "git fetch" at some point
BRANCH := origin/master

all: myfile
.PHONY: all

ifeq '$(call check_repo_change,myfile,$(BRANCH))' 'true'
myfile:
    set -x; echo ok >> $@
else
myfile:
    $(info No change detected in branch $(BRANCH))
endif
.PHONY: myfile
</code>```

Note: the .PHONY option is mandatory so that the myfile target will be triggered even if the file already exists and doesn't have (more recent) dependencies.

Body:
I have seen this answer and it is almost exactly what I need.

Difference is that will print date for human eyes, while I need to check it in a Makefile.

In particular I need to rebuild a certain file IFF something changed in repo after its creation.

I might not have a local copy of repo, so I might need a full "git clone" (possibly shallow), but I cannot directly use file dates because git does not preserve them.

I need something like:
   if myfile is_older $(git log -1 --format=%cd origin/master); then ... or, in Makefile:

myfile: $(somefunc $(shell git log -1 --format=%cd origin/master))
        commands to rebuild myfile

but I don't know how to write it.

Body:
As pointed out by @Slavomir, a key ingredient will be the --date option, but not with the raw value but rather the unix value (in order to only get the number of seconds from the epoch in UTC, without the timezone).

$ git log -1 --format=%cd --date=unix
1582030040

(cf. doc).

Then, you'll be able to use the date +%s -r myfile shell command to get the timestamp of myfile.

(cf. man page).

Finally, you can devise a Makefile function to ease the comparison, which leads to a minimal working example like the following one:

Makefile

# Return 'true' if $(1) does not exist or is older than branch $(2)
check_repo_change = $(shell if [ ! -e $(1) ] || [ $$(date +%s -r $(1)) -lt \
  $$(git log -1 --format=%cd --date=unix $(2)) ]; then echo true; fi)

# Note that you'll probably need to run "git fetch" at some point
BRANCH := origin/master

all: myfile
.PHONY: all

ifeq '$(call check_repo_change,myfile,$(BRANCH))' 'true'
myfile:
    set -x; echo ok >> $@
else
myfile:
    $(info No change detected in branch $(BRANCH))
endif
.PHONY: myfile

Note: the .PHONY option is mandatory so that the myfile target will be triggered even if the file already exists and doesn't have (more recent) dependencies.


问:
Increase speed of fetching contacts with cursor
In my app I'm fetching all contacts with cursor.

```<code>private static final String[] PROJECTION = new String[]{
        PHONE_CONTACT_ID,
        DISPLAY_NAME,
        TIMESTAMP,
        HAS_PHONE_NUMBER};

CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
            ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
            "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
    Cursor cursor = cursorLoader.loadInBackground();
    // Loop for every contact in the phone
    if (cursor != null && cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            ArrayList<String> phoneNumbers = new ArrayList<>();
            String contact_id = cursor.getString(cursor.getColumnIndex(PHONE_CONTACT_ID));
            String   name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
            String  timeStamp = cursor.getString(cursor.getColumnIndex(TIMESTAMP));
            cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                    new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor emailCur = cursorLoader.loadInBackground();
            while (emailCur.moveToNext()) {
                String email = emailCur.getString(emailCur.getColumnIndex(EMAIL));
                if (TmlyUtils.isValidEmail(email)) {
                    phoneNumbers.add(ContactUtils.MAIL_TAG + email);
                }
            }
            emailCur.close();
            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER))) > 0) {
                cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
                Cursor phones = cursorLoader.loadInBackground();
                while (phones.moveToNext()) {
                    String phoneNumber = phones.getString(phones.getColumnIndex(NUMBER));
                    phoneNumber = isValidMobileNumber(phoneNumber);
                    if (!phoneNumber.isEmpty() && !phoneNumbers.contains(ContactUtils.UPN_TAG + phoneNumber)) {
                        phoneNumbers.add(ContactUtils.UPN_TAG + phoneNumber);
                    }
                }
                phones.close();
            }
        }
        cursor.close();
    }
</code>```

The code works fine but when you have thousands of contacts the app freeze during several seconds.

I'm using three cursor, the first one allow me to get all contacts in my phone

```<code>CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
        ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
        "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
Cursor cursor = cursorLoader.loadInBackground();
</code>```

The second one loop for every email adress

```<code> cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
        Cursor emailCur = cursorLoader.loadInBackground();
</code>```

The third one loop for every phone

```<code>cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor phones = cursorLoader.loadInBackground();
</code>```

I need to use the second and the third one If I'm not using it I can't get all phones and email for every contacts, because one contact can have several phones and email address

I try to use CursorLoader for speed up, but it's not sufficient, is it possible to get rid of the second and the third cursor ?

EDIT : I forgot to say that all the query is already inside a Retrofit call

答:
This is a very common issue when working with Android ContactsContract APIs, you're basically doing one big query to get all contacts, and then a ton of little queries to get phones and emails.

So on a phone with 1000 contacts, you may have to do 2001 queries to get all info.

Instead, you can have one query to get all the info you need, you just need to skip the Contacts table and query directly on the Data table which contains all the info you need.

I didn't quite understand what you're doing with contact_id, name, and those MAIL_TAG/UPN_TAG's, so I'll just print to the log the info you'd need and you'll need to sort that into the java objects that make sense to your app.

```<code>String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1};
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur.moveToNext()) {
    long id = cur.getLong(0); // contact-id
    String name = cur.getString(1); // contact name
    String mime = cur.getString(2); // type: email / phone
    String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234

    switch (mime) {
        case Phone.CONTENT_ITEM_TYPE:
            Log.i("Contacts", "got a phone: " + id + ", " + name + ", " + data);
            break;
        case Email.CONTENT_ITEM_TYPE:
            Log.i("Contacts", "got an email: " + id + ", " + name + ", " + data);
            break;
    }
}
cur.close();
</code>```

Also, as @IliaKuzmin said, you should run this on a background thread, not the UI thread.

Body:
In my app I'm fetching all contacts with cursor.

private static final String[] PROJECTION = new String[]{
        PHONE_CONTACT_ID,
        DISPLAY_NAME,
        TIMESTAMP,
        HAS_PHONE_NUMBER};

CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
            ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
            "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
    Cursor cursor = cursorLoader.loadInBackground();
    // Loop for every contact in the phone
    if (cursor != null && cursor.getCount() > 0) {
        while (cursor.moveToNext()) {
            ArrayList<String> phoneNumbers = new ArrayList<>();
            String contact_id = cursor.getString(cursor.getColumnIndex(PHONE_CONTACT_ID));
            String   name = cursor.getString(cursor.getColumnIndex(DISPLAY_NAME));
            String  timeStamp = cursor.getString(cursor.getColumnIndex(TIMESTAMP));
            cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                    new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor emailCur = cursorLoader.loadInBackground();
            while (emailCur.moveToNext()) {
                String email = emailCur.getString(emailCur.getColumnIndex(EMAIL));
                if (TmlyUtils.isValidEmail(email)) {
                    phoneNumbers.add(ContactUtils.MAIL_TAG + email);
                }
            }
            emailCur.close();
            if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(HAS_PHONE_NUMBER))) > 0) {
                cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
                Cursor phones = cursorLoader.loadInBackground();
                while (phones.moveToNext()) {
                    String phoneNumber = phones.getString(phones.getColumnIndex(NUMBER));
                    phoneNumber = isValidMobileNumber(phoneNumber);
                    if (!phoneNumber.isEmpty() && !phoneNumbers.contains(ContactUtils.UPN_TAG + phoneNumber)) {
                        phoneNumbers.add(ContactUtils.UPN_TAG + phoneNumber);
                    }
                }
                phones.close();
            }
        }
        cursor.close();
    }

The code works fine but when you have thousands of contacts the app freeze during several seconds.

I'm using three cursor, the first one allow me to get all contacts in my phone

CursorLoader cursorLoader = new CursorLoader(ResUtils.getInstance().getContext(),
        ContactsContract.Contacts.CONTENT_URI, PROJECTION, null, null,
        "UPPER(" + ContactsContract.Contacts.DISPLAY_NAME + ")ASC");
Cursor cursor = cursorLoader.loadInBackground();

The second one loop for every email adress

 cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(), ContactsContract.CommonDataKinds.Email.CONTENT_URI,
                new String[]{EMAIL},ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[]{contact_id}, null);
        Cursor emailCur = cursorLoader.loadInBackground();

The third one loop for every phone

cursorLoader = new CursorLoader( ResUtils.getInstance().getContext(),   ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                    new String[]{NUMBER},ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contact_id}, null);
            Cursor phones = cursorLoader.loadInBackground();

I need to use the second and the third one If I'm not using it I can't get all phones and email for every contacts, because one contact can have several phones and email address

I try to use CursorLoader for speed up, but it's not sufficient, is it possible to get rid of the second and the third cursor ?

EDIT : I forgot to say that all the query is already inside a Retrofit call

Body:
This is a very common issue when working with Android ContactsContract APIs, you're basically doing one big query to get all contacts, and then a ton of little queries to get phones and emails.

So on a phone with 1000 contacts, you may have to do 2001 queries to get all info.

Instead, you can have one query to get all the info you need, you just need to skip the Contacts table and query directly on the Data table which contains all the info you need.

I didn't quite understand what you're doing with contact_id, name, and those MAIL_TAG/UPN_TAG's, so I'll just print to the log the info you'd need and you'll need to sort that into the java objects that make sense to your app.

String[] projection = {Data.CONTACT_ID, Data.DISPLAY_NAME, Data.MIMETYPE, Data.DATA1};
String selection = Data.MIMETYPE + " IN ('" + Phone.CONTENT_ITEM_TYPE + "', '" + Email.CONTENT_ITEM_TYPE + "')";
Cursor cur = cr.query(Data.CONTENT_URI, projection, selection, null, null);

while (cur.moveToNext()) {
    long id = cur.getLong(0); // contact-id
    String name = cur.getString(1); // contact name
    String mime = cur.getString(2); // type: email / phone
    String data = cur.getString(3); // the actual info, e.g. +1-212-555-1234

    switch (mime) {
        case Phone.CONTENT_ITEM_TYPE:
            Log.i("Contacts", "got a phone: " + id + ", " + name + ", " + data);
            break;
        case Email.CONTENT_ITEM_TYPE:
            Log.i("Contacts", "got an email: " + id + ", " + name + ", " + data);
            break;
    }
}
cur.close();

Also, as @IliaKuzmin said, you should run this on a background thread, not the UI thread.


问:
Bootstrap 4 carousel-fade animation not working properly
So I was working on my web project where I used form over carousel using css. It's working perfectly with sliding animation but when I am adding class carousel-fade the form at the center is also fading with the carousel but I want to prevent that. Here, In example instead of that big form I used a simple
 tag for demonstration. How can I solve this issue ?

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

I am at center

```

答:
Add z-index: 1; css property to #vcenter ..

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

I am at center

```

Body:
Add z-index: 1; css property to #vcenter ..

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js">
</script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>

  <script>
  $(function(){
  $('.carousel').carousel({
    interval: 1000
  }) ;
  }) ;
  </script>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">

  <style>
  /*CSS*/
#vcenter {
   position: absolute ;
   top: 55%;
   left: 50%;
   transform: translate(-50%, -50%);
   font-weight: bold ;
   z-index: 1;
}

div#back1{
   background-image: url('https://images.pexels.com/photos/11744/pexels-photo-11744.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500');
   height: 100vh ;
   background-attachment: scroll;
   background-position: center;
   background-size: cover;
   background-repeat: no-repeat;
}

div#back2{
   background-image: url('https://images.pexels.com/photos/207130/pexels-photo-207130.jpeg?    auto=compress&cs=tinysrgb&dpr=1&w=500');
   height: 100vh ;
   background-attachment: scroll;
   background-position: center;
   background-size: cover;
   background-repeat: no-repeat;
}

div#back3{
   background-image: url('https://images.pexels.com/photos/1178683/pexels-photo-1178683.jpeg?    auto=compress&cs=tinysrgb&dpr=1&w=500');
   height: 100vh ;
   background-attachment: scroll;
   background-position: center;
   background-size: cover;
   background-repeat: no-repeat;
}

</style>

<body>

<!-- carousel -->
<div class="carousel slide carousel-fade" data-ride="carousel">
    <div class="carousel-inner">
      <div class="carousel-item active">
        <div id="back1"></div>
      </div>
      <div class="carousel-item">
        <div id="back2"></div>
      </div>
      <div class="carousel-item">
        <div id="back3"></div>
      </div>
    </div>
</div>

<div id="vcenter" class="container">
  <p class="text-center text-primary">I am at center</p>
</div>

</body>


问:
Does snowflake support ssl?
Hi I want to have the ability to connect from jdbc driver to snowflake with ssl. I did it many times with other db, just add ssl=true(sometimes other properties) in connection url.

Unfortunately I didn't find this option in snowflake documentation. I found that snowflake supports something like ssl they call it Using Key Pair Authentication
Does it ssl mode for snowflake?
Does snowflake support ssl?

答:
SSL encryption cannot be switched off when connecting to Snowflake. Full Stop.

There is no option in the JDBC or ODBC driver to disable (or enable) SSL. That is why this parameter is not mentioned on the documentation pages of Snowflake.

Generic

ODBC

Snowflake connections use SSL by default.

And using only HTTPS connections. Regardless whether it is a driver or the GUI.

That is also the reason that you do not need to add https:// to your server connection.

More on this can be found here.

The http-connections you might see Snowflake drivers make are to satisfy OCSP.

If you trying to test whether Snowflake supports un-encrypted connections and you get the information back that Snowflake does support unencrypted connections or does support TLS1.0 or TLS1.1 you have been testing your proxy-server settings and not snowflakecomputing.com or snowflake.com.

BTW : Currently only TLS1.2 is supported by Snowflake for HTTPS connections.

Title: Does snowflake support ssl?