⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 readline.c

📁 asterisk 是一个很有知名度开源软件
💻 C
📖 第 1 页 / 共 3 页
字号:
					continue;				size = 16;				with = realloc(to, size);				len = 0;				from_len = strlen(from);				for (; *cmd && *cmd != delim; cmd++) {					if (len + from_len + 1 >= size) {						size += from_len + 1;						with = realloc(with, size);					}					if (*cmd == '&') {						/* safe */						(void) strcpy(&with[len], from);						len += from_len;						continue;					}					if (*cmd == '\\'					    && (*(cmd + 1) == delim						|| *(cmd + 1) == '&'))						cmd++;					with[len++] = *cmd;				}				with[len] = '\0';				to = with;				tempcmd = _rl_compat_sub(line, from, to,				    (g_on) ? 1 : 0);				free(line);				line = tempcmd;				g_on = 0;			}		}	}	arr = history_tokenize(line);	free(line);		/* no more needed */	if (arr && *arr == NULL)		free(arr), arr = NULL;	if (!arr)		return (-1);	/* find out max valid idx to array of array */	max = 0;	for (i = 0; arr[i]; i++)		max++;	max--;	/* set boundaries to something relevant */	if (start < 0)		start = 1;	if (end < 0)		end = max - ((end < -1) ? 1 : 0);	/* check boundaries ... */	if (start > max || end > max || start > end)		return (-1);	for (i = 0; i <= max; i++) {		char *temp;		if (h_on && (i == 1 || h_on > 1) &&		    (temp = strrchr(arr[i], '/')))			*(temp + 1) = '\0';		if (t_on && (i == 1 || t_on > 1) &&		    (temp = strrchr(arr[i], '/')))			(void) strcpy(arr[i], temp + 1);		if (r_on && (i == 1 || r_on > 1) &&		    (temp = strrchr(arr[i], '.')))			*temp = '\0';		if (e_on && (i == 1 || e_on > 1) &&		    (temp = strrchr(arr[i], '.')))			(void) strcpy(arr[i], temp);	}	cmdsize = 1, cmdlen = 0;	tempcmd = malloc(cmdsize);	for (i = start; start <= i && i <= end; i++) {		int arr_len;		arr_len = strlen(arr[i]);		if (cmdlen + arr_len + 1 >= cmdsize) {			cmdsize += arr_len + 1;			tempcmd = realloc(tempcmd, cmdsize);		}		(void) strcpy(&tempcmd[cmdlen], arr[i]);	/* safe */		cmdlen += arr_len;		tempcmd[cmdlen++] = ' ';	/* add a space */	}	while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1]))		cmdlen--;	tempcmd[cmdlen] = '\0';	*result = tempcmd;	for (i = 0; i <= max; i++)		free(arr[i]);	free(arr), arr = (char **) NULL;	return (p_on) ? 2 : 1;}/* * csh-style history expansion */inthistory_expand(char *str, char **output){	int i, retval = 0, idx;	size_t size;	char *temp, *result;	if (h == NULL || e == NULL)		rl_initialize();	*output = strdup(str);	/* do it early */	if (str[0] == history_subst_char) {		/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */		temp = alloca(4 + strlen(str) + 1);		temp[0] = temp[1] = history_expansion_char;		temp[2] = ':';		temp[3] = 's';		(void) strcpy(temp + 4, str);		str = temp;	}#define	ADD_STRING(what, len) 						\	{								\		if (idx + len + 1 > size)				\			result = realloc(result, (size += len + 1));	\		(void)strncpy(&result[idx], what, len);			\		idx += len;						\		result[idx] = '\0';					\	}	result = NULL;	size = idx = 0;	for (i = 0; str[i];) {		int start, j, loop_again;		size_t len;		loop_again = 1;		start = j = i;loop:		for (; str[j]; j++) {			if (str[j] == '\\' &&			    str[j + 1] == history_expansion_char) {				(void) strcpy(&str[j], &str[j + 1]);				continue;			}			if (!loop_again) {				if (str[j] == '?') {					while (str[j] && str[++j] != '?');					if (str[j] == '?')						j++;				} else if (isspace((unsigned char) str[j]))					break;			}			if (str[j] == history_expansion_char			    && !strchr(history_no_expand_chars, str[j + 1])			    && (!history_inhibit_expansion_function ||			    (*history_inhibit_expansion_function)(str, j) == 0))				break;		}		if (str[j] && str[j + 1] != '#' && loop_again) {			i = j;			j++;			if (str[j] == history_expansion_char)				j++;			loop_again = 0;			goto loop;		}		len = i - start;		temp = &str[start];		ADD_STRING(temp, len);		if (str[i] == '\0' || str[i] != history_expansion_char		    || str[i + 1] == '#') {			len = j - i;			temp = &str[i];			ADD_STRING(temp, len);			if (start == 0)				retval = 0;			else				retval = 1;			break;		}		retval = _history_expand_command(&str[i], (size_t) (j - i),		    &temp);		if (retval != -1) {			len = strlen(temp);			ADD_STRING(temp, len);		}		i = j;	}			/* for(i ...) */	if (retval == 2) {		add_history(temp);#ifdef GDB_411_HACK		/* gdb 4.11 has been shipped with readline, where */		/* history_expand() returned -1 when the line	  */		/* should not be executed; in readline 2.1+	  */		/* it should return 2 in such a case		  */		retval = -1;#endif	}	free(*output);	*output = result;	return (retval);}/* * Parse the string into individual tokens, similarily to how shell would do it. */char **history_tokenize(const char *str){	int size = 1, result_idx = 0, i, start;	size_t len;	char **result = NULL, *temp, delim = '\0';	for (i = 0; str[i]; i++) {		while (isspace((unsigned char) str[i]))			i++;		start = i;		for (; str[i]; i++) {			if (str[i] == '\\') {				if (str[i+1] != '\0')					i++;			} else if (str[i] == delim)				delim = '\0';			else if (!delim &&				    (isspace((unsigned char) str[i]) ||				strchr("()<>;&|$", str[i])))				break;			else if (!delim && strchr("'`\"", str[i]))				delim = str[i];		}		if (result_idx + 2 >= size) {			size <<= 1;			result = realloc(result, size * sizeof(char *));		}		len = i - start;		temp = malloc(len + 1);		(void) strncpy(temp, &str[start], len);		temp[len] = '\0';		result[result_idx++] = temp;		result[result_idx] = NULL;	}	return (result);}/* * limit size of history record to ``max'' events */voidstifle_history(int max){	HistEvent ev;	if (h == NULL || e == NULL)		rl_initialize();	if (history(h, &ev, H_SETSIZE, max) == 0)		max_input_history = max;}/* * "unlimit" size of history - set the limit to maximum allowed int value */intunstifle_history(void){	HistEvent ev;	int omax;	history(h, &ev, H_SETSIZE, INT_MAX);	omax = max_input_history;	max_input_history = INT_MAX;	return (omax);		/* some value _must_ be returned */}inthistory_is_stifled(void){	/* cannot return true answer */	return (max_input_history != INT_MAX);}/* * read history from a file given */intread_history(const char *filename){	HistEvent ev;	if (h == NULL || e == NULL)		rl_initialize();	return (history(h, &ev, H_LOAD, filename));}/* * write history to a file given */intwrite_history(const char *filename){	HistEvent ev;	if (h == NULL || e == NULL)		rl_initialize();	return (history(h, &ev, H_SAVE, filename));}/* * returns history ``num''th event * * returned pointer points to static variable */HIST_ENTRY *history_get(int num){	static HIST_ENTRY she;	HistEvent ev;	int i = 1, curr_num;	if (h == NULL || e == NULL)		rl_initialize();	/* rewind to beginning */	if (history(h, &ev, H_CURR) != 0)		return (NULL);	curr_num = ev.num;	if (history(h, &ev, H_LAST) != 0)		return (NULL);	/* error */	while (i < num && history(h, &ev, H_PREV) == 0)		i++;	if (i != num)		return (NULL);	/* not so many entries */	she.line = ev.str;	she.data = NULL;	/* rewind history to the same event it was before */	(void) history(h, &ev, H_FIRST);	(void) history(h, &ev, H_NEXT_EVENT, curr_num);	return (&she);}/* * add the line to history table */intadd_history(const char *line){	HistEvent ev;	if (h == NULL || e == NULL)		rl_initialize();	(void) history(h, &ev, H_ENTER, line);	if (history(h, &ev, H_GETSIZE) == 0)		history_length = ev.num;	return (!(history_length > 0));	/* return 0 if all is okay */}/* * clear the history list - delete all entries */voidclear_history(void){	HistEvent ev;	history(h, &ev, H_CLEAR);}/* * returns offset of the current history event */intwhere_history(void){	HistEvent ev;	int curr_num, off;	if (history(h, &ev, H_CURR) != 0)		return (0);	curr_num = ev.num;	history(h, &ev, H_FIRST);	off = 1;	while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)		off++;	return (off);}/* * returns current history event or NULL if there is no such event */HIST_ENTRY *current_history(void){	return (_move_history(H_CURR));}/* * returns total number of bytes history events' data are using */inthistory_total_bytes(void){	HistEvent ev;	int curr_num, size;	if (history(h, &ev, H_CURR) != 0)		return (-1);	curr_num = ev.num;	history(h, &ev, H_FIRST);	size = 0;	do		size += strlen(ev.str);	while (history(h, &ev, H_NEXT) == 0);	/* get to the same position as before */	history(h, &ev, H_PREV_EVENT, curr_num);	return (size);}/* * sets the position in the history list to ``pos'' */inthistory_set_pos(int pos){	HistEvent ev;	int off, curr_num;	if (pos > history_length || pos < 0)		return (-1);	history(h, &ev, H_CURR);	curr_num = ev.num;	history(h, &ev, H_FIRST);	off = 0;	while (off < pos && history(h, &ev, H_NEXT) == 0)		off++;	if (off != pos) {	/* do a rollback in case of error */		history(h, &ev, H_FIRST);		history(h, &ev, H_NEXT_EVENT, curr_num);		return (-1);	}	return (0);}/* * returns previous event in history and shifts pointer accordingly */HIST_ENTRY *previous_history(void){	return (_move_history(H_PREV));}/* * returns next event in history and shifts pointer accordingly */HIST_ENTRY *next_history(void){	return (_move_history(H_NEXT));}/* * generic history search function */static int_history_search_gen(const char *str, int direction, int pos){	HistEvent ev;	const char *strp;	int curr_num;	if (history(h, &ev, H_CURR) != 0)		return (-1);	curr_num = ev.num;	for (;;) {		strp = strstr(ev.str, str);		if (strp && (pos < 0 || &ev.str[pos] == strp))			return (int) (strp - ev.str);		if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0)			break;	}	history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);	return (-1);}/* * searches for first history event containing the str */inthistory_search(const char *str, int direction){	return (_history_search_gen(str, direction, -1));}/* * searches for first history event beginning with str */inthistory_search_prefix(const char *str, int direction){	return (_history_search_gen(str, direction, 0));}/* * search for event in history containing str, starting at offset

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -