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; }
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; }
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; }
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; }
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; }
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; }
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; }
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(>his, 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 = >his; 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; }
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; }
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; }
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); }
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; } }
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); }
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; }
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; }
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; }
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; }
/* * 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 */ }
/** * 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; }
int x_match(Sentence sent, Connector *a, Connector *b) { return do_match(sent, a, b, 0, 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; }
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; }