/*- * Update the status of this vertex on the forced vertex queue. If * the vertex has become untileable set tp->done. This is supposed * to detect dislocations -- never call this routine with a completely * tiled vertex. * * Check for untileable vertices in check_vertex and stop tiling as * soon as one finds one. I don't know if it is possible to run out * of forced vertices while untileable vertices exist (or will * cavities inevitably appear). If this can happen, add_random_tile * might get called with an untileable vertex, causing ( n <= 1). * (This is what the tp->done checks for). * * A delayLoop celebrates the dislocation. */ static void check_vertex(ModeInfo * mi, fringe_node_c * vertex, tiling_c * tp) { rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES]; int n_hits = match_rules(vertex, hits, False); unsigned forced_sides = 0; if (vertex->rule_mask == 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Dislocation occurred!\n"); } tp->busyLoop = CELEBRATE; /* Should be able to recover */ } if (1 == find_completions(vertex, hits, n_hits, S_LEFT, 0 /*, False */ )) forced_sides |= S_LEFT; if (1 == find_completions(vertex, hits, n_hits, S_RIGHT, 0 /*, False */ )) forced_sides |= S_RIGHT; if (forced_sides == 0) { if (vertex->list_ptr != 0) { forced_node_c *node = *vertex->list_ptr; *vertex->list_ptr = node->next; if (node->next != 0) node->next->vertex->list_ptr = vertex->list_ptr; free(node); tp->forced.n_nodes--; if (!vertex->off_screen) tp->forced.n_visible--; vertex->list_ptr = 0; } } else { forced_node_c *node; if (vertex->list_ptr == 0) { if ((node = ALLOC_NODE(forced_node_c)) == NULL) return; node->vertex = vertex; node->next = tp->forced.first; if (tp->forced.first != 0) tp->forced.first->vertex->list_ptr = &(node->next); tp->forced.first = node; vertex->list_ptr = &(tp->forced.first); tp->forced.n_nodes++; if (!vertex->off_screen) tp->forced.n_visible++; } else node = *vertex->list_ptr; node->forced_sides = forced_sides; } }
void assist_find_symbol(Node* n, Scope* sc, Name symbol){ int max=10; MyVec<pair<Name,int>> completions; dbprintf("...completions:-"); find_completions(symbol, [&](Name s,int score)->void{ completions.push_back(std::make_pair(s,score)); } ); // todo sort them for (auto i=0; i<max && i<completions.size();i++){ auto& c=completions[i]; auto ni=sc->find_named_items_rec(c.first); if (ni){ // TODO: sort by distance from current locatino; // allow searching forward too. for (auto fd=ni->fn_defs; fd;fd=fd->next_of_name){ info(fd,"\t", str(fd->name)); fd->dump_signature(); } for (auto sd=ni->structs; sd;sd=sd->next_of_name){ info(sd,"\tstruct\t%s", str(sd->name)); } for (auto fd=ni->fields; fd;fd=fd->next_of_name){ info(fd,"\tfield\t%s.'t%s:", fd->owner->name_str(), str(fd->name)); fd->type()->dump_if(-1); } } } }
bool edit_interface_rep::complete_try () { tree st= subtree (et, path_up (tp)); if (is_compound (st)) return false; string s= st->label, ss; int end= last_item (tp); array<string> a; if (inside (LABEL) || inside (REFERENCE) || inside (PAGEREF)) { if (end != N(s)) return false; ss= copy (s); tree t= get_labels (); int i, n= N(t); for (i=0; i<n; i++) if (is_atomic (t[i]) && starts (t[i]->label, s)) a << string (t[i]->label (N(s), N(t[i]->label))); } else { if ((end==0) || (!is_iso_alpha (s[end-1])) || ((end!=N(s)) && is_iso_alpha (s[end]))) return false; int start= end-1; while ((start>0) && is_iso_alpha (s[start-1])) start--; ss= s (start, end); a= find_completions (drd, et, ss); } if (N(a) == 0) return false; complete_start (ss, a); return true; }
static void find_completions ( drd_info drd, tree t, hashset<string>& h, string prefix= "") { if (is_atomic (t)) { string s= t->label; int i= 0, n= N(s); while (i<n) { if (is_iso_alpha (s[i])) { int start= i; while ((i<n) && (is_iso_alpha (s[i]))) i++; string r= s (start, i); if (starts (r, prefix) && (r != prefix)) h->insert (r (N(prefix), N(r))); } else skip_symbol (s, i); } } else { int i, n= N(t); for (i=0; i<n; i++) if (drd->is_accessible_child (t, i)) find_completions (drd, t[i], h, prefix); } }
/*- * Whether the addition of a tile of vtype on the given side of vertex * would conform to the rules. The efficient way to do this would be * to add the new tile and then use the same type of search as in * match_rules. However, this function is not a performance * bottleneck (only needed for random tile additions, which are * relatively infrequent), so I will settle for a simpler implementation. */ static int legal_move(fringe_node_c * vertex, unsigned side, vertex_type_c vtype) { rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES]; vertex_type_c legal_vt[MAX_COMPL]; int n_hits, n_legal, i; n_hits = match_rules(vertex, hits, False); n_legal = find_completions(vertex, hits, n_hits, side, legal_vt /*, False */ ); for (i = 0; i < n_legal; i++) if (legal_vt[i] == vtype) return True; return False; }
/*- * Add a forced tile to a given forced vertex. Basically an easy job, * since we know what to add. But it might fail if adding the tile * would cause some untiled area to become enclosed. There is also another * more exotic culprit: we might have a dislocation. Fortunately, they * are very rare (the PRL article reported that perfect tilings of over * 2^50 tiles had been generated). There is a version of the algorithm * that doesn't produce dislocations, but it's a lot hairier than the * simpler version I used. */ static int add_forced_tile(ModeInfo * mi, forced_node_c * node) { tiling_c *tp = &tilings[MI_SCREEN(mi)]; unsigned side; vertex_type_c vtype; rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES]; int n; if (node->forced_sides == (S_LEFT | S_RIGHT)) side = NRAND(2) ? S_LEFT : S_RIGHT; else side = node->forced_sides; n = match_rules(node->vertex, hits, True); n = find_completions(node->vertex, hits, n, side, &vtype /*, True */ ); if (n <= 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_forced_tile()\n"); (void) fprintf(stderr, "n = %d\n", n); } } return add_tile(mi, node->vertex, side, vtype); }
static array<string> find_completions (drd_info drd, tree t, string prefix= "") { hashset<string> h; find_completions (drd, t, h, prefix); return as_completions (h); }
/*------------------------------------------------------------------------ * x_snmp - SNMP shell that does MIB object name completion *------------------------------------------------------------------------ */ int x_snmp(int stdin, int stdout, int stderr, int nargs, char *args[]) { int ch; char snmpservstr[BUFSIZE]; struct tty *ttyp; int ct, i, mode; IPaddr destmach; if (nargs != 2) { snusage(stdout); return OK; } args++; nargs--; sninit(); if ((destmach = name2ip(*args)) == (IPaddr)SYSERR) { fprintf(stdout,"snmp: couldn't resolve name %s\n", *args); return OK; } ip2dot(snmpservstr, destmach); sprintf(snmpservstr + strlen(snmpservstr), ":%d", SNMPPORT); ttyp = &ttytab[stdin]; ct = 0; mode = M_CHARIN; next_completion = num_completions = 0; control(stdin, TTC_MODER); /* put stdin into raw mode */ write(stdout, PROMPT, strlen(PROMPT)); /* print the prompt */ while (TRUE) { if ((ch = getc(stdin)) == EOF) { write(stdout, EXITSTR, strlen(EXITSTR)); putc(stdout, '\n'); control(stdin, TTC_MODEC); return OK; } if (ch == SYSERR) { return SYSERR; } if (ch == COMPLETE) { if (mode == M_CHARIN) { mode = M_COMPL; /* find beginning of word */ for (i=ct-1; i >= 0 && buf[i] != ' '; i--) /* empty */; s2clen = ct - ++i; strncpy(str2compl, buf + i, s2clen); find_completions(); } if (num_completions == 0) { putc(stdout, BELL); mode = M_CHARIN; } else print_completion(&ct, stdout); continue; } if (ch == KILLWORD && mode == M_COMPL) { /* kill word in compl. mode goes back to original string to complete. */ eraseword(&ct, stdout); strncpy(buf + ct, str2compl, s2clen); write(stdout, buf + ct, s2clen); ct += s2clen; mode = M_CHARIN; next_completion = num_completions = 0; continue; } if (mode == M_COMPL) { /* && ch != KILLWORD */ mode = M_CHARIN; str2compl[(s2clen = 0)] = '\0'; num_completions = next_completion = 0; } if (ch == KILLWORD) { /* && mode != M_COMPL */ eraseword(&ct, stdout); continue; } if ((ch == ttyp->tty_tchars.tc_kill)) { eraseall(ct, stdout); ct = 0; continue; } if ((ch == ttyp->tty_tchars.tc_erase)) { if (ct > 0) erase1(--ct, stdout); continue; } if ((ch == '\r') || (ch == '\n')) { echoch(ch, stdout); buf[ct] = '\0'; if (strequ(buf, EXITSTR)) { control(stdin, TTC_MODEC); return OK; } sendquery(stdout, snmpservstr); for (i = 0; i < BUFSIZE; i++) buf[i] = '\0'; write(stdout, PROMPT, strlen(PROMPT)); ct = 0; continue; } /* all non-special characters */ if (ct == BUFSIZE - 1) putc(stdout, BELL); else { echoch(ch, stdout); buf[ct++] = ch; } } return OK; }
/*- * Add a randomly chosen tile to a given vertex. This requires more checking * as we must make sure the new tile conforms to the vertex rules at every * vertex it touches. */ static void add_random_tile(fringe_node_c * vertex, ModeInfo * mi) { fringe_node_c *right, *left, *far; int i, j, n, n_hits, n_good; unsigned side, fc, no_good, s; vertex_type_c vtypes[MAX_COMPL]; rule_match_c hits[MAX_TILES_PER_VERTEX * N_VERTEX_RULES]; tiling_c *tp = &tilings[MI_SCREEN(mi)]; if (MI_NPIXELS(mi) > 2) { tp->thick_color = NRAND(MI_NPIXELS(mi)); /* Insure good contrast */ tp->thin_color = (NRAND(2 * MI_NPIXELS(mi) / 3) + tp->thick_color + MI_NPIXELS(mi) / 6) % MI_NPIXELS(mi); } else { unsigned long temp = tp->thick_color; tp->thick_color = tp->thin_color; tp->thin_color = temp; } n_hits = match_rules(vertex, hits, False); side = NRAND(2) ? S_LEFT : S_RIGHT; n = find_completions(vertex, hits, n_hits, side, vtypes /*, False */ ); /* One answer would mean a forced tile. */ if (n <= 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n = %d\n", n); } } no_good = 0; n_good = n; for (i = 0; i < n; i++) { fc = fringe_changes(mi, vertex, side, vtypes[i], &right, &far, &left); if (fc & FC_BAG) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "fc = %d, FC_BAG = %d\n", fc, FC_BAG); } } if (right) { s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_LEFT)) ? S_RIGHT : S_LEFT); if (!legal_move(right, s, VT_RIGHT(vtypes[i]))) { no_good |= (1 << i); n_good--; continue; } } if (left) { s = (((fc & FC_CUT_FAR) && (fc & FC_CUT_RIGHT)) ? S_LEFT : S_RIGHT); if (!legal_move(left, s, VT_LEFT(vtypes[i]))) { no_good |= (1 << i); n_good--; continue; } } if (far) { s = ((fc & FC_CUT_LEFT) ? S_RIGHT : S_LEFT); if (!legal_move(far, s, VT_FAR(vtypes[i]))) { no_good |= (1 << i); n_good--; } } } if (n_good <= 0) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); (void) fprintf(stderr, "n_good = %d\n", n_good); } } n = NRAND(n_good); for (i = j = 0; i <= n; i++, j++) while (no_good & (1 << j)) j++; if (!add_tile(mi, vertex, side, vtypes[j - 1])) { tp->done = True; if (MI_IS_VERBOSE(mi)) { (void) fprintf(stderr, "Weirdness in add_random_tile()\n"); } free_penrose(tp); } }