+/* Extract the breakpoint/location range specified by ARG. Returns
+ the breakpoint range in BP_NUM_RANGE, and the location range in
+ BP_LOC_RANGE.
+
+ ARG may be in any of the following forms:
+
+ x where 'x' is a breakpoint number.
+ x-y where 'x' and 'y' specify a breakpoint numbers range.
+ x.y where 'x' is a breakpoint number and 'y' a location number.
+ x.y-z where 'x' is a breakpoint number and 'y' and 'z' specify a
+ location number range.
+*/
+
+static bool
+extract_bp_number_and_location (const std::string &arg,
+ std::pair<int, int> &bp_num_range,
+ std::pair<int, int> &bp_loc_range)
+{
+ std::string::size_type dot = arg.find ('.');
+
+ if (dot != std::string::npos)
+ {
+ /* Handle 'x.y' and 'x.y-z' cases. */
+
+ if (arg.length () == dot + 1 || dot == 0)
+ error (_("bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ const char *ptb = arg.c_str ();
+ int bp_num = get_number_trailer (&ptb, '.');
+ if (bp_num == 0)
+ error (_("Bad breakpoint number '%s'"), arg.c_str ());
+
+ bp_num_range.first = bp_num;
+ bp_num_range.second = bp_num;
+
+ const char *bp_loc = &arg[dot + 1];
+ std::string::size_type dash = arg.find ('-', dot + 1);
+ if (dash != std::string::npos)
+ {
+ /* bp_loc is a range (x-z). */
+ if (arg.length () == dash + 1)
+ error (_("bad breakpoint number at or near: '%s'"), bp_loc);
+
+ const char *ptlf = bp_loc;
+ bp_loc_range.first = get_number_trailer (&ptlf, '-');
+
+ const char *ptls = &arg[dash + 1];
+ bp_loc_range.second = get_number_trailer (&ptls, '\0');
+ }
+ else
+ {
+ /* bp_loc is a single value. */
+ const char *ptls = bp_loc;
+ bp_loc_range.first = get_number_trailer (&ptls, '\0');
+ if (bp_loc_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%s'"), arg.c_str ());
+ return false;
+ }
+ bp_loc_range.second = bp_loc_range.first;
+ }
+ }
+ else
+ {
+ /* Handle x and x-y cases. */
+ std::string::size_type dash = arg.find ('-');
+ if (dash != std::string::npos)
+ {
+ if (arg.length () == dash + 1 || dash == 0)
+ error (_("bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ const char *ptf = arg.c_str ();
+ bp_num_range.first = get_number_trailer (&ptf, '-');
+
+ const char *pts = &arg[dash + 1];
+ bp_num_range.second = get_number_trailer (&pts, '\0');
+ }
+ else
+ {
+ const char *ptf = arg.c_str ();
+ bp_num_range.first = get_number (&ptf);
+ if (bp_num_range.first == 0)
+ {
+ warning (_("bad breakpoint number at or near '%s'"), arg.c_str ());
+ return false;
+ }
+ bp_num_range.second = bp_num_range.first;
+ }
+ bp_loc_range.first = 0;
+ bp_loc_range.second = 0;
+ }
+
+ if (bp_num_range.first == 0 || bp_num_range.second == 0)
+ error (_("bad breakpoint number at or near: '%s'"), arg.c_str ());
+
+ return true;
+}
+
+/* Enable or disable a breakpoint location BP_NUM.LOC_NUM. ENABLE
+ specifies whether to enable or disable. */
+
+static void
+enable_disable_bp_num_loc (int bp_num, int loc_num, bool enable)
+{
+ struct bp_location *loc = find_location_by_number (bp_num, loc_num);
+ if (loc != NULL)
+ {
+ if (loc->enabled != enable)
+ {
+ loc->enabled = enable;
+ mark_breakpoint_location_modified (loc);
+ }
+ if (target_supports_enable_disable_tracepoint ()
+ && current_trace_status ()->running && loc->owner
+ && is_tracepoint (loc->owner))
+ target_disable_tracepoint (loc);
+ }
+ update_global_location_list (UGLL_DONT_INSERT);
+}
+
+/* Enable or disable a range of breakpoint locations. BP_NUM is the
+ number of the breakpoint, and BP_LOC_RANGE specifies the
+ (inclusive) range of location numbers of that breakpoint to
+ enable/disable. ENABLE specifies whether to enable or disable the
+ location. */
+
+static void
+enable_disable_breakpoint_location_range (int bp_num,
+ std::pair<int, int> &bp_loc_range,
+ bool enable)
+{
+ for (int i = bp_loc_range.first; i <= bp_loc_range.second; i++)
+ enable_disable_bp_num_loc (bp_num, i, enable);
+}