void sinsp_filter::parse_check(sinsp_filter_expression* parent_expr, boolop op) { uint32_t startpos = m_scanpos; vector<char> operand1 = next_operand(true); string str_operand1 = string((char *)&operand1[0]); sinsp_filter_check* chk = g_filterlist.new_filter_check_from_fldname(str_operand1, m_inspector, true); if(chk == NULL) { throw sinsp_exception("filter error: unrecognized field " + str_operand1 + " at pos " + to_string((long long) startpos)); } if(m_ttable_only) { if(!(chk->get_fields()->m_flags & filter_check_info::FL_WORKS_ON_THREAD_TABLE)) { throw sinsp_exception("the given filter is not supported for thread table filtering"); } } ppm_cmp_operator co = next_comparison_operator(); vector<char> operand2 = next_operand(false); chk->m_boolop = op; chk->m_cmpop = co; chk->parse_field_name((char *)&operand1[0]); chk->parse_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1); parent_expr->add_check(chk); }
void sinsp_filter::parse_check(sinsp_filter_expression* parent_expr, boolop op) { uint32_t startpos = m_scanpos; string operand1 = next_operand(true); sinsp_filter_check* chk = g_filterlist.new_filter_check_from_fldname(operand1, m_inspector, true); if(chk == NULL) { throw sinsp_exception("filter error: unrecognized field " + operand1 + " at pos " + to_string((long long) startpos)); } ppm_cmp_operator co = next_comparison_operator(); string operand2 = next_operand(false); chk->m_boolop = op; chk->m_cmpop = co; chk->parse_field_name(operand1.c_str()); chk->parse_filter_value(operand2.c_str()); parent_expr->add_check(chk); }
void sinsp_filter_compiler::parse_check() { uint32_t startpos = m_scanpos; vector<char> operand1 = next_operand(true, false); string str_operand1 = string((char *)&operand1[0]); sinsp_filter_check* chk = g_filterlist.new_filter_check_from_fldname(str_operand1, m_inspector, true); boolop op = m_last_boolop; if(chk == NULL) { throw sinsp_exception("filter error: unrecognized field " + str_operand1 + " at pos " + to_string((long long) startpos)); } if(m_ttable_only) { if(!(chk->get_fields()->m_flags & filter_check_info::FL_WORKS_ON_THREAD_TABLE)) { throw sinsp_exception("the given filter is not supported for thread table filtering"); } } cmpop co = next_comparison_operator(); chk->m_boolop = op; chk->m_cmpop = co; chk->parse_field_name((char *)&operand1[0], true); if(co == CO_IN || co == CO_PMATCH) { // // Skip spaces // if(isblank(m_fltstr[m_scanpos])) { next(); } if(m_fltstr[m_scanpos] != '(') { throw sinsp_exception("expected '(' after 'in/pmatch' operand"); } // // Skip '(' // m_scanpos++; if(chk->get_field_info()->m_type == PT_CHARBUF) { // // For character buffers, we can check all // values at once by putting them in a set and // checking for set membership. // // // Create the 'or' sequence // uint64_t num_values = 0; while(true) { // 'in' clause aware vector<char> operand2 = next_operand(false, true); chk->add_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1, num_values); num_values++; next(); if(m_fltstr[m_scanpos] == ')') { break; } else if(m_fltstr[m_scanpos] == ',') { m_scanpos++; } else { throw sinsp_exception("expected either ')' or ',' after a value inside the 'in/pmatch' clause"); } } m_filter->add_check(chk); } else if (co == CO_PMATCH) { // the pmatch operator can only work on charbufs throw sinsp_exception("pmatch requires all charbuf arguments"); } else { // // In this case we need to create '(field=value1 or field=value2 ...)' // // // Separate the 'or's from the // rest of the conditions // m_filter->push_expression(op); m_last_boolop = BO_NONE; m_nest_level++; // // The first boolean operand will be BO_NONE // Then we will start putting BO_ORs // op = BO_NONE; // // Create the 'or' sequence // uint64_t num_values = 0; while(true) { // 'in' clause aware vector<char> operand2 = next_operand(false, true); // // Append every sinsp_filter_check creating the 'or' sequence // sinsp_filter_check* newchk = g_filterlist.new_filter_check_from_another(chk); newchk->m_boolop = op; newchk->m_cmpop = CO_EQ; newchk->add_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1, num_values); num_values++; m_filter->add_check(newchk); next(); if(m_fltstr[m_scanpos] == ')') { break; } else if(m_fltstr[m_scanpos] == ',') { m_scanpos++; } else { throw sinsp_exception("expected either ')' or ',' after a value inside the 'in' clause"); } // // From now on we 'or' every newchk // op = BO_OR; } // // Come back to the rest of the filter // m_filter->pop_expression(); m_nest_level--; } } else { // // In this case we want next() to return the very next character // At this moment m_scanpos is already at it // e.g. "(field exists) and ..." // if(co == CO_EXISTS) { m_scanpos--; } // // Otherwise we need a value for the operand // else { vector<char> operand2 = next_operand(false, false); chk->add_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1); } m_filter->add_check(chk); } }
void sinsp_filter::parse_check(sinsp_filter_expression* parent_expr, boolop op) { uint32_t startpos = m_scanpos; vector<char> operand1 = next_operand(true, false); string str_operand1 = string((char *)&operand1[0]); sinsp_filter_check* chk = g_filterlist.new_filter_check_from_fldname(str_operand1, m_inspector, true); if(chk == NULL) { throw sinsp_exception("filter error: unrecognized field " + str_operand1 + " at pos " + to_string((long long) startpos)); } if(m_ttable_only) { if(!(chk->get_fields()->m_flags & filter_check_info::FL_WORKS_ON_THREAD_TABLE)) { throw sinsp_exception("the given filter is not supported for thread table filtering"); } } ppm_cmp_operator co = next_comparison_operator(); chk->m_boolop = op; chk->m_cmpop = co; chk->parse_field_name((char *)&operand1[0], true); // // In this case we need to create '(field=value1 or field=value2 ...)' // if(co == CO_IN) { // // Separate the 'or's from the // rest of the conditions // push_expression(op); // // Skip spaces // if(isblank(m_fltstr[m_scanpos])) { next(); } if(m_fltstr[m_scanpos] != '(') { throw sinsp_exception("expected '(' after 'in' operand"); } // // Skip '(' // m_scanpos++; // // The first boolean operand will be BO_NONE // Then we will start putting BO_ORs // op = BO_NONE; // // Create the 'or' sequence // while(true) { // 'in' clause aware vector<char> operand2 = next_operand(false, true); // // Append every sinsp_filter_check creating the 'or' sequence // sinsp_filter_check* newchk = g_filterlist.new_filter_check_from_another(chk); newchk->m_boolop = op; newchk->m_cmpop = CO_EQ; newchk->parse_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1); // // We pushed another expression before // so 'parent_expr' still referers to // the old one, this is the new nested // level for the 'or' sequence // m_curexpr->add_check(newchk); next(); if(m_fltstr[m_scanpos] == ')') { break; } else if(m_fltstr[m_scanpos] == ',') { m_scanpos++; } else { throw sinsp_exception("expected either ')' or ',' after a value inside the 'in' clause"); } // // From now on we 'or' every newchk // op = BO_OR; } // // Come back to the rest of the filter // pop_expression(); } else { // // In this case we want next() to return the very next character // At this moment m_scanpos is already at it // e.g. "(field exists) and ..." // if(co == CO_EXISTS) { m_scanpos--; } // // Otherwise we need a value for the operand // else { vector<char> operand2 = next_operand(false, false); chk->parse_filter_value((char *)&operand2[0], (uint32_t)operand2.size() - 1); } parent_expr->add_check(chk); } }
char * concatenate_results (RESULT_NODE *r, int shuffle, Bool convert_indent, char **error_text) { RESULT_NODE *op; int indent = 0, shuffle_cnt, oplines, totlines, linewidth, opwidth, totwidth, totlinelength, runlength, line; char **blk, *txt, *line_end, *last_line, *rc; if (error_text) *error_text = NULL; /* No errors yet */ totlines = 0; totwidth = 0; totlinelength = 0; shuffle_cnt = 0; op = first_operand (r, & indent); if (convert_indent) r-> indent = 0; /* Coz indent has been migrated. */ else indent = 0; /* Forget about initial indentation */ while (op) { op-> indent = indent; /* Copy indent value to operand. */ /* Perform shuffle */ if (shuffle > 0 && op-> indent >= shuffle) { if (op-> indent - shuffle_cnt >= shuffle) op-> indent -= shuffle_cnt; else op-> indent = shuffle; } /* Calculate length & width of operand for shuffle. */ if (op-> value. type == TYPE_BLOCK) { /* Catch undefined operand. */ if (! op-> value. b) return NULL; oplines = 0; opwidth = 0; blk = op-> value. b; while (*blk) { oplines++; linewidth = strlen (*blk); if (linewidth > opwidth) opwidth = linewidth; blk++; } opwidth += op-> indent; totwidth += opwidth; totlinelength += opwidth; } else { if (op-> value. type != TYPE_UNDEFINED) string_value (& op-> value); /* Catch undefined operand. */ if (op-> value. type == TYPE_UNDEFINED || (! op-> value. s)) { /* Pass node result coz that's where culprit is stored */ result_node_error ("Undefined expression", r, error_text); return NULL; } string_value (& op-> value); oplines = 1; opwidth = op-> indent + strllen (op-> value. s); if (strchr (op-> value. s, '\n')) totwidth = opwidth; else totwidth += opwidth; totlinelength += op-> indent + strlen (op-> value. s); } if (oplines > totlines) totlines = oplines; if (op-> value. s && strchr (op-> value. s, '\n')) shuffle_cnt = 0; else if (op-> script_node-> extend) shuffle_cnt = totwidth; else shuffle_cnt += opwidth - (op-> script_node-> width + indent); op = next_operand (op, & indent); } /* Now build the result */ rc = mem_alloc (totlines * totlinelength + 1); memset (rc, ' ', totlines * totlinelength + 1); op = first_operand (r, NULL); runlength = 0; while (op) { line = 0; if (op-> value. type == TYPE_BLOCK) { opwidth = 0; blk = op-> value. b; while (*blk) { linewidth = strlen (*blk); if (linewidth > opwidth) opwidth = linewidth; txt = rc + line * totlinelength + runlength + op-> indent; memcpy (txt, *blk, strlen (*blk)); blk++; line++; } opwidth += op-> indent; runlength += opwidth; } else { for (line = 0; line < totlines; line++) { txt = rc + line * totlinelength + runlength + op-> indent; memcpy (txt, op-> value. s, strlen (op-> value. s)); } runlength += op-> indent + strlen (op-> value. s); } op = next_operand (op, NULL); } rc [totlines * totlinelength] = 0; /* Trim whitespace from all lines */ txt = rc; while (txt) { line_end = strchr(txt, '\n'); if (!line_end) break; if (*(line_end - 1) == '\r') line_end = line_end - 1; last_line = line_end; while (last_line > txt) { if (!isspace (*(last_line - 1))) break; last_line--; } memmove(last_line, line_end, strlen(line_end) + 1); txt = last_line + (*last_line == '\r' ? 2 : 1); } /* JS Blunder check */ ASSERT (runlength == totlinelength); return rc; }