Wolfgang Thallergcc16 merge934c3885 months agoHistory
514 lines · 11.5 KB · C++
RawDownload
/* Copyright (C) 2021-2026 Free Software Foundation, Inc.   Contributed by Oracle.    This file is part of GNU Binutils.    This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 3, or (at your option)   any later version.    This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.    You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, 51 Franklin Street - Fifth Floor, Boston,   MA 02110-1301, USA.  */ #include "config.h"#include <ctype.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <errno.h>#include "Filter.h"#include "util.h"#include "i18n.h"#include "data_pckts.h"#include "StringBuilder.h"#include "Experiment.h"  // ========================================================================// Subclass: FilterNumeric// Public Methods FilterNumeric::FilterNumeric (Experiment *_exp, const char *_cmd,			      const char *_name){  exp = _exp;  cmd = dbe_strdup (_cmd);  name = dbe_strdup (_name);  pattern = NULL;  status = NULL;  items = NULL;  prop_name = NULL;  first = (uint64_t) - 1;  last = (uint64_t) - 1;  nselected = 0;  nitems = 0;} FilterNumeric::~FilterNumeric (){  free (cmd);  free (name);  free (pattern);  free (status);  Destroy (items);} // sets min and max for this filter; should be called when the range is//	known -- that comes after the first PathTree build, in the current//	sequence of thingsvoidFilterNumeric::set_range (uint64_t findex, uint64_t lindex, uint64_t total){  if (first == findex && last == lindex)    return;  first = findex;  last = lindex;  nitems = total;  nselected = nitems;  if (pattern)    {      free (pattern);      pattern = NULL;    }  if (status)    {      free (status);      status = NULL;    }} voidFilterNumeric::update_range (){  if (exp == NULL)    return;  if (streq (cmd, NTXT ("sample")))    set_range (1, (uint64_t) exp->nsamples (), exp->nsamples ());  else if (streq (cmd, NTXT ("thread")))    set_range (exp->min_thread, exp->max_thread, exp->thread_cnt);  else if (streq (cmd, NTXT ("LWP")))    set_range (exp->min_lwp, exp->max_lwp, exp->lwp_cnt);  else if (streq (cmd, NTXT ("cpu")))    {      if (exp->min_cpu != (uint64_t) - 1)	set_range (exp->min_cpu, exp->max_cpu, exp->cpu_cnt);    }} // get_advanced_filter -- returns a string matching the current settingchar *FilterNumeric::get_advanced_filter (){  if (items == NULL)    return NULL;  if (items->size () == 0)    return dbe_strdup (NTXT ("0"));   StringBuilder sb;  if (items->size () > 1)    sb.append ('(');  for (int i = 0; i < items->size (); i++)    {      RangePair *rp = items->fetch (i);      if (i > 0)	sb.append (NTXT (" || "));      sb.append ('(');      sb.append (prop_name);      if (rp->first == rp->last)	{	  sb.append (NTXT ("=="));	  sb.append ((long long) rp->first);	}      else	{	  sb.append (NTXT (">="));	  sb.append ((long long) rp->first);	  sb.append (NTXT (" && "));	  sb.append (prop_name);	  sb.append (NTXT ("<="));	  sb.append ((long long) rp->last);	}      sb.append (')');    }  if (items->size () > 1)    sb.append (')');  return sb.toString ();}  // get_pattern -- returns a string matching the current setting char *FilterNumeric::get_pattern (){  update_range ();  if (pattern)    return pattern;  StringBuilder sb;  if (items == NULL)    {      if (last == (uint64_t) - 1 && last == first)	// neither set; data not available	sb.append (GTXT ("(data not recorded)"));      else	sb.append (GTXT ("all"));    }  else if (items->size () == 0)    sb.append (GTXT ("none"));  else    {      for (int i = 0; i < items->size (); i++)	{	  RangePair *rp = items->fetch (i);	  if (i > 0)	    sb.append (',');	  sb.append ((long long) rp->first);	  if (rp->first != rp->last)	    {	      sb.append ('-');	      sb.append ((long long) rp->last);	    }	}    }  pattern = sb.toString ();  return pattern;} char *FilterNumeric::get_status (){  update_range ();  if (status == NULL)    update_status ();  return dbe_strdup (status);} // set_pattern -- set the filter to a new pattern//	set error true/false if there was or was not an error parsing string//	Returns true/false if the filter changed, implying a rebuild of databoolFilterNumeric::set_pattern (char *str, bool *error){  update_range ();  // save the old filter  Vector<RangePair *> *olditems = items;  *error = false;  if (strcmp (str, NTXT ("all")) == 0)    // if all, leave items NULL    items = NULL;  else if (strcmp (str, NTXT ("none")) == 0)    // if none, leave items as a zero-length vector    items = new Vector<RangePair *>(0);  else    {      uint64_t val, val2;      char *s = str;      char *nexts = s;      items = NULL;      for (bool done = false; done == false;)	{	  // tokenize the string	  // Does it start with a "-" ?	  if (*nexts == '-')	    val = first; // yes, set val to first, and see what follows	  else	    {	      // it must start with a number	      val = get_next_number (s, &nexts, error);	      if (*error == true)		break;	    } 	  // look at the next character	  switch (*nexts)	    {	    case ',':	      s = ++nexts;	      *error = include_range (val, val);	      if (*error == true)		done = true;	      break;	    case '-':	      s = ++nexts;	      if (*nexts == ',' || *nexts == '\0')		val2 = last;	      else		{		  val2 = get_next_number (s, &nexts, error);		  if (*error == true)		    {		      done = true;		      break;		    }		}	      if (val > val2)		{		  *error = true;		  done = true;		  break;		}	      *error = include_range (val, val2);	      if (*error == true)		{		  done = true;		  break;		}	      if (*nexts == ',')		{		  s = ++nexts;		  break;		}	      if (*nexts == '\0')		{		  done = true;		  break;		}	      break;	    case '\0':	      *error = include_range (val, val);	      done = true;	      break;	    default:	      *error = true;	      done = true;	      break;	    }	}      // if there was a parser error leave old setting      if (*error == true)	{	  if (items)	    {	      items->destroy ();	      delete items;	    }	  items = olditems;	  return false;	}    }   if (first != (uint64_t) - 1 && last != (uint64_t) - 1)    {      for (long i = VecSize (items) - 1; i >= 0; i--)	{	  RangePair *rp = items->get (i);	  if ((rp->first > last) || (rp->last < first))	    {	      delete rp;	      items->remove (i);	      continue;	    }	  if (rp->first < first)	    rp->first = first;	  if (rp->last > last)	    rp->last = last;	}      if (VecSize (items) == 1)	{	  RangePair *rp = items->get (0);	  if ((rp->first == first) && (rp->last == last))	    {	      // All, leave items NULL	      items->destroy ();	      delete items;	      items = NULL;	    }	}    }   // no error, delete the old setting  if (olditems != NULL)    {      olditems->destroy ();      delete olditems;    }   bool changed;  // regenerate the pattern  if (pattern == NULL)    changed = true;  else    {      char *oldpattern = pattern;      pattern = NULL; // to force a recompute with new values      (void) get_pattern ();      changed = strcmp (pattern, oldpattern) != 0;      free (oldpattern);    }  return changed;} //================================================================// Protected methods // set_status -- regenerate the status line, describing the current settingvoidFilterNumeric::update_status (){  // regenerate the status line  free (status);  nselected = 0;  if (items == NULL)    {      if (last == (uint64_t) - 1 && last == first)	// neither set; data not available	status = dbe_sprintf (GTXT ("(data not recorded)"));      else if (first == (uint64_t) - 1 || last == (uint64_t) - 1)	// range was not set	status = dbe_sprintf (GTXT ("(all)"));      else	// range was set, compute percentage	status = dbe_sprintf (GTXT ("total %lld, range: %lld-%lld"),			      (long long) nitems, (long long) first,			      (long long) last);    }  else    {      // some are selected      int index;      RangePair *rp;      Vec_loop (RangePair *, items, index, rp)      {	nselected += rp->last - rp->first + 1;      }      if (last == (uint64_t) - 1)	// range was not set	status = dbe_sprintf (GTXT ("(%lld items selected)"),			      (long long) nselected);      else	// range was set	status = dbe_sprintf (GTXT ("total %lld, range: %lld-%lld"),			      (long long) nitems, (long long) first,			      (long long) last);    }} // Add a range to the filter; called from set_pattern for each index,//	or index pairboolFilterNumeric::include_range (uint64_t findex, uint64_t lindex){  int index;  RangePair *rp;  if (findex > lindex)    return true;   bool done = false;  if (items == NULL)    items = new Vector<RangePair *>(0);   Vec_loop (RangePair *, items, index, rp)  {    if (findex < rp->first)      {	// Case where the new pair starts before the old	if (lindex + 1 < rp->first)	  {	    // this pair comes cleanly in front of the current item	    RangePair *rp2 = new RangePair ();	    rp2->first = findex;	    rp2->last = lindex;	    items->insert (index, rp2);	    done = true;	    break;	  }	// This new one extends the previous from the front	rp->first = findex;chkextend:	if (lindex <= rp->last)	  {	    // but does not extend the back	    done = true;	    break;	  }	// extend this one out	rp->last = lindex; 	// does it go into the next range?	if (index == items->size () - 1)	  {	    // this is the last range, so it does not	    done = true;	    break;	  }	RangePair *next = items->fetch (index + 1);	if (lindex + 1 < next->first)	  {	    // no extension, we're done	    done = true;	    break;	  }	// it does extend the next one	next->first = rp->first;	rp = next;	// remove the current one, promoting next	items->remove (index);	goto chkextend;      }    else if (findex > rp->last + 1)      // the new one is completely beyond the current      continue;    else      {	// the new one may start at or after the current, but it	// extends it out;  set the current	// this pair overlaps the current item	// rp-> first is OK -- it's equal or less than findex	goto chkextend;      }  }   if (done != true)    {      // fall through -- append to list      rp = new RangePair ();      rp->first = findex;      rp->last = lindex;      items->append (rp);    }   return false;} // Scan the filter to see if the number given is filtered in or out//	return true if number is in, false if it's outboolFilterNumeric::is_selected (uint64_t number){  int index;  RangePair *rp;  if (items == NULL)    return true;  if (items->size () == 0)    return false;   Vec_loop (RangePair *, items, index, rp)  {    if (number >= rp->first && number <= rp->last)      return true;  }  return false;} 

Lines 1–500 of 514.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t