X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftid-parse.c;h=6ad8b1f4aff47175b348f374fa74d40b75819851;hb=1d29ab86cb5145cac5045c1a4113d8b8fbd4d9c6;hp=21b872d39d35529d6bd8140ab1c0b6b6ad3cb9e9;hpb=5d5658a1d3c3eb2a09c03f2f0662a1c01963c869;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/tid-parse.c b/gdb/tid-parse.c index 21b872d39d..6ad8b1f4af 100644 --- a/gdb/tid-parse.c +++ b/gdb/tid-parse.c @@ -1,6 +1,6 @@ /* TID parsing for GDB, the GNU debugger. - Copyright (C) 2015-2016 Free Software Foundation, Inc. + Copyright (C) 2015-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -31,6 +31,23 @@ invalid_thread_id_error (const char *string) error (_("Invalid thread ID: %s"), string); } +/* Wrapper for get_number_trailer that throws an error if we get back + a negative number. We'll see a negative value if the number is + stored in a negative convenience variable (e.g., $minus_one = -1). + STRING is the parser string to be used in the error message if we + do get back a negative number. */ + +static int +get_positive_number_trailer (const char **pp, int trailer, const char *string) +{ + int num; + + num = get_number_trailer (pp, trailer); + if (num < 0) + error (_("negative value: %s"), string); + return num; +} + /* See tid-parse.h. */ struct thread_info * @@ -38,7 +55,6 @@ parse_thread_id (const char *tidstr, const char **end) { const char *number = tidstr; const char *dot, *p1; - struct thread_info *tp; struct inferior *inf; int thr_num; int explicit_inf_id = 0; @@ -51,7 +67,7 @@ parse_thread_id (const char *tidstr, const char **end) int inf_num; p1 = number; - inf_num = get_number_trailer (&p1, '.'); + inf_num = get_positive_number_trailer (&p1, '.', number); if (inf_num == 0) invalid_thread_id_error (number); @@ -69,16 +85,17 @@ parse_thread_id (const char *tidstr, const char **end) p1 = number; } - thr_num = get_number_const (&p1); + thr_num = get_positive_number_trailer (&p1, 0, number); if (thr_num == 0) invalid_thread_id_error (number); - ALL_THREADS (tp) - { - if (ptid_get_pid (tp->ptid) == inf->pid - && tp->per_inf_num == thr_num) + thread_info *tp = nullptr; + for (thread_info *it : inf->threads ()) + if (it->per_inf_num == thr_num) + { + tp = it; break; - } + } if (tp == NULL) { @@ -96,28 +113,42 @@ parse_thread_id (const char *tidstr, const char **end) /* See tid-parse.h. */ +tid_range_parser::tid_range_parser (const char *tidlist, + int default_inferior) +{ + init (tidlist, default_inferior); +} + +/* See tid-parse.h. */ + void -tid_range_parser_init (struct tid_range_parser *parser, const char *tidlist, - int default_inferior) +tid_range_parser::init (const char *tidlist, int default_inferior) { - parser->state = TID_RANGE_STATE_INFERIOR; - parser->string = tidlist; - parser->inf_num = 0; - parser->qualified = 0; - parser->default_inferior = default_inferior; + m_state = STATE_INFERIOR; + m_cur_tok = tidlist; + m_inf_num = 0; + m_qualified = false; + m_default_inferior = default_inferior; } /* See tid-parse.h. */ -int -tid_range_parser_finished (struct tid_range_parser *parser) +bool +tid_range_parser::finished () const { - switch (parser->state) + switch (m_state) { - case TID_RANGE_STATE_INFERIOR: - return *parser->string == '\0'; - case TID_RANGE_STATE_THREAD_RANGE: - return parser->range_parser.finished; + case STATE_INFERIOR: + /* Parsing is finished when at end of string or null string, + or we are not in a range and not in front of an integer, negative + integer, convenience var or negative convenience var. */ + return (*m_cur_tok == '\0' + || !(isdigit (*m_cur_tok) + || *m_cur_tok == '$' + || *m_cur_tok == '*')); + case STATE_THREAD_RANGE: + case STATE_STAR_RANGE: + return m_range_parser.finished (); } gdb_assert_not_reached (_("unhandled state")); @@ -126,55 +157,54 @@ tid_range_parser_finished (struct tid_range_parser *parser) /* See tid-parse.h. */ const char * -tid_range_parser_string (struct tid_range_parser *parser) +tid_range_parser::cur_tok () const { - switch (parser->state) + switch (m_state) { - case TID_RANGE_STATE_INFERIOR: - return parser->string; - case TID_RANGE_STATE_THREAD_RANGE: - return parser->range_parser.string; + case STATE_INFERIOR: + return m_cur_tok; + case STATE_THREAD_RANGE: + case STATE_STAR_RANGE: + return m_range_parser.cur_tok (); } gdb_assert_not_reached (_("unhandled state")); } -/* See tid-parse.h. */ - void -tid_range_parser_skip (struct tid_range_parser *parser) +tid_range_parser::skip_range () { - gdb_assert ((parser->state == TID_RANGE_STATE_THREAD_RANGE) - && parser->range_parser.in_range); + gdb_assert (m_state == STATE_THREAD_RANGE + || m_state == STATE_STAR_RANGE); - tid_range_parser_init (parser, parser->range_parser.end_ptr, - parser->default_inferior); + m_range_parser.skip_range (); + init (m_range_parser.cur_tok (), m_default_inferior); } /* See tid-parse.h. */ -int -tid_range_parser_qualified (struct tid_range_parser *parser) +bool +tid_range_parser::tid_is_qualified () const { - return parser->qualified; + return m_qualified; } -/* Helper for tid_range_parser_get_tid and - tid_range_parser_get_tid_range. Return the next range if THR_END +/* Helper for tid_range_parser::get_tid and + tid_range_parser::get_tid_range. Return the next range if THR_END is non-NULL, return a single thread ID otherwise. */ -static int -get_tid_or_range (struct tid_range_parser *parser, int *inf_num, - int *thr_start, int *thr_end) +bool +tid_range_parser::get_tid_or_range (int *inf_num, + int *thr_start, int *thr_end) { - if (parser->state == TID_RANGE_STATE_INFERIOR) + if (m_state == STATE_INFERIOR) { const char *p; const char *space; - space = skip_to_space (parser->string); + space = skip_to_space (m_cur_tok); - p = parser->string; + p = m_cur_tok; while (p < space && *p != '.') p++; if (p < space) @@ -182,41 +212,53 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num, const char *dot = p; /* Parse number to the left of the dot. */ - p = parser->string; - parser->inf_num = get_number_trailer (&p, '.'); - if (parser->inf_num == 0) - invalid_thread_id_error (parser->string); + p = m_cur_tok; + m_inf_num = get_positive_number_trailer (&p, '.', m_cur_tok); + if (m_inf_num == 0) + return 0; - parser->qualified = 1; + m_qualified = true; p = dot + 1; if (isspace (*p)) - invalid_thread_id_error (parser->string); + return false; } else { - parser->inf_num = parser->default_inferior; - parser->qualified = 0; - p = parser->string; + m_inf_num = m_default_inferior; + m_qualified = false; + p = m_cur_tok; } - init_number_or_range (&parser->range_parser, p); - parser->state = TID_RANGE_STATE_THREAD_RANGE; + m_range_parser.init (p); + if (p[0] == '*' && (p[1] == '\0' || isspace (p[1]))) + { + /* Setup the number range parser to return numbers in the + whole [1,INT_MAX] range. */ + m_range_parser.setup_range (1, INT_MAX, skip_spaces (p + 1)); + m_state = STATE_STAR_RANGE; + } + else + m_state = STATE_THREAD_RANGE; } - *inf_num = parser->inf_num; - *thr_start = get_number_or_range (&parser->range_parser); + *inf_num = m_inf_num; + *thr_start = m_range_parser.get_number (); + if (*thr_start < 0) + error (_("negative value: %s"), m_cur_tok); if (*thr_start == 0) - invalid_thread_id_error (parser->string); + { + m_state = STATE_INFERIOR; + return false; + } /* If we successfully parsed a thread number or finished parsing a thread range, switch back to assuming the next TID is inferior-qualified. */ - if (parser->range_parser.end_ptr == NULL - || parser->range_parser.string == parser->range_parser.end_ptr) + if (!m_range_parser.in_range ()) { - parser->state = TID_RANGE_STATE_INFERIOR; - parser->string = parser->range_parser.string; + m_state = STATE_INFERIOR; + m_cur_tok = m_range_parser.cur_tok (); if (thr_end != NULL) *thr_end = *thr_start; @@ -224,10 +266,13 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num, /* If we're midway through a range, and the caller wants the end value, return it and skip to the end of the range. */ - if (thr_end != NULL && parser->state == TID_RANGE_STATE_THREAD_RANGE) + if (thr_end != NULL + && (m_state == STATE_THREAD_RANGE + || m_state == STATE_STAR_RANGE)) { - *thr_end = parser->range_parser.end_value; - tid_range_parser_skip (parser); + *thr_end = m_range_parser.end_value (); + + skip_range (); } return (*inf_num != 0 && *thr_start != 0); @@ -235,24 +280,37 @@ get_tid_or_range (struct tid_range_parser *parser, int *inf_num, /* See tid-parse.h. */ -int -tid_range_parser_get_tid_range (struct tid_range_parser *parser, int *inf_num, - int *thr_start, int *thr_end) +bool +tid_range_parser::get_tid_range (int *inf_num, + int *thr_start, int *thr_end) { gdb_assert (inf_num != NULL && thr_start != NULL && thr_end != NULL); - return get_tid_or_range (parser, inf_num, thr_start, thr_end); + return get_tid_or_range (inf_num, thr_start, thr_end); } /* See tid-parse.h. */ -int -tid_range_parser_get_tid (struct tid_range_parser *parser, - int *inf_num, int *thr_num) +bool +tid_range_parser::get_tid (int *inf_num, int *thr_num) { gdb_assert (inf_num != NULL && thr_num != NULL); - return get_tid_or_range (parser, inf_num, thr_num, NULL); + return get_tid_or_range (inf_num, thr_num, NULL); +} + +/* See tid-parse.h. */ + +bool +tid_range_parser::in_star_range () const +{ + return m_state == STATE_STAR_RANGE; +} + +bool +tid_range_parser::in_thread_range () const +{ + return m_state == STATE_THREAD_RANGE; } /* See tid-parse.h. */ @@ -261,19 +319,18 @@ int tid_is_in_list (const char *list, int default_inferior, int inf_num, int thr_num) { - struct tid_range_parser parser; - if (list == NULL || *list == '\0') return 1; - tid_range_parser_init (&parser, list, default_inferior); - while (!tid_range_parser_finished (&parser)) + tid_range_parser parser (list, default_inferior); + if (parser.finished ()) + invalid_thread_id_error (parser.cur_tok ()); + while (!parser.finished ()) { int tmp_inf, tmp_thr_start, tmp_thr_end; - if (!tid_range_parser_get_tid_range (&parser, &tmp_inf, - &tmp_thr_start, &tmp_thr_end)) - invalid_thread_id_error (parser.string); + if (!parser.get_tid_range (&tmp_inf, &tmp_thr_start, &tmp_thr_end)) + invalid_thread_id_error (parser.cur_tok ()); if (tmp_inf == inf_num && tmp_thr_start <= thr_num && thr_num <= tmp_thr_end) return 1;