📄 qspy.cpp
字号:
//////////////////////////////////////////////////////////////////////////////// Product: Quantum Spy -- Host resident component// Last Updated for Version: 4.0.00// Date of the Last Update: Apr 07, 2008//// Q u a n t u m L e a P s// ---------------------------// innovating embedded systems//// Copyright (C) 2002-2008 Quantum Leaps, LLC. All rights reserved.//// This software may be distributed and modified under the terms of the GNU// General Public License version 2 (GPL) as published by the Free Software// Foundation and appearing in the file GPL.TXT included in the packaging of// this file. Please note that GPL Section 2[b] requires that all works based// on this software must also be made publicly available under the terms of// the GPL ("Copyleft").//// Alternatively, this software may be distributed and modified under the// terms of Quantum Leaps commercial licenses, which expressly supersede// the GPL and are specifically designed for licensees interested in// retaining the proprietary status of their code.//// Contact information:// Quantum Leaps Web site: http://www.quantum-leaps.com// e-mail: info@quantum-leaps.com//////////////////////////////////////////////////////////////////////////////#include <stdint.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <time.h>#include "qspy.h"#include "dict.h"#define Q_SPY#include "qs.h" // the target-resident QS//............................................................................class QSpyRecord { uint8_t m_rec; // enumerated type of the record uint8_t const *m_pos; // current position in the stream int32_t m_len; // current length of the stream (till the last byte)public: QSpyRecord(uint8_t rec, uint8_t const *pos, int32_t len) : m_rec(rec), m_pos(pos), m_len(len) { } void parse(void); void parseUser(void); void error(void); bool OK(void); int32_t getInt(uint8_t size); uint32_t getUint(uint8_t size); char const *getStr(void); uint8_t const *getMem(uint8_t *pl); char const *getMatDict(char const *s); // get MATLAB dictionary};//............................................................................static DictEntry l_funSto[512];static DictEntry l_objSto[256];static SigDictEntry l_sigSto[256];static Dictionary l_funDict(l_funSto, sizeof(l_funSto)/sizeof(l_funSto[0]));static Dictionary l_objDict(l_objSto, sizeof(l_objSto)/sizeof(l_objSto[0]));static SigDictionary l_sigDict(l_sigSto, sizeof(l_sigSto)/sizeof(l_sigSto[0]));//............................................................................static uint8_t l_objPtrSize;static uint8_t l_funPtrSize;static uint8_t l_tstampSize;static uint8_t l_sigSize;static uint8_t l_evtSize;static uint8_t l_queueCtrSize;static uint8_t l_poolCtrSize;static uint8_t l_poolBlkSize;static uint8_t l_tevtCtrSize;static uint8_t l_quiet;static FILE * l_outFile;static FILE * l_matFile;static char l_line[512]; // last formatted line ready for output//............................................................................static void print(void) { if (!l_quiet) { fputs(l_line, stdout); } if (l_outFile != (FILE *)0) { fputs(l_line, l_outFile); }}//............................................................................void qsConfig(uint8_t quiet, uint8_t objPtrSize, uint8_t funPtrSize, uint8_t tstampSize, uint8_t sigSize, uint8_t evtSize, uint8_t queueCtrSize, uint8_t poolCtrSize, uint8_t poolBlkSize, uint8_t tevtCtrSize, FILE *outFile, FILE *matFile){ l_quiet = quiet; l_objPtrSize = objPtrSize; l_funPtrSize = funPtrSize; l_tstampSize = tstampSize; l_sigSize = sigSize; l_evtSize = evtSize; l_queueCtrSize = queueCtrSize; l_poolCtrSize = poolCtrSize; l_poolBlkSize = poolBlkSize; l_tevtCtrSize = tevtCtrSize; l_outFile = outFile; l_matFile = matFile; if (l_outFile != (FILE *)0) { time_t now = time(NULL); fprintf(l_outFile, "QSPY host application 3.5.00\n" "Copyright (c) Quantum Leaps, LLC.\n" "%s\n", ctime(&now)); } sprintf(l_line, "-T %d\n", (unsigned)tstampSize); print(); sprintf(l_line, "-O %d\n", (unsigned)objPtrSize); print(); sprintf(l_line, "-F %d\n", (unsigned)funPtrSize); print(); sprintf(l_line, "-S %d\n", (unsigned)sigSize); print(); sprintf(l_line, "-E %d\n", (unsigned)evtSize); print(); sprintf(l_line, "-Q %d\n", (unsigned)queueCtrSize); print(); sprintf(l_line, "-P %d\n", (unsigned)poolCtrSize); print(); sprintf(l_line, "-B %d\n", (unsigned)poolBlkSize); print(); sprintf(l_line, "-C %d\n", (unsigned)tevtCtrSize); print(); sprintf(l_line, "\n"); print();}//............................................................................bool QSpyRecord::OK(void) { if (m_len != (uint8_t)0) { sprintf(l_line, "********** %03u: Error %d bytes unparsed\n", (unsigned)m_rec, (int)m_len); print(); return false; } return true;}//............................................................................int32_t QSpyRecord::getInt(uint8_t size) { int32_t ret = (int32_t)0; if (m_len >= size) { if (size == (uint8_t)1) { ret = (int32_t)((uint32_t)m_pos[0] << 24); ret >>= 24; // sign-extend } else if (size == (uint8_t)2) { ret = (int32_t)((uint32_t)m_pos[1] << 24) | ((uint32_t)m_pos[0] << 16); ret >>= 16; // sign-extend } else if (size == (uint8_t)4) { ret = (int32_t)((((((uint8_t)m_pos[3] << 8) | (uint8_t)m_pos[2]) << 8) | (uint8_t)m_pos[1]) << 8) | (uint8_t)m_pos[0]; } else { assert(0); } m_pos += size; m_len -= size; } else { m_len = -1; sprintf(l_line, "Uint overrun\n"); print(); } return ret;}//............................................................................uint32_t QSpyRecord::getUint(uint8_t size) { uint32_t ret = (uint32_t)0; if (m_len >= size) { if (size == (uint8_t)1) { ret = (uint32_t)m_pos[0]; } else if (size == (uint8_t)2) { ret = (((uint32_t)m_pos[1] << 8) | (uint32_t)m_pos[0]); } else if (size == (uint8_t)4) { ret = ((((((uint32_t)m_pos[3] << 8) | (uint32_t)m_pos[2]) << 8) | (uint32_t)m_pos[1]) << 8) | (uint32_t)m_pos[0]; } else { assert(0); } m_pos += size; m_len -= size; } else { m_len = -1; sprintf(l_line, "Uint overrun\n"); print(); } return ret;}//............................................................................char const *QSpyRecord::getStr(void) { uint8_t const *p; int32_t l; for (l = m_len, p = m_pos; l > 0; --l, ++p) { if (*p == (uint8_t)0) { char const *s = (char const *)m_pos; m_len = l - 1; m_pos = p + 1; return s; } } m_len = -1; sprintf(l_line, "String overrun\n"); print(); return "";}//............................................................................uint8_t const *QSpyRecord::getMem(uint8_t *pl) { if ((m_len >= 1) && ((*m_pos) <= m_len - 1)) { uint8_t const *mem = m_pos + 1; *pl = *m_pos; m_len -= 1 + *m_pos; m_pos += 1 + *m_pos; return mem; } m_len = -1; *pl = (uint8_t)0; sprintf(l_line, "Mem overrun\n"); print(); return (uint8_t *)0;}//............................................................................char const *QSpyRecord::getMatDict(char const *s) { static char dict[65]; char *pc = dict; while ((*s != '\0') && (pc < &dict[sizeof(dict)] - 1)) { if ((*s == '[') || (*s == ']') || (*s == '.') || (*s == ':')) { *pc++ = '_'; ++s; } else { *pc++ = *s++; } } *pc = '\0'; return (dict[0] == '&' ? dict+1 : dict);}//............................................................................void QSpyRecord::parseUser(void) { uint32_t f; int32_t i; uint32_t u; static char const *ifmt[] = { "%li ", "%1i ", "%2i ", "%3i ", "%4i ", "%5i ", "%6i ", "%7i ", "%8li ", "%9i ", "%10i ", "%11i ", "%12i ", "%13i ", "%14i ", "%15i " }; static char const *ufmt[] = { "%lu ", "%1u ", "%2u ", "%3u ", "%4u ", "%5u ", "%6u ", "%7u ", "%8lu ", "%9u ", "%10u ", "%11u ", "%12u ", "%13u ", "%14u ", "%15u " }; static char const *efmt[] = { "%7.0Le ", "%9.1Le ", "%10.2Le ", "%11.3Le ", "%12.4Le ", "%13.5Le ", "%14.6Le ", "%15.7Le ", "%16.8Le ", "%17.9Le ", "%18.10Le ", "%19.11Le ", "%20.12Le ", "%21.13Le ", "%22.14Le ", "%23.15Le ", }; u = getUint(l_tstampSize); sprintf(l_line, "%010u User%03u: ", u, (unsigned)(m_rec - QS_USER)); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, "%3d %10u ", m_rec, u); } while (m_len > 0) { char const *s; f = getUint(1); // get the format byte switch (f & 0x0F) { case QS_I8_T: { i = getInt(1); sprintf(l_line, ifmt[f >> 4], i); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ifmt[f >> 4], i); } break; } case QS_U8_T: { u = getUint(1); sprintf(l_line, ufmt[f >> 4], u); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ufmt[f >> 4], u); } break; } case QS_I16_T: { i = getInt(2); sprintf(l_line, ifmt[f >> 4], i); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ifmt[f >> 4], i); } break; } case QS_U16_T: { u = getUint(2); sprintf(l_line, ufmt[f >> 4], u); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ufmt[f >> 4], u); } break; } case QS_I32_T: { i = getInt(4); sprintf(l_line, ifmt[f >> 4], i); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ifmt[f >> 4], i); } break; } case QS_U32_T: { u = getUint(4); sprintf(l_line, ufmt[f >> 4], u); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, ufmt[f >> 4], u); } break; } case QS_F32_T: { u = (uint32_t)getUint(4); sprintf(l_line, efmt[f >> 4], (double)(*((float *)&u))); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, efmt[f >> 4], (double)(*((float *)&u))); } break; } case QS_F64_T: { union F64Rep { double d; struct UInt2 { uint32_t u1, u2; } i; } data; data.i.u1 = (uint32_t)getUint(4); data.i.u2 = (uint32_t)getUint(4); sprintf(l_line, efmt[f >> 4], data.d); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, efmt[f >> 4], data.d); } break; } case QS_STR_T: { s = getStr(); sprintf(l_line, "%s ", s); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, "%s ", s); } break; } case QS_MEM_T: { uint8_t l; uint8_t const *mem = getMem(&l); while (l-- != (uint8_t)0) { sprintf(l_line, "%02X ", (int)*mem); print(); if (l_matFile != (FILE *)0) { fprintf(l_matFile, "%03d ", (int)*mem); } ++mem;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -