Пример #1
0
// Find path of source file SOURCE
string dbx_path(const string& source)
{
    string path;
    if (gdb->has_setenv_command() && gdb->has_edit_command())
    {
	// The DBX `file' command issues only the base name of the
	// current file.  The `edit' command, however, invokes an
	// editor with the entire path.  So, we misuse the `edit'
	// command such that it reports the entire path.
	gdb_question("setenv EDITOR \"echo\"");
	path = gdb_question("edit " + source);
	gdb_question(string("setenv EDITOR ") + 
		     quote(getenv("EDITOR") ? getenv("EDITOR") : "vi"));
    }
    else if (gdb->type() == DBX)
    {
	// We have DBX, but no `setenv' and no `edit' command.  Check
	// whether the `file' command with no arguments provides the
	// full path, as in AIX DBX 3.1.  This shouldn't affect other
	// DBX variants as `file' will simply return the same thing
	// already contained in source.
	gdb_question("file " + source);
	path = gdb_question("file");
    }

    strip_leading_space(path);
    if (!path.contains('/', 0) || path.contains(' '))
	path = source;		// Sanity check

    strip_trailing_space(path);
    return path;
}
Пример #2
0
// Remove and return display name from DISPLAY
string read_disp_name (string& display, GDBAgent *gdb)
{
    strip_leading_space(display);
    string name = display.before (" = ");
    display = get_disp_value_str(display, gdb);
    return name;
}
Пример #3
0
// Return next display from DISPLAYS ("" if none); remove it from
// DISPLAYS
string read_next_display (string& displays, GDBAgent *gdb)
{
    string next_display;
    strip_leading_space(displays);

    // string old_displays = displays;
    // std::clog << "read_next_display(" << quote(old_displays) << ")...\n";

    if (is_disabling(displays, gdb))
    {
	// After a `disabling' message, `display' output finishes
	next_display = displays;
	displays = "";
    }
    else
    {
	for (;;)
	{
	    next_display += read_token(displays);

	    if (displays.empty())
		break;		// All done

	    if (next_display.contains(":()", -1))
	    {
		// AIX DBX gives weird `members' like
		// "pcg =     OM_PCGDownCasters:()\n(_root = 0x2004c248 ..."
		// Be sure to continue such displays.
		continue;
	    }

	    if (next_is_nl(displays))
		break;		// At end of display
	}
    }

    displays = displays.after('\n');
    strip_leading_space(displays);

    // std::clog << "read_next_display(" << quote(old_displays) << ") = "
    //           << quote(next_display) << "\n";
    return next_display;
}
Пример #4
0
bool add_running_arguments(string& cmd, Widget origin)
{
    if (cmd == "run")
	cmd = gdb->rerun_command();

    if (gdb->type() != JDB)
	return true;		// Ok, perform the command

    if (!is_run_cmd(cmd))
	return true;		// Ok, perform the command

    strip_leading_space(cmd);
    string args = cmd.after(rxwhite);

    ProgramInfo info;

    if (args.empty() && gdb->has_debug_command())
    {
	// JDB 1.1 requires at least a class name after the `run' command.
	cmd += " " + info.file;
    }

    if (info.running && !gdb->has_debug_command())
    {
	// JDB 1.2 cannot rerun a program after it has been started.
	// Offer to restart JDB instead.
	static Widget restart_jdb = 0;
	static string saved_run_command;

	if (restart_jdb == 0)
	{
	    restart_jdb = 
		verify(XmCreateQuestionDialog(find_shell(origin),
				 XMST("confirm_restart_gdb_dialog"), 
				 ArgList(0), 0));
	    Delay::register_shell(restart_jdb);
	    XtAddCallback(restart_jdb, XmNhelpCallback,   
			  ImmediateHelpCB, XtPointer(0));
	    XtAddCallback(restart_jdb, XmNokCallback,     
			  RestartAndRunCB, (XtPointer)&saved_run_command);
	}

	saved_run_command = cmd;
	XtManageChild(restart_jdb);

	return false;		// Don't perform the command yet
    }

    return true;
}
Пример #5
0
// Store first function name in ANSWER after INDEX in BUFFER
static void fetch_function(const string& answer, int index, string& buffer,
			   bool in_required = false)
{
    if (!buffer.empty())
	return;			// Already have a function

    string line = answer.from(index);
    line = line.before('\n');
    if (in_required)
	line = line.after(" in ");

    // The function name is the word before the opening parenthesis
    line = line.before('(');
    strip_trailing_space(line);
    int ws_index = line.index(' ', -1) + 1;
    line = line.from(ws_index);
    strip_leading_space(line);
    if (!line.empty() && line.contains(rxidentifier, 0))
	buffer = line;
}
Пример #6
0
// True if more sequence members are coming
bool DispValue::sequence_pending(const string& value, 
				 const DispValue *parent)
{
    if (parent != 0)
    {
	switch (parent->type())
	{
	case Sequence:
	case List:
	case Struct:
	case Reference:
	case Array:
	    // In a composite, we always read everything up to the
	    // final delimiter.
	    return false;

	case Simple:
	case Pointer:
	case Text:
	case UnknownType:
	    break;
	}
    }

    string v = value;
    strip_leading_space(v);

    if (!v.empty() && parent == 0)
	return true;		// Still more to read

    if (!is_delimited(value))
	return true;		// Not at delimiter - more stuff follows

    // Sequence is done
    return false;
}
Пример #7
0
void BreakPoint::process_dbx(string& info_output)
{
    if (info_output.contains("PC==", 0) ||
	info_output.contains("stop ", 0) ||
	info_output.contains("stopped ", 0))
    {
	// Breakpoint

	info_output = info_output.after(rxblanks_or_tabs);
	strip_leading_space (info_output);

	if (info_output.contains ("at ", 0))
	{
	    info_output = info_output.after(rxblanks_or_tabs);
	    string file_name;
	    if (info_output.contains('"', 0))
	    {
		// `stop at "FILE":LINE'
		file_name = unquote(info_output.before(":"));
		info_output = info_output.after (":");
	    }
	    else if (info_output.contains('[', 0))
	    {
		// `stop at [file:line ...]'
		file_name = info_output.before(":");
		file_name = file_name.after('[');
		info_output = info_output.after (":");
	    }
	    else
	    {
		// `stop at LINE'
		file_name = "";
	    }

	    int new_line_nr = 0;
	    if (!info_output.empty() && isdigit(info_output[0]))
		new_line_nr = get_positive_nr(info_output);

	    if (!file_name.empty())
		myfile_name = file_name;

	    if (new_line_nr != 0)
		myline_nr = new_line_nr;

	    // DBX issues either locations or functions
	    myfunc = "";
	}
	else if (info_output.contains ("in ", 0))
	{
	    string line = info_output.after("in ");
	    if (line.contains('\n'))
		line = line.before('\n');

	    if (line.contains("\":"))
	    {
		// Ladebug output:
		// `PC==x in TYPE FUNC(ARGS...) "FILE":LINE { COMMANDS }

		myfile_name = line.after("\"");
		myfile_name = myfile_name.before("\"");
		myline_nr   = get_positive_nr(line.after("\":"));
		myfunc      = line.before("\"");
		strip_space(myfunc);

		// Be sure to remove TYPE
		while (myfunc.contains(" "))
		    myfunc = myfunc.after(" ");
	    }
	    else
	    {
		// DBX output:
		// `stop in FUNC'
		myfunc = line.before(rxblanks_or_tabs);
		strip_space(myfunc);

		myfile_name = "";
		myline_nr = 0;

		// Attempt to get exact position of FUNC
		const string pos = dbx_lookup(myfunc);
		if (!pos.empty())
		{
		    const string file_name = pos.before(":");
		    const string line_s    = pos.after(":");
		    int new_line_nr  = get_positive_nr(line_s);

		    myfile_name = file_name;
		    if (new_line_nr != 0)
			myline_nr = new_line_nr;
		}
	    }
	}
	else
	{
	    // `stop VAR'
	    mytype       = WATCHPOINT;
	    mywatch_mode = WATCH_CHANGE;

	    string expr = info_output;
	    if (expr.contains('\n'))
		expr = expr.before('\n');
	    if (expr.contains(rxblanks_or_tabs))
		expr = expr.before(rxblanks_or_tabs);

	    myexpr = expr;
	}

	// Sun DBX 3.0 issues extra characters like 
	// (2) stop in main -count 0/10
	// [3] stop in main -disable
	string options;
	if (info_output.contains('\n'))
	    options = info_output.before('\n');
	else
	    options = info_output;
	bool new_enabled = !options.contains(" -disable");
	myenabled = new_enabled;

	myinfos = "";
	if (options.contains(" -count "))
	{
	    string count = options.after(" -count ");
	    strip_leading_space(count);
	    if (count.contains(' '))
		count = count.before(' ');

	    myinfos = "count " + count;
	    if (count.contains('/'))
		count = count.after('/');
	    myignore_count = atoi(count.chars());
	}

	if (options.contains(" if ") || options.contains(" -if "))
	{
	    string cond = options.after("if ");
	    if (!myinfos.empty())
		myinfos += '\n';
	    myinfos += "stop only if " + cond;
	    mycondition = cond;
	}
    }

    info_output = info_output.after('\n');
}
Пример #8
0
void BreakPoint::process_gdb(string& info_output)
{
    // Read type (`breakpoint' or `watchpoint')
    // The type may be prefixed by `hw ' or other details.
    const string word1 = info_output.before('\n');
    const string word2 = word1.after(rxblanks_or_tabs);

    if (word1.contains("watchpoint", 0) || 
	word2.contains("watchpoint", 0))
    {
	mytype = WATCHPOINT;

	// Fetch breakpoint mode detail (`acc' or `read')
	if (word1.contains("acc ", 0))
	    mywatch_mode = WATCH_ACCESS;
	else if (word1.contains("read ", 0))
	    mywatch_mode = WATCH_READ;
	else
	    mywatch_mode = WATCH_CHANGE;
    }
    else if (word1.contains("breakpoint", 0) || 
	     word2.contains("breakpoint", 0))
    {
	mytype = BREAKPOINT;
    }
    info_output = info_output.after("point");
    info_output = info_output.after(rxblanks_or_tabs);

    // Read disposition (`dis', `del', or `keep')
    if (info_output.contains("dis", 0))
    {
	mydispo = BPDIS;
    }
    else if (info_output.contains("del", 0))
    {
	mydispo = BPDEL;
    }
    else if (info_output.contains("keep", 0))
    {
	mydispo = BPKEEP;
    }
    info_output = info_output.after(rxblanks_or_tabs);

    // Read enabled flag (`y' or `n')
    if (info_output.contains('y', 0))
    {
	myenabled = true;
    }
    else if (info_output.contains('n', 0))
    {
	myenabled = false;
    }
    info_output = info_output.after(rxblanks_or_tabs);

    string new_info = "";
    if (mytype == BREAKPOINT) 
    {
        if (MAKE != gdb->type() && BASH != gdb->type())
	{
	    // Read address
	    myaddress = info_output.through(rxalphanum);
	  
	    info_output = info_output.after(myaddress);
	    strip_leading_space(info_output);
	    
	}
	  
        if (BASH != gdb->type()) {
	  if (info_output.contains("in ", 0))
	  {
	      // Function name
	      string func = info_output.after("in ");
	      if (func.contains('\n'))
		  func = func.before('\n');
	      if (func.contains(" at "))
		  func = func.before(" at ");
	      strip_space(func);

	      myfunc = func;
	  }
	}

	// Location
 	string remainder = info_output.through('\n');
	info_output = info_output.after('\n');

	// GDB 5.0 may issue an (indented) file name in the following line
	if (!remainder.contains(rxname_colon_int_nl))
	{
	    remainder += info_output.through('\n');
	    if (remainder.contains(rxname_colon_int_nl))
		info_output = info_output.after('\n');
	}

 	remainder = remainder.from(rxname_colon_int_nl);
 	myfile_name = remainder.before(":");

 	remainder = remainder.after(":");
 	if (!remainder.empty() && isdigit(remainder[0]))
 	    myline_nr = get_positive_nr(remainder);
    }
    else if (mytype == WATCHPOINT)
    {
	// Read watched expression
	myexpr = info_output.before('\n');
	info_output = info_output.after('\n');
    }

    int ignore_count = 0;
    string cond      = "";
    StringArray commands;

    if (!info_output.empty() && !isdigit(info_output[0]))
    {
	// Extra info follows
	int next_nl = index(info_output, rxnl_int, "\n");
	if (next_nl == -1)
	{
	    new_info += info_output;
	    info_output = "";
	}
	else
	{
	    new_info += info_output.through(next_nl);
	    info_output = info_output.after(next_nl);
	}

	int n = new_info.freq('\n');
	string *lines = new string[n + 1];
	split(new_info, lines, n + 1, '\n');
	string newer_info = "";

	for (int i = 0; i < n; i++)
	{
	    bool save_info = true;

	    string line = lines[i];
	    bool starts_with_space = (!line.empty() && isspace(line[0]));
	    strip_leading_space(line);

	    if (line.contains("ignore next ", 0))
	    {
		// Fetch ignore count
		string count = line.after("ignore next ");
		count = count.before(" hits");
		ignore_count = atoi(count.chars());
	    }
	    else if (line.contains("stop only if ", 0))
	    {
		// Fetch condition
		cond = line.after("stop only if ");
	    }
	    else if (line.contains("stop ", 0))
	    {
		// Any info (no GDB command starts with `stop')
	    }
	    else if (line.contains("breakpoint ", 0))
	    {
		// Any info (no GDB command starts with `breakpoint')
	    }
	    else if (starts_with_space)
	    {
		// A command (GDB indents all commands)
		commands += line;
		save_info = false;
	    }
	    else
	    {
		// Some other info
	    }

	    if (save_info)
		newer_info += line + '\n';
	}

	new_info = newer_info;
	delete[] lines;
    }

    myinfos = new_info;
    myignore_count = ignore_count;
    mycondition = cond;
    mycommands = commands;
}
Пример #9
0
// True if CMD quits GDB
bool is_quit_cmd (const string& cmd)
{
    string c = cmd;
    strip_leading_space(c);
    return c.contains('q', 0);	// `quit', `q', or whatever
}
Пример #10
0
string dbx_lookup(const string& func_name, bool silent)
{
    // Protect against `1' or `' being looked up as function names
    if (!func_name.contains(rxidentifier, 0))
	return "";		// Bad function name

    if (pos_cache.has(func_name))
    {
	string pos = pos_cache[func_name];
	if (silent || !pos.empty())
	    return pos;
    }

    string reply;
    switch (gdb->type())
    {
    case DBG:
    case DBX:
    case GDB:
    case JDB:
    case PYDB:
	reply = gdb_question("list " + func_name, 0, true);
	break;

    case XDB:
	reply = gdb_question("v " + func_name, 0, true);
	break;

    case PERL:
	reply = gdb_question("l " + func_name, 0, true);
	break;

    case BASH:
	reply = gdb_question("l " + func_name, 0, true);
	break;

    case MAKE:
	reply = gdb_question("target " + func_name, 0, true);
	break;
    }

    if (reply == NO_GDB_ANSWER)
    {
	// post_gdb_busy();
	return "";
    }

    string file = "";
    int line    = 0;
    switch (gdb->type())
    {
    case GDB:
    case PYDB:	// XXX
    {
	file = reply.from('\"');
	file = file.before('\"');
	const string line_s = reply.after("Line ");
	line = atoi(line_s.chars());
	break;
    }

    case DBX:
	line = line_of_listing(reply, silent);
	if (line > 0)
	{
	    file = gdb_question("file");
	    strip_trailing_space(file);
	}
	break;

    case BASH:
    case DBG:
    case JDB:
    case MAKE:
    case PERL:
	line = line_of_listing(reply, silent);
	file = source_view->line_of_cursor();
	file = file.before(':');
	break;

    case XDB:
    {
#if RUNTIME_REGEX
	static regex rxcolons("[^:]*:[^:]*: *[0-9][0-9]*.*");
#endif
	if (reply.matches(rxcolons))
	{
	    file = reply.before(':');
	    reply = reply.after(':'); // Skip file
	    reply = reply.after(':'); // Skip function
	    strip_leading_space(reply);
	    const string line_s = reply.before(':');
	    line = atoi(line_s.chars());
	}
	else
	{
	    // post_gdb_message(reply);
	    return "";
	}
	break;
    }
    }

    string pos = "";
    if (line > 0)
	pos = file + ":" + itostring(line);

    pos_cache[func_name] = pos;
    return pos;
}
Пример #11
0
// If LINE is an argument-setting command, add it to the list of arguments
void add_to_arguments(const string& line)
{
    if (is_set_args_cmd(line))
    {
	string args = line.after("args");
	args = args.after(rxwhite);
	add_argument(args, run_arguments, last_run_argument, 
		     run_arguments_updated);
    }
    else if (gdb->type() == PERL && line.contains("@ARGV = ", 0))
    {
	// @ARGV = ('arg1', 'arg2', )
	string args = line.after("('");
	args.gsub("', '", " ");
	args = args.before("', )");

	add_argument(args, run_arguments, last_run_argument, 
		     run_arguments_updated);
    }
    else if (is_run_cmd(line))
    {
	string args;
	if (gdb->type() == JDB)
	{
	    // `run CLASS ARGS...'
	    args = line.after(rxwhite);
	    args = args.after(rxwhite);
	}
	else if (gdb->type() == PERL && line.contains("exec ", 0))
	{
	    // `exec "perl -d PROGRAM ARGS..."'
	    args = line.after("exec ");
	    strip_leading_space(args);
	    if (args.contains('\"', 0) || args.contains('\'', 0))
		args = unquote(args);

	    args = args.after("-d ");
	    strip_leading_space(args);
	    args = args.after(rxwhite);
	}
	else
	{
	    // `run ARGS...'
	    args = line.after(rxwhite);
	}

	add_argument(args, run_arguments, last_run_argument, 
		     run_arguments_updated);
    }
    else if (is_make_cmd(line))
    {
	string args = line.after("make");
	args = args.after(rxwhite);
	add_argument(args, make_arguments, last_make_argument, 
		     make_arguments_updated);
    }
    else if (gdb->type() == PERL && line.contains("system 'make", 0))
    {
	string args = line.after("make");
	args = args.after(rxwhite);
	args = args.before("'");
	add_argument(args, make_arguments, last_make_argument, 
		     make_arguments_updated);
    }
    else if (is_cd_cmd(line))
    {
	string dir = line.after("cd");
	dir = dir.after(rxwhite);
	dir = source_view->full_path(dir);
	if (dir.contains('/', 0))
	    add_argument(dir, cd_arguments, last_cd_argument, 
			 cd_arguments_updated);
    }
    else if (gdb->type() == PERL && line.contains("chdir '", 0))
    {
	string dir = line.after("'");
	dir = dir.before("'");
	add_argument(dir, cd_arguments, last_cd_argument, 
		     cd_arguments_updated);
    }
    else if (gdb->type() == PERL && is_file_cmd(line, gdb))
    {
	string args = line.after(" -d ");
	args = args.after(rxwhite); // Skip file name
	args = args.before('\"');
	add_argument(args, run_arguments, last_run_argument, 
		     run_arguments_updated);
    }
}
Пример #12
0
void PosBuffer::filter_dbx(string& answer)
{
    string file;		// File name found
    string line;		// Line number found

    // When reaching a breakpoint, DBX issues the breakpoint
    // number before the status line.  Check for this and
    // initialize defaults from breakpoint position.
    strip_leading_space(answer);
    if (answer.contains('(', 0) || answer.contains('[', 0))
    {
	// Get breakpoint position
	string ans = answer;
	int num = read_positive_nr(ans);
	string pos = source_view->bp_pos(num);
	if (!pos.empty())
	{
	    file = pos.before(':');
	    line = pos.after(':');
	}
    }

    // DEC DBX way issue warnings like
    // `warning: "./cxxtest.C":157 has no code associated with it'
    // right within the position info.

    int start_of_warning = answer.index("\nwarning");
    if (start_of_warning >= 0)
    {
	int open_bracket  = answer.index('[');
	int close_bracket = answer.index(']');
	if (open_bracket >= 0 && open_bracket < start_of_warning &&
	    close_bracket >= 0 && close_bracket > start_of_warning)
	{
	    // Remove warning

	    int end_of_warning = answer.index('\n', start_of_warning + 1);
	    while (end_of_warning < int(answer.length()) && 
		   answer[end_of_warning] == '\n')
		end_of_warning++;

	    while (start_of_warning > 0 && 
		   answer[start_of_warning - 1] == '\n')
		start_of_warning--;

	    int warning_length = end_of_warning - start_of_warning;
	    answer.at(start_of_warning, warning_length) = "";
	}
    }

#if RUNTIME_REGEX
    static regex rxdbxfunc2(
	".*line  *[1-9][0-9]*  *in  *(file  *)?\"[^\"]*\"\n.*");
#endif
    if (already_read != PosComplete && answer.matches(rxdbxfunc2))
    {
	// AIX DBX issues `up', `down' and `func' output
	// in the format `FUNCTION(ARGS), line LINE in "FILE"'.
	// SUN DBX uses `line LINE in file "FILE"' instead.
	// We check for the `line LINE' part.

	line = answer.after(" line ");
	line = line.through(rxint);

	file = answer.after('\"');
	file = file.before('\"');

	if (!line.empty())
	{
	    already_read = PosComplete;
	    // answer = answer.after("\n");
	}
    }

#if RUNTIME_REGEX
    static regex rxdbxpos("[[][^]]*:[1-9][0-9]*[^]]*[]].*");
#endif
    int dbxpos_index = -1;
    if (already_read != PosComplete && 
	(dbxpos_index = index(answer, rxdbxpos, "[")) >= 0)
    {
	// DEC DBX issues breakpoint lines in the format
	// "[new_tree:113 ,0x400858] \ttree->right = NULL;"
		
	line = answer.from(dbxpos_index);
	if (line.contains("[#", 0))
	{
	    // This is a Ladebug breakpoint, no position info.
	}
	else
	{
	    // Note that the function name may contain "::" sequences.
	    while (line.contains("::"))
		line = line.after("::");
	    line = line.after(":");
	    line = line.through(rxint);
	    if (!line.empty())
	    {
		if (answer.index('\n', dbxpos_index) >= 0)
		{
		    already_read = PosComplete;

		    // Strip position info and line
		    strip_leading_space(answer);
		    if (answer.contains('[', 0))
			answer = answer.after("\n");
		}
		else
		{
		    // Wait for `\n' such that we can delete the line
		    answer_buffer = answer;
		    answer = "";
		    already_read = PosPart;
		    return;
		}
	    }
	}
    }

    if (already_read != PosComplete && 
	(answer.contains("stopped in ") || 
	 answer.contains("stopped at ")))
    {
	int stopped_index = answer.index("stopped");
	assert(stopped_index >= 0);

	// Stop reached
	// AIX DBX issues lines like
	// `[4] stopped in unnamed block $b382 at line 4259 in file
	//      "/msdev/sms/ms7/riosqa/src/tffi/fi2tofu.c" ($t1)'
	int in_file_index = answer.index("in file ", stopped_index);
	int bracket_index = answer.index("[", stopped_index);

	if (in_file_index >= 0)
	{
	    // File name given
	    file = answer.from(in_file_index);
	    file = file.after("in file ");
	    if (file.contains('\n'))
		file = file.before('\n');
	    if (file.contains('"', 0))
	    {
		file = file.after('"');
		file = file.before('"');
	    }
	}
	else if (bracket_index >= 0)
	{
	    // DEC DBX and SGI DBX output format:
	    // `[3] Process  1852 (cxxtest) 
	    // stopped at [::main:266 ,0x1000a028]'
	    line = answer.after(bracket_index);
	    func_buffer = line;
	    while (line.contains("::"))
		line = line.after("::");
	    line = line.from(":");
	    func_buffer = func_buffer.before(line);
	    line = line.after(":");
	    line = line.through(rxint);
	    // answer = answer.after("\n");
	}
	else
	{
	    // Function name given
	    string func = answer.after(stopped_index);
	    func = func.after("stopped");
	    if (func.contains(" at "))
		func = func.before(" at ");
	    func_buffer = func;
	}

	if (!func_buffer.empty())
	{
	    // With DEC's `ladebug', the function name is fully qualified,
	    // as in `stopped at [void tree_test(void):277 0x120003f44]'
	    // We use only the base name (`tree_test' in this case).

	    // (We could avoid this if `ladebug' offered a way to look
	    // up fully qualified names.  Does it? - AZ)
	    if (func_buffer.contains('('))
		func_buffer = func_buffer.before('(');
	    while (func_buffer.contains(' '))
		func_buffer = func_buffer.after(' ');
	}

	if (line.empty())
	{
	    line = answer.after("at line ", stopped_index);
	    line = line.through(rxint);
	    if ((!file.empty() || !func_buffer.empty()) &&
		!answer.contains("at line "))
		line = "0";
	}

	if (!line.empty())
	    already_read = PosComplete;
    }

#if RUNTIME_REGEX
    static regex rxdbxfunc("[a-zA-Z_][^[]*: *[1-9][0-9]*  *.*");
#endif
    if (already_read != PosComplete && answer.matches(rxdbxfunc))
    {
	// DEC DBX issues `up', `down' and `func' output
	// in the format `FUNCTION: LINE  TEXT'
		
	// Note that the function name may contain "::" sequences.
	line = answer;
	while (line.contains("::"))
	    line = line.after("::");

	line = line.after(":");
	strip_leading_space(line);
	if (line.contains(rxint, 0))
	{
	    line = line.through(rxint);
	    if (!line.empty())
	    {
		if (answer.contains('\n'))
		{
		    // Got it!
		    already_read = PosComplete;
		    answer = answer.after("\n");
		}
		else
		{
		    // Wait for `\n' such that we can delete the line
		    answer_buffer = answer;
		    answer = "";
		    already_read = PosPart;
		    return;
		}
	    }
	}
    }

    if (already_read != PosComplete && 
	answer.contains("Current function is "))
    {
	// Up/Down command entered
	string nr = answer.after("\n");
	if (!nr.empty())
	{
	    line = itostring(atoi(nr.chars()));
	    already_read = PosComplete;
		    
	    // Show current function only
	    answer = answer.from("Current function is ");
	    answer = answer.through("\n");
	    func_buffer = answer.after("function is ");
	    func_buffer = func_buffer.before("\n");
	}
	else
	{
	    answer_buffer = answer;
	    answer = "";
	    already_read = PosPart;
	    return;
	}
    }

    if (already_read != PosComplete && 
	(!answer.contains('\n') ||
	 (answer.contains('[') && !answer.contains(']'))))
    {
	// Position info is incomplete
	answer_buffer = answer;
	answer = "";
	already_read = PosPart;
	return;
    }

    if (already_read == PosComplete && !line.empty())
    {
	if (!file.empty())
	    pos_buffer = file + ":" + line;
	else
	    pos_buffer = line;
    }

    if (already_read == PosComplete && pos_buffer.empty())
	already_read = Null;
}
Пример #13
0
void PosBuffer::filter_dbg(string& answer)
{
    int idx1, idx2;
    
    if (already_read != PosComplete && !answer.contains('\n'))
    {
	// Position info is incomplete
	answer_buffer = answer;
	answer = "";
	already_read = PosPart;
	return;
    }

    idx1 = 0;
    while (idx1 < (int)answer.length())
    {
        idx2 = answer.index('\n', idx1);
	if (idx2 < 0) idx2 = answer.length();	
	string line = answer.at(idx1, idx2 - idx1);
	if (line.contains('\n'))
	    line = line.before('\n');
	strip_trailing_space(line);
		
	// DBG uses a format like `test.php:4 <main>\n echo $a."hello world."'
#if RUNTIME_REGEX
	static regex rxdbgpos("[^ \t]*:[ \t]*[1-9][0-9]*[ \t]*<.*>");
	static regex rxdbgframepos("#[0-9]*[ \t]*<.*>[ \t]*at[ \t]*[^ \t]*:[ \t]*[1-9][0-9]*");
#endif
	if (line.matches(rxdbgpos)) 
	{
	    string file = line.before(':');
	    line = line.after(':');
		    
	    string line_no = line;
	    strip_leading_space(line_no);
	    line_no = line_no.before(' ');
	    
	    line = line.after('<');
	    func_buffer  = line.before('>');
	    strip_leading_space(func_buffer);
		    
	    pos_buffer   = file + ":" + line_no;
	    
	    // Delete this line from output
	    answer.at(idx1, idx2 - idx1 + 1) = "";
	    already_read = PosComplete;
	    break;

	} else if (line.matches(rxdbgframepos)) 
	{
	    string addr = line.before(">");
	    func_buffer = addr.after('<');
	    strip_leading_space(func_buffer);
	    
	    string file = line.after(">");
	    file = file.after("at");
	    strip_leading_space(file);
	    
	    string line_no = file.after(':');
	    strip_leading_space(line_no);
	
	    file = file.before(':');
	    	    
	    pos_buffer   = file + ":" + line_no;
	    
	    // Delete this line from output
	    answer.at(idx1, idx2 - idx1 + 1) = "";
	    already_read = PosComplete;
	    break;
	}
	
	idx1 = idx2+1;
    }
}
Пример #14
0
void PosBuffer::filter_xdb(string& answer)
{
    if (already_read != PosComplete && !answer.contains('\n'))
    {
	// Position info is incomplete
	answer_buffer = answer;
	answer = "";
	already_read = PosPart;
	return;
    }

    // INDEX points at the start of a line
    int index = 0;
    while (index >= 0 && !answer.empty())
    {
	string line = answer.from(index);
	if (line.contains('\n'))
	    line = line.before('\n');
	strip_trailing_space(line);
		
	// XDB uses a format like `ctest.c: main: 4: int a = 33;'
#if RUNTIME_REGEX
	static regex rxxdbpos("[^ \t]*:.*: [1-9][0-9]*[: ].*");
#endif
	if (line.matches(rxxdbpos))
	{
	    string file = line.before(':');
	    line = line.after(':');
		    
	    // The function name may contain "::"
	    string func = line;
	    while (line.contains("::"))
		line = line.after("::");
	    line = line.from(':');
	    func = func.before(line);
		    
	    line = line.after(':');
	    string line_no = line.before(':');
		    
	    strip_leading_space(func);
	    strip_leading_space(line_no);
	    line_no = line_no.through(rxint);
		    
	    pos_buffer   = file + ":" + line_no;
	    func_buffer  = func;
	    already_read = PosComplete;
		    
	    // Delete this line from output
	    int next_index = answer.index('\n', index);
	    if (next_index < 0)
		next_index = answer.length();
	    else
		next_index++;
	    answer.at(index, next_index - index) = "";
	    break;
	}
	else
	{
	    // Look at next line
	    index = answer.index('\n', index);
	    if (index >= 0)
		index++;
	}
    }
	    
    // Check for trailing `:' in last line
    index = answer.index('\n', -1) + 1;
    if (already_read != PosComplete 
	&& answer.index(':', index) >= 0)
    {
	answer_buffer = answer.from(index);
	answer.from(index) = "";
	already_read = PosPart;
	return;
    }
}
Пример #15
0
void BreakPoint::process_xdb(string& info_output)
{
    // Strip leading `:'.
    // Bob Wiegand <*****@*****.**>
    if (info_output.contains(':', 0))
	info_output = info_output.after(0);

    strip_leading_space(info_output);

    // Skip `count: N'
    if (info_output.contains("count:", 0))
    {
	info_output = info_output.after("count:");
	strip_leading_space(info_output);
	string count = info_output.before(rxblanks_or_tabs);
	info_output = info_output.after(rxblanks_or_tabs);

	myignore_count = atoi(count.chars());
    }
	    
    // Check for `Active' or `Suspended' and strip them
    // Bob Wiegand <*****@*****.**>
    if (info_output.contains("Active", 0))
    {
	info_output = info_output.after("Active");
	myenabled   = true;
    }
    else if (info_output.contains("Suspended", 0))
    {
	info_output = info_output.after("Suspended");
	myenabled   = false;
    }

    // Get function name and position
    info_output = info_output.after(rxblanks_or_tabs);
    myfunc = info_output.before(": ");

    const string pos = dbx_lookup(myfunc);
    if (!pos.empty())
    {
	myfile_name = pos.before(":");
    }

    info_output = info_output.after(": ");
    myline_nr = get_positive_nr(info_output);

    info_output = info_output.after('\n');

    // Examine commands for condition
    string commands = info_output;
    strip_leading_space(commands);
    if (commands.contains('{', 0))
    {
	// A condition has the form `{if COND {} {Q; c}}'.
	if (commands.contains("{if ", 0))
	{
	    string cond = commands.after("{if ");
	    cond = cond.before('{');
	    strip_space(cond);
	    mycondition = cond;
	}

	// Skip this line, too
	info_output = info_output.after('\n');
    }
}
Пример #16
0
// Create new breakpoint from INFO_OUTPUT
BreakPoint::BreakPoint(string& info_output, const string& arg, 
		       int number, string& file)
    : mynumber(number),
      mytype(BREAKPOINT),
      mydispo(BPKEEP),
      myenabled(true),
      myfile_name(file),
      myline_nr(0),
      myaddress(""),
      myfunc(""),
      myexpr(""),
      myinfos(""),
      myignore_count(0),
      mycondition(""),
      mycommands(0),
      myarg(arg),
      mywatch_mode(WATCH_CHANGE),
      myenabled_changed(true),
      myfile_changed(true),
      myposition_changed(true),
      myaddress_changed(true),
      myselected(false),
      mysource_glyph(0),
      mycode_glyph(0)
{
    if (gdb->has_numbered_breakpoints())
    {
	// Read leading breakpoint number
	strip_leading_space(info_output);
	string number_str = read_nr_str (info_output);
	int number = get_positive_nr (number_str);
	if (number < 0)
	    return;

	mynumber = number;
    }

    if (gdb->type() != PERL)
	strip_leading_space(info_output);

    switch(gdb->type())
    {
    case GDB:
    case MAKE:
    case BASH:
	process_gdb(info_output);
	break;

    case DBX:
	process_dbx(info_output);
	break;

    case XDB:
	process_xdb(info_output);
	break;

    case JDB:
	process_jdb(info_output);
	break;

    case PYDB:
	process_pydb(info_output);
	break;

    case PERL:
	process_perl(info_output);
	break;

    case DBG:
	process_dbg(info_output);
	break;
    }

    // If we found a file name, propagate it to next breakpoint
    file = file_name();
}
Пример #17
0
int
cddb_handle_data (const char *data, char **artist, char **dtitle,
		  char *titles[], int *totaltracks, char **year,
		  char **dgenre)
{
  char *row, *mark;
  const char *tmp = data;
  int i, j, counter = 0, track, previoustrack = 100, ttcounter = 0;
  char *tempstr;

  if (strncmp (data, "# xmcd", 6) != 0)
    return -1;

  (*dtitle) = NULL;

  while (*tmp != 0)
    {				/* check against end of string */

      /* get the row */
      i = strcspn (tmp, "\r\n");
      while (tmp[i] == '\r' || tmp[i] == '\n')
	i++;

      row = (char *) malloc (i + 1);
      strncpy (row, tmp, i);
      row[i] = 0;
      tmp += i;

      /* eval the row */
      if (strncmp (row, "DYEAR", 5) == 0)
	{			/* CD Year */
	  tempstr = malloc (MAX_YEAR_LENGTH);
	  strcpy (tempstr, row);
	  tempstr = strchr (row, '=');
	  tempstr++;
	  j = strlen (tempstr);

	  (*year) = (char *) malloc (j + 1);

	  strncpy ((*year), tempstr, (j + 1));
	  remove_non_unix_chars (*year);
	}
      else if (strncmp (row, "DGENRE", 6) == 0)
	{			/* Disc Genre */
	  tempstr = malloc (MAX_GENRE_LENGTH);
	  strcpy (tempstr, row);
	  tempstr = strchr (row, '=');
	  tempstr++;

	  j = strlen (tempstr);
	  (*dgenre) = (char *) malloc (j + 1);
	  strncpy ((*dgenre), tempstr, (j + 1));
	  remove_non_unix_chars (*dgenre);
	}
      else if (strncmp (row, "TTITLE", 6) == 0)
	{			/* Track Title */
	  /* get the track number before going on */
	  /* skip the TTITLE */
	  mark = row + 6;
	  counter = 0;

	  /* convert ascii -> int */
	  while (*mark != '=')
	    {
	      counter *= 10;
	      counter += *mark - 0x30;
	      mark++;
	    }
	  mark++;		/* and skip the '=' */
	  track = counter;

	  if (previoustrack != track)
	    ttcounter++;

	  /* create the filename. Append previous title if necessary */
	  tempstr = malloc (MAX_TITLE_LENGTH);
	  if (previoustrack == track)
	    strcpy (tempstr, titles[track]);
	  else
	    strcpy (tempstr, "");

	  /* put in the track name */
	  titles[track] = strcat (tempstr, mark);

	  strip_trailing_space (&titles[track]);
	  strip_leading_space (&titles[track]);

	  previoustrack = track;

	  remove_non_unix_chars (titles[track]);

#ifdef DEBUG
	  printf ("Track %d: %s\n", track, titles[track]);
#endif
	}
      else if ((strncmp (row, "DTITLE", 6) == 0) && (*dtitle == NULL))
	{			/* CD Title */
	  i = strcspn (row, "=");
	  i++;			/* skip to the data */
	  mark = row + i;

	  // tm:  hack around bogus CDDB entries
	  if (strstr (mark, " / "))
	    {
	      j = strstr (mark, " / ") - mark + 1;
	      (*artist) = (char *) malloc (j + 1);
	      strncpy ((*artist), mark, j);
	      (*artist)[j] = 0;
	      (*dtitle) = (char *) malloc (strlen (mark) - j);
	      mark = mark + j + 1;
	      strcpy ((*dtitle), mark);
	    }
	  else
	    {
#ifdef DEBUG
	      printf
		("malformed DTITLE, copying full DTITLE into both artist and dtitle\n");
#endif
	      j = strlen (mark);
	      (*artist) = (char *) malloc (j + 1);
	      strncpy ((*artist), mark, j);
	      (*artist)[j] = 0;
	      (*dtitle) = (char *) malloc (j + 1);
	      strncpy ((*dtitle), mark, j);
	      (*dtitle)[j] = 0;
	    }

	  strip_trailing_space (artist);
	  strip_leading_space (artist);
	  strip_trailing_space (dtitle);
	  strip_leading_space (dtitle);

	  remove_non_unix_chars (*artist);
	  remove_non_unix_chars (*dtitle);
	  convert_slashes (*artist, '_');	// dc: _ Artist, - others
	  convert_slashes (*dtitle, '-');
#ifdef CONVERT_SPACES_IN_ID3_DATA
	  if (((int) config_read (CONF_CDDB_CONVSPC)) == TRUE)
	    {
	      convert_spaces (*artist, '_');
	      convert_spaces (*dtitle, '_');
	    }
#endif
#ifdef DEBUG
	  printf ("Artist: %s\n", (*artist));
	  printf ("Dtitle: %s\n", (*dtitle));
#endif
	}

      /* ignore any other results */
      free (row);
    }

  *totaltracks = ttcounter;
  return 0;
}