void DbgGdb::GetDebugeePID(const wxString& line) { if(m_debuggeePid == wxNOT_FOUND) { if(GetIsRemoteDebugging()) { m_debuggeePid = m_gdbProcess->GetPid(); } else { static wxRegEx reDebuggerPidWin(wxT("New Thread ([0-9]+)\\.(0[xX][0-9a-fA-F]+)")); static wxRegEx reGroupStarted(wxT("id=\"([0-9]+)\"")); static wxRegEx reSwitchToThread(wxT("Switching to process ([0-9]+)")); // test for the debuggee PID // in the line with the following pattern: // =thread-group-started,id="i1",pid="15599" if(m_debuggeePid < 0 && !line.IsEmpty()) { wxString debuggeePidStr; if(line.Contains(wxT("=thread-group-started")) && reGroupStarted.Matches(line)) { debuggeePidStr = reGroupStarted.GetMatch(line, 1); } else if(line.Contains(wxT("=thread-group-created")) && reGroupStarted.Matches(line)) { debuggeePidStr = reGroupStarted.GetMatch(line, 1); } else if(reDebuggerPidWin.Matches(line)) { debuggeePidStr = reDebuggerPidWin.GetMatch(line, 1); } else if(reSwitchToThread.Matches(line)) { debuggeePidStr = reSwitchToThread.GetMatch(line, 1); } if(!debuggeePidStr.IsEmpty()) { long iPid(0); if(debuggeePidStr.ToLong(&iPid)) { m_debuggeePid = iPid; wxString msg; msg << wxT(">> Debuggee process ID: ") << m_debuggeePid; m_observer->UpdateAddLine(msg); // Now there's a known pid, the debugger can be interrupted to let any to-be-disabled bps be // disabled. So... m_observer->DebuggerPidValid(); } } } } } }
void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems ) { wxCHECK_RET( IsBusLabel( m_Label ), wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) ); if( m_Type == NET_HIERLABEL ) m_Type = NET_HIERBUSLABELMEMBER; else if( m_Type == NET_GLOBLABEL ) m_Type = NET_GLOBBUSLABELMEMBER; else if( m_Type == NET_SHEETLABEL ) m_Type = NET_SHEETBUSLABELMEMBER; else if( m_Type == NET_LABEL ) m_Type = NET_BUSLABELMEMBER; else wxCHECK_RET( false, wxT( "Net list object type is not valid." ) ); unsigned i; wxString tmp, busName, busNumber; long begin, end, member; busName = busLabelRe.GetMatch( m_Label, 1 ); busNumber = busLabelRe.GetMatch( m_Label, 2 ); /* Search for '[' because a bus label is like "busname[nn..mm]" */ i = busNumber.Find( '[' ); i++; while( busNumber[i] != '.' && i < busNumber.Len() ) { tmp.Append( busNumber[i] ); i++; } tmp.ToLong( &begin ); while( busNumber[i] == '.' && i < busNumber.Len() ) i++; tmp.Empty(); while( busNumber[i] != ']' && i < busNumber.Len() ) { tmp.Append( busNumber[i] ); i++; } tmp.ToLong( &end ); if( begin < 0 ) begin = 0; if( end < 0 ) end = 0; if( begin > end ) EXCHG( begin, end ); member = begin; tmp = busName; tmp << member; m_Label = tmp; m_Member = member; for( member++; member <= end; member++ ) { NETLIST_OBJECT* item = new NETLIST_OBJECT( *this ); // Conversion of bus label to the root name + the current member id. tmp = busName; tmp << member; item->m_Label = tmp; item->m_Member = member; aNetListItems.push_back( item ); } }
bool mmg_track_t::is_webm_compatible() { static wxRegEx re_valid_webm_codecs(wxT("VP8|Vorbis"), wxRE_ICASE); return (is_audio() || is_video()) && re_valid_webm_codecs.Matches(ctype); }
bool IsVisible(wxRegEx const& filter) const { return filter.Matches(cmd_name) || filter.Matches(cmd_str); }
static void trim_text(AssDialogue *diag) { static wxRegEx start("^( |\t|\\\\[nNh])+"); static wxRegEx end("( |\t|\\\\[nNh])+$"); start.ReplaceFirst(&diag->Text, ""); end.ReplaceFirst(&diag->Text, ""); }
//this allows copy/paste from Vixen grid: void RgbEffects::LoadPixelsFromTextFile(wxFile& debug, const wxString& filename) { imageCount = 0; imageIndex = 0; if (image.GetWidth() && image.GetHeight()) image.Clear(); //CAUTION: image must be non-empty to clear it (memory error otherwise) if (!PictureName.CmpNoCase(filename)) { wrdebug("no change: " + filename); return; } if (!wxFileExists(filename)) { wrdebug("not found: " + filename); return; } wxTextFile f; PixelsByFrame.clear(); if (!f.Open(filename.c_str())) { wrdebug("can't open: " + filename); return; } //read channel values from Vixen grid or routine: // std::vector<std::vector<std::pair<int, byte>>> ChannelsByFrame; //list of channel#s by frame and their associated value int numch = 0, chbase = 0, nodesize = 1; for (wxString linebuf = f.GetFirstLine(); !f.Eof(); linebuf = f.GetNextLine()) { std::string::size_type ofs; if ((ofs = linebuf.find("#")) != std::string::npos) linebuf.erase(ofs); //remove comments while (!linebuf.empty() && isspace(linebuf.Last())) linebuf.RemoveLast(); //trim trailing spaces if (linebuf.empty()) continue; //skip blank lines wrdebug(wxString::Format("read line '%s'", (const char*)linebuf.c_str())); static wxRegEx chbase_re("^\\s*ChannelBase\\s*=\\s*(-?[0-9]+)\\s*$", wxRE_ICASE); if (!PixelsByFrame.size() && chbase_re.Matches(linebuf)) //allow channels to be shifted { chbase = wxAtoi(chbase_re.GetMatch(linebuf, 1)); wrdebug(wxString::Format("got ch base %d", chbase)); continue; } static wxRegEx nodesize_re("^\\s*ChannelsPerNode\\s*=\\s*([13])\\s*$", wxRE_ICASE); if (!PixelsByFrame.size() && nodesize_re.Matches(linebuf)) //allow channels to be shifted { nodesize = wxAtoi(nodesize_re.GetMatch(linebuf, 1)); wrdebug(wxString::Format("got node size %d", nodesize)); continue; } PixelVector frame; wrdebug(wxString::Format("load channels for frame %d (%.3f sec): '" + linebuf + "'", PixelsByFrame.size(), PixelsByFrame.size() * 50/1000.)); wxStringTokenizer tkz(linebuf, " "); for (int chnum = 0; tkz.HasMoreTokens(); ++chnum) { wxByte chval = wxAtoi(tkz.GetNextToken()); wrdebug(wxString::Format("got chval %d for ch %d, frame %d", (int)chval, chnum, PixelsByFrame.size())); if (!chval) continue; //only need to remember channels that are on (assume most channels are off) std::pair<wxPoint, wxColor> new_pixel; static wxByte rgb[3]; switch (nodesize) { case 1: //map each Vixen channel to a monochrome pixel new_pixel.second.Set(chval, chval, chval); //grayscale break; case 3: //map Vixen triplets to an RGB pixel switch (chnum % 3) { case 0: rgb[0] = chval; continue; case 1: rgb[1] = chval; continue; case 2: rgb[2] = chval; break; } } new_pixel.second.Set(rgb[0], rgb[1], rgb[2]); // for (each wxPoint where chnum + chbase occurs in current model) frame.push_back(new_pixel); //build list of pixels that must be set if (chnum + 1 > numch) numch = chnum + 1; //vix grid or routine should be rectangular, but in case it isn't, pad out the shorter rows } PixelsByFrame.push_back(frame); //add new frame, MSVC 2010 doesn't support emplace_back } //now create an image to look like it was loaded like the other picture functions: // image.Create(maxcol + 1, pixels.size()); // for (int y = 0; y < pixels.size(); ++y) // for (int x = 0; x < pixels[y].size(); x += 3) // image.SetRGB(x, y, pixels[y][x + 0], pixels[y][x + 1], pixels[y][x + 2]); wrdebug(wxString::Format("read %d channels (relative to %d) x %d frames from Vixen, channels/node: %d", numch, chbase, PixelsByFrame.size(), nodesize)); // imageCount = 1; //TODO: allow multiple? // imageIndex = 0; PictureName = filename; }
void DebuggerTree::ParseEntry(WatchTreeEntry& entry, Watch* watch, wxString& text, long array_index) { if (text.IsEmpty()) return; // Manager::Get()->GetLogManager()->DebugLog(F(_T("DebuggerTree::ParseEntry(): %s"), text.c_str())); while (1) { // trim the string from left and right text.Trim(true); text.Trim(false); // find position of '{', '}' and ',' ***outside*** of any quotes. // decide which is nearer to the start int braceOpenPos = FindCharOutsideQuotes(text, _T('{')); if (braceOpenPos == -1) braceOpenPos = 0xFFFFFE; int braceClosePos = FindCharOutsideQuotes(text, _T('}')); if (braceClosePos == -1) braceClosePos = 0xFFFFFE; int commaPos = FindCommaPos(text); if (commaPos == -1) commaPos = 0xFFFFFE; int pos = std::min(commaPos, std::min(braceOpenPos, braceClosePos)); if (pos == 0xFFFFFE) { // no comma, opening or closing brace if (text.Right(3).Matches(_T(" = "))) text.Truncate(text.Length() - 3); if (!text.IsEmpty()) { entry.AddChild(text, watch); text.Clear(); } break; } else { // display array on a single line? // normal (multiple lines) display is taken care below, with array indexing if (watch && watch->is_array && braceOpenPos != 0xFFFFFE && braceClosePos != 0xFFFFFE) { wxString tmp = text.Left(braceClosePos + 1); // if more than one opening/closing brace, then it's a complex array so // ignore single-line if (text.Freq(_T('{')) == 1 && text.Freq(_T('}')) == 1) { // array on single line for up to 8 (by default) elements // if more elements, fall through to the multi-line display int commas = Manager::Get()->GetConfigManager(_T("debugger"))->ReadInt(_T("/single_line_array_elem_count"), 8); if (tmp.Freq(_T(',')) < commas) { // array watch type tmp[braceOpenPos] = _T('['); tmp.Last() = _T(']'); entry.AddChild(tmp, watch); text.Remove(0, braceClosePos + 1); continue; } } } wxString tmp = text.Left(pos); WatchTreeEntry* newchild = 0; if (tmp.Right(3).Matches(_T(" = "))) tmp.Truncate(tmp.Length() - 3); // remove " = " if last in string if (!tmp.IsEmpty()) { // take array indexing into account (if applicable) if (array_index != -1) { tmp.Prepend(wxString::Format(_T("[%ld]: "), array_index)); // if array element would occur multiple times, gdb adds as default "<repeated xx times> to the output // so we have to look for it and increase the array_index correctly // as default we increase by 1 long incIndex = 1; if (reRepeatedElements.Matches(tmp)) { reRepeatedElements.GetMatch(tmp, 1).ToLong(&incIndex); } array_index += incIndex; } newchild = &entry.AddChild(tmp, watch); } text.Remove(0, pos + 1); if (pos == braceOpenPos) { if (!newchild) newchild = &entry; // enable array indexing (if applicable) bool no_indexing = array_index == -1; if (watch && watch->is_array && no_indexing && text.Freq(_T('{')) == 0 && text.Freq(_T('}')) == 1) // don't index complex arrays { array_index = 0; } ParseEntry(*newchild, watch, text, array_index); // proceed one level deeper // reset array indexing if (no_indexing) array_index = -1; } else if (pos == braceClosePos) break; // return one level up } } }
void DbgGdb::Poke() { static wxRegEx reCommand(wxT("^([0-9]{8})")); //poll the debugger output wxString line; if ( !m_gdbProcess || m_gdbOutputArr.IsEmpty() ) { return; } if (m_debuggeePid == wxNOT_FOUND) { if (GetIsRemoteDebugging()) { m_debuggeePid = m_gdbProcess->GetPid(); } else { std::vector<long> children; ProcUtils::GetChildren(m_gdbProcess->GetPid(), children); std::sort(children.begin(), children.end()); if (children.empty() == false) { m_debuggeePid = children.at(0); } if (m_debuggeePid != wxNOT_FOUND) { wxString msg; msg << wxT("Debuggee process ID: ") << m_debuggeePid; m_observer->UpdateAddLine(msg); } } } while ( DoGetNextLine( line ) ) { // For string manipulations without damaging the original line read wxString tmpline ( line ); StripString( tmpline ); tmpline.Trim().Trim(false); if (m_info.enableDebugLog) { //Is logging enabled? if (line.IsEmpty() == false && !tmpline.StartsWith(wxT(">")) ) { wxString strdebug(wxT("DEBUG>>")); strdebug << line; m_observer->UpdateAddLine(strdebug); } } if (reConnectionRefused.Matches(line)) { StripString(line); #ifdef __WXGTK__ m_consoleFinder.FreeConsole(); #endif m_observer->UpdateAddLine(line); m_observer->UpdateGotControl(DBG_EXITED_NORMALLY); return; } if( tmpline.StartsWith(wxT(">")) ) { // Shell line, probably user command line continue; } if (line.StartsWith(wxT("~")) || line.StartsWith(wxT("&"))) { // lines starting with ~ are considered "console stream" message // and are important to the CLI handler bool consoleStream(false); if ( line.StartsWith(wxT("~")) ) { consoleStream = true; } // Filter out some gdb error lines... if (FilterMessage(line)) { continue; } StripString( line ); // If we got a valid "CLI Handler" instead of writing the output to // the output view, concatenate it into the handler buffer if ( GetCliHandler() && consoleStream ) { GetCliHandler()->Append( line ); } else if ( consoleStream ) { // log message m_observer->UpdateAddLine( line ); } } else if (reCommand.Matches(line)) { //not a gdb message, get the command associated with the message wxString id = reCommand.GetMatch(line, 1); if ( GetCliHandler() && GetCliHandler()->GetCommandId() == id ) { // probably the "^done" message of the CLI command GetCliHandler()->ProcessOutput( line ); SetCliHandler( NULL ); // we are done processing the CLI } else { //strip the id from the line line = line.Mid(8); DoProcessAsyncCommand(line, id); } } else if (line.StartsWith(wxT("^done")) || line.StartsWith(wxT("*stopped"))) { //Unregistered command, use the default AsyncCommand handler to process the line DbgCmdHandlerAsyncCmd cmd(m_observer); cmd.ProcessOutput(line); } else { //Unknow format, just log it if( m_info.enableDebugLog && !FilterMessage(line)) { m_observer->UpdateAddLine(line); } } } }