contrib/gdb-7/gdb/linespec.c
static struct symtabs_and_lines
decode_all_digits (struct linespec_state *self,
		   char **argptr,
		   char *q)
{
  struct symtabs_and_lines values;
  struct symtab_and_line val;
  int use_default = 0;
  char *saved_arg = *argptr;

  enum sign
    {
      none, plus, minus
    }
  sign = none;

  init_sal (&val);
  values.sals = NULL;
  values.nelts = 0;

  /* This is where we need to make sure that we have good defaults.
     We must guarantee that this section of code is never executed
     when we are called with just a function name, since
     set_default_source_symtab_and_line uses
     select_source_symtab that calls us with such an argument.  */

  if (VEC_length (symtab_p, self->file_symtabs) == 1
      && VEC_index (symtab_p, self->file_symtabs, 0) == NULL)
    {
      set_current_program_space (self->program_space);

      /* Make sure we have at least a default source file.  */
      set_default_source_symtab_and_line ();
      initialize_defaults (&self->default_symtab, &self->default_line);
      VEC_pop (symtab_p, self->file_symtabs);
      VEC_free (symtab_p, self->file_symtabs);
      self->file_symtabs
	= collect_symtabs_from_filename (self->default_symtab->filename);
      use_default = 1;
    }

  if (**argptr == '+')
    sign = plus, (*argptr)++;
  else if (**argptr == '-')
    sign = minus, (*argptr)++;
  val.line = atoi (*argptr);
  switch (sign)
    {
    case plus:
      if (q == *argptr)
	val.line = 5;
      if (use_default)
	val.line = self->default_line + val.line;
      break;
    case minus:
      if (q == *argptr)
	val.line = 15;
      if (use_default)
	val.line = self->default_line - val.line;
      else
	val.line = 1;
      break;
    case none:
      break;		/* No need to adjust val.line.  */
    }

  *argptr = skip_spaces (q);

  if (self->list_mode)
    decode_digits_list_mode (self, &values, val);
  else
    {
      struct linetable_entry *best_entry = NULL;
      int *filter;
      struct block **blocks;
      struct cleanup *cleanup;
      struct symtabs_and_lines intermediate_results;
      int i, j;

      intermediate_results.sals = NULL;
      intermediate_results.nelts = 0;

      decode_digits_ordinary (self, val.line, &intermediate_results,
			      &best_entry);
      if (intermediate_results.nelts == 0 && best_entry != NULL)
	decode_digits_ordinary (self, best_entry->line, &intermediate_results,
				&best_entry);

      cleanup = make_cleanup (xfree, intermediate_results.sals);

      /* For optimized code, compiler can scatter one source line
	 accross disjoint ranges of PC values, even when no duplicate
	 functions or inline functions are involved.  For example,
	 'for (;;)' inside non-template non-inline non-ctor-or-dtor
	 function can result in two PC ranges.  In this case, we don't
	 want to set breakpoint on first PC of each range.  To filter
	 such cases, we use containing blocks -- for each PC found
	 above we see if there are other PCs that are in the same
	 block.  If yes, the other PCs are filtered out.  */

      filter = xmalloc (intermediate_results.nelts * sizeof (int));
      make_cleanup (xfree, filter);
      blocks = xmalloc (intermediate_results.nelts * sizeof (struct block *));
      make_cleanup (xfree, blocks);

      for (i = 0; i < intermediate_results.nelts; ++i)
	{
	  set_current_program_space (intermediate_results.sals[i].pspace);

	  filter[i] = 1;
	  blocks[i] = block_for_pc_sect (intermediate_results.sals[i].pc,
					 intermediate_results.sals[i].section);
	}

      for (i = 0; i < intermediate_results.nelts; ++i)
	{
	  if (blocks[i] != NULL)
	    for (j = i + 1; j < intermediate_results.nelts; ++j)
	      {
		if (blocks[j] == blocks[i])
		  {
		    filter[j] = 0;
		    break;
		  }
	      }
	}

      for (i = 0; i < intermediate_results.nelts; ++i)
	if (filter[i])
	  {
	    struct symbol *sym = (blocks[i]
				  ? block_containing_function (blocks[i])
				  : NULL);

	    if (self->funfirstline)
	      skip_prologue_sal (&intermediate_results.sals[i]);
	    /* Make sure the line matches the request, not what was
	       found.  */
	    intermediate_results.sals[i].line = val.line;
	    add_sal_to_sals (self, &values, &intermediate_results.sals[i],
			     sym ? SYMBOL_NATURAL_NAME (sym) : NULL);
	  }

      do_cleanups (cleanup);
    }

  if (values.nelts == 0)
    {
      if (self->user_filename)
	throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
		     val.line, self->user_filename);
      else
	throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."),
		     val.line);
    }

  if (self->canonical)
    {
      char *copy = savestring (saved_arg, q - saved_arg);

      self->canonical->pre_expanded = 1;
      gdb_assert (self->user_filename || use_default);
      self->canonical->addr_string
	= xstrprintf ("%s:%s", (self->user_filename
				? self->user_filename
				: self->default_symtab->filename),
		      copy);
      xfree (copy);
    }

  return values;
}
/* This decodes a line where the argument is all digits (possibly
   preceded by a sign).  Q should point to the end of those digits;
   the other arguments are as usual.  */
This decodes a line where the argument is all digits (possibly
preceded by a sign).  Q should point to the end of those digits;
the other arguments are as usual.
This decodes a line where the argument is all digits ( possibly preceded by a sign ) . Q should point to the end of those digits ; the other arguments are as usual .
static struct symtabs_and_lines
decode_all_digits (struct linespec_state *self,
		   char **argptr,
		   char *q)
{
  struct symtabs_and_lines values;
  struct symtab_and_line val;
  int use_default = 0;
  char *saved_arg = *argptr;
  enum sign
    {
      none, plus, minus
    }
  sign = none;
  init_sal (&val);
  values.sals = NULL;
  values.nelts = 0;
  if (VEC_length (symtab_p, self->file_symtabs) == 1
      && VEC_index (symtab_p, self->file_symtabs, 0) == NULL)
    {
      set_current_program_space (self->program_space);
      set_default_source_symtab_and_line ();
      initialize_defaults (&self->default_symtab, &self->default_line);
      VEC_pop (symtab_p, self->file_symtabs);
      VEC_free (symtab_p, self->file_symtabs);
      self->file_symtabs
	= collect_symtabs_from_filename (self->default_symtab->filename);
      use_default = 1;
    }
  if (**argptr == '+')
    sign = plus, (*argptr)++;
  else if (**argptr == '-')
    sign = minus, (*argptr)++;
  val.line = atoi (*argptr);
  switch (sign)
    {
    case plus:
      if (q == *argptr)
	val.line = 5;
      if (use_default)
	val.line = self->default_line + val.line;
      break;
    case minus:
      if (q == *argptr)
	val.line = 15;
      if (use_default)
	val.line = self->default_line - val.line;
      else
	val.line = 1;
      break;
    case none:
      break;		
    }
  *argptr = skip_spaces (q);
  if (self->list_mode)
    decode_digits_list_mode (self, &values, val);
  else
    {
      struct linetable_entry *best_entry = NULL;
      int *filter;
      struct block **blocks;
      struct cleanup *cleanup;
      struct symtabs_and_lines intermediate_results;
      int i, j;
      intermediate_results.sals = NULL;
      intermediate_results.nelts = 0;
      decode_digits_ordinary (self, val.line, &intermediate_results,
			      &best_entry);
      if (intermediate_results.nelts == 0 && best_entry != NULL)
	decode_digits_ordinary (self, best_entry->line, &intermediate_results,
				&best_entry);
      cleanup = make_cleanup (xfree, intermediate_results.sals);
      filter = xmalloc (intermediate_results.nelts * sizeof (int));
      make_cleanup (xfree, filter);
      blocks = xmalloc (intermediate_results.nelts * sizeof (struct block *));
      make_cleanup (xfree, blocks);
      for (i = 0; i < intermediate_results.nelts; ++i)
	{
	  set_current_program_space (intermediate_results.sals[i].pspace);
	  filter[i] = 1;
	  blocks[i] = block_for_pc_sect (intermediate_results.sals[i].pc,
					 intermediate_results.sals[i].section);
	}
      for (i = 0; i < intermediate_results.nelts; ++i)
	{
	  if (blocks[i] != NULL)
	    for (j = i + 1; j < intermediate_results.nelts; ++j)
	      {
		if (blocks[j] == blocks[i])
		  {
		    filter[j] = 0;
		    break;
		  }
	      }
	}
      for (i = 0; i < intermediate_results.nelts; ++i)
	if (filter[i])
	  {
	    struct symbol *sym = (blocks[i]
				  ? block_containing_function (blocks[i])
				  : NULL);
	    if (self->funfirstline)
	      skip_prologue_sal (&intermediate_results.sals[i]);
	    intermediate_results.sals[i].line = val.line;
	    add_sal_to_sals (self, &values, &intermediate_results.sals[i],
			     sym ? SYMBOL_NATURAL_NAME (sym) : NULL);
	  }
      do_cleanups (cleanup);
    }
  if (values.nelts == 0)
    {
      if (self->user_filename)
	throw_error (NOT_FOUND_ERROR, _("No line %d in file \"%s\"."),
		     val.line, self->user_filename);
      else
	throw_error (NOT_FOUND_ERROR, _("No line %d in the current file."),
		     val.line);
    }
  if (self->canonical)
    {
      char *copy = savestring (saved_arg, q - saved_arg);
      self->canonical->pre_expanded = 1;
      gdb_assert (self->user_filename || use_default);
      self->canonical->addr_string
	= xstrprintf ("%s:%s", (self->user_filename
				? self->user_filename
				: self->default_symtab->filename),
		      copy);
      xfree (copy);
    }
  return values;
}
static struct symtabs_and_lines decode_all_digits ( struct linespec_state * self , char * * argptr , char * q ) { struct symtabs_and_lines values ; struct symtab_and_line val ; int use_default = 0 ; char * saved_arg = * argptr ; enum sign { none , plus , minus } sign = none ; init_sal ( & val ) ; values . sals = NULL ; values . nelts = 0 ; if ( VEC_length ( symtab_p , self -> file_symtabs ) == 1 && VEC_index ( symtab_p , self -> file_symtabs , 0 ) == NULL ) { set_current_program_space ( self -> program_space ) ; set_default_source_symtab_and_line ( ) ; initialize_defaults ( & self -> default_symtab , & self -> default_line ) ; VEC_pop ( symtab_p , self -> file_symtabs ) ; VEC_free ( symtab_p , self -> file_symtabs ) ; self -> file_symtabs = collect_symtabs_from_filename ( self -> default_symtab -> filename ) ; use_default = 1 ; } if ( * * argptr == ' ' ) sign = plus , ( * argptr ) ++ ; else if ( * * argptr == ' ' ) sign = minus , ( * argptr ) ++ ; val . line = atoi ( * argptr ) ; switch ( sign ) { case plus : if ( q == * argptr ) val . line = 5 ; if ( use_default ) val . line = self -> default_line + val . line ; break ; case minus : if ( q == * argptr ) val . line = 15 ; if ( use_default ) val . line = self -> default_line - val . line ; else val . line = 1 ; break ; case none : break ; } * argptr = skip_spaces ( q ) ; if ( self -> list_mode ) decode_digits_list_mode ( self , & values , val ) ; else { struct linetable_entry * best_entry = NULL ; int * filter ; struct block * * blocks ; struct cleanup * cleanup ; struct symtabs_and_lines intermediate_results ; int i , j ; intermediate_results . sals = NULL ; intermediate_results . nelts = 0 ; decode_digits_ordinary ( self , val . line , & intermediate_results , & best_entry ) ; if ( intermediate_results . nelts == 0 && best_entry != NULL ) decode_digits_ordinary ( self , best_entry -> line , & intermediate_results , & best_entry ) ; cleanup = make_cleanup ( xfree , intermediate_results . sals ) ; filter = xmalloc ( intermediate_results . nelts * sizeof ( int ) ) ; make_cleanup ( xfree , filter ) ; blocks = xmalloc ( intermediate_results . nelts * sizeof ( struct block * ) ) ; make_cleanup ( xfree , blocks ) ; for ( i = 0 ; i < intermediate_results . nelts ; ++ i ) { set_current_program_space ( intermediate_results . sals [ i ] . pspace ) ; filter [ i ] = 1 ; blocks [ i ] = block_for_pc_sect ( intermediate_results . sals [ i ] . pc , intermediate_results . sals [ i ] . section ) ; } for ( i = 0 ; i < intermediate_results . nelts ; ++ i ) { if ( blocks [ i ] != NULL ) for ( j = i + 1 ; j < intermediate_results . nelts ; ++ j ) { if ( blocks [ j ] == blocks [ i ] ) { filter [ j ] = 0 ; break ; } } } for ( i = 0 ; i < intermediate_results . nelts ; ++ i ) if ( filter [ i ] ) { struct symbol * sym = ( blocks [ i ] ? block_containing_function ( blocks [ i ] ) : NULL ) ; if ( self -> funfirstline ) skip_prologue_sal ( & intermediate_results . sals [ i ] ) ; intermediate_results . sals [ i ] . line = val . line ; add_sal_to_sals ( self , & values , & intermediate_results . sals [ i ] , sym ? SYMBOL_NATURAL_NAME ( sym ) : NULL ) ; } do_cleanups ( cleanup ) ; } if ( values . nelts == 0 ) { if ( self -> user_filename ) throw_error ( NOT_FOUND_ERROR , _ ( " \" \" " ) , val . line , self -> user_filename ) ; else throw_error ( NOT_FOUND_ERROR , _ ( " " ) , val . line ) ; } if ( self -> canonical ) { char * copy = savestring ( saved_arg , q - saved_arg ) ; self -> canonical -> pre_expanded = 1 ; gdb_assert ( self -> user_filename || use_default ) ; self -> canonical -> addr_string = xstrprintf ( " " , ( self -> user_filename ? self -> user_filename : self -> default_symtab -> filename ) , copy ) ; xfree ( copy ) ; } return values ; }
This decodes a line where the argument is all digits (possibly
preceded by a sign).
This decodes a line where the argument is all digits ( possibly preceded by a sign ) .
/* This is where we need to make sure that we have good defaults.
     We must guarantee that this section of code is never executed
     when we are called with just a function name, since
     set_default_source_symtab_and_line uses
     select_source_symtab that calls us with such an argument.  */ /* Make sure we have at least a default source file.  */ /* No need to adjust val.line.  */ /* For optimized code, compiler can scatter one source line
	 accross disjoint ranges of PC values, even when no duplicate
	 functions or inline functions are involved.  For example,
	 'for (;;)' inside non-template non-inline non-ctor-or-dtor
	 function can result in two PC ranges.  In this case, we don't
	 want to set breakpoint on first PC of each range.  To filter
	 such cases, we use containing blocks -- for each PC found
	 above we see if there are other PCs that are in the same
	 block.  If yes, the other PCs are filtered out.  */ /* Make sure the line matches the request, not what was
	       found.  */