Example #1
0
R_API void r_cons_grep(const char *str) {
	int wlen, len;
	RCons *cons;
	char buf[4096];
	char *ptr, *optr, *ptr2, *ptr3;

	if (!str || !*str)
		return;

	cons = r_cons_singleton ();
	cons->grep.str = NULL;
	cons->grep.neg = 0;
	cons->grep.amp = 0;
	cons->grep.end = 0;
	cons->grep.begin = 0;
	cons->grep.nstrings = 0;
	cons->grep.tokenfrom = 0;
	cons->grep.tokento = ST32_MAX;
	cons->grep.line = -1;
	cons->grep.counter = cons->grep.neg = 0;

	while (*str) {
		switch (*str) {
		case '&': str++; cons->grep.amp = 1; break;
		case '^': str++; cons->grep.begin = 1;  break;
		case '!': str++; cons->grep.neg = 1; break;
		case '?': str++; cons->grep.counter = 1;
			if (*str=='?') {
				r_cons_grep_help ();
				return;
			}
			break;
		default: goto while_end;
		}
	} while_end:

	len = strlen (str)-1;
	if (len>0 && str[len] == '?') {
		cons->grep.counter = 1;
		strncpy (buf, str, R_MIN (len, sizeof (buf)-1));
		buf[len]=0;
		len--;
	} else strncpy (buf, str, sizeof (buf)-1);

	if (len>1 && buf[len]=='$' && buf[len-1]!='\\') {
		cons->grep.end = 1;
		buf[len] = 0;
	}
	ptr = buf;
	ptr3 = strchr (ptr, '['); // column number
	if (ptr3) {
		ptr3[0] = '\0';
		cons->grep.tokenfrom = r_num_get (cons->num, ptr3+1);
		ptr3 = strchr (ptr3+1, '-');
		if (ptr3) {
			cons->grep.tokento = r_num_get (cons->num, ptr3+1);
			if (cons->grep.tokento == 0)
				cons->grep.tokento = ST32_MAX;
		} else cons->grep.tokento = cons->grep.tokenfrom;
		if (cons->grep.tokenfrom<0)
			cons->grep.tokenfrom = 0;
		if (cons->grep.tokento<0)
			cons->grep.tokento = ST32_MAX;
	}
	ptr2 = strchr (ptr, ':'); // line number
	if (ptr2) {
		*ptr2 = '\0';
		cons->grep.line = r_num_get (cons->num, ptr2+1);
		if (cons->grep.line<0)
			cons->grep.line = -1;
	}
	free (cons->grep.str);
	if (*ptr) {
		cons->grep.str = (char *)strdup (ptr);
		do {
			optr = ptr;
			ptr = strchr (ptr, ','); // grep keywords
			if (ptr) *ptr++ = '\0';
			wlen = strlen (optr);	
			if (wlen==0) continue;
			if (wlen>=R_CONS_GREP_WORD_SIZE-1) {
				eprintf ("grep string too long\n");
				continue;
			}
			strncpy (cons->grep.strings[cons->grep.nstrings],
				optr, R_CONS_GREP_WORD_SIZE-1);
			cons->grep.nstrings++;
			if (cons->grep.nstrings>R_CONS_GREP_WORDS-1) {
				eprintf ("too many grep strings\n");
				break;
			}
		} while (ptr);
	} else {
		cons->grep.str = strdup (ptr);
		cons->grep.nstrings++;
		cons->grep.strings[0][0] = 0;
	}
}
Example #2
0
static void parse_grep_expression(const char *str) {
	static char buf[R_CONS_GREP_BUFSIZE];
	int wlen, len, is_range, num_is_parsed, fail = 0;
	char *ptr, *optr, *ptr2, *ptr3;
	ut64 range_begin, range_end;
	RCons *cons;

	if (!str || !*str) {
		return;
	}
	cons = r_cons_singleton ();
	memset (&(cons->grep), 0, sizeof (cons->grep));
	sorted_column = 0;
	cons->grep.sort = -1;
	cons->grep.line = -1;
	bool first = true;
	while (*str) {
		switch (*str) {
		case '.':
			if (str[1] == '.') {
				if (str[2] == '.') {
					cons->grep.less = 2;
				} else {
					cons->grep.less = 1;
				}
				return;
			}
			str++;
			break;
		case '{':
			if (str[1] == '}') {
				cons->grep.json = 1;
				if (!strncmp (str, "{}..", 4)) {
					cons->grep.less = 1;
				}
			} else {
				char *jsonPath = strdup (str + 1);
				char *jsonPathEnd = strchr (jsonPath, '}');
				if (jsonPathEnd) {
					*jsonPathEnd = 0;
					free (cons->grep.json_path);
					cons->grep.json_path = jsonPath;
					cons->grep.json = 1;
				} else {
					free (jsonPath);
				}
				return;
			}
			str++;
			break;
		case '$':
			str++;
			if (*str == '!') {
				cons->grep.sort_invert = true;
				str++;
			} else {
				cons->grep.sort_invert = false;
			}
			cons->grep.sort = atoi (str);
			while (IS_DIGIT (*str)) {
				str++;
			}
			if (*str == ':') {
				cons->grep.sort_row = atoi (++str);
				str++;
			}
			break;
		case '&':
			str++;
			cons->grep.amp = 1;
			break;
		case '+':
			if (first) {
				str++;
				cons->grep.icase = 1;
			} else {
				goto while_end;
			}
			break;
		case '^':
			str++;
			cons->grep.begin = 1;
			break;
		case '!':
			str++;
			cons->grep.neg = 1;
			break;
		case '?':
			str++;
			cons->grep.counter = 1;
			if (*str == '.') {
				cons->grep.charCounter = true;
				str++;
			} else if (*str == '?') {
				cons->filter = true;
				r_cons_grep_help ();
				return;
			}
			break;
		default:
			goto while_end;
		}
		first = false;
	}
while_end:

	len = strlen (str) - 1;
	if (len > R_CONS_GREP_BUFSIZE - 1) {
		eprintf ("r_cons_grep: too long!\n");
		return;
	}
	if (len > 0 && str[len] == '?') {
		cons->grep.counter = 1;
		strncpy (buf, str, R_MIN (len, sizeof (buf) - 1));
		buf[len] = 0;
		len--;
	} else {
		strncpy (buf, str, sizeof (buf) - 1);
	}

	if (len > 1 && buf[len] == '$' && buf[len - 1] != '\\') {
		cons->grep.end = 1;
		buf[len] = 0;
	}

	ptr = buf;
	ptr2 = strchr (ptr, '[');
	ptr3 = strchr (ptr, ']');
	is_range = 0;
	num_is_parsed = 0;
	fail = 0;
	range_begin = range_end = -1;

	if (ptr2 && ptr3) {
		ptr2[0] = '\0';
		ptr2++;
		for (; ptr2 <= ptr3; ++ptr2) {
			if (fail) {
				ZERO_FILL (cons->grep.tokens);
				cons->grep.tokens_used = 0;
				fail = 0;
				break;
			}
			switch (*ptr2) {
			case '-':
				is_range = 1;
				num_is_parsed = 0;
				range_end = -1;
				break;
			case ']':  // fallthrough to handle ']' like ','
			case ',':
				for (; range_begin <= range_end; range_begin++) {
					if (range_begin >= R_CONS_GREP_TOKENS) {
						fail = 1;
						break;
					}
					cons->grep.tokens[range_begin] = 1;
					cons->grep.tokens_used = 1;
				}
				// case of [n-]
				if (*ptr2 == ']' && is_range && !num_is_parsed) {
					num_is_parsed = 1;
					range_end = -1;
				} else {
					is_range = 0;
					num_is_parsed = 0;
				}
				break;
			default:
				if (!num_is_parsed) {
					if (is_range) {
						range_end = r_num_get (cons->num, ptr2);
						// check for bad value, if range_end == 0, we check if ptr2 == '0'
						if (range_end == 0 && *ptr != '0') {
							range_end = -1; // this allow [n- ]
						}
					} else {
						range_begin = range_end = r_num_get (cons->num, ptr2);
					}
					num_is_parsed = 1;
				}
			}
		}
	}

	ptr2 = strchr_ns (ptr, ':'); // line number
	cons->grep.range_line = 2; // there is not :
	if (ptr2 && ptr2[1] != ':' && ptr2[1]) {
		*ptr2 = '\0';
		char *p, *token = ptr + 1;
		p = strstr (token, "..");
		if (!p) {
			cons->grep.line = r_num_get (cons->num, ptr2 + 1);
			cons->grep.range_line = 0;
		} else {
			*p = '\0';
			cons->grep.range_line = 1;
			if (*token) {
				cons->grep.f_line = r_num_get (cons->num, token);
			} else {
				cons->grep.f_line = 0;
			}
			if (p[2]) {
				cons->grep.l_line = r_num_get (cons->num, p + 2);
			} else {
				cons->grep.l_line = -1;
			}
		}
	}
	free (cons->grep.str);
	if (*ptr) {
		cons->grep.str = (char *) strdup (ptr);
		do {
			optr = ptr;
			ptr = strchr (ptr, ','); // grep keywords
			if (ptr) {
				*ptr++ = '\0';
			}
			wlen = strlen (optr);
			if (!wlen) {
				continue;
			}
			if (wlen >= R_CONS_GREP_WORD_SIZE - 1) {
				eprintf ("grep string too long\n");
				continue;
			}
			strncpy (cons->grep.strings[cons->grep.nstrings],
				optr, R_CONS_GREP_WORD_SIZE - 1);
			cons->grep.nstrings++;
			if (cons->grep.nstrings > R_CONS_GREP_WORDS - 1) {
				eprintf ("too many grep strings\n");
				break;
			}
		} while (ptr);
	} else {
		cons->grep.str = strdup (ptr);
		cons->grep.nstrings++;
		cons->grep.strings[0][0] = 0;
	}
}
Example #3
0
R_API void r_cons_grep(const char *str) {
	int wlen, len, is_range, num_is_parsed, fail = 0;
	ut64 range_begin, range_end;
	RCons *cons;
	char buf[R_CONS_GREP_BUFSIZE];
	char *ptr, *optr, *ptr2, *ptr3;

	if (!str || !*str)
		return;

	cons = r_cons_singleton ();
	memset (&(cons->grep), 0, sizeof (cons->grep));
	cons->grep.line = -1;

	while (*str) {
		switch (*str) {
		case '.':
			if (str[1] == '.') {
				cons->grep.less = 1;
				return;
			}
			str++;
			break;
		case '{':
			if (str[1] == '}') {
				cons->grep.json = 1;
				if (!strncmp (str, "{}..", 4))
					cons->grep.less = 1;
				str++;
				return;
			}
			str++;
			break;
		case '&': str++; cons->grep.amp = 1; break;
		case '^': str++; cons->grep.begin = 1; break;
		case '!': str++; cons->grep.neg = 1; break;
		case '?': str++; cons->grep.counter = 1;
			if (*str == '?') {
				r_cons_grep_help ();
				return;
			}
			break;
		default: goto while_end;
		}
	} while_end:

	len = strlen (str) - 1;
	if (len > R_CONS_GREP_BUFSIZE - 1) {
		eprintf("r_cons_grep: too long!\n");
		return;
	}
	if (len > 0 && str[len] == '?') {
		cons->grep.counter = 1;
		strncpy (buf, str, R_MIN (len, sizeof (buf) - 1));
		buf[len]=0;
		len--;
	} else strncpy (buf, str, sizeof (buf) - 1);

	if (len > 1 && buf[len] == '$' && buf[len - 1] != '\\') {
		cons->grep.end = 1;
		buf[len] = 0;
	}

	ptr = buf;
	ptr2 = strchr (ptr, '[');
	ptr3 = strchr (ptr, ']');
	is_range = 0;
	num_is_parsed = 0;
	fail = 0;
	range_begin = range_end = -1;

	if (ptr2 && ptr3) {
		ptr2[0] = '\0';
		ptr2++;

		for (; ptr2 <= ptr3; ++ptr2) {
			if (fail) {
				memset (cons->grep.tokens, 0, R_CONS_GREP_TOKENS);
				cons->grep.tokens_used = 0;
				fail = 0;
				break;
			}

			switch (*ptr2) {
			case '-':
				is_range = 1;
				num_is_parsed = 0;
				break;
			case ']':  // fallthrough to handle ']' like ','
			case ',':
				for (; range_begin <= range_end; range_begin++) {
					if (range_begin >= R_CONS_GREP_TOKENS) {
						fail = 1;
						break;
					}
					cons->grep.tokens[range_begin] = 1;
					cons->grep.tokens_used = 1;
				}
				is_range = 0;
				num_is_parsed = 0;
				break;
			default:
				if (!num_is_parsed) {
					if (is_range) {
						range_end = r_num_get (cons->num, ptr2);
					} else {
						range_begin = range_end = r_num_get (cons->num, ptr2);
					}
					num_is_parsed = 1;
				}
			}
		}
	}

	ptr2 = strchr (ptr, ':'); // line number
	if (ptr2 && ptr2[1] != ':') {
		*ptr2 = '\0';
		cons->grep.line = r_num_get (cons->num, ptr2 + 1);
		if (cons->grep.line < 0) {
			eprintf ("Negative line grep not yet implented\n");
			cons->grep.line = -1;
		}
	}
	free (cons->grep.str);
	if (*ptr) {
		cons->grep.str = (char *)strdup (ptr);
		do {
			optr = ptr;
			ptr = strchr (ptr, ','); // grep keywords
			if (ptr) *ptr++ = '\0';
			wlen = strlen (optr);
			if (wlen == 0) continue;
			if (wlen >= R_CONS_GREP_WORD_SIZE - 1) {
				eprintf ("grep string too long\n");
				continue;
			}
			strncpy (cons->grep.strings[cons->grep.nstrings],
				optr, R_CONS_GREP_WORD_SIZE - 1);
			cons->grep.nstrings++;
			if (cons->grep.nstrings > R_CONS_GREP_WORDS - 1) {
				eprintf ("too many grep strings\n");
				break;
			}
		} while (ptr);
	} else {
		cons->grep.str = strdup (ptr);
		cons->grep.nstrings++;
		cons->grep.strings[0][0] = 0;
	}
}