/* TID parsing for GDB, the GNU debugger.

   Copyright (C) 2015-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   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 of the License, 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, see <http://www.gnu.org/licenses/>.  */

#ifndef TID_PARSE_H
#define TID_PARSE_H

#include "cli/cli-utils.h"

struct thread_info;

/* Issue an invalid thread ID error, pointing at STRING, the invalid
   ID.  */
[[noreturn]] extern void invalid_thread_id_error (const char *string);

/* Parse TIDSTR as a per-inferior thread ID, in either INF_NUM.THR_NUM
   or THR_NUM form.  In the latter case, the missing INF_NUM is filled
   in from the current inferior.  If ENDPTR is not NULL,
   parse_thread_id stores the address of the first character after the
   thread ID.  Either a valid thread is returned, or an error is
   thrown.  */
struct thread_info *parse_thread_id (const char *tidstr, const char **end);

/* Return true if TIDSTR is pointing to a string that looks like a
   thread-id.  This doesn't mean that TIDSTR identifies a valid thread, but
   the string does at least look like a valid thread-id.  If END is not
   NULL, parse_thread_id stores the address of the first character after
   the thread-id into *END.  */

bool is_thread_id (const char *tidstr, const char **end);

/* Parse a thread ID or a thread range list.

   A range will be of the form

     <inferior_num>.<thread_number1>-<thread_number2>

   and will represent all the threads of inferior INFERIOR_NUM with
   number between THREAD_NUMBER1 and THREAD_NUMBER2, inclusive.
   <inferior_num> can also be omitted, as in

     <thread_number1>-<thread_number2>

   in which case GDB infers the inferior number from the default
   passed to the constructor or to the last call to the init
   function.  */
class tid_range_parser
{
public:
  /* Default construction.  Must call init before calling get_*.  */
  tid_range_parser () {}

  /* Calls init automatically.  See init for description of
     parameters.  */
  tid_range_parser (const char *tidlist, int default_inferior);

  /* Reinitialize a tid_range_parser.  TIDLIST is the string to be
     parsed.  DEFAULT_INFERIOR is the inferior number to assume if a
     non-qualified thread ID is found.  */
  void init (const char *tidlist, int default_inferior);

  /* Parse a thread ID or a thread range list.

     This function is designed to be called iteratively.  While
     processing a thread ID range list, at each call it will return
     (in the INF_NUM and THR_NUM output parameters) the next thread ID
     in the range (irrespective of whether the thread actually
     exists).

     At the beginning of parsing a thread range, the char pointer
     PARSER->m_cur_tok will be advanced past <thread_number1> and left
     pointing at the '-' token.  Subsequent calls will not advance the
     pointer until the range is completed.  The call that completes
     the range will advance the pointer past <thread_number2>.

     This function advances through the input string for as long you
     call it.  Once the end of the input string is reached, a call to
     finished returns false (see below).

     E.g., with list: "1.2 3.4-6":

     1st call: *INF_NUM=1; *THR_NUM=2 (finished==0)
     2nd call: *INF_NUM=3; *THR_NUM=4 (finished==0)
     3rd call: *INF_NUM=3; *THR_NUM=5 (finished==0)
     4th call: *INF_NUM=3; *THR_NUM=6 (finished==1)

     Returns true if a thread/range is parsed successfully, false
     otherwise.  */
  bool get_tid (int *inf_num, int *thr_num);

  /* Like get_tid, but return a thread ID range per call, rather then
     a single thread ID.

     If the next element in the list is a single thread ID, then
     *THR_START and *THR_END are set to the same value.

     E.g.,. with list: "1.2 3.4-6"

     1st call: *INF_NUM=1; *THR_START=2; *THR_END=2 (finished==0)
     2nd call: *INF_NUM=3; *THR_START=4; *THR_END=6 (finished==1)

     Returns true if parsed a thread/range successfully, false
     otherwise.  */
  bool get_tid_range (int *inf_num, int *thr_start, int *thr_end);

  /* Returns true if processing a star wildcard (e.g., "1.*")
     range.  */
  bool in_star_range () const;

  /* Returns true if processing a thread range (e.g., 1.2-3).  */
  bool in_thread_range () const;

  /* Returns true if parsing has completed.  */
  bool finished () const;

  /* Return the current token being parsed.  When parsing has
     finished, this points past the last parsed token.  */
  const char *cur_tok () const;

  /* When parsing a range, advance past the final token in the
     range.  */
  void skip_range ();

  /* True if the TID last parsed was explicitly inferior-qualified.
     IOW, whether the spec specified an inferior number
     explicitly.  */
  bool tid_is_qualified () const;

private:
  /* No need for these.  They are intentionally not defined anywhere.  */
  tid_range_parser (const tid_range_parser &);
  tid_range_parser &operator= (const tid_range_parser &);

  bool get_tid_or_range (int *inf_num, int *thr_start, int *thr_end);

  /* The possible states of the tid range parser's state machine,
     indicating what sub-component are we expecting.  */
  enum
    {
      /* Parsing the inferior number.  */
      STATE_INFERIOR,

      /* Parsing the thread number or thread number range.  */
      STATE_THREAD_RANGE,

      /* Parsing a star wildcard thread range.  E.g., "1.*".  */
      STATE_STAR_RANGE,
    } m_state;

  /* The string being parsed.  When parsing has finished, this points
     past the last parsed token.  */
  const char *m_cur_tok;

  /* The range parser state when we're parsing the thread number
     sub-component.  */
  number_or_range_parser m_range_parser;

  /* Last inferior number returned.  */
  int m_inf_num;

  /* True if the TID last parsed was explicitly inferior-qualified.
     IOW, whether the spec specified an inferior number
     explicitly.  */
  bool m_qualified;

  /* The inferior number to assume if the TID is not qualified.  */
  int m_default_inferior;
};


/* Accept a string-form list of thread IDs such as is accepted by
   tid_range_parser.  Return true if the INF_NUM.THR.NUM thread is in
   the list.  DEFAULT_INFERIOR is the inferior number to assume if a
   non-qualified thread ID is found in the list.

   By definition, an empty list includes all threads.  This is to be
   interpreted as typing a command such as "info threads" with no
   arguments.  */
extern int tid_is_in_list (const char *list, int default_inferior,
			   int inf_num, int thr_num);

#endif /* TID_PARSE_H */
