int X509_PURPOSE_add(int id, int trust, int flags,
                     int (*ck) (const X509_PURPOSE *, const X509 *, int),
                     const char *name, const char *sname, void *arg)
{
    int idx;
    X509_PURPOSE *ptmp;
    flags &= ~X509_PURPOSE_DYNAMIC;
    flags |= X509_PURPOSE_DYNAMIC_NAME;
    idx = X509_PURPOSE_get_by_id(id);
    if (idx == -1) {
        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            return 0;
        }
        ptmp->flags = X509_PURPOSE_DYNAMIC;
    } else
        ptmp = X509_PURPOSE_get0(idx);
    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {
        OPENSSL_free(ptmp->name);
        OPENSSL_free(ptmp->sname);
    }
    ptmp->name = OPENSSL_strdup(name);
    ptmp->sname = OPENSSL_strdup(sname);
    if (!ptmp->name || !ptmp->sname) {
        X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    ptmp->flags &= X509_PURPOSE_DYNAMIC;
    ptmp->flags |= flags;
    ptmp->purpose = id;
    ptmp->trust = trust;
    ptmp->check_purpose = ck;
    ptmp->usr_data = arg;
    if (idx == -1) {
        if (xptable == NULL
            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    }
    return 1;
 err:
    if (idx == -1) {
        OPENSSL_free(ptmp->name);
        OPENSSL_free(ptmp->sname);
        OPENSSL_free(ptmp);
    }
    return 0;
}
['int X509_PURPOSE_add(int id, int trust, int flags,\n                     int (*ck) (const X509_PURPOSE *, const X509 *, int),\n                     const char *name, const char *sname, void *arg)\n{\n    int idx;\n    X509_PURPOSE *ptmp;\n    flags &= ~X509_PURPOSE_DYNAMIC;\n    flags |= X509_PURPOSE_DYNAMIC_NAME;\n    idx = X509_PURPOSE_get_by_id(id);\n    if (idx == -1) {\n        if ((ptmp = OPENSSL_malloc(sizeof(*ptmp))) == NULL) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            return 0;\n        }\n        ptmp->flags = X509_PURPOSE_DYNAMIC;\n    } else\n        ptmp = X509_PURPOSE_get0(idx);\n    if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) {\n        OPENSSL_free(ptmp->name);\n        OPENSSL_free(ptmp->sname);\n    }\n    ptmp->name = OPENSSL_strdup(name);\n    ptmp->sname = OPENSSL_strdup(sname);\n    if (!ptmp->name || !ptmp->sname) {\n        X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    ptmp->flags &= X509_PURPOSE_DYNAMIC;\n    ptmp->flags |= flags;\n    ptmp->purpose = id;\n    ptmp->trust = trust;\n    ptmp->check_purpose = ck;\n    ptmp->usr_data = arg;\n    if (idx == -1) {\n        if (xptable == NULL\n            && (xptable = sk_X509_PURPOSE_new(xp_cmp)) == NULL) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n        if (!sk_X509_PURPOSE_push(xptable, ptmp)) {\n            X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n    }\n    return 1;\n err:\n    if (idx == -1) {\n        OPENSSL_free(ptmp->name);\n        OPENSSL_free(ptmp->sname);\n        OPENSSL_free(ptmp);\n    }\n    return 0;\n}', 'int X509_PURPOSE_get_by_id(int purpose)\n{\n    X509_PURPOSE tmp;\n    int idx;\n    if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX))\n        return purpose - X509_PURPOSE_MIN;\n    tmp.purpose = purpose;\n    if (!xptable)\n        return -1;\n    idx = sk_X509_PURPOSE_find(xptable, &tmp);\n    if (idx == -1)\n        return -1;\n    return idx + X509_PURPOSE_COUNT;\n}', 'DEFINE_STACK_OF(X509_PURPOSE)', 'int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data)\n{\n    return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH);\n}', 'static int internal_find(OPENSSL_STACK *st, const void *data,\n                         int ret_val_options)\n{\n    const void *r;\n    int i;\n    if (st == NULL)\n        return -1;\n    if (st->comp == NULL) {\n        for (i = 0; i < st->num; i++)\n            if (st->data[i] == data)\n                return (i);\n        return (-1);\n    }\n    OPENSSL_sk_sort(st);\n    if (data == NULL)\n        return (-1);\n    r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp,\n                        ret_val_options);\n    if (r == NULL)\n        return (-1);\n    return (int)((const void **)r - st->data);\n}', 'X509_PURPOSE *X509_PURPOSE_get0(int idx)\n{\n    if (idx < 0)\n        return NULL;\n    if (idx < (int)X509_PURPOSE_COUNT)\n        return xstandard + idx;\n    return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT);\n}']