⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utils.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
    dsbufp->str = (char *) erts_alloc(ERTS_ALC_T_TMP_DSBUF, init_size);    dsbufp->str[0] = '\0';    dsbufp->size = init_size;    return dsbufp;}voiderts_destroy_tmp_dsbuf(erts_dsprintf_buf_t *dsbufp){    if (dsbufp->str)	erts_free(ERTS_ALC_T_TMP_DSBUF, (void *) dsbufp->str);    erts_free(ERTS_ALC_T_TMP_DSBUF, (void *) dsbufp);}/* eq and cmp are written as separate functions a eq is a little faster *//* * Test for equality of two terms. * Returns 0 if not equal, or a non-zero value otherwise. */inteq(Eterm a, Eterm b){ tailrecur:    if (a == b) 	return 1;    switch (primary_tag(a)) {    case TAG_PRIMARY_BOXED:	{		    Eterm hdr = *boxed_val(a);	    switch (hdr & _TAG_HEADER_MASK) {	    case ARITYVAL_SUBTAG:		{		    Eterm* aa;		    Eterm* bb;		    Sint i;  		    aa = tuple_val(a);		    if (!is_boxed(b) || *boxed_val(b) != *aa)			return 0;		    bb = tuple_val(b);		    i = arityval(*aa); /* get the arity*/		    while (i--) {			Eterm atmp = *++aa;			Eterm btmp = *++bb;			if (!EQ(atmp, btmp))			    return 0;		    }		    return 1;		}	    case REFC_BINARY_SUBTAG:	    case HEAP_BINARY_SUBTAG:	    case SUB_BINARY_SUBTAG:		{		    byte* a_ptr;		    byte* b_ptr;		    size_t a_size;		    size_t b_size;		    Uint a_bitsize;		    Uint b_bitsize;		    Uint a_bitoffs;		    Uint b_bitoffs;		    		    if (is_not_binary(b)) {			return 0;		    }		    a_size = binary_size(a);		    b_size = binary_size(b); 		    if (a_size != b_size) {			return 0;		    }		    ERTS_GET_BINARY_BYTES(a, a_ptr, a_bitoffs, a_bitsize);		    ERTS_GET_BINARY_BYTES(b, b_ptr, b_bitoffs, b_bitsize);		    if ((a_bitsize | b_bitsize | a_bitoffs | b_bitoffs) == 0) {			return sys_memcmp(a_ptr, b_ptr, a_size) == 0;		    } else if (a_bitsize == b_bitsize) {			return erts_cmp_bits(a_ptr, a_bitoffs, b_ptr, b_bitoffs,					     (a_size << 3) + a_bitsize) == 0;		    } else {			return 0;		    }		}	case EXPORT_SUBTAG:		{		    Export* a_exp;		    Export* b_exp;		    if (is_not_export(b)) {			return 0;		    }		    a_exp = (Export *) (export_val(a))[1];		    b_exp = (Export *) (export_val(b))[1];		    return a_exp == b_exp;		}	    case FUN_SUBTAG:		{		    ErlFunThing* f1;		    ErlFunThing* f2;		    int num_free;		    int i;  		    if (is_not_fun(b))			return 0;		    f1 = (ErlFunThing *) fun_val(a);		    f2 = (ErlFunThing *) fun_val(b);		    if (f1->fe->module != f2->fe->module ||			f1->fe->old_index != f2->fe->old_index ||			f1->fe->old_uniq != f2->fe->old_uniq ||			f1->num_free != f2->num_free) {			return 0;		    }		    num_free = f1->num_free;		    for (i = 0; i < num_free; i++) {			if (!EQ(f1->env[i], f2->env[i])) {			    return 0;			}		    }		    return 1;		}	    case EXTERNAL_PID_SUBTAG:	    case EXTERNAL_PORT_SUBTAG: {		ExternalThing *ap;		ExternalThing *bp;		if(is_not_external(b))		    return 0;		ap = external_thing_ptr(a);		bp = external_thing_ptr(b);		if(ap->header != bp->header)		    return 0;		if(ap->node != bp->node)		    return 0;		ASSERT(1 == external_data_words(a));		ASSERT(1 == external_data_words(b));		if(ap->data[0] != bp->data[0])		    return 0;		return 1;	    }	    case EXTERNAL_REF_SUBTAG: {		/*		 * Observe!		 *  When comparing refs we need to compare ref numbers		 * (32-bit words) *not* ref data words.		 */		Uint32 *anum;		Uint32 *bnum;		Uint common_len;		Uint alen;		Uint blen;		Uint i;		if(is_not_external_ref(b))		    return 0;		if(external_node(a) != external_node(b))		    return 0;		anum = external_ref_numbers(a);		bnum = external_ref_numbers(b);		alen = external_ref_no_of_numbers(a);		blen = external_ref_no_of_numbers(b);		goto ref_common;	    case REF_SUBTAG:  		    if (is_not_internal_ref(b))			return 0;		    alen = internal_ref_no_of_numbers(a);		    blen = internal_ref_no_of_numbers(b);		    anum = internal_ref_numbers(a);		    bnum = internal_ref_numbers(b);	    ref_common:		    ASSERT(alen > 0 && blen > 0);		    if (anum[0] != bnum[0])			return 0;		    if (alen == 3 && blen == 3) {			/* Most refs are of length 3 */			if (anum[1] == bnum[1] && anum[2] == bnum[2])			    return 1;			return 0;		    }		    common_len = alen;		    if (blen < alen)			common_len = blen;		    for (i = 1; i < common_len; i++)			if (anum[i] != bnum[i])			    return 0;		    if(alen != blen) {			if (alen > blen) {			    for (i = common_len; i < alen; i++)				if (anum[i] != 0)				    return 0;			}			else {			    for (i = common_len; i < blen; i++)				if (bnum[i] != 0)				    return 0;			}					    }		    return 1;	    }	    case POS_BIG_SUBTAG:	    case NEG_BIG_SUBTAG:		{		    Eterm* aa;		    Eterm* bb;		    int i;  		    if (is_not_big(b))			return 0;		    aa = big_val(a); /* get pointer to thing */		    bb = big_val(b);		    if (*aa != *bb)			return 0;		    i = BIG_ARITY(aa);		    while(i--) {			if (*++aa != *++bb)			    return 0;		    }		    return 1;		}	    case FLOAT_SUBTAG:		{		    FloatDef af;		    FloatDef bf;  		    if (is_not_float(b))			return 0;		    GET_DOUBLE(a, af);		    GET_DOUBLE(b, bf);		    return (af.fd == bf.fd) ? 1 : 0;		}	    }	    break;	}    case TAG_PRIMARY_LIST:	{	    Eterm atmp;	    Eterm btmp;	    if (is_not_list(b))		return 0;	    atmp = CAR(list_val(a));	    btmp = CAR(list_val(b));	    if (!EQ(atmp, btmp))		return 0;	    a = CDR(list_val(a));	    b = CDR(list_val(b));	    goto tailrecur;	}    }    return 0;}/*  * Lexically compare two strings of bytes (string s1 length l1 and s2 l2). * *	s1 < s2	return -1 *	s1 = s2	return  0 *	s1 > s2 return +1 */static int cmpbytes(byte *s1, int l1, byte *s2, int l2){    int i;    i = 0;    while((i < l1) && (i < l2)) {	if (s1[i] < s2[i]) return(-1);	if (s1[i] > s2[i]) return(1);	i++;    }    if (l1 < l2) return(-1);    if (l1 > l2) return(1);    return(0);}/* * Compare objects. * Returns 0 if equal, a negative value if a < b, or a positive number a > b. * * According to the Erlang Standard, types are orderered as follows: *   numbers < (characters) < atoms < refs < funs < ports < pids < *   tuples < [] < conses < binaries. * * Note that characters are currently not implemented. * */#define float_comp(x,y)    (((x)<(y)) ? -1 : (((x)==(y)) ? 0 : 1))static int cmp_atoms(Eterm a, Eterm b){    Atom *aa = atom_tab(atom_val(a));    Atom *bb = atom_tab(atom_val(b));    int diff = aa->ord0 - bb->ord0;    if (diff)	return diff;    return cmpbytes(aa->name+3, aa->len-3,		    bb->name+3, bb->len-3);}Sintcmp(Eterm a, Eterm b){    Eterm* aa;    Eterm* bb;    int i;    Sint j;    Eterm big_buf[2];    int a_tag;    int b_tag;    ErlNode *anode;    ErlNode *bnode;    Uint adata;    Uint bdata;    Uint alen;    Uint blen;    Uint32 *anum;    Uint32 *bnum;#undef  CMP_NODES#define CMP_NODES(AN, BN)						\    do {								\	if((AN) != (BN)) {						\	    if((AN)->sysname != (BN)->sysname)				\		return cmp_atoms((AN)->sysname, (BN)->sysname);		\	    ASSERT((AN)->creation != (BN)->creation);			\	    return ((AN)->creation < (BN)->creation) ? -1 : 1;		\	}								\    } while (0) tailrecur:    if (a == b) {		/* Equal values or pointers. */	return 0;    }    /* deal with majority (?) cases by brute-force */    if (is_atom(a)) {	if (is_atom(b))	    return cmp_atoms(a, b);    } else if (is_both_small(a, b)) {	return signed_val(a) - signed_val(b);    }    /*     * Take care of cases where the types are the same.     */    a_tag = 42;			/* Suppress warning */    switch (primary_tag(a)) {    case TAG_PRIMARY_IMMED1:	switch ((a & _TAG_IMMED1_MASK) >> _TAG_PRIMARY_SIZE) {	case (_TAG_IMMED1_PORT >> _TAG_PRIMARY_SIZE):	    if (is_internal_port(b)) {		bnode = erts_this_node;		bdata = internal_port_data(b);	    } else if (is_external_port(b)) {		bnode = external_port_node(b);		bdata = external_port_data(b);	    } else {		a_tag = PORT_DEF;		goto mixed_types;	    }	    anode = erts_this_node;	    adata = internal_port_data(a);			port_common:	    CMP_NODES(anode, bnode);	    if (adata != bdata) {		return adata < bdata ? -1 : 1;	    }	    return 0;	case (_TAG_IMMED1_PID >> _TAG_PRIMARY_SIZE):	    if (is_internal_pid(b)) {		bnode = erts_this_node;		bdata = internal_pid_data(b);	    } else if (is_external_pid(b)) {		bnode = external_pid_node(b);		bdata = external_pid_data(b);	    } else {		a_tag = PID_DEF;		goto mixed_types;	    }	    anode = erts_this_node;	    adata = internal_pid_data(a);	    	pid_common:	    if (adata != bdata) {		return adata < bdata ? -1 : 1;	    }	    CMP_NODES(anode, bnode);	    return 0;	case (_TAG_IMMED1_SMALL >> _TAG_PRIMARY_SIZE):	    a_tag = SMALL_DEF;	    goto mixed_types;	case (_TAG_IMMED1_IMMED2 >> _TAG_PRIMARY_SIZE): {	    switch ((a & _TAG_IMMED2_MASK) >> _TAG_IMMED1_SIZE) {	    case (_TAG_IMMED2_ATOM >> _TAG_IMMED1_SIZE):		a_tag = ATOM_DEF;		goto mixed_types;	    case (_TAG_IMMED2_NIL >> _TAG_IMMED1_SIZE):		a_tag = NIL_DEF;		goto mixed_types;	    }	}	}    case TAG_PRIMARY_LIST:	if (is_not_list(b)) {	    a_tag = LIST_DEF;	    goto mixed_types;	}	aa = list_val(a);	bb = list_val(b);	while (1) {	    if ((j = cmp(*aa++, *bb++)) != 0) 		return j;	    if (*aa==*bb)		return 0;	    if (is_not_list(*aa) || is_not_list(*bb)) {		a = *aa;		b = *bb;		goto tailrecur;	    }	    aa = list_val(*aa);	    bb = list_val(*bb);	}    case TAG_PRIMARY_BOXED:	{	    Eterm ahdr = *boxed_val(a);	    switch ((ahdr & _TAG_HEADER_MASK) >> _TAG_PRIMARY_SIZE) {	    case (_TAG_HEADER_ARITYVAL >> _TAG_PRIMARY_SIZE):		if (is_not_tuple(b)) {		    a_tag = TUPLE_DEF;		    goto mixed_types;		}		aa = tuple_val(a);		bb = tuple_val(b);		/* compare the arities */		i = arityval(ahdr);	/* get the arity*/		if (i < arityval(*bb)) return(-1);		if (i > arityval(*bb)) return(1);		if (i == 0) {		    return 0;		}		while (--i) {		    a = *++aa;		    b = *++bb;		    if (a != b) {			if (is_atom(a) && is_atom(b)) {			    if ((j = cmp_atoms(a, b)) != 0) {				return j;			    }			} else if (is_both_small(a, b)) {			    if ((j = signed_val(a)-signed_val(b)) != 0) {				return j;			    }			} else if ((j = cmp(a, b)) != 0) {			    return j;			}		    }		}		a = *++aa;		b = *++bb;		goto tailrecur;	    case (_TAG_HEADER_FLOAT >> _TAG_PRIMARY_SIZE):		if (is_not_float(b)) {		    a_tag = FLOAT_DEF;		    goto mixed_types;		} else {		    FloatDef af;		    FloatDef bf; 		    GET_DOUBLE(a, af);		    GET_DOUBLE(b, bf);		    return float_comp(af.fd, bf.fd);		}	    case (_TAG_HEADER_POS_BIG >> _TAG_PRIMARY_SIZE):	    case (_TAG_HEADER_NEG_BIG >> _TAG_PRIMARY_SIZE):		if (is_not_big(b)) {		    a_tag = BIG_DEF;		    goto mixed_types;		}		return big_comp(a, b);	    case (_TAG_HEADER_EXPORT >> _TAG_PRIMARY_SIZE):		if (is_not_export(b)) {		    a_tag = EXPORT_DEF;		    goto mixed_types;		} else {		    Export* a_exp = (Export *) (export_val(a))[1];		    Export* b_exp = (Export *) (export_val(b))[1];		    if ((j = cmp_atoms(a_exp->code[0], b_exp->code[0])) != 0) {			return j;		    }		    if ((j = cmp_atoms(a_exp->code[1], b_exp->code[1])) != 0) {			return j;		    }		    return (Sint) a_exp->code[2] - (Sint) b_exp->code[2];		}		break;	    case (_TAG_HEADER_FUN >> _TAG_PRIMARY_SIZE):		if (is_not_fun(b)) {		    a_tag = FUN_DEF;		    goto mixed_types;		} else {		    ErlFunThing* f1 = (ErlFunThing *) fun_val(a);		    ErlFunThing* f2 = (ErlFunThing *) fun_val(b);		    int num_free;		    Sint diff;		    diff = cmpbytes(atom_tab(atom_val(f1->fe->module))->name,				    atom_tab(atom_val(f1->fe->module))->len,				    atom_tab(atom_val(f2->fe->module))->name,				    atom_tab(atom_val(f2->fe->module))->len);		    if (diff != 0) {			return diff;		    }		    diff = f1->fe->old_index - f2->fe->old_index;		    if (diff != 0) {			return diff;		    }		    diff = f1->fe->old_uniq - f2->fe->old_uniq;		    if (diff != 0) {			return diff;		    }		    diff = f1->num_free - f2->num_free;		    if (diff != 0) {			return diff;		    }		    num_free = f1->num_free;		    for (i = 0; i < num_free; i++) {			if ((diff = cmp(f1->env[i], f2->env[i])) != 0) {			    return diff;			}		    }		    return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -