/* Search for the last string without prompting. */ void do_research(void) { linestruct *fileptr = openfile->current; size_t fileptr_x = openfile->current_x; size_t pww_save = openfile->placewewant; bool didfind; focusing = TRUE; #ifndef DISABLE_HISTORIES /* If nothing was searched for yet during this run of nano, but * there is a search history, take the most recent item. */ if (last_search[0] == '\0' && searchbot->prev != NULL) last_search = mallocstrcpy(last_search, searchbot->prev->data); #endif if (last_search[0] != '\0') { #ifdef HAVE_REGEX_H /* Since answer is "", use last_search! */ if (ISSET(USE_REGEXP) && !regexp_init(last_search)) return; #endif findnextstr_wrap_reset(); didfind = findnextstr( #ifndef DISABLE_SPELLER FALSE, #endif openfile->current, openfile->current_x, last_search, NULL); /* If we found something, and we're back at the exact same spot * where we started searching, then this is the only occurrence. */ if (fileptr == openfile->current && fileptr_x == openfile->current_x && didfind) { statusbar(_("This is the only occurrence")); } } else statusbar(_("No current search pattern")); openfile->placewewant = xplustabs(); edit_redraw(fileptr, pww_save); search_replace_abort(); }
/* Set up the system variables for a search or replace. If use_answer * is TRUE, only set backupstring to answer. Return -2 to run the * opposite program (search -> replace, replace -> search), return -1 if * the search should be canceled (due to Cancel, a blank search string, * Go to Line, or a failed regcomp()), return 0 on success, and return 1 * on rerun calling program. * * replacing is TRUE if we call from do_replace(), and FALSE if called * from do_search(). */ int search_init(bool replacing, bool use_answer) { int i = 0; char *buf; static char *backupstring = NULL; /* The search string we'll be using. */ /* If backupstring doesn't exist, initialize it to "". */ if (backupstring == NULL) backupstring = mallocstrcpy(NULL, ""); /* If use_answer is TRUE, set backupstring to answer and get out. */ if (use_answer) { backupstring = mallocstrcpy(backupstring, answer); return 0; } /* We display the search prompt below. If the user types a partial * search string and then Replace or a toggle, we will return to * do_search() or do_replace() and be called again. In that case, * we should put the same search string back up. */ focusing = TRUE; if (last_search[0] != '\0') { char *disp = display_string(last_search, 0, COLS / 3, FALSE); buf = charalloc(strlen(disp) + 7); /* We use (COLS / 3) here because we need to see more on the line. */ sprintf(buf, " [%s%s]", disp, (strlenpt(last_search) > COLS / 3) ? "..." : ""); free(disp); } else buf = mallocstrcpy(NULL, ""); /* This is now one simple call. It just does a lot. */ i = do_prompt(FALSE, #ifndef DISABLE_TABCOMP TRUE, #endif replacing ? MREPLACE : MWHEREIS, backupstring, #ifndef DISABLE_HISTORIES &search_history, #endif /* TRANSLATORS: This is the main search prompt. */ edit_refresh, "%s%s%s%s%s%s", _("Search"), #ifndef NANO_TINY /* TRANSLATORS: The next three strings are modifiers of the search prompt. */ ISSET(CASE_SENSITIVE) ? _(" [Case Sensitive]") : #endif "", #ifdef HAVE_REGEX_H ISSET(USE_REGEXP) ? _(" [Regexp]") : #endif "", #ifndef NANO_TINY ISSET(BACKWARDS_SEARCH) ? _(" [Backwards]") : #endif "", replacing ? #ifndef NANO_TINY /* TRANSLATORS: The next two strings are modifiers of the search prompt. */ openfile->mark_set ? _(" (to replace) in selection") : #endif _(" (to replace)") : "", buf); fflush(stderr); /* Release buf now that we don't need it anymore. */ free(buf); free(backupstring); backupstring = NULL; /* Cancel any search, or just return with no previous search. */ if (i == -1 || (i < 0 && *last_search == '\0') || (!replacing && i == 0 && *answer == '\0')) { statusbar(_("Cancelled")); return -1; } else { functionptrtype func = func_from_key(&i); if (i == -2 || i == 0 ) { #ifdef HAVE_REGEX_H /* Use last_search if answer is an empty string, or * answer if it isn't. */ if (ISSET(USE_REGEXP) && !regexp_init((i == -2) ? last_search : answer)) return -1; #endif ; #ifndef NANO_TINY } else if (func == case_sens_void) { TOGGLE(CASE_SENSITIVE); backupstring = mallocstrcpy(backupstring, answer); return 1; } else if (func == backwards_void) { TOGGLE(BACKWARDS_SEARCH); backupstring = mallocstrcpy(backupstring, answer); return 1; #endif #ifdef HAVE_REGEX_H } else if (func == regexp_void) { TOGGLE(USE_REGEXP); backupstring = mallocstrcpy(backupstring, answer); return 1; #endif } else if (func == do_replace || func == flip_replace_void) { backupstring = mallocstrcpy(backupstring, answer); return -2; /* Call the opposite search function. */ } else if (func == do_gotolinecolumn_void) { do_gotolinecolumn(openfile->current->lineno, openfile->placewewant + 1, TRUE, TRUE); /* Put answer up on the statusbar and * fall through. */ return 3; } else { return -1; } } return 0; }
/* perform a forward search across all modules */ int perform_next_find (GHolder * h, GScroll * gscroll) { int y, x, j, n, rc; char buf[REGEX_ERROR]; char *data; regex_t regex; GModule module; GSubList *sub_list; getmaxyx (stdscr, y, x); if (find_t.pattern == NULL || *find_t.pattern == '\0') return 1; /* compile and initialize regexp */ if (regexp_init (®ex, find_t.pattern)) return 1; /* use last find_t.module and start search */ for (module = find_t.module; module < TOTAL_MODULES; module++) { n = h[module].idx; for (j = find_t.next_parent_idx; j < n; j++, find_t.next_idx++) { data = h[module].items[j].metrics->data; rc = regexec (®ex, data, 0, NULL, 0); if (rc != 0 && rc != REG_NOMATCH) { regerror (rc, ®ex, buf, sizeof (buf)); draw_header (stdscr, buf, "%s", y - 1, 0, x, WHITE_RED, 0); refresh (); regfree (®ex); return 1; } else if (rc == 0 && !find_t.look_in_sub) { find_t.look_in_sub = 1; goto found; } else { sub_list = h[module].items[j].sub_list; if (find_next_sub_item (sub_list, ®ex) == 0) goto found; } } /* reset find */ find_t.next_idx = 0; find_t.next_parent_idx = 0; find_t.next_sub_idx = 0; if (find_t.module != module) { reset_scroll_offsets (gscroll); gscroll->expanded = 0; } if (module == TOTAL_MODULES - 1) { find_t.module = 0; goto out; } } found: perform_find_dash_scroll (gscroll, module); out: regfree (®ex); return 0; }
/* Creates the rubinius object universe from scratch. */ void cpu_bootstrap(STATE) { OBJECT cls, obj, tmp, tmp2; int i; /* Class is created first by hand, and twittle to setup the internal recursion. */ cls = NEW_OBJECT(Qnil, CLASS_FIELDS); cls->klass = cls; class_set_instance_fields(cls, I2N(CLASS_FIELDS)); class_set_has_ivars(cls, Qtrue); class_set_object_type(cls, I2N(ClassType)); cls->obj_type = ClassType; BC(class) = cls; obj = _object_basic_class(state, Qnil); BC(object) = obj; BC(module) = _module_basic_class(state, obj); class_set_superclass(cls, BC(module)); BC(metaclass) = _metaclass_basic_class(state, cls); class_set_object_type(BC(metaclass), I2N(MetaclassType)); BC(tuple) = _tuple_basic_class(state, obj); BC(hash) = _hash_basic_class(state, obj); BC(lookuptable) = _lookuptable_basic_class(state, obj); BC(methtbl) = _methtbl_basic_class(state, BC(lookuptable)); object_create_metaclass(state, obj, cls); object_create_metaclass(state, BC(module), object_metaclass(state, obj)); object_create_metaclass(state, BC(class), object_metaclass(state, BC(module))); object_create_metaclass(state, BC(tuple), (OBJECT)0); object_create_metaclass(state, BC(hash), (OBJECT)0); object_create_metaclass(state, BC(lookuptable), (OBJECT)0); object_create_metaclass(state, BC(methtbl), (OBJECT)0); module_setup_fields(state, object_metaclass(state, obj)); module_setup_fields(state, object_metaclass(state, BC(module))); module_setup_fields(state, object_metaclass(state, BC(class))); module_setup_fields(state, object_metaclass(state, BC(tuple))); module_setup_fields(state, object_metaclass(state, BC(hash))); module_setup_fields(state, object_metaclass(state, BC(lookuptable))); module_setup_fields(state, object_metaclass(state, BC(methtbl))); BC(symbol) = _symbol_class(state, obj); BC(array) = _array_class(state, obj); BC(bytearray) = _bytearray_class(state, obj); BC(string) = _string_class(state, obj); BC(symtbl) = _symtbl_class(state, obj); BC(cmethod) = _cmethod_class(state, obj); BC(io) = _io_class(state, obj); BC(blokenv) = _blokenv_class(state, obj); BC(icache) = _icache_class(state, obj); BC(staticscope) = _staticscope_class(state, obj); class_set_object_type(BC(bytearray), I2N(ByteArrayType)); class_set_object_type(BC(string), I2N(StringType)); class_set_object_type(BC(methtbl), I2N(MTType)); class_set_object_type(BC(tuple), I2N(TupleType)); class_set_object_type(BC(hash), I2N(HashType)); class_set_object_type(BC(lookuptable), I2N(LookupTableType)); /* The symbol table */ state->global->symbols = symtbl_new(state); module_setup(state, obj, "Object"); module_setup(state, cls, "Class"); module_setup(state, BC(module), "Module"); module_setup(state, BC(metaclass), "MetaClass"); module_setup(state, BC(symbol), "Symbol"); module_setup(state, BC(tuple), "Tuple"); module_setup(state, BC(array), "Array"); module_setup(state, BC(bytearray), "ByteArray"); module_setup(state, BC(hash), "Hash"); module_setup(state, BC(lookuptable), "LookupTable"); module_setup(state, BC(string), "String"); module_setup(state, BC(symtbl), "SymbolTable"); module_setup(state, BC(methtbl), "MethodTable"); module_setup(state, BC(cmethod), "CompiledMethod"); module_setup(state, BC(io), "IO"); module_setup(state, BC(blokenv), "BlockEnvironment"); module_setup(state, BC(icache), "InlineCache"); module_setup(state, BC(staticscope), "StaticScope"); class_set_object_type(BC(array), I2N(ArrayType)); class_set_object_type(BC(cmethod), I2N(CMethodType)); class_set_object_type(BC(blokenv), I2N(BlockEnvType)); rbs_const_set(state, obj, "Symbols", state->global->symbols); BC(nil_class) = rbs_class_new(state, "NilClass", 0, obj); BC(true_class) = rbs_class_new(state, "TrueClass", 0, obj); BC(false_class) = rbs_class_new(state, "FalseClass", 0, obj); tmp = rbs_class_new(state, "Numeric", 0, obj); tmp2 = rbs_class_new(state, "Integer", 0, tmp); BC(fixnum_class) = rbs_class_new(state, "Fixnum", 0, tmp2); class_set_object_type(BC(fixnum_class), I2N(FixnumType)); BC(bignum) = rbs_class_new(state, "Bignum", 0, tmp2); class_set_object_type(BC(bignum), I2N(BignumType)); bignum_init(state); BC(floatpoint) = rbs_class_new(state, "Float", 0, tmp); class_set_object_type(BC(floatpoint), I2N(FloatType)); BC(undef_class) = rbs_class_new(state, "UndefClass", 0, obj); BC(fastctx) = rbs_class_new(state, "MethodContext", 0, obj); BC(methctx) = BC(fastctx); BC(blokctx) = rbs_class_new(state, "BlockContext", 0, BC(fastctx)); BC(task) = rbs_class_new(state, "Task", 0, obj); class_set_object_type(BC(task), I2N(TaskType)); BC(iseq) = rbs_class_new(state, "InstructionSequence", 0, BC(bytearray)); class_set_object_type(BC(iseq), I2N(ISeqType)); #define bcs(name, sup, string) BC(name) = _ ## name ## _class(state, sup); \ module_setup(state, BC(name), string); /* the special_classes C array is use do quickly calculate the class of an immediate by just indexing into the array using (obj & 0x1f) */ /* fixnum, symbol, and custom can have a number of patterns below 0x1f, so we fill them all. */ for(i = 0; i < SPECIAL_CLASS_SIZE; i += 4) { state->global->special_classes[i + 0] = Qnil; state->global->special_classes[i + 1] = BC(fixnum_class); state->global->special_classes[i + 2] = Qnil; if(((i + 3) & 0x7) == 0x3) { state->global->special_classes[i + 3] = BC(symbol); } else { state->global->special_classes[i + 3] = CUSTOM_CLASS; } } /* These only have one value, so they only need one spot in the array */ state->global->special_classes[(intptr_t)Qundef] = BC(undef_class); state->global->special_classes[(intptr_t)Qfalse] = BC(false_class); state->global->special_classes[(intptr_t)Qnil ] = BC(nil_class); state->global->special_classes[(intptr_t)Qtrue ] = BC(true_class); bcs(regexp, obj, "Regexp"); class_set_object_type(BC(regexp), I2N(RegexpType)); bcs(regexpdata, obj, "RegexpData"); class_set_object_type(BC(regexpdata), I2N(RegexpDataType)); bcs(matchdata, obj, "MatchData"); cpu_bootstrap_exceptions(state); rbs_module_new(state, "Rubinius", BC(object)); Init_list(state); Init_cpu_task(state); Init_ffi(state); regexp_init(state); selector_init(state); send_site_init(state); rbs_const_set(state, rbs_const_get(state, BASIC_CLASS(object), "Rubinius"), "Primitives", cpu_populate_prim_names(state)); state->global->external_ivars = lookuptable_new(state); }