示例#1
0
文件: utils.c 项目: sria91/nano
/* If we are searching backwards, we will find the last match that
 * starts no later than start.  Otherwise we find the first match
 * starting no earlier than start.  If we are doing a regexp search, we
 * fill in the global variable regmatches with at most 9 subexpression
 * matches.  Also, all .rm_so elements are relative to the start of the
 * whole match, so regmatches[0].rm_so == 0. */
const char *strstrwrapper(const char *haystack, const char *needle,
	const char *start)
{
    /* start can be 1 character before the start or after the end of the
     * line.  In either case, we just say no match was found. */
    if ((start > haystack && *(start - 1) == '\0') || start < haystack)
	return NULL;

    assert(haystack != NULL && needle != NULL && start != NULL);

#ifdef HAVE_REGEX_H
    if (ISSET(USE_REGEXP)) {
#ifndef NANO_TINY
	if (ISSET(BACKWARDS_SEARCH)) {
	    if (regexec(&search_regexp, haystack, 1, regmatches,
		0) == 0 && haystack + regmatches[0].rm_so <= start) {
		const char *retval = haystack + regmatches[0].rm_so;

		/* Search forward until there are no more matches. */
		while (regexec(&search_regexp, retval + 1, 1,
			regmatches, REG_NOTBOL) == 0 &&
			retval + regmatches[0].rm_so + 1 <= start)
		    retval += regmatches[0].rm_so + 1;
		/* Finally, put the subexpression matches in global
		 * variable regmatches.  The REG_NOTBOL flag doesn't
		 * matter now. */
		regexec(&search_regexp, retval, 10, regmatches, 0);
		return retval;
	    }
	} else
#endif /* !NANO_TINY */
	if (regexec(&search_regexp, start, 10, regmatches,
		(start > haystack) ? REG_NOTBOL : 0) == 0) {
	    const char *retval = start + regmatches[0].rm_so;

	    regexec(&search_regexp, retval, 10, regmatches, 0);
	    return retval;
	}
	return NULL;
    }
#endif /* HAVE_REGEX_H */
#if !defined(NANO_TINY) || !defined(DISABLE_SPELLER)
    if (ISSET(CASE_SENSITIVE)) {
#ifndef NANO_TINY
	if (ISSET(BACKWARDS_SEARCH))
	    return revstrstr(haystack, needle, start);
	else
#endif
	    return strstr(start, needle);
    }
#endif /* !DISABLE_SPELLER || !NANO_TINY */
#ifndef NANO_TINY
    else if (ISSET(BACKWARDS_SEARCH))
	return mbrevstrcasestr(haystack, needle, start);
#endif
    return mbstrcasestr(start, needle);
}
示例#2
0
/* Load the recorded cursor positions for files that were edited. */
void load_poshistory(void)
{
	FILE *hisfile = fopen(poshistname, "rb");

	if (hisfile == NULL) {
		if (errno != ENOENT) {
			/* When reading failed, don't save history when we quit. */
			UNSET(POSITIONLOG);
			history_error(N_("Error reading %s: %s"), poshistname, strerror(errno));
		}
	} else {
		char *line = NULL, *lineptr, *xptr;
		size_t buf_len = 0;
		ssize_t read, count = 0;
		poshiststruct *record_ptr = NULL, *newrecord;

		/* Read and parse each line, and store the extracted data. */
		while ((read = getline(&line, &buf_len, hisfile)) > 5) {
			/* Decode nulls as embedded newlines. */
			unsunder(line, read);

			/* Find where the x index and line number are in the line. */
			xptr = revstrstr(line, " ", line + read - 3);
			if (xptr == NULL)
				continue;
			lineptr = revstrstr(line, " ", xptr - 2);
			if (lineptr == NULL)
				continue;

			/* Now separate the three elements of the line. */
			*(xptr++) = '\0';
			*(lineptr++) = '\0';

			/* Create a new position record. */
			newrecord = (poshiststruct *)nmalloc(sizeof(poshiststruct));
			newrecord->filename = mallocstrcpy(NULL, line);
			newrecord->lineno = atoi(lineptr);
			newrecord->xno = atoi(xptr);
			newrecord->next = NULL;

			/* Add the record to the list. */
			if (position_history == NULL)
				position_history = newrecord;
			else
				record_ptr->next = newrecord;

			record_ptr = newrecord;

			/* Impose a limit, so the file will not grow indefinitely. */
			if (++count > 200) {
				poshiststruct *drop_record = position_history;

				position_history = position_history->next;

				free(drop_record->filename);
				free(drop_record);
			}
		}
		fclose(hisfile);
		free(line);

		stat(poshistname, &stat_of_positions_file);
	}
}