private string InterpolateToken()

in src/OpenDebugAD7/Tracepoint.cs [120:250]


        private string InterpolateToken(string token, IDebugThread2 pThread, IDebugStackFrame2 topFrame, uint radix, string processName, int processId)
        {
            switch (token)
            {
                case "$FUNCTION":
                    {
                        int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext);
                        if (hr >= 0)
                        {
                            CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1];
                            hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, pInfo);
                            if (hr >= 0)
                            {
                                return pInfo[0].bstrFunction;
                            }
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No Function Found>");
                    }
                case "$ADDRESS":
                    {
                        int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext);
                        if (hr >= 0)
                        {
                            CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1];
                            hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, pInfo);
                            if (hr >= 0)
                            {
                                return pInfo[0].bstrAddress;
                            }
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No Address Found>");
                    }
                case "$FILEPOS":
                    {
                        int hr = topFrame.GetDocumentContext(out IDebugDocumentContext2 pDocumentContext);
                        if (hr >= 0)
                        {
                            hr = pDocumentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName);
                            if (hr >= 0)
                            {
                                TEXT_POSITION[] textPosBeg = new TEXT_POSITION[1];
                                TEXT_POSITION[] textPosEnd = new TEXT_POSITION[1];
                                hr = pDocumentContext.GetStatementRange(textPosBeg, textPosEnd);
                                if (hr >= 0)
                                {
                                    return string.Format(CultureInfo.InvariantCulture, "{0}:{1}", fileName, textPosBeg[0].dwLine + 1);
                                }
                            }
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No File Position>");
                    }
                case "$CALLER":
                    {
                        IEnumDebugFrameInfo2 frameInfoEnum;
                        int hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum);
                        if (hr >= 0)
                        {
                            FRAMEINFO[] frames = new FRAMEINFO[2];
                            uint fetched = 0;
                            hr = frameInfoEnum.Next(2, frames, ref fetched);
                            if (hr < 0 && fetched == 2)
                            {
                                return frames[1].m_bstrFuncName;
                            }
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No Caller Avaliable>");
                    }
                case "$TID":
                    {
                        int hr = pThread.GetThreadId(out uint threadId);
                        if (hr == 0)
                        {
                            if (radix == 16)
                            {
                                return string.Format(CultureInfo.InvariantCulture, "{0:X}", threadId);
                            }
                            else
                            {
                                return string.Format(CultureInfo.InvariantCulture, "{0}", threadId);
                            }
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No Thread Id>");
                    }
                case "$TNAME":
                    {
                        int hr = pThread.GetName(out string name);
                        if (hr == 0)
                        {
                            return name;
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<No Thread Name>");
                    }
                case "$PID":
                    {
                        if (processId != Constants.InvalidProcessId)
                        {
                            return processId.ToString(CultureInfo.InvariantCulture);
                        }
                        return string.Format(CultureInfo.InvariantCulture, "<Unknown PID>", token);
                    }
                case "$PNAME":
                    {
                        return processName;
                    }
                case "$CALLSTACK":
                    {
                        IEnumDebugFrameInfo2 frameInfoEnum;
                        int hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum);
                        int count = 0;
                        StringBuilder sb = new StringBuilder();
                        while (count < Constants.DefaultTracepointCallstackDepth)
                        {
                            FRAMEINFO[] frames = new FRAMEINFO[1];
                            uint fetched = 0;
                            hr = frameInfoEnum.Next(1, frames, ref fetched);
                            if (fetched == 1)
                            {
                                // TODO: Do we want function arguments?
                                frames[0].m_pFrame.GetName(out string name);
                                sb.AppendLine(name);
                            }
                            count++;
                        }
                        return sb.ToString();
                    }
                case "$TICK":
                    return string.Format(CultureInfo.InvariantCulture, "{0}", Environment.TickCount);
                default:
                    return string.Format(CultureInfo.InvariantCulture, "<Unknown Token: ${0}>", token);
            }
        }