Beispiel #1
0
// Display the content of a file in the hud
R_API char *r_cons_hud_file(const char *f) {
	char *s = r_file_slurp (f, NULL);
	if (s) {
		char *ret = r_cons_hud_string (s);
		free (s);
		return ret;
	}
	return NULL;
}
Beispiel #2
0
// Display the content of a file in the hud
R_API char *r_cons_hud_file(const char *f, const bool usecolor) {
	char *s = r_file_slurp (f, NULL);
	if (s) {
		char *ret = r_cons_hud_string (s, usecolor);
		free (s);
		if (!ret)
			ret = strdup ("");
		return ret;
	}
	return NULL;
}
Beispiel #3
0
R_API int r_cons_grepbuf(char *buf, int len) {
	RCons *cons = r_cons_singleton ();
	char *tline, *tbuf, *p, *out, *in = buf;
	int ret, total_lines = 0, buffer_len = 0, l = 0, tl = 0;
	bool show = false;
	if (cons->filter) {
		cons->buffer_len = 0;
		R_FREE (cons->buffer);
		return 0;
	}

	if ((!len || !buf || buf[0] == '\0') &&
	    (cons->grep.json || cons->grep.less)) {
		cons->grep.json = 0;
		cons->grep.less = 0;
		return 0;
	}
	if (cons->grep.json) {
		if (cons->grep.json_path) {
			char *u = sdb_json_get_str (cons->buffer, cons->grep.json_path);
			if (u) {
				cons->buffer = u;
				cons->buffer_len = strlen (u);
				cons->buffer_sz = cons->buffer_len + 1;
				cons->grep.json = 0;
				r_cons_newline ();
			}
			R_FREE (cons->grep.json_path);
		} else {
			const char *palette[] = {
				cons->pal.graph_false, // f
				cons->pal.graph_true, // t
				cons->pal.num, // k
				cons->pal.comment, // v
				Color_RESET,
				NULL
			};
			char *out = r_print_json_indent (buf, I (color), "  ", palette);
			if (!out) {
				return 0;
			}
			free (cons->buffer);
			cons->buffer = out;
			cons->buffer_len = strlen (out);
			cons->buffer_sz = cons->buffer_len + 1;
			cons->grep.json = 0;
			if (cons->grep.less) {
				cons->grep.less = 0;
				r_cons_less_str (cons->buffer, NULL);
			}
		}
		return 3;
	}
	if (cons->grep.less) {
		int less = cons->grep.less;
		cons->grep.less = 0;
		if (less == 2) {
			char *res = r_cons_hud_string (buf);
			r_cons_println (res);
			free (res);
		} else {
			r_cons_less_str (buf, NULL);
			buf[0] = 0;
			cons->buffer_len = 0;
			if (cons->buffer) {
				cons->buffer[0] = 0;
			}
			R_FREE (cons->buffer);
		}
		return 0;
	}
	if (!cons->buffer) {
		cons->buffer_len = len + 20;
		cons->buffer = malloc (cons->buffer_len);
		cons->buffer[0] = 0;
	}
	out = tbuf = calloc (1, len);
	if (!out) {
		return 0;
	}
	tline = malloc (len);
	if (!tline) {
		free (out);
		return 0;
	}
	cons->lines = 0;
	// used to count lines and change negative grep.line values
	while ((int) (size_t) (in - buf) < len) {
		p = strchr (in, '\n');
		if (!p) {
			break;
		}
		l = p - in;
		if (l > 0) {
			in += l + 1;
		} else {
			in++;
		}
		total_lines++;
	}
	if (!cons->grep.range_line && cons->grep.line < 0) {
		cons->grep.line = total_lines + cons->grep.line;
	}
	if (cons->grep.range_line == 1) {
		if (cons->grep.f_line < 0) {
			cons->grep.f_line = total_lines + cons->grep.f_line;
		}
		if (cons->grep.l_line < 0) {
			cons->grep.l_line = total_lines + cons->grep.l_line;
		}
	}
	in = buf;
	while ((int) (size_t) (in - buf) < len) {
		p = strchr (in, '\n');
		if (!p) {
			free (tbuf);
			free (tline);
			return 0;
		}
		l = p - in;
		if (l > 0) {
			memcpy (tline, in, l);
			if (cons->grep_color) {
				tl = l;
			} else {
				tl = r_str_ansi_filter (tline, NULL, NULL, l);
			}
			if (tl < 0) {
				ret = -1;
			} else {
				ret = r_cons_grep_line (tline, tl);
				if (!cons->grep.range_line) {
					if (cons->grep.line == cons->lines) {
						show = true;
					}
				} else if (cons->grep.range_line == 1) {
					if (cons->grep.f_line == cons->lines) {
						show = true;
					}
					if (cons->grep.l_line == cons->lines) {
						show = false;
					}
				} else {
					show = true;
				}
			}
			if (ret > 0) {
				if (show) {
					memcpy (out, tline, ret);
					memcpy (out + ret, "\n", 1);
					out += ret + 1;
					buffer_len += ret + 1;
				}
				if (!cons->grep.range_line) {
					show = false;
				}
				cons->lines++;
			} else if (ret < 0) {
				free (tbuf);
				free (tline);
				return 0;
			}
			in += l + 1;
		} else {
			in++;
		}
	}
	memcpy (buf, tbuf, len);
	cons->buffer_len = buffer_len;
	free (tbuf);
	free (tline);
	if (cons->grep.counter) {
		int cnt = cons->grep.charCounter? strlen (cons->buffer): cons->lines;
		if (cons->buffer_len < 10) {
			cons->buffer_len = 10; // HACK
		}
		snprintf (cons->buffer, cons->buffer_len, "%d\n", cnt);
		cons->buffer_len = strlen (cons->buffer);
		cons->num->value = cons->lines;
	}
	if (cons->grep.sort != -1) {
#define INSERT_LINES(list)\
	do {\
		r_list_foreach (list, iter, str) {\
			int len = strlen (str);\
			memcpy (ptr, str, len);\
			memcpy (ptr + len, "\n", 2);\
			ptr += len + 1;\
			nl++;\
		}\
	}\
	while (false)

		RListIter *iter;
		int nl = 0;
		char *ptr = cons->buffer;
		char *str;
		sorted_column = cons->grep.sort;
		r_list_sort (sorted_lines, cmp);
		if (cons->grep.sort_invert) {
			r_list_reverse (sorted_lines);
		}
		INSERT_LINES (unsorted_lines);
		INSERT_LINES (sorted_lines);
		cons->lines = nl;
		r_list_free (sorted_lines);
		sorted_lines = NULL;
		r_list_free (unsorted_lines);
		unsorted_lines = NULL;
	}
	return cons->lines;
}
Beispiel #4
0
R_API int r_cons_less_str(const char *str, const char *exitkeys) {
	static int in_help = false;
	static const char *r_cons_less_help = \
		" u/space  - page up/down\n"
		" jk       - line down/up\n"
		" gG       - begin/end buffer\n"
		" /        - search in buffer\n"
		" _        - enter the hud mode\n"
		" n/p      - next/prev search result\n"
		" q        - quit\n"
		" ?        - show this help\n"
		"\n";
	int lines_count = 0;
	RRegex *rx = NULL;
	int w, h, ch, to, ui = 1, from = 0, i;
	const char *sreg;
	RList **mla;

	if (!str || !*str) {
		return 0;
	}
	// rcons kills str after flushing the buffer, so we must keep a copy
	char *ostr = strdup (str);
	if (!ostr) {
		return 0;
	}
	char *p = strdup (str);
	if (!p) {
		free (ostr);
		return 0;
	}
	int *lines = pager_splitlines (p, &lines_count);
	if (lines_count < 1) {
		mla = NULL;
	} else {
		mla = calloc (lines_count, sizeof (RList *));
		if (!mla) {
			free (p);
			free (ostr);
			free (lines);
			return 0;
		}
	}
	for (i = 0; i < lines_count; i++) {
		mla[i] = r_list_new ();
	}
	r_cons_set_raw (true);
	r_cons_show_cursor (false);
	r_cons_reset ();
	h = 0;
	while (ui) {
		w = r_cons_get_size (&h);
		to = R_MIN (lines_count, from + h);
		if (from + 3 > lines_count) {
			from = lines_count - 3;
		}
		if (from < 0) {
			from = 0;
		}
		pager_printpage (p, lines, mla, from, to, w);
		ch = r_cons_readchar ();
		if (exitkeys && strchr (exitkeys, ch)) {
			for (i = 0; i < lines_count; i++) {
				r_list_free (mla[i]);
			}
			free (p);
			free (mla);
			free (ostr);
			free (lines);
			return ch;
		}
		ch = r_cons_arrow_to_hjkl (ch);
		switch (ch) {
		case '_':
			r_cons_hud_string (ostr);
			break;
		case '?':
			if (!in_help) {
				in_help = true;
				r_cons_less_str (r_cons_less_help, NULL);
				in_help = false;
			}
			break;
		case 'u':
			from -= h;
			if (from < 0) {
				from = 0;
			}
			break;
		case ' ': from += h; break;
		case 'g': from = 0; break;
		case 'G': from = lines_count-h; break;
		case -1: // EOF
		case '\x03': // ^C
		case 'q': ui = 0; break;
		case '\r':
		case '\n':
		case 'j': from++; break;
		case 'J': from+=h; break;
		case 'k':
			if (from > 0) {
				from--;
			}
			break;
		case 'K': from = (from>=h)? from-h: 0;
			break;
		case '/': 	/* search */
			r_cons_reset_colors ();
			r_line_set_prompt ("/");
			sreg = r_line_readline ();
			from = R_MIN (lines_count - 1, from);
			/* repeat last search if empty string is provided */
			if (sreg[0]) { /* prepare for a new search */
				if (rx) {
					r_regex_free (rx);
				}
				rx = r_regex_new (sreg, "");
			} else { /* we got an empty string */
				from = pager_next_match (from, mla, lines_count);
				break;
			}
			if (!rx) {
				break;
			}
			/* find all occurences */
			if (pager_all_matches (p, rx, mla, lines, lines_count)) {
				from = pager_next_match (from, mla, lines_count);
			}
			break;
		case 'n': 	/* next match */
			/* search already performed */
			if (rx) {
				from = pager_next_match (from, mla, lines_count);
			}
			break;
		case 'N':
		case 'p': 	/* previous match */
			if (rx) {
				from = pager_prev_match (from, mla);
			}
			break;
		}
	}
	for (i = 0; i < lines_count; i++) {
		r_list_free (mla[i]);
	}
	free (mla);
	r_regex_free (rx);
	free (lines);
	free (p);
	r_cons_reset_colors ();
	r_cons_set_raw (false);
	r_cons_show_cursor (true);
	free (ostr);
	return 0;
}