Example #1
0
void
start_order_char(wchar_t wc)
{
	collchar_t	*cc;
	int32_t		ref;

	start_order(T_CHAR);

	/*
	 * If we last saw an ellipsis, then we need to close the range.
	 * Handle that here.  Note that we have to be careful because the
	 * items *inside* the range are treated exclusiveley to the items
	 * outside of the range.  The ends of the range can have quite
	 * different weights than the range members.
	 */
	if (lastorder == T_ELLIPSIS) {
		int		i;

		if (wc < ellipsis_start) {
			errf(_("malformed range!"));
			return;
		}
		while (ellipsis_start < wc) {
			/*
			 * pick all of the saved weights for the
			 * ellipsis.  note that -1 encodes for the
			 * ellipsis itself, which means to take the
			 * current relative priority.
			 */
			if ((cc = get_collchar(ellipsis_start, 1)) == NULL) {
				INTERR;
				return;
			}
			for (i = 0; i < NUM_WT; i++) {
				collpri_t *p;
				if (((ref = ellipsis_weights[i]) == -1) ||
				    ((p = get_pri(ref)) == NULL) ||
				    (p->pri == -1)) {
					set_pri(cc->ref[i], nextpri, RESOLVED);
				} else {
					set_pri(cc->ref[i], ref, REFER);
				}
				ellipsis_weights[i] = 0;
			}
			ellipsis_start++;
			nextpri++;
		}
	}

	currchar = get_collchar(wc, 1);
}
Example #2
0
File: sys.c Project: 1153/otp
static ERTS_INLINE int
prepare_crash_dump(int secs)
{
#define NUFBUF (3)
    int i, max;
    char env[21]; /* enough to hold any 64-bit integer */
    size_t envsz;
    /*DeclareTmpHeapNoproc(heap,NUFBUF);*/
    /*Eterm *hp = heap;*/
    /*Eterm list = NIL;*/
    int has_heart = 0;

    UseTmpHeapNoproc(NUFBUF);

    if (ERTS_PREPARED_CRASH_DUMP)
	return 0; /* We have already been called */


    /* Positive secs means an alarm must be set
     * 0 or negative means no alarm
     *
     * Set alarm before we try to write to a port
     * we don't want to hang on a port write with
     * no alarm.
     *
     */

#if 0 /*ose TBD!!!*/
    if (secs >= 0) {
	alarm((unsigned int)secs);
    }
#endif

    /* Make sure we unregister at epmd (unknown fd) and get at least
       one free filedescriptor (for erl_crash.dump) */

    max = max_files;
    if (max < 1024)
	max = 1024;
    for (i = 3; i < max; i++) {
	close(i);
    }

    envsz = sizeof(env);
    i = erts_sys_getenv__("ERL_CRASH_DUMP_NICE", env, &envsz);
    if (i >= 0) {
	int nice_val;
	nice_val = i != 0 ? 0 : atoi(env);
	if (nice_val > 39) {
	    nice_val = 39;
	}
	set_pri(nice_val);
    }

    UnUseTmpHeapNoproc(NUFBUF);
#undef NUFBUF
    return has_heart;
}
Example #3
0
void
end_order_collsym(collsym_t *sym)
{
	start_order(T_COLLSYM);
	/* update the weight */

	set_pri(sym->ref, nextpri, RESOLVED);
	nextpri++;
}
Example #4
0
void
add_order_subst(void)
{
	subst_t srch;
	subst_t	*s;
	avl_index_t where;
	int i;

	(void) memset(&srch, 0, sizeof (srch));
	for (i = 0; i < curr_subst; i++) {
		srch.ref[i] = subst_weights[i];
		subst_weights[i] = 0;
	}
	s = avl_find(&substs_ref[curr_weight], &srch, &where);

	if (s == NULL) {
		if ((s = calloc(sizeof (*s), 1)) == NULL) {
			errf(_("out of memory"));
			return;
		}
		s->key = new_pri();

		/*
		 * We use a self reference for our key, but we set a
		 * high bit to indicate that this is a substitution
		 * reference.  This will expedite table lookups later,
		 * and prevent table lookups for situations that don't
		 * require it.  (In short, its a big win, because we
		 * can skip a lot of binary searching.)
		 */
		set_pri(s->key,
		    (nextsubst[curr_weight] | COLLATE_SUBST_PRIORITY),
		    RESOLVED);
		nextsubst[curr_weight] += 1;

		for (i = 0; i < curr_subst; i++) {
			s->ref[i] = srch.ref[i];
		}

		avl_insert(&substs_ref[curr_weight], s, where);

		if (avl_find(&substs[curr_weight], s, &where) != NULL) {
			INTERR;
			return;
		}
		avl_insert(&substs[curr_weight], s, where);
	}
	curr_subst = 0;


	/*
	 * We are using the current (unique) priority as a search key
	 * in the substitution table.
	 */
	add_order_pri(s->key);
}
Example #5
0
void
init_collate(void)
{
	int i;

	avl_create(&collsyms, collsym_compare, sizeof (collsym_t),
	    offsetof(collsym_t, avl));

	avl_create(&collundefs, collundef_compare, sizeof (collsym_t),
	    offsetof(collundef_t, avl));

	avl_create(&elem_by_symbol, element_compare_symbol, sizeof (collelem_t),
	    offsetof(collelem_t, avl_bysymbol));
	avl_create(&elem_by_expand, element_compare_expand, sizeof (collelem_t),
	    offsetof(collelem_t, avl_byexpand));

	avl_create(&collchars, collchar_compare, sizeof (collchar_t),
	    offsetof(collchar_t, avl));

	for (i = 0; i < COLL_WEIGHTS_MAX; i++) {
		avl_create(&substs[i], subst_compare, sizeof (subst_t),
		    offsetof(subst_t, avl));
		avl_create(&substs_ref[i], subst_compare_ref,
		    sizeof (subst_t), offsetof(subst_t, avl_ref));
		avl_create(&weights[i], weight_compare, sizeof (weight_t),
		    offsetof(weight_t, avl));
		nweight[i] = 1;
	}

	(void) memset(&collinfo, 0, sizeof (collinfo));

	/* allocate some initial priorities */
	pri_ignore = new_pri();

	set_pri(pri_ignore, 0, RESOLVED);

	for (i = 0; i < COLL_WEIGHTS_MAX; i++) {
		pri_undefined[i] = new_pri();

		/* we will override this later */
		set_pri(pri_undefined[i], COLLATE_MAX_PRIORITY, UNKNOWN);
	}
}
Example #6
0
void
end_order(void)
{
	int		i;
	int32_t		pri;
	int32_t		ref;
	collpri_t	*p;

	/* advance the priority/weight */
	pri = nextpri;

	switch (currorder) {
	case T_CHAR:
		for (i = 0; i < NUM_WT; i++) {
			if (((ref = order_weights[i]) < 0) ||
			    ((p = get_pri(ref)) == NULL) ||
			    (p->pri == -1)) {
				/* unspecified weight is a self reference */
				set_pri(currchar->ref[i], pri, RESOLVED);
			} else {
				set_pri(currchar->ref[i], ref, REFER);
			}
			order_weights[i] = -1;
		}

		/* leave a cookie trail in case next symbol is ellipsis */
		ellipsis_start = currchar->wc + 1;
		currchar = NULL;
		break;

	case T_ELLIPSIS:
		/* save off the weights were we can find them */
		for (i = 0; i < NUM_WT; i++) {
			ellipsis_weights[i] = order_weights[i];
			order_weights[i] = -1;
		}
		break;

	case T_COLLELEM:
		if (currelem == NULL) {
			INTERR;
		} else {
			for (i = 0; i < NUM_WT; i++) {

				if (((ref = order_weights[i]) < 0) ||
				    ((p = get_pri(ref)) == NULL) ||
				    (p->pri == -1)) {
					set_pri(currelem->ref[i], pri,
					    RESOLVED);
				} else {
					set_pri(currelem->ref[i], ref, REFER);
				}
				order_weights[i] = -1;
			}
		}
		break;

	case T_UNDEFINED:
		for (i = 0; i < NUM_WT; i++) {
			if (((ref = order_weights[i]) < 0) ||
			    ((p = get_pri(ref)) == NULL) ||
			    (p->pri == -1)) {
				set_pri(pri_undefined[i], -1, RESOLVED);
			} else {
				set_pri(pri_undefined[i], ref, REFER);
			}
			order_weights[i] = -1;
		}
		break;

	case T_SYMBOL:
		for (i = 0; i < NUM_WT; i++) {
			if (((ref = order_weights[i]) < 0) ||
			    ((p = get_pri(ref)) == NULL) ||
			    (p->pri == -1)) {
				set_pri(currundef->ref[i], pri, RESOLVED);
			} else {
				set_pri(currundef->ref[i], ref, REFER);
			}
			order_weights[i] = -1;
		}
		break;

	default:
		INTERR;
	}

	nextpri++;
}
Example #7
0
void
dump_collate(void)
{
	FILE			*f;
	int			i, j, n;
	size_t			sz;
	int32_t			pri;
	collelem_t		*ce;
	collchar_t		*cc;
	subst_t			*sb;
	char			vers[COLLATE_STR_LEN];
	collate_char_t		chars[UCHAR_MAX + 1];
	collate_large_t		*large;
	collate_subst_t		*subst[COLL_WEIGHTS_MAX];
	collate_chain_t		*chain;

	/*
	 * We have to run throught a preliminary pass to identify all the
	 * weights that we use for each sorting level.
	 */
	for (i = 0; i < NUM_WT; i++) {
		add_weight(pri_ignore, i);
	}
	for (i = 0; i < NUM_WT; i++) {
		for (sb = avl_first(&substs[i]); sb;
		    sb = AVL_NEXT(&substs[i], sb)) {
			for (j = 0; sb->ref[j]; j++) {
				add_weight(sb->ref[j], i);
			}
		}
	}
	for (ce = avl_first(&elem_by_expand);
	    ce != NULL;
	    ce = AVL_NEXT(&elem_by_expand, ce)) {
		add_weights(ce->ref);
	}
	for (cc = avl_first(&collchars); cc; cc = AVL_NEXT(&collchars, cc)) {
		add_weights(cc->ref);
	}

	/*
	 * Now we walk the entire set of weights, removing the gaps
	 * in the weights.  This gives us optimum usage.  The walk
	 * occurs in priority.
	 */
	for (i = 0; i < NUM_WT; i++) {
		weight_t *w;
		for (w = avl_first(&weights[i]); w;
		    w = AVL_NEXT(&weights[i], w)) {
			w->opt = nweight[i];
			nweight[i] += 1;
		}
	}

	(void) memset(&chars, 0, sizeof (chars));
	(void) memset(vers, 0, COLLATE_STR_LEN);
	(void) strlcpy(vers, COLLATE_VERSION, sizeof (vers));

	/*
	 * We need to make sure we arrange for the UNDEFINED field
	 * to show up.  Also, set the total weight counts.
	 */
	for (i = 0; i < NUM_WT; i++) {
		if (resolve_pri(pri_undefined[i]) == -1) {
			set_pri(pri_undefined[i], -1, RESOLVED);
			/* they collate at the end of everything else */
			collinfo.undef_pri[i] = COLLATE_MAX_PRIORITY;
		}
		collinfo.pri_count[i] = nweight[i];
	}

	collinfo.pri_count[NUM_WT] = max_wide();
	collinfo.undef_pri[NUM_WT] = COLLATE_MAX_PRIORITY;
	collinfo.directive[NUM_WT] = DIRECTIVE_UNDEFINED;

	/*
	 * Ordinary character priorities
	 */
	for (i = 0; i <= UCHAR_MAX; i++) {
		if ((cc = get_collchar(i, 0)) != NULL) {
			for (j = 0; j < NUM_WT; j++) {
				chars[i].pri[j] = get_weight(cc->ref[j], j);
			}
		} else {
			for (j = 0; j < NUM_WT; j++) {
				chars[i].pri[j] =
				    get_weight(pri_undefined[j], j);
			}
			/*
			 * Per POSIX, for undefined characters, we
			 * also have to add a last item, which is the
			 * character code.
			 */
			chars[i].pri[NUM_WT] = i;
		}
	}

	/*
	 * Substitution tables
	 */
	for (i = 0; i < NUM_WT; i++) {
		collate_subst_t *st = NULL;
		n = collinfo.subst_count[i] = avl_numnodes(&substs[i]);
		if ((st = calloc(sizeof (collate_subst_t) * n, 1)) == NULL) {
			errf(_("out of memory"));
			return;
		}
		n = 0;
		for (sb = avl_first(&substs[i]); sb;
		    sb = AVL_NEXT(&substs[i], sb)) {
			if ((st[n].key = resolve_pri(sb->key)) < 0) {
				/* by definition these resolve! */
				INTERR;
			}
			if (st[n].key != (n | COLLATE_SUBST_PRIORITY)) {
				INTERR;
			}
			for (j = 0; sb->ref[j]; j++) {
				st[n].pri[j] = get_weight(sb->ref[j], i);
			}
			n++;
		}
		if (n != collinfo.subst_count[i])
			INTERR;
		subst[i] = st;
	}


	/*
	 * Chains, i.e. collating elements
	 */
	collinfo.chain_count = avl_numnodes(&elem_by_expand);
	chain = calloc(sizeof (collate_chain_t), collinfo.chain_count);
	if (chain == NULL) {
		errf(_("out of memory"));
		return;
	}
	for (n = 0, ce = avl_first(&elem_by_expand);
	    ce != NULL;
	    ce = AVL_NEXT(&elem_by_expand, ce), n++) {
		(void) wsncpy(chain[n].str, ce->expand, COLLATE_STR_LEN);
		for (i = 0; i < NUM_WT; i++) {
			chain[n].pri[i] = get_weight(ce->ref[i], i);
		}
	}
	if (n != collinfo.chain_count)
		INTERR;

	/*
	 * Large (> UCHAR_MAX) character priorities
	 */
	large = calloc(sizeof (collate_large_t) * avl_numnodes(&collchars), 1);
	if (large == NULL) {
		errf(_("out of memory"));
		return;
	}

	i = 0;
	for (cc = avl_first(&collchars); cc; cc = AVL_NEXT(&collchars, cc)) {
		int	undef = 0;
		/* we already gathered those */
		if (cc->wc <= UCHAR_MAX)
			continue;
		for (j = 0; j < NUM_WT; j++) {
			if ((pri = get_weight(cc->ref[j], j)) < 0) {
				undef = 1;
			}
			if (undef && (pri >= 0)) {
				/* if undefined, then all priorities are */
				INTERR;
			} else {
				large[i].pri.pri[j] = pri;
			}
		}
		if (!undef) {
			large[i].val = cc->wc;
			collinfo.large_count = i++;
		}
	}

	if ((f = open_category()) == NULL) {
		return;
	}

	/* Time to write the entire data set out */

	if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) ||
	    (wr_category(&collinfo, sizeof (collinfo), f) < 0) ||
	    (wr_category(&chars, sizeof (chars), f) < 0)) {
		delete_category(f);
		return;
	}

	for (i = 0; i < NUM_WT; i++) {
		sz =  sizeof (collate_subst_t) * collinfo.subst_count[i];
		if (wr_category(subst[i], sz, f) < 0) {
			delete_category(f);
			return;
		}
	}
	sz = sizeof (collate_chain_t) * collinfo.chain_count;
	if (wr_category(chain, sz, f) < 0) {
		delete_category(f);
		return;
	}
	sz = sizeof (collate_large_t) * collinfo.large_count;
	if (wr_category(large, sz, f) < 0) {
		delete_category(f);
		return;
	}

	close_category(f);
}