Exemple #1
0
static int match_bol(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm)
{
	if (str == ctx->str_start && !(ctx->flags & REG_NOTBOL))
		return do_match(ctx, op->next, str, gm);
	else if (str != ctx->str_start && str[-1] == '\n' && (ctx->flags & REG_NEWLINE))
		return do_match(ctx, op->next, str, gm);
	return REG_NOMATCH;
}
Exemple #2
0
static int match_eol(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm)
{
	if (*str == '\n' && (ctx->flags & REG_NEWLINE))
		return do_match(ctx, op->next, str, gm);
	else if (*str == 0 && !(ctx->flags & REG_NOTEOL))
		return do_match(ctx, op->next, str, gm);
	return REG_NOMATCH;
}
Exemple #3
0
void sub_command(player *p,char *str,struct command *comlist)
{
  char *oldstack,*rol;
  void (*fn)();
  oldstack=stack;
  
  while(comlist->text) {
    if ((!comlist->level) || ((p->residency)&(comlist->level))) {
      rol=do_match(str,comlist);
      if (rol) {
	last_com=comlist;
	stack_check=stack;
        fn=comlist->function;
        (*fn)(p,rol);
	if (stack!=stack_check) bad_stack();
	sys_flags &= ~(FAILED_COMMAND|PIPE|ROOM_TAG|FRIEND_TAG|EVERYONE_TAG);
	command_type=0;
        return;
      }
    }
    comlist++;
  }
  rol=str;
  while(*rol && !isspace(*rol)) rol++;
  *rol=0;
  sprintf(oldstack,"Cannot find sub command '%s'\n",str);
  stack=end_string(oldstack);
  tell_player(p,oldstack);
  stack=oldstack;
}
Exemple #4
0
static int match_gend(struct ExecCtx *ctx, const struct Op *f_op, const char *str, struct GMatch *gm)
{
	int err = REG_NOMATCH;
	const struct Op *op = gm->owner;
	bool zeromatch = (str == gm->start);
	bool gotmatch = false;

	/* ignore follow-up empty matches, unless it has backrefs */
	if (zeromatch && gm->count > 0 && gm->count >= op->mincnt && !gm->owner->gdata.has_refs)
		return REG_NOMATCH;

	/* tag as matched */
	gm->end = str;

	/* try more repeats, stop if count full or last match was zero-length */
	if (gm->count + 1 < op->maxcnt && !zeromatch) {
		err = match_group(ctx, op, str, gm);
		if (err == 0 && STRICT)
			gotmatch = true;
		else if (err != REG_NOMATCH)
			return err;
	}

	/* fail if not enough repeats */
	if (!zeromatch && gm->count + 1 < op->mincnt)
		return err;

	/* continue with parent branch */
	err = do_match(ctx, op->next, str, gm->parent);
	if (err == REG_NOMATCH && gotmatch)
		err = 0;
	return err;
}
Exemple #5
0
void            match_commands(player * p, char *str)
{
   struct command *comlist;
   char           *rol, *oldstack, *space;
   void            (*fn) ();
   oldstack = stack;

   while (*str && *str == ' ')
      str++;
   space = strchr(str, 0);
   space--;
   while (*space == ' ')
      *space-- = 0;
   if (!*str)
      return;
   if (isalpha(*str))
      comlist = coms[((int) (tolower(*str)) - (int) 'a' + 1)];
   else
      comlist = coms[0];

   while (comlist->text)
   {
      if (((!comlist->level) || ((p->residency) & (comlist->level))) &&
	  ((!comlist->andlevel) || ((p->residency) & (comlist->andlevel))))
      {
    rol = do_match(str, comlist);
    if (rol)
    {
       last_com = comlist;
       stack_check = stack;
       fn = comlist->function;
       (*fn) (p, rol);
       if (stack != stack_check)
          bad_stack();
       sys_flags &= ~(FAILED_COMMAND | PIPE | ROOM_TAG | FRIEND_TAG | EVERYONE_TAG);
       command_type = 0;
       return;
    }
      }
      comlist++;
   }
   p->antipipe++;

/*
   if (p->antipipe > 30)
   {
      quit(p, 0);
      return;
   }
*/
   rol = str;
   while (*rol && !isspace(*rol))
      rol++;
   *rol = 0;
   sprintf(oldstack, " Cannot find command '%s'\n", str);
   stack = end_string(oldstack);
   tell_player(p, oldstack);
   stack = oldstack;
}
Exemple #6
0
static int match_wchange(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm)
{
	bool prevw = (str == ctx->str_start) ? false : is_word(str[-1]);
	bool curw = is_word(str[0]);
	bool ischange = prevw ^ curw;

	if ((op->type == OP_WCHANGE) ? ischange : !ischange)
		return do_match(ctx, op->next, str, gm);
	return REG_NOMATCH;
}
Exemple #7
0
void partial_do_match(std::vector<Shape*>& shapes, size_t L, size_t R, std::atomic<size_t>& result)
{
    size_t a = 0;
    unsigned char j = (unsigned char)L;

    for (size_t i = L; i < R; ++i)
        a += do_match(*shapes[i],some_numbers[j++]);

    result += a;
}
Exemple #8
0
static int match_group(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm)
{
	int err = REG_NOMATCH;
	bool gotmatch = false;
	struct GMatch gthis;

	/* per-group-match context */
	memset(&gthis, 0, sizeof(gthis));
	gthis.owner = op;
	gthis.start = str;
	gthis.parent = gm;
	if (gm && gm->owner == op) {
		gthis.parent = gm->parent;
		gthis.count = gm->count + 1;
	}
	gm = &gthis;
	push_gm(ctx, gm);

	if (op->maxcnt > 0) {
		struct AndList *alist = op->gdata.or_list;
		/* check all branches, unless relaxed matching */
		while (alist) {
			err = do_match(ctx, alist->op_list, str, gm);
			if (err == 0 && STRICT) {
				gm->end = NULL;
				gotmatch = true;
			} else if (err != REG_NOMATCH)
				break;
			alist = alist->next;
		}
	}

	/* is no-match allowed? */
	if ((op->mincnt == 0) && (gm->count == 0)
	    && (err == REG_NOMATCH || (err == 0 && STRICT))) {
		gm->end = NULL;
		err = do_match(ctx, op->next, str, gm->parent);
	}

	pop_gm(ctx, gm);
	return gotmatch ? 0 : err;
}
Exemple #9
0
static int scan_next(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm, int curcnt, int alen)
{
	int err = REG_NOMATCH;
	bool gotmatch = false;

	if (curcnt == op->mincnt)
		return do_match(ctx, op->next, str, gm);

	for (; curcnt >= op->mincnt; curcnt--) {
		err = do_match(ctx, op->next, str, gm);
		if (STRICT && err == 0)
			gotmatch = true;
		else if (err != REG_NOMATCH)
			break;
		str -= alen;
	}
	if (err == REG_NOMATCH && gotmatch)
		err = 0;
	return err;
}
Exemple #10
0
int
matches(char *subject, const char *pattern)
{
    Var ans, req;
    int  result;
    
    req = new_list(2);
    req.v.list[1].type = TYPE_STR;
    req.v.list[2].type = TYPE_STR;
    req.v.list[1].v.str  = str_dup(subject);
    req.v.list[2].v.str  = str_dup(pattern);
    ans = do_match(req, 0);
    result = is_true(ans);
    free_var(ans);
    free_var(req);
    return result;
}
Exemple #11
0
size_t run_timings(
        std::vector<Shape*>&    shapes, 
        std::vector<long long>& timingsV, 
        std::vector<long long>& timingsM,
        size_t& aV,
        size_t& aM
     )
{
    XTL_ASSERT(timingsM.size() == timingsV.size());

    size_t N = shapes.size();
    size_t M = timingsV.size();

    for (size_t m = 0; m < M; ++m)
    {
        unsigned char j = 0;
        time_stamp liStart1 = get_time_stamp();

        for (size_t i = 0; i < N-3; i += 4)
            aV += do_visit(*shapes[i],*shapes[i+1],*shapes[i+2],*shapes[i+3],some_numbers[j++]);

        time_stamp liFinish1 = get_time_stamp();

        j = 0;

        time_stamp liStart2 = get_time_stamp();

        for (size_t i = 0; i < N-3; i += 4)
            aM += do_match(*shapes[i],*shapes[i+1],*shapes[i+2],*shapes[i+3],some_numbers[j++]);

        time_stamp liFinish2 = get_time_stamp();

        XTL_ASSERT(aV==aM);

        timingsV[m] = liFinish1-liStart1;
        timingsM[m] = liFinish2-liStart2;
    }

    return N/4; // Number of iterations per measurement
}
/**
 * cinnamon_contact_system_initial_search:
 * @cinnamon: A #CinnamonContactSystem
 * @terms: (element-type utf8): List of terms, logical AND
 *
 * Search through contacts for the given search terms.
 *
 * Returns: (transfer container) (element-type utf8): List of contact
 * identifiers
 */
GSList *
cinnamon_contact_system_initial_search (CinnamonContactSystem *self,
                                     GSList             *terms)
{
  FolksIndividual *individual;
  GSList *results = NULL;
  GeeMap *individuals = NULL;
  ContactSearchResult *result;
  GeeMapIterator *iter;
  gpointer key;
  guint weight;
  GSList *normalized_terms = normalize_terms (terms);

  g_return_val_if_fail (CINNAMON_IS_CONTACT_SYSTEM (self), NULL);

  individuals = folks_individual_aggregator_get_individuals (self->priv->aggregator);

  iter = gee_map_map_iterator (individuals);

  while (gee_map_iterator_next (iter))
    {
      individual = gee_map_iterator_get_value (iter);
      weight = do_match (self, individual, normalized_terms);

      if (weight != 0)
        {
          key = gee_map_iterator_get_key (iter);

          result = g_slice_new (ContactSearchResult);
          result->key = (gchar *) key;
          result->weight = weight;

          results = g_slist_append (results, result);
        }

      g_object_unref (individual);
    }

  return sort_and_prepare_results (results);
}
Exemple #13
0
void run_timings(
    std::vector<Shape*>&    shapes,
    std::vector<long long>& timingsV,
    std::vector<long long>& timingsM,
    size_t& aV,
    size_t& aM
)
{
    XTL_ASSERT(timingsM.size() == timingsV.size());

    size_t N = shapes.size();
    size_t M = timingsV.size();

    for (size_t m = 0; m < M; ++m)
    {
        unsigned char j = 0;
        time_stamp liStart1 = get_time_stamp();

        for (size_t i = 0; i < N; ++i)
            aV += do_visit(*shapes[i],some_numbers[j++]);

        time_stamp liFinish1 = get_time_stamp();

        j = 0;

        time_stamp liStart2 = get_time_stamp();

        for (size_t i = 0; i < N; ++i)
            aM += do_match(*shapes[i],some_numbers[j++]);

        time_stamp liFinish2 = get_time_stamp();

        XTL_ASSERT(aV==aM);

        timingsV[m] = liFinish1-liStart1;
        timingsM[m] = liFinish2-liStart2;
    }
}
Exemple #14
0
static int match_bref(struct ExecCtx *ctx, const struct Op *op, const char *str, struct GMatch *gm)
{
	bool icase = ctx->flags & REG_ICASE;
	int i;
	struct GMatch *bgm = ctx->gm_stack[op->bref];
	int blen = (bgm && bgm->end) ? (bgm->end - bgm->start) : -1;

	/* handle no-match, zero-len, zero-count */
	if (blen < 0 && op->mincnt > 0)
		return REG_NOMATCH;
	if (blen <= 0 || op->maxcnt == 0)
		return do_match(ctx, op->next, str, gm);

	/* find max matches */
	for (i = 0; (i < op->maxcnt) && *str; i++) {
		if (icase && strncasecmp(str, bgm->start, blen) != 0)
			break;
		else if (!icase && strncmp(str, bgm->start, blen) != 0)
			break;
		str += blen;
	}
	return scan_next(ctx, op, str, gm, i, blen);
}
Exemple #15
0
int regexec(const regex_t *rx, const char *str, size_t nmatch, regmatch_t pmatch[], int eflags)
{
	int err;
	struct ExecCtx ctx;

	if (eflags & ~(REG_NOTBOL | REG_NOTEOL))
		return REG_BADPAT;

	/* init local context */
	memset(&ctx, 0, sizeof(ctx));
	ctx.pmatch = pmatch;
	ctx.nmatch = nmatch;
	ctx.str_start = str;
	ctx.rx = rx;
	ctx.rxi = rx->internal;
	ctx.flags = ctx.rxi->flags | eflags;

	/* reset pmatch area */
	if (!(ctx.flags & REG_NOSUB))
		memset(pmatch, -1, nmatch * sizeof(regmatch_t));

	/* decide pmatch area that will be used */
	if (!pmatch || (ctx.flags & REG_NOSUB))
		ctx.nmatch = 0;
	else if (nmatch > (size_t)rx->re_nsub + 1)
		ctx.nmatch = rx->re_nsub + 1;
	ctx.strict = !(ctx.flags & REG_RELAXED_MATCHING) && (ctx.nmatch > 0);

	/* execute search */
	str--;
	do {
		str++;
		err = do_match(&ctx, ctx.rxi->root, str, NULL);
	} while ((err == REG_NOMATCH) && *str);

	return err;
}
Exemple #16
0
static s64 do_count(Sentence sent, int lw, int rw,
                    Connector *le, Connector *re, int cost)
{
	Disjunct * d;
	s64 total, pseudototal;
	int start_word, end_word, w;
	s64 leftcount, rightcount;
	int lcost, rcost, Lmatch, Rmatch;

	Match_node * m, *m1;
	Table_connector *t;

	count_context_t *ctxt = sent->count_ctxt;

	if (cost < 0) return 0;  /* will we ever call it with cost<0 ? */

	t = find_table_pointer(ctxt, lw, rw, le, re, cost);

	if (t == NULL) {
		/* Create the table entry with a tentative cost of 0. 
	    * This cost must be updated before we return. */
		t = table_store(ctxt, lw, rw, le, re, cost, 0);
	} else {
		return t->count;
	}

	if (rw == 1+lw)
	{
		/* lw and rw are neighboring words */
		/* You can't have a linkage here with cost > 0 */
		if ((le == NULL) && (re == NULL) && (cost == 0))
		{
			t->count = 1;
		}
		else
		{
			t->count = 0;
		}
		return t->count;
	}

	if ((le == NULL) && (re == NULL))
	{
		if (!ctxt->islands_ok && (lw != -1))
		{
			/* If we don't allow islands (a set of words linked together
			 * but separate from the rest of the sentence) then the cost
			 * of skipping n words is just n */
			if (cost == ((rw-lw-1) + ctxt->null_block-1)/ctxt->null_block)
			{
				/* If null_block=4 then the cost of
				   1,2,3,4 nulls is 1; and 5,6,7,8 is 2 etc. */
				t->count = 1;
			}
			else
			{
				t->count = 0;
			}
			return t->count;
		}
		if (cost == 0)
		{
			/* There is no zero-cost solution in this case. There is
			 * a slight efficiency hack to separate this cost=0 case
			 * out, but not necessary for correctness */
			t->count = 0;
		}
		else
		{
			total = 0;
			w = lw+1;
			for (d = ctxt->local_sent[w].d; d != NULL; d = d->next)
			{
				if (d->left == NULL)
				{
					total += do_count(sent, w, rw, d->right, NULL, cost-1);
				}
			}
			total += do_count(sent, w, rw, NULL, NULL, cost-1);
			t->count = total;
		}
		return t->count;
	}

	if (le == NULL)
	{
		start_word = lw+1;
	}
	else
	{
		start_word = le->word;
	}

	if (re == NULL)
	{
		end_word = rw-1;
	}
	else
	{
		end_word = re->word;
	}

	total = 0;

	for (w = start_word; w < end_word+1; w++)
	{
		m1 = m = form_match_list(sent, w, le, lw, re, rw);
		for (; m!=NULL; m=m->next)
		{
			d = m->d;
			for (lcost = 0; lcost <= cost; lcost++)
			{
				rcost = cost-lcost;
				/* Now lcost and rcost are the costs we're assigning
				 * to those parts respectively */

				/* Now, we determine if (based on table only) we can see that
				   the current range is not parsable. */
				Lmatch = (le != NULL) && (d->left != NULL) && 
				         do_match(sent, le, d->left, lw, w);
				Rmatch = (d->right != NULL) && (re != NULL) && 
				         do_match(sent, d->right, re, w, rw);

				rightcount = leftcount = 0;
				if (Lmatch)
				{
					leftcount = pseudocount(sent, lw, w, le->next, d->left->next, lcost);
					if (le->multi) leftcount += pseudocount(sent, lw, w, le, d->left->next, lcost);
					if (d->left->multi) leftcount += pseudocount(sent, lw, w, le->next, d->left, lcost);
					if (le->multi && d->left->multi) leftcount += pseudocount(sent, lw, w, le, d->left, lcost);
				}

				if (Rmatch)
				{
					rightcount = pseudocount(sent, w, rw, d->right->next, re->next, rcost);
					if (d->right->multi) rightcount += pseudocount(sent, w,rw,d->right,re->next, rcost);
					if (re->multi) rightcount += pseudocount(sent, w, rw, d->right->next, re, rcost);
					if (d->right->multi && re->multi) rightcount += pseudocount(sent, w, rw, d->right, re, rcost);
				}

				/* total number where links are used on both sides */
				pseudototal = leftcount*rightcount;

				if (leftcount > 0) {
					/* evaluate using the left match, but not the right */
					pseudototal += leftcount * pseudocount(sent, w, rw, d->right, re, rcost);
				}
				if ((le == NULL) && (rightcount > 0)) {
					/* evaluate using the right match, but not the left */
					pseudototal += rightcount * pseudocount(sent, lw, w, le, d->left, lcost);
				}

				/* now pseudototal is 0 implies that we know that the true total is 0 */
				if (pseudototal != 0) {
					rightcount = leftcount = 0;
					if (Lmatch) {
						leftcount = do_count(sent, lw, w, le->next, d->left->next, lcost);
						if (le->multi) leftcount += do_count(sent, lw, w, le, d->left->next, lcost);
						if (d->left->multi) leftcount += do_count(sent, lw, w, le->next, d->left, lcost);
						if (le->multi && d->left->multi) leftcount += do_count(sent, lw, w, le, d->left, lcost);
					}

					if (Rmatch) {
						rightcount = do_count(sent, w, rw, d->right->next, re->next, rcost);
						if (d->right->multi) rightcount += do_count(sent, w,rw,d->right,re->next, rcost);
						if (re->multi) rightcount += do_count(sent, w, rw, d->right->next, re, rcost);
						if (d->right->multi && re->multi) rightcount += do_count(sent, w, rw, d->right, re, rcost);
					}

					total += leftcount*rightcount;  /* total number where links are used on both sides */

					if (leftcount > 0) {
						/* evaluate using the left match, but not the right */
						total += leftcount * do_count(sent, w, rw, d->right, re, rcost);
					}
					if ((le == NULL) && (rightcount > 0)) {
						/* evaluate using the right match, but not the left */
						total += rightcount * do_count(sent, lw, w, le, d->left, lcost);
					}
				}
			}
		}

		put_match_list(sent, m1);
	}
	t->count = total;
	return total;
}
Exemple #17
0
static int match_word(const char *glob, const char *word, const char separator)
{
    char *wrapped_word = wrap_word(word, separator, glob);
    struct mword_regexes *regexes = &mword_slash_regexes;
    struct subst_table *table = &mword_slash_subst_table;
    gboolean not_slash = (separator != '/');
    int ret;

    /*
     * We only expect two separators: '/' or '.'. If it's not '/', it has to be
     * the other one...
     */
    if (not_slash) {
        regexes = &mword_dot_regexes;
        table = &mword_dot_subst_table;
    }

    if(glob_is_separator_only(glob, separator)) {
        ret = do_match(regexes->re_double_sep, wrapped_word, TRUE);
        goto out;
    } else {
        /*
         * Unlike what happens for tar and disk expressions, we need to
         * calculate the beginning and end of our regex before calling
         * amglob_to_regex().
         */

        const char *begin, *end;
        char *glob_copy = g_strdup(glob);
        char *p, *g = glob_copy;
        char *regex;

        /*
         * Calculate the beginning of the regex:
         * - by default, it is an unanchored separator;
         * - if the glob begins with a caret, make that an anchored separator,
         *   and increment g appropriately;
         * - if it begins with a separator, make it the empty string.
         */

        p = glob_copy;
        begin = regexes->re_separator;

        if (*p == '^') {
            begin = "^";
            p++, g++;
            if (*p == separator) {
		begin = regexes->re_begin_full;
                g++;
	    }
        } else if (*p == separator)
            begin = "";

        /*
         * Calculate the end of the regex:
         * - an unanchored separator by default;
         * - if the last character is a backslash or the separator itself, it
         *   should be the empty string;
         * - if it is a dollar sign, overwrite it with 0 and look at the
         *   character before it: if it is the separator, only anchor at the
         *   end, otherwise, add a separator before the anchor.
         */

        p = &(glob_copy[strlen(glob_copy) - 1]);
        end = regexes->re_separator;
        if (*p == '\\' || *p == separator) {
            end = "";
        } else if (*p == '$') {
            char prev = *(p - 1);
            *p = '\0';
	    if (prev == separator) {
		*(p-1) = '\0';
		if (p-2 >= glob_copy) {
		    prev = *(p - 2);
		    if (prev == '\\') {
			*(p-2) = '\0';
		    }
		}
		end = regexes->re_end_full;
	    } else {
		end = "$";
	    }
        }

        regex = amglob_to_regex(g, begin, end, table);
        ret = do_match(regex, wrapped_word, TRUE);

        g_free(glob_copy);
        g_free(regex);
    }

out:
    g_free(wrapped_word);
    return ret;
}
Exemple #18
0
static int gather_and_build_remap(
  ZZ *zz, 
  int *new_map,               /* Upon return, flag indicating whether parts
                                 assignments were changed due to remap. */
  int HEcnt,                  /* # of HEs allocated. */
  int *HEinfo                 /* Array of HE info; for each HE, two pins and 
                                 one edge weight. Stored as a single vector
                                 to minimize communication calls.  */
)
{
char *yo = "gather_and_remap";
int ierr = ZOLTAN_OK;
int i, uidx, tmp;
int *each_size = NULL;        /* sizes (# HEs * HEINFO_ENTRIES) for each proc */
int *recvbuf = NULL;          /* Receive buffer for gatherv */
int *displs = NULL;           /* Displacement buffer for gatherv */
int send_size;                /* Local # HEs * HEINFO_ENTRIES */
int total_size;               /* Total # ints in gatherv */
int total_HEcnt;              /* Total (across all procs) number of HEs. */
int max0, max1;               /* Max values of pin 0 and pin 1 for each HE. */
int *match = NULL;            /* Vector describing the matching. 
                                 match[i] = j ==> match[j] = i ==> 
                                 vertices i and j are matched. */
int *used = NULL;             /* Vector indicating which partitions are used
                                 in the matching. */
int limit;                    /* Maximum number of matches that are allowed */
HGraph hg;                    /* Hypergraph for matching */
float before_remap = 0,       /* Amount of data that overlaps between old and */
      after_remap = 0;        /* new decomposition before and after remapping, 
                                 respectively. */
float with_oldremap = 0;      /* Amount of data that overlaps between old and
                                 new decomposition using the OldRemap vector
                                 (remapping from the previous decomposition). */


  /* Gather HEs from each processor into a local complete HG. */

  each_size = (int *) ZOLTAN_MALLOC(zz->Num_Proc * sizeof(int));
  if (!each_size) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
    ierr = ZOLTAN_MEMERR;
    goto End;
  }
  send_size = HEcnt * HEINFO_ENTRIES;
  MPI_Allgather(&send_size, 1, MPI_INT, each_size, 1, MPI_INT,
                zz->Communicator);

  for (total_size = 0, i = 0; i < zz->Num_Proc; i++) {
    total_size += each_size[i];
  }

  recvbuf = (int *) ZOLTAN_MALLOC((zz->Num_Proc + total_size) * sizeof(int));
  displs = recvbuf + total_size;
  if (!recvbuf) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
    ierr = ZOLTAN_MEMERR;
    goto End;
  }

  displs[0] = 0;
  for (i = 1; i < zz->Num_Proc; i++)
    displs[i] = displs[i-1] + each_size[i-1];

  MPI_Allgatherv(HEinfo, send_size, MPI_INT, 
                 recvbuf, each_size, displs, MPI_INT, zz->Communicator);

  total_HEcnt = total_size / HEINFO_ENTRIES;
  for (max0 = -1, max1 = -1, i = 0; i < total_HEcnt; i++) {
    tmp = i * HEINFO_ENTRIES;
    if (recvbuf[tmp] > max0) max0 = recvbuf[tmp];
    if (recvbuf[tmp+1] > max1) max1 = recvbuf[tmp+1];
  }
  /* Increment max0 and max1 so that they are the maximum number of unique
     pin values for pin0 and pin1 respectively; i.e., allow pin value == 0. */
  max0++;
  max1++;
  
  /* Sanity check */
  /* Ideally, max1 should equal LB.Num_Global_Parts, but ParMETIS3 sometimes
   * does not return the correct number of non-empty partitions, allowing
   * max1 to be less than LB.Num_Global_Parts. 
   * (e.g., ewgt.adaptive-partlocal1-v3.4.?).
   */
  if (max1 > zz->LB.Num_Global_Parts) 
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Unexpected value for max1.");

  /* Set up global HG */

  Zoltan_HG_HGraph_Init(&hg);
  if (total_HEcnt) {
    hg.nVtx = max0 + zz->LB.Num_Global_Parts;  
    hg.nEdge = total_HEcnt;
    hg.nPins = total_HEcnt * 2;   /* two pins per HE */
    hg.EdgeWeightDim = 1;
    hg.ewgt = (float *) ZOLTAN_MALLOC(total_HEcnt * sizeof(float));
    hg.hindex = (int *) ZOLTAN_MALLOC((total_HEcnt + 1) * sizeof(int));
    hg.hvertex = (int *) ZOLTAN_MALLOC((hg.nPins) * sizeof(int));
    if (!hg.ewgt || !hg.hindex || !hg.hvertex) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
      ierr = ZOLTAN_MEMERR;
      goto End;
    }

    for (i = 0; i < total_HEcnt; i++) {
      tmp = i * HEINFO_ENTRIES;
      hg.hindex[i] = i+i; 
      hg.hvertex[i+i] = recvbuf[tmp];
      hg.hvertex[i+i+1] = recvbuf[tmp+1]+max0;
      hg.ewgt[i] = recvbuf[tmp+2];
    }
    hg.hindex[total_HEcnt] = total_HEcnt + total_HEcnt;

    ierr = Zoltan_HG_Create_Mirror(zz, &hg);
    if (ierr < 0) goto End;
  }

  before_remap = measure_stays(zz, &hg, max0, NULL, "BEFORE");

  /* Compute the amount of overlap when using the old remap vector. */

  with_oldremap = measure_stays(zz, &hg, max0, zz->LB.OldRemap, "WITHOLD");

  /* Do matching */

  match = (int *) ZOLTAN_CALLOC(hg.nVtx + zz->LB.Num_Global_Parts, sizeof(int));
  used = match + hg.nVtx;
  if (hg.nVtx && !match) {
    ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
    ierr = ZOLTAN_MEMERR;
    goto End;
  }

  /* Max # matches allowed */
  limit = (max0 < zz->LB.Num_Global_Parts ? max0 : zz->LB.Num_Global_Parts); 
  do_match(zz, &hg, match, limit);

      
  /* Build remapping vector, if non-trivial matching was returned. */

  *new_map = 0;
  for (i = 0; i < zz->LB.Num_Global_Parts; i++) 
    if (match[i+max0] != i+max0) {
      *new_map = 1;
      break;
    }

  if (*new_map) {

    zz->LB.Remap = (int *) ZOLTAN_MALLOC(zz->LB.Num_Global_Parts * sizeof(int));
    if (!(zz->LB.Remap)) {
      ZOLTAN_PRINT_ERROR(zz->Proc, yo, "Memory error.");
      ierr = ZOLTAN_MEMERR;
      goto End;
    }


    /* First, process all parts that were matched. Mark matched parts as used.*/

    for (i = 0; i < zz->LB.Num_Global_Parts; i++) {
      zz->LB.Remap[i] = -1; 
      tmp = match[i+max0];
      if (tmp != i+max0) {
        zz->LB.Remap[i] = tmp;
        used[tmp] = 1;
      }
    }

    /* Second, process unmatched parts; if possible, keep same part number. */

    for (i = 0; i < zz->LB.Num_Global_Parts; i++) {
      if (zz->LB.Remap[i] > -1) continue;  /* Already processed part i */
      /* match[i+max0] == i+max0 */
      if (!used[i]) {  /* Keep the same part number if it is not used */
        zz->LB.Remap[i] = i;
        used[i] = 1;
      }
    }
  
    /* Third, process remaining unmatched parts; assign them to 
       unused partitions.*/
  
    for (uidx = 0, i = 0; i < zz->LB.Num_Global_Parts; i++) {
      if (zz->LB.Remap[i] > -1) continue;  /* Already processed part i */
      /* match[i+max0] == i+max0 */
      while (used[uidx]) uidx++;   /* Find next unused partition */
      zz->LB.Remap[i] = uidx;
      used[uidx] = 1;
    }
  }

  if (*new_map) 
    after_remap = measure_stays(zz, &hg, max0, zz->LB.Remap, "AFTER ");

  if ((before_remap >= after_remap) && (before_remap >= with_oldremap)) {
    /* No benefit from remapping; don't keep it! */
    ZOLTAN_FREE(&zz->LB.Remap);
    ZOLTAN_FREE(&zz->LB.OldRemap);
    *new_map = 0;
  }
  else if (with_oldremap >= after_remap) {
    /* The old remap vector is better than the new one; keep the old one. */
    ZOLTAN_FREE(&zz->LB.Remap);
    zz->LB.Remap = zz->LB.OldRemap;
    zz->LB.OldRemap = NULL;
    *new_map = 1;
  }
  else {
    /* Going to use the new remap vector; free the old one. */
    ZOLTAN_FREE(&zz->LB.OldRemap);
  }

  if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL && zz->Proc == zz->Debug_Proc &&
      zz->LB.Remap) 
    for (i = 0; i < zz->LB.Num_Global_Parts; i++) 
      printf("%d REMAP Part %d to Part %d\n", zz->Proc, i, zz->LB.Remap[i]);

End:
  ZOLTAN_FREE(&match);
  ZOLTAN_FREE(&each_size);
  ZOLTAN_FREE(&recvbuf);
  Zoltan_HG_HGraph_Free(&hg);
  return ierr;
}
Exemple #19
0
/*
 * Is a tree entry interesting given the pathspec we have?
 *
 * Pre-condition: either baselen == base_offset (i.e. empty path)
 * or base[baselen-1] == '/' (i.e. with trailing slash).
 */
enum interesting tree_entry_interesting(const struct name_entry *entry,
					struct strbuf *base, int base_offset,
					const struct pathspec *ps)
{
	enum interesting positive, negative;
	positive = do_match(entry, base, base_offset, ps, 0);

	/*
	 * case | entry | positive | negative | result
	 * -----+-------+----------+----------+-------
	 *   1  |  file |   -1     |  -1..2   |  -1
	 *   2  |  file |    0     |  -1..2   |   0
	 *   3  |  file |    1     |   -1     |   1
	 *   4  |  file |    1     |    0     |   1
	 *   5  |  file |    1     |    1     |   0
	 *   6  |  file |    1     |    2     |   0
	 *   7  |  file |    2     |   -1     |   2
	 *   8  |  file |    2     |    0     |   2
	 *   9  |  file |    2     |    1     |   0
	 *  10  |  file |    2     |    2     |  -1
	 * -----+-------+----------+----------+-------
	 *  11  |  dir  |   -1     |  -1..2   |  -1
	 *  12  |  dir  |    0     |  -1..2   |   0
	 *  13  |  dir  |    1     |   -1     |   1
	 *  14  |  dir  |    1     |    0     |   1
	 *  15  |  dir  |    1     |    1     |   1 (*)
	 *  16  |  dir  |    1     |    2     |   0
	 *  17  |  dir  |    2     |   -1     |   2
	 *  18  |  dir  |    2     |    0     |   2
	 *  19  |  dir  |    2     |    1     |   1 (*)
	 *  20  |  dir  |    2     |    2     |  -1
	 *
	 * (*) An exclude pattern interested in a directory does not
	 * necessarily mean it will exclude all of the directory. In
	 * wildcard case, it can't decide until looking at individual
	 * files inside. So don't write such directories off yet.
	 */

	if (!(ps->magic & PATHSPEC_EXCLUDE) ||
	    positive <= entry_not_interesting) /* #1, #2, #11, #12 */
		return positive;

	negative = do_match(entry, base, base_offset, ps, 1);

	/* #3, #4, #7, #8, #13, #14, #17, #18 */
	if (negative <= entry_not_interesting)
		return positive;

	/* #15, #19 */
	if (S_ISDIR(entry->mode) &&
	    positive >= entry_interesting &&
	    negative == entry_interesting)
		return entry_interesting;

	if ((positive == entry_interesting &&
	     negative >= entry_interesting) || /* #5, #6, #16 */
	    (positive == all_entries_interesting &&
	     negative == entry_interesting)) /* #9 */
		return entry_not_interesting;

	return all_entries_not_interesting; /* #10, #20 */
}
Exemple #20
0
/**
 * returns NULL if there are no ways to parse, or returns a pointer
 * to a set structure representing all the ways to parse.
 *
 * This code is similar to do_count() in count.c -- for a good reason:
 * the do_count() function did a full parse, but didn't actually
 * allocate an memory structures to hold the parse.  This also does
 * a full parse, but it also allocates and fills out the various
 * parse structures.
 */
static
Parse_set * mk_parse_set(Sentence sent, fast_matcher_t *mchxt,
                         count_context_t * ctxt,
                         Disjunct *ld, Disjunct *rd, int lw, int rw,
                         Connector *le, Connector *re, unsigned int null_count,
                         bool islands_ok, Parse_info pi)
{
    Disjunct * d, * dis;
    int start_word, end_word, w;
    bool Lmatch, Rmatch;
    unsigned int lnull_count, rnull_count;
    int i, j;
    Parse_set *ls[4], *rs[4], *lset, *rset;
    Parse_choice * a_choice;

    Match_node * m, *m1;
    X_table_connector *xt;
    s64 count;

    assert(null_count < 0x7fff, "mk_parse_set() called with null_count < 0.");

    count = table_lookup(ctxt, lw, rw, le, re, null_count);

    /*
      assert(count >= 0, "mk_parse_set() called on params that were not in the table.");
      Actually, we can't assert this, because of the pseudocount technique that's
      used in count().  It's not the case that every call to mk_parse_set() has already
      been put into the table.
     */

    if ((count == 0) || (count == -1)) return NULL;

    xt = x_table_pointer(lw, rw, le, re, null_count, pi);

    if (xt != NULL) return xt->set;  /* we've already computed it */

    /* Start it out with the empty set of options. */
    /* This entry must be updated before we return. */
    xt = x_table_store(lw, rw, le, re, null_count, pi);

    xt->set->count = count;  /* the count we already computed */
    /* this count is non-zero */

    if (rw == 1 + lw) return xt->set;

    if ((le == NULL) && (re == NULL))
    {
        if (!islands_ok && (lw != -1)) return xt->set;

        if (null_count == 0) return xt->set;

        w = lw + 1;
        for (dis = sent->word[w].d; dis != NULL; dis = dis->next)
        {
            if (dis->left == NULL)
            {
                rs[0] = mk_parse_set(sent, mchxt, ctxt, dis, NULL, w, rw, dis->right,
                                     NULL, null_count-1, islands_ok, pi);
                if (rs[0] == NULL) continue;
                a_choice = make_choice(dummy_set(), lw, w, NULL, NULL,
                                       rs[0], w, rw, NULL, NULL,
                                       NULL, NULL, NULL);
                put_choice_in_set(xt->set, a_choice);
            }
        }
        rs[0] = mk_parse_set(sent, mchxt, ctxt, NULL, NULL, w, rw, NULL, NULL,
                             null_count-1, islands_ok, pi);
        if (rs[0] != NULL)
        {
            a_choice = make_choice(dummy_set(), lw, w, NULL, NULL,
                                   rs[0], w, rw, NULL, NULL,
                                   NULL, NULL, NULL);
            put_choice_in_set(xt->set, a_choice);
        }
        return xt->set;
    }

    if (le == NULL)
    {
        start_word = lw + 1;
    }
    else
    {
        start_word = le->word;
    }

    if (re == NULL)
    {
        end_word = rw;
    }
    else
    {
        end_word = re->word + 1;
    }

    /* This condition can never be true here. It is included so GCC will be able
     * to optimize the loop over "null_count".  Without this check, GCC thinks this
     * loop may be an infinite loop and it may omit some optimizations. */
    if (UINT_MAX == null_count) return NULL;

    for (w = start_word; w < end_word; w++)
    {
        m1 = m = form_match_list(mchxt, w, le, lw, re, rw);
        for (; m!=NULL; m=m->next)
        {
            d = m->d;
            for (lnull_count = 0; lnull_count <= null_count; lnull_count++)
            {
                rnull_count = null_count-lnull_count;
                /* now lnull_count and rnull_count are the null_counts we're assigning to
                 * those parts respectively */

                /* Now, we determine if (based on table only) we can see that
                   the current range is not parsable. */

                Lmatch = (le != NULL) && (d->left != NULL) && do_match(le, d->left, lw, w);
                Rmatch = (d->right != NULL) && (re != NULL) && do_match(d->right, re, w, rw);
                for (i=0; i<4; i++) {
                    ls[i] = rs[i] = NULL;
                }
                if (Lmatch)
                {
                    ls[0] = mk_parse_set(sent, mchxt, ctxt, ld, d, lw, w, le->next, d->left->next, lnull_count, islands_ok, pi);
                    if (le->multi) ls[1] = mk_parse_set(sent, mchxt, ctxt, ld, d, lw, w, le, d->left->next, lnull_count, islands_ok, pi);
                    if (d->left->multi) ls[2] = mk_parse_set(sent, mchxt, ctxt, ld, d, lw, w, le->next, d->left, lnull_count, islands_ok, pi);
                    if (le->multi && d->left->multi) ls[3] = mk_parse_set(sent, mchxt, ctxt, ld, d, lw, w, le, d->left, lnull_count, islands_ok, pi);
                }
                if (Rmatch)
                {
                    rs[0] = mk_parse_set(sent, mchxt, ctxt, d, rd, w, rw, d->right->next, re->next, rnull_count, islands_ok, pi);
                    if (d->right->multi) rs[1] = mk_parse_set(sent, mchxt, ctxt, d, rd, w,rw,d->right,re->next, rnull_count, islands_ok, pi);
                    if (re->multi) rs[2] = mk_parse_set(sent, mchxt, ctxt, d, rd, w, rw, d->right->next, re, rnull_count, islands_ok, pi);
                    if (d->right->multi && re->multi) rs[3] = mk_parse_set(sent, mchxt, ctxt, d, rd, w, rw, d->right, re, rnull_count, islands_ok, pi);
                }

                for (i=0; i<4; i++)
                {
                    /* this ordering is probably not consistent with that
                     *  needed to use list_links */
                    if (ls[i] == NULL) continue;
                    for (j=0; j<4; j++)
                    {
                        if (rs[j] == NULL) continue;
                        a_choice = make_choice(ls[i], lw, w, le, d->left,
                                               rs[j], w, rw, d->right, re,
                                               ld, d, rd);
                        put_choice_in_set(xt->set, a_choice);
                    }
                }

                if (ls[0] != NULL || ls[1] != NULL || ls[2] != NULL || ls[3] != NULL)
                {
                    /* evaluate using the left match, but not the right */
                    rset = mk_parse_set(sent, mchxt, ctxt, d, rd, w, rw, d->right, re, rnull_count, islands_ok, pi);
                    if (rset != NULL)
                    {
                        for (i=0; i<4; i++)
                        {
                            if (ls[i] == NULL) continue;
                            /* this ordering is probably not consistent with
                             * that needed to use list_links */
                            a_choice = make_choice(ls[i], lw, w, le, d->left,
                                                   rset, w, rw, NULL /* d->right */,
                                                   re,  /* the NULL indicates no link*/
                                                   ld, d, rd);
                            put_choice_in_set(xt->set, a_choice);
                        }
                    }
                }
                if ((le == NULL) && (rs[0] != NULL ||
                                     rs[1] != NULL || rs[2] != NULL || rs[3] != NULL))
                {
                    /* evaluate using the right match, but not the left */
                    lset = mk_parse_set(sent, mchxt, ctxt, ld, d, lw, w, le, d->left, lnull_count, islands_ok, pi);

                    if (lset != NULL)
                    {
                        for (i=0; i<4; i++)
                        {
                            if (rs[i] == NULL) continue;
                            /* this ordering is probably not consistent with
                             * that needed to use list_links */
                            a_choice = make_choice(lset, lw, w, NULL /* le */,
                                                   d->left,  /* NULL indicates no link */
                                                   rs[i], w, rw, d->right, re,
                                                   ld, d, rd);
                            put_choice_in_set(xt->set, a_choice);
                        }
                    }
                }
            }
        }
        put_match_list(mchxt, m1);
    }
    xt->set->current = xt->set->first;
    return xt->set;
}
Exemple #21
0
int x_match(Sentence sent, Connector *a, Connector *b)
{
	return do_match(sent, a, b, 0, 0);
}
Exemple #22
0
static Count_bin do_count(fast_matcher_t *mchxt,
                          count_context_t *ctxt,
                          int lw, int rw,
                          Connector *le, Connector *re,
                          int null_count)
{
	Count_bin zero = hist_zero();
	Count_bin total;
	int start_word, end_word, w;
	Table_connector *t;

	assert (0 <= null_count, "Bad null count");

	t = find_table_pointer(ctxt, lw, rw, le, re, null_count);

	if (t) return t->count;

	/* Create the table entry with a tentative null count of 0.
	 * This count must be updated before we return. */
	t = table_store(ctxt, lw, rw, le, re, null_count);

	if (rw == 1+lw)
	{
		/* lw and rw are neighboring words */
		/* You can't have a linkage here with null_count > 0 */
		if ((le == NULL) && (re == NULL) && (null_count == 0))
		{
			t->count = hist_one();
		}
		else
		{
			t->count = zero;
		}
		return t->count;
	}

	/* The left and right connectors are null, but the two words are
	 * NOT next to each-other. */
	if ((le == NULL) && (re == NULL))
	{
		if (!ctxt->islands_ok && (lw != -1))
		{
			/* If we don't allow islands (a set of words linked together
			 * but separate from the rest of the sentence) then the
			 * null_count of skipping n words is just n. */
			if (null_count == (rw-lw-1))
			{
				t->count = hist_one();
			}
			else
			{
				t->count = zero;
			}
			return t->count;
		}
		if (null_count == 0)
		{
			/* There is no solution without nulls in this case. There is
			 * a slight efficiency hack to separate this null_count==0
			 * case out, but not necessary for correctness */
			t->count = zero;
		}
		else
		{
			t->count = zero;
			Disjunct * d;
			int w = lw + 1;
			for (d = ctxt->local_sent[w].d; d != NULL; d = d->next)
			{
				if (d->left == NULL)
				{
					hist_accumv(&t->count, d->cost,
						do_count(mchxt, ctxt, w, rw, d->right, NULL, null_count-1));
				}
			}
			hist_accumv(&t->count, 0.0,
				do_count(mchxt, ctxt, w, rw, NULL, NULL, null_count-1));
		}
		return t->count;
	}

	if (le == NULL)
	{
		start_word = lw+1;
	}
	else
	{
		start_word = le->word;
	}

	if (re == NULL)
	{
		end_word = rw;
	}
	else
	{
		end_word = re->word +1;
	}

	total = zero;

	for (w = start_word; w < end_word; w++)
	{
		Match_node *m, *m1;
		m1 = m = form_match_list(mchxt, w, le, lw, re, rw);
		for (; m != NULL; m = m->next)
		{
			unsigned int lnull_cnt, rnull_cnt;
			Disjunct * d = m->d;
			/* _p1 avoids a gcc warning about unsafe loop opt */
			unsigned int null_count_p1 = null_count + 1;

			for (lnull_cnt = 0; lnull_cnt < null_count_p1; lnull_cnt++)
			{
				bool Lmatch, Rmatch;
				bool leftpcount = false;
				bool rightpcount = false;
				bool pseudototal = false;

				rnull_cnt = null_count - lnull_cnt;
				/* Now lnull_cnt and rnull_cnt are the costs we're assigning
				 * to those parts respectively */

				/* Now, we determine if (based on table only) we can see that
				   the current range is not parsable. */
				Lmatch = (le != NULL) && (d->left != NULL) &&
				         do_match(le, d->left, lw, w);
				Rmatch = (d->right != NULL) && (re != NULL) &&
				         do_match(d->right, re, w, rw);

				/* First, perform pseudocounting as an optimization. If
				 * the pseudocount is zero, then we know that the true
				 * count will be zero, and so skip counting entirely,
				 * in that case.
				 */
				if (Lmatch)
				{
					leftpcount = pseudocount(ctxt, lw, w, le->next, d->left->next, lnull_cnt);
					if (!leftpcount && le->multi)
						leftpcount =
							pseudocount(ctxt, lw, w, le, d->left->next, lnull_cnt);
					if (!leftpcount && d->left->multi)
						leftpcount =
							pseudocount(ctxt, lw, w, le->next, d->left, lnull_cnt);
					if (!leftpcount && le->multi && d->left->multi)
						leftpcount =
							pseudocount(ctxt, lw, w, le, d->left, lnull_cnt);
				}

				if (Rmatch)
				{
					rightpcount = pseudocount(ctxt, w, rw, d->right->next, re->next, rnull_cnt);
					if (!rightpcount && d->right->multi)
						rightpcount =
							pseudocount(ctxt, w,rw, d->right, re->next, rnull_cnt);
					if (!rightpcount && re->multi)
						rightpcount =
							pseudocount(ctxt, w, rw, d->right->next, re, rnull_cnt);
					if (!rightpcount && d->right->multi && re->multi)
						rightpcount =
							pseudocount(ctxt, w, rw, d->right, re, rnull_cnt);
				}

				/* Total number where links are used on both sides */
				pseudototal = leftpcount && rightpcount;

				if (!pseudototal && leftpcount) {
					/* Evaluate using the left match, but not the right. */
					pseudototal =
						pseudocount(ctxt, w, rw, d->right, re, rnull_cnt);
				}
				if (!pseudototal && (le == NULL) && rightpcount) {
					/* Evaluate using the right match, but not the left. */
					pseudototal =
						pseudocount(ctxt, lw, w, le, d->left, lnull_cnt);
				}

				/* If pseudototal is zero (false), that implies that
				 * we know that the true total is zero. So we don't
				 * bother counting at all, in that case. */
				if (pseudototal)
				{
					Count_bin leftcount = zero;
					Count_bin rightcount = zero;
					if (Lmatch) {
						leftcount = do_count(mchxt, ctxt, lw, w, le->next, d->left->next, lnull_cnt);
						if (le->multi)
							hist_accumv(&leftcount, d->cost,
								do_count(mchxt, ctxt, lw, w, le, d->left->next, lnull_cnt));
						if (d->left->multi)
							hist_accumv(&leftcount, d->cost,
								 do_count(mchxt, ctxt, lw, w, le->next, d->left, lnull_cnt));
						if (le->multi && d->left->multi)
							hist_accumv(&leftcount, d->cost,
								do_count(mchxt, ctxt, lw, w, le, d->left, lnull_cnt));
					}

					if (Rmatch) {
						rightcount = do_count(mchxt, ctxt, w, rw, d->right->next, re->next, rnull_cnt);
						if (d->right->multi)
							hist_accumv(&rightcount, d->cost,
								do_count(mchxt, ctxt, w, rw, d->right,re->next, rnull_cnt));
						if (re->multi)
							hist_accumv(&rightcount, d->cost,
								do_count(mchxt, ctxt, w, rw, d->right->next, re, rnull_cnt));
						if (d->right->multi && re->multi)
							hist_accumv(&rightcount, d->cost,
								do_count(mchxt, ctxt, w, rw, d->right, re, rnull_cnt));
					}

					/* Total number where links are used on both sides */
					hist_muladd(&total, &leftcount, 0.0, &rightcount);

					if (0 < hist_total(&leftcount))
					{
						/* Evaluate using the left match, but not the right */
						hist_muladdv(&total, &leftcount, d->cost,
							do_count(mchxt, ctxt, w, rw, d->right, re, rnull_cnt));
					}
					if ((le == NULL) && (0 < hist_total(&rightcount)))
					{
						/* Evaluate using the right match, but not the left */
						hist_muladdv(&total, &rightcount, d->cost,
							do_count(mchxt, ctxt, lw, w, le, d->left, lnull_cnt));
					}

					/* Sigh. Overflows can and do occur, esp for the ANY language. */
					if (INT_MAX < hist_total(&total))
					{
#ifdef PERFORM_COUNT_HISTOGRAMMING
						total.total = INT_MAX;
#else
						total = INT_MAX;
#endif /* PERFORM_COUNT_HISTOGRAMMING */
						t->count = total;
						put_match_list(mchxt, m1);
						return total;
					}
				}
			}
		}
		put_match_list(mchxt, m1);
	}
	t->count = total;
	return total;
}
Exemple #23
0
bool string_matches_pattern (const char* string, const char* passed_pattern)
{
    /* is the whole pattern stars? ... */
    const char* p;
    bool all_stars;
    for (p = passed_pattern, all_stars = true;  *p;  p++)
	if (*p != '*')
	{
	    all_stars = false;
	    break;
	}

    /* ... if so, it matches everything */
    if (all_stars) return true;

    /* if wildcarding is disabled, just do a string match */
    if (*passed_pattern == '\\') return strequal (string, passed_pattern+1);

    char *pattern;
    strcpy (&pattern, passed_pattern);
	
    /* 
    split the pattern into non-star groups, eg "?[a-c]**[abe-hkr-s]?*" 
    => n_sub_pats = 2 sub_pats[1] = "?[a-c]", sub_pats[2] = "[abe-hkr-s]?"

    The idea is that each * (or run of them) means "omit as many characters
    as necessary (including none) in order to be able to match the next set
    of characters in the string"
    */

    /* allow for a * in [...] */
    int len = strlen (pattern);
    bool in_brackets = false;
    for (int i = 0;  i < len;  i++)
    {
	/* not perfect ... */
	if (pattern[i] == '[')
	    in_brackets = true;
	else if (pattern[i] == ']')
	    in_brackets = false;

	if (pattern[i] == '*' && in_brackets)
	    pattern[i] = 1;
    }

    char** sub_pats;
    int n_sub_pats;
    split_by_delimiter (pattern, &sub_pats, &n_sub_pats, "*");

    /* undo the star encoding */
    for (int j = 1;  j <= n_sub_pats;  j++)
    {
	len = strlen (sub_pats[j]);
	in_brackets = false;
	for (int i = 0;  i < len;  i++)
	{
	    /* not perfect ... */
	    if (sub_pats[j][i] == '[')
		in_brackets = true;
	    else if (sub_pats[j][i] == ']')
		in_brackets = false;

	    if (sub_pats[j][i] == 1 && in_brackets)
		sub_pats[j][i] = '*';
	}
    }

    /* does the whole pattern start and/or end with stars? */
    bool star_at_start = pattern[0] == '*';
    bool star_at_end = pattern[strlen(pattern)-1] == '*';

    bool matched = do_match (string, sub_pats, n_sub_pats, star_at_start,
								star_at_end);

    /* free-off allocated space*/
    words_free (sub_pats, n_sub_pats);

    free (pattern);
    return matched;
}