kopia lustrzana https://github.com/jamescoxon/dl-fldigi
1130 wiersze
23 KiB
C++
1130 wiersze
23 KiB
C++
// ----------------------------------------------------------------------------
|
|
// rigxml.cxx - parse a rig control xml file
|
|
//
|
|
// Copyright (C) 2007-2009
|
|
// Dave Freese, W1HKJ
|
|
//
|
|
// This file is part of fldigi.
|
|
//
|
|
// Fldigi is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Fldigi is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
|
// ----------------------------------------------------------------------------
|
|
|
|
#include <config.h>
|
|
|
|
#include <fstream>
|
|
#include <string>
|
|
#include <list>
|
|
|
|
#include <FL/filename.H>
|
|
|
|
#include "gettext.h"
|
|
#include "rigio.h"
|
|
#include "rigxml.h"
|
|
#include "rigsupport.h"
|
|
#ifdef RIGCATTEST
|
|
#include "rigCAT.h"
|
|
#else
|
|
#include "main.h"
|
|
#endif
|
|
#include "debug.h"
|
|
|
|
#include "configuration.h"
|
|
#include "fileselect.h"
|
|
#include "confdialog.h"
|
|
|
|
#include "icons.h"
|
|
#include "fl_digi.h"
|
|
|
|
using namespace std;
|
|
|
|
//#define DEBUGXML 1
|
|
|
|
void parseRIGDEF(size_t &);
|
|
void parseRIG(size_t &);
|
|
void parseCOMMAND(size_t &);
|
|
void parseREPLY(size_t &);
|
|
void parseMODES(size_t &);
|
|
void parseBANDWIDTHS(size_t &);
|
|
void parseBWCMD(size_t &);
|
|
void parseBWREPLY(size_t &);
|
|
void parseMODECMD(size_t &);
|
|
void parseMODEREPLY(size_t &);
|
|
void parseTITLE(size_t &);
|
|
void parseLSBMODES(size_t &);
|
|
void parseDISCARD(size_t &);
|
|
void parseDEBUG(size_t &);
|
|
void parseNOSERIAL(size_t &);
|
|
void parseASCII(size_t &);
|
|
|
|
void parseWRITE_DELAY(size_t &);
|
|
void parseINIT_DELAY(size_t &);
|
|
void parseWAIT_FOR_DEVICE(size_t &);
|
|
void parsePOST_WRITE_DELAY(size_t &);
|
|
void parseRETRIES(size_t &);
|
|
void parseTIMEOUT(size_t &);
|
|
void parseBAUDRATE(size_t &);
|
|
void parseSTOPBITS(size_t &);
|
|
void parseRTSCTS(size_t &);
|
|
void parseCMDPTT(size_t &);
|
|
void parseRTSPLUS(size_t &);
|
|
void parseDTRPLUS(size_t &);
|
|
void parseRTSPTT(size_t &);
|
|
void parseDTRPTT(size_t &);
|
|
void parseRESTORE_TIO(size_t &);
|
|
void parseECHO(size_t &);
|
|
void parseVSP(size_t &);
|
|
void parseLOGSTR(size_t &);
|
|
void parsePOLLINT(size_t &);
|
|
void parseSMETER(size_t &);
|
|
void parsePMETER(size_t &);
|
|
void parseNOTCH(size_t &);
|
|
void parsePWRLEVEL(size_t &);
|
|
|
|
void parseIOSsymbol(size_t &);
|
|
void parseIOSsize(size_t &);
|
|
void parseIOSbytes(size_t &);
|
|
void parseIOSbyte(size_t &);
|
|
void parseIOSdata(size_t &);
|
|
void parseIOSinfo(size_t &);
|
|
void parseIOSok(size_t &);
|
|
void parseIOSbad(size_t &);
|
|
void parseIOSstring(size_t &);
|
|
void parseIOSint(size_t &);
|
|
void parseIOSfill(size_t &);
|
|
|
|
void parseDTYPE(size_t &);
|
|
void parseDSIZE(size_t &);
|
|
void parseDMAX(size_t &);
|
|
void parseDMIN(size_t &);
|
|
void parseDRESOL(size_t &);
|
|
void parseDREV(size_t &);
|
|
void parseDMAKS(size_t &);
|
|
void parseDSHIFT(size_t &);
|
|
|
|
void print(size_t &);
|
|
|
|
list<XMLIOS> commands;
|
|
list<XMLIOS> reply;
|
|
list<MODE> lmodes;
|
|
list<BW> lbws;
|
|
list<BW> lbwCMD;
|
|
list<BW> lbwREPLY;
|
|
list<MODE> lmodeCMD;
|
|
list<MODE> lmodeREPLY;
|
|
list<string> LSBmodes;
|
|
|
|
XMLRIG xmlrig;
|
|
|
|
XMLIOS iosTemp;
|
|
|
|
string strXML;
|
|
|
|
TAGS rigdeftags[] = {
|
|
{"<RIGDEF", parseRIGDEF},
|
|
{"<RIG", parseRIG},
|
|
{"<COMMAND", parseCOMMAND},
|
|
{"<REPLY", parseREPLY},
|
|
{"<BANDWIDTHS", parseBANDWIDTHS},
|
|
{"<BW-CMD", parseBWCMD},
|
|
{"<BW-REPLY", parseBWREPLY},
|
|
{"<MODES", parseMODES},
|
|
{"<MODE-CMD", parseMODECMD},
|
|
{"<MODE-REPLY", parseMODEREPLY},
|
|
{"<TITLE", parseTITLE},
|
|
{"<LSBMODES", parseLSBMODES},
|
|
{"<PROGRAMMER", parseDISCARD},
|
|
{"<STATUS", parseDISCARD},
|
|
{"<WRITE_DELAY", parseWRITE_DELAY},
|
|
{"<INIT_DELAY", parseINIT_DELAY},
|
|
{"<POST_WRITE_DELAY", parsePOST_WRITE_DELAY},
|
|
{"<RETRIES", parseRETRIES},
|
|
{"<TIMEOUT", parseTIMEOUT},
|
|
{"<BAUDRATE", parseBAUDRATE},
|
|
{"<RTSCTS", parseRTSCTS},
|
|
{"<RTSPLUS", parseRTSPLUS},
|
|
{"<DTRPLUS", parseDTRPLUS},
|
|
{"<RTSPTT", parseRTSPTT},
|
|
{"<DTRPTT", parseDTRPTT},
|
|
{"<WAIT_FOR_DEVICE", parseWAIT_FOR_DEVICE},
|
|
{"<RESTORE_TIO", parseRESTORE_TIO},
|
|
{"<ECHO", parseECHO},
|
|
{"<CMDPTT", parseCMDPTT},
|
|
{"<STOPBITS", parseSTOPBITS},
|
|
{"<VSP", parseVSP},
|
|
{"<LOGSTR", parseLOGSTR},
|
|
{"<POLLINT", parsePOLLINT},
|
|
{"<SMETER", parseSMETER},
|
|
{"<PMETER", parsePMETER},
|
|
{"<NOTCH", parseNOTCH},
|
|
{"<PWRLEVEL", parsePWRLEVEL},
|
|
{"<DEBUG", parseDEBUG},
|
|
{"<NOSERIAL", parseNOSERIAL},
|
|
{"<ASCII", parseASCII},
|
|
{0, 0}
|
|
};
|
|
|
|
TAGS commandtags[] = {
|
|
{"<SIZE", parseIOSsize},
|
|
{"<SYMBOL", parseIOSsymbol},
|
|
{"<BYTES", parseIOSbytes},
|
|
{"<BYTE", parseIOSbyte},
|
|
{"<DATA", parseIOSdata},
|
|
{"<STRING", parseIOSstring},
|
|
{"<INT", parseIOSint},
|
|
{"<INFO", parseIOSinfo},
|
|
{"<OK", parseIOSok},
|
|
{"<BAD", parseIOSbad},
|
|
{0,0}
|
|
};
|
|
|
|
TAGS replytags[] = {
|
|
{"<SIZE", parseIOSsize},
|
|
{"<SYMBOL", parseIOSsymbol},
|
|
{"<BYTES", parseIOSbytes},
|
|
{"<BYTE", parseIOSbyte},
|
|
{"<DATA", parseIOSdata},
|
|
{"<STRING", parseIOSstring},
|
|
{"<INT", parseIOSint},
|
|
{"<FILL", parseIOSfill},
|
|
{0,0}
|
|
};
|
|
|
|
TAGS datatags[] = {
|
|
{"<DTYPE", parseDTYPE},
|
|
{"<SIZE", parseDSIZE},
|
|
{"<MAX", parseDMAX},
|
|
{"<MIN", parseDMIN},
|
|
{"<RESOL", parseDRESOL},
|
|
{"<REV", parseDREV},
|
|
{"<MASK", parseDMAKS},
|
|
{"<SHIFT", parseDSHIFT},
|
|
{0,0}
|
|
}
|
|
;
|
|
|
|
//=====================================================================
|
|
|
|
void print(size_t &p0, int indent)
|
|
{
|
|
#ifdef DEBUGXML
|
|
std::string istr(indent, '\t');
|
|
size_t tend = strXML.find(">", p0);
|
|
LOG_INFO("%s%s", istr.c_str(), strXML.substr(p0, tend - p0 + 1).c_str());
|
|
#endif
|
|
}
|
|
|
|
size_t tagEnd(size_t p0)
|
|
{
|
|
size_t p1, p2, p3;
|
|
p1 = p0;
|
|
string strtag = "</";
|
|
p2 = strXML.find(">", p0);
|
|
p3 = strXML.find(" ", p0);
|
|
if (p2 == string::npos) {
|
|
return p2;
|
|
}
|
|
if (p3 < p2)
|
|
p2 = p3;
|
|
strtag.append(strXML.substr(p1 + 1, p2 - p1 - 1));
|
|
strtag.append(">");
|
|
p3 = strXML.find(strtag, p1);
|
|
return p3;
|
|
}
|
|
|
|
size_t nextTag(size_t p0)
|
|
{
|
|
p0 = strXML.find("<", p0+1);
|
|
return p0;
|
|
}
|
|
|
|
string getElement(size_t p0)
|
|
{
|
|
size_t p1 = strXML.find(">",p0),
|
|
p2 = nextTag(p1+1);
|
|
if (p1 == string::npos || p2 == string::npos)
|
|
return "";
|
|
p1++; p2--;
|
|
while (p1 < p2 && strXML[p1] == ' ') p1++; // skip leading spaces
|
|
while (p1 < p2 && strXML[p2] == ' ') p2--; // skip trailing spaces
|
|
return strXML.substr(p1, p2 - p1 + 1);
|
|
}
|
|
|
|
int getInt(size_t p0)
|
|
{
|
|
string stemp = getElement(p0);
|
|
if (stemp.length() == 0)
|
|
return 0;
|
|
return atoi(stemp.c_str());
|
|
}
|
|
|
|
float getFloat(size_t p0)
|
|
{
|
|
string stemp = getElement(p0);
|
|
if (stemp.length() == 0)
|
|
return 0;
|
|
return atof(stemp.c_str());
|
|
}
|
|
|
|
bool getBool( size_t p0)
|
|
{
|
|
string stemp = getElement(p0);
|
|
if (stemp.length() == 0)
|
|
return false;
|
|
if (strcasecmp(stemp.c_str(), "true") == 0)
|
|
return true;
|
|
if (stemp == "1") return true;
|
|
return false;
|
|
}
|
|
|
|
char getByte(size_t p0)
|
|
{
|
|
unsigned int val;
|
|
if (sscanf( getElement(p0).c_str(), "%x", &val ) != 1)
|
|
return 0;
|
|
return (val & 0xFF);
|
|
}
|
|
|
|
string getBytes(size_t p0)
|
|
{
|
|
unsigned int val;
|
|
size_t space;
|
|
string stemp = getElement(p0);
|
|
string s;
|
|
while ( stemp.length() ) {
|
|
if (sscanf( stemp.c_str(), "%x", &val) != 1) {
|
|
s = "";
|
|
return s;
|
|
}
|
|
s += (char)(val & 0xFF);
|
|
space = stemp.find(" ");
|
|
if (space == string::npos) break;
|
|
stemp.erase(0, space + 1);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
bool isInt(size_t p0, int &i)
|
|
{
|
|
// p0 = nextTag(p0);
|
|
if (strXML.find("<INT", p0) != p0)
|
|
return false;
|
|
i = getInt(p0);
|
|
return true;
|
|
}
|
|
|
|
bool isByte(size_t p0, char &ch)
|
|
{
|
|
// p0 = nextTag(p0);
|
|
if (strXML.find("<BYTE", p0) != p0)
|
|
return false;
|
|
ch = getByte(p0);
|
|
return true;
|
|
}
|
|
|
|
bool isBytes( size_t p0, string &s )
|
|
{
|
|
// p0 = nextTag(p0);
|
|
if (strXML.find ("<BYTES", p0) != p0)
|
|
return false;
|
|
s = getBytes(p0);
|
|
return true;
|
|
}
|
|
|
|
bool isString( size_t p0, string &s )
|
|
{
|
|
// p0 = nextTag(p0);
|
|
if (strXML.find("<STRING", p0) != p0)
|
|
return false;
|
|
s = getElement(p0);
|
|
return true;
|
|
}
|
|
|
|
bool isSymbol( size_t p0, string &s)
|
|
{
|
|
if (strXML.find("<SYMBOL", p0) != p0)
|
|
return false;
|
|
s = getElement(p0);
|
|
return true;
|
|
}
|
|
|
|
bool tagIs(size_t &p0, string tag)
|
|
{
|
|
return (strXML.find(tag,p0) == p0);
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse modesTO definitions
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseMODEdefs(size_t &p0, list<MODE> &lmd)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
size_t elend;
|
|
char ch;
|
|
int n;
|
|
string stemp;
|
|
string strELEMENT;
|
|
if (pend == string::npos) {
|
|
p0++;
|
|
return;
|
|
}
|
|
print(p0,0);
|
|
p0 = nextTag(p0);
|
|
while (p0 != string::npos && p0 < pend && tagIs(p0, "<ELEMENT")) {
|
|
elend = tagEnd(p0);
|
|
p0 = nextTag(p0);
|
|
if (isSymbol(p0, strELEMENT)) {
|
|
p0 = tagEnd(p0);
|
|
p0 = nextTag(p0);
|
|
while (p0 != string::npos && p0 < elend) {
|
|
print(p0,1);
|
|
if ( isBytes(p0, stemp) ) {
|
|
lmd.push_back(MODE(strELEMENT,stemp));
|
|
}
|
|
else if ( isByte(p0, ch) ) {
|
|
stemp = ch;
|
|
lmd.push_back(MODE(strELEMENT,stemp));
|
|
}
|
|
else if ( isInt(p0, n) ) {
|
|
stemp = (char)(n & 0xFF);
|
|
lmd.push_back(MODE(strELEMENT, stemp));
|
|
}
|
|
else if ( isString(p0, stemp) ) {
|
|
lmd.push_back(MODE(strELEMENT,stemp));
|
|
}
|
|
p0 = tagEnd(p0);
|
|
p0 = nextTag(p0);
|
|
}
|
|
}
|
|
p0 = nextTag(p0);
|
|
}
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseMODES(size_t &p0)
|
|
{
|
|
parseMODEdefs(p0, lmodes);
|
|
}
|
|
|
|
|
|
void parseMODECMD(size_t &p0)
|
|
{
|
|
parseMODEdefs(p0, lmodeCMD);
|
|
}
|
|
|
|
void parseMODEREPLY(size_t &p0)
|
|
{
|
|
parseMODEdefs(p0, lmodeREPLY);
|
|
}
|
|
|
|
void parseLSBMODES(size_t &p0)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
string sMode;
|
|
print(p0,0);
|
|
p0 = nextTag(p0);
|
|
while (p0 < pend && isString(p0, sMode)) {
|
|
LSBmodes.push_back(sMode);
|
|
print (p0,1);
|
|
p0 = tagEnd(p0);
|
|
p0 = nextTag(p0);
|
|
}
|
|
p0 = pend;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse Bandwidth definitions
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseBWdefs(size_t &p0, list<BW> &lbw)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
size_t elend;
|
|
char ch;
|
|
int n;
|
|
string strELEMENT;
|
|
string stemp;
|
|
if (pend == string::npos) {
|
|
LOG_ERROR("Unmatched tag %s", strXML.substr(p0, 10).c_str());
|
|
p0++;
|
|
return;
|
|
}
|
|
print(p0,0);
|
|
size_t p1 = nextTag(p0);
|
|
while (p1 != string::npos && p1 < pend && tagIs(p1, "<ELEMENT")) {
|
|
elend = tagEnd(p1);
|
|
if (elend == string::npos || elend > pend) {
|
|
LOG_ERROR("Unmatched tag %s", "<ELEMENT");
|
|
p0 = pend;
|
|
return;
|
|
}
|
|
p1 = nextTag(p1);
|
|
if (isSymbol(p1, strELEMENT)) {
|
|
p1 = tagEnd(p1);
|
|
p1 = nextTag(p1);
|
|
while (p1 != string::npos && p1 < elend) {
|
|
print(p1,1);
|
|
if ( isBytes(p1, stemp) ) {
|
|
lbw.push_back(BW(strELEMENT,stemp));
|
|
p1 = tagEnd(p1);
|
|
}
|
|
else if ( isByte(p1, ch) ) {
|
|
stemp = ch;
|
|
lbw.push_back(BW(strELEMENT,stemp));
|
|
p1 = tagEnd(p1);
|
|
}
|
|
else if ( isInt(p1, n) ) {
|
|
stemp = (char)(n & 0xFF);
|
|
lbw.push_back(BW(strELEMENT, stemp));
|
|
p1 = tagEnd(p1);
|
|
}
|
|
else if ( isString(p1, stemp) ) {
|
|
lbw.push_back(BW(strELEMENT,stemp));
|
|
p1 = tagEnd(p1);
|
|
} else {
|
|
LOG_ERROR("Invalid tag: %s", strXML.substr(p1, 10).c_str());
|
|
parseDISCARD(p1);
|
|
}
|
|
p1 = nextTag(p1);
|
|
}
|
|
}
|
|
p1 = nextTag(p1);
|
|
}
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseBANDWIDTHS(size_t &p0)
|
|
{
|
|
parseBWdefs(p0, lbws);
|
|
}
|
|
|
|
void parseBWCMD(size_t &p0)
|
|
{
|
|
parseBWdefs(p0, lbwCMD);
|
|
}
|
|
|
|
void parseBWREPLY(size_t &p0)
|
|
{
|
|
parseBWdefs(p0, lbwREPLY);
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse Title definition
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseTITLE(size_t &p0)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
xmlrig.rigTitle = getElement(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse Rig definition
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseRIG(size_t &p0)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse DEBUG, use during xml file creation/testing
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseDEBUG(size_t &p0){
|
|
bool val = getBool(p0);
|
|
xmlrig.debug = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse NOSERIAL, use during xml file creation/testing
|
|
// suppresses serial port i/o
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseNOSERIAL(size_t &p0){
|
|
bool val = getBool(p0);
|
|
xmlrig.noserial = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse ASCII, use during xml file creation/testing
|
|
// prints events as ASCII string vice HEX sequence
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseASCII(size_t &p0){
|
|
bool val = getBool(p0);
|
|
xmlrig.ascii = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse Baudrate, write_delay, post_write_delay, timeout, retries
|
|
// RTSCTS handshake
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseBAUDRATE(size_t &p0)
|
|
{
|
|
string sVal = getElement(p0);
|
|
xmlrig.baud = progdefaults.nBaudRate(sVal.c_str());
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseSTOPBITS(size_t &p0){
|
|
int val = getInt(p0);
|
|
if (val < 0 || val > 2) val = 2;
|
|
xmlrig.stopbits = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseWRITE_DELAY(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.write_delay = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseINIT_DELAY(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.init_delay = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseWAIT_FOR_DEVICE(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.wait_for_device = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parsePOST_WRITE_DELAY(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.post_write_delay = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseRETRIES(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.retries = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseTIMEOUT(size_t &p0){
|
|
int val = getInt(p0);
|
|
xmlrig.timeout = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseRTSCTS(size_t &p0){
|
|
bool val = getBool(p0);
|
|
xmlrig.rtscts = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseRTSPLUS(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.rts = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseDTRPLUS(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.dtr = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseRTSPTT(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.rtsptt = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseDTRPTT(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.dtrptt = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseRESTORE_TIO(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.restore_tio = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseCMDPTT(size_t &p0) {
|
|
bool val = getBool(p0);
|
|
xmlrig.cmdptt = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseECHO(size_t &p0) {
|
|
bool val = getBool(p0);
|
|
xmlrig.echo = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseVSP(size_t &p0)
|
|
{
|
|
bool val = getBool(p0);
|
|
xmlrig.vsp = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseLOGSTR(size_t &p0) {
|
|
bool val = getBool(p0);
|
|
xmlrig.logstr = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parsePOLLINT(size_t &p0) {
|
|
int val = getInt(p0);
|
|
if (val < 100) val = 1000;
|
|
if (val > 20000) val = 20000;
|
|
xmlrig.pollinterval = val;
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
}
|
|
|
|
void parseSMETER(size_t &p0) {
|
|
string strmeter = getElement(p0);
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
xmlrig.smeter.clear();
|
|
int val, sm;
|
|
size_t p = strmeter.find(",");
|
|
while ( !strmeter.empty() && (p != string::npos) ) {
|
|
val = atoi(&strmeter[0]);
|
|
sm = atoi(&strmeter[p+1]);
|
|
xmlrig.smeter.push_back(PAIR(val,sm));
|
|
p = strmeter.find(";");
|
|
if (p == string::npos) strmeter.clear();
|
|
else {
|
|
strmeter.erase(0, p+1);
|
|
p = strmeter.find(",");
|
|
}
|
|
}
|
|
xmlrig.use_smeter = true;
|
|
}
|
|
|
|
void parsePMETER(size_t &p0) {
|
|
string strmeter = getElement(p0);
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
xmlrig.smeter.clear();
|
|
int val, sm;
|
|
size_t p = strmeter.find(",");
|
|
while ( !strmeter.empty() && (p != string::npos) ) {
|
|
val = atoi(&strmeter[0]);
|
|
sm = atoi(&strmeter[p+1]);
|
|
xmlrig.pmeter.push_back(PAIR(val,sm));
|
|
p = strmeter.find(";");
|
|
if (p == string::npos) strmeter.clear();
|
|
else {
|
|
strmeter.erase(0, p+1);
|
|
p = strmeter.find(",");
|
|
}
|
|
}
|
|
xmlrig.use_pwrmeter = true;
|
|
}
|
|
|
|
void parseNOTCH(size_t &p0) {
|
|
string strnotch = getElement(p0);
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
xmlrig.notch.clear();
|
|
int val, ntch;
|
|
size_t p = strnotch.find(",");
|
|
while ( !strnotch.empty() && (p != string::npos) ) {
|
|
val = atoi(&strnotch[0]);
|
|
ntch = atoi(&strnotch[p+1]);
|
|
xmlrig.notch.push_back(PAIR(val,ntch));
|
|
p = strnotch.find(";");
|
|
if (p == string::npos) strnotch.clear();
|
|
else {
|
|
strnotch.erase(0, p+1);
|
|
p = strnotch.find(",");
|
|
}
|
|
}
|
|
xmlrig.use_notch = true;
|
|
}
|
|
|
|
void parsePWRLEVEL(size_t &p0) {
|
|
string strpwrlevel = getElement(p0);
|
|
size_t pend = tagEnd(p0);
|
|
p0 = pend;
|
|
xmlrig.pwrlevel.clear();
|
|
int val, pwr;
|
|
float min = 500, max = 0;
|
|
size_t p = strpwrlevel.find(",");
|
|
while ( !strpwrlevel.empty() && (p != string::npos) ) {
|
|
val = atoi(&strpwrlevel[0]);
|
|
pwr = atoi(&strpwrlevel[p+1]);
|
|
if (pwr < min) min = pwr;
|
|
if (pwr > max) max = pwr;
|
|
xmlrig.pwrlevel.push_back(PAIR(val,pwr));
|
|
p = strpwrlevel.find(";");
|
|
if (p == string::npos) strpwrlevel.clear();
|
|
else {
|
|
strpwrlevel.erase(0, p+1);
|
|
p = strpwrlevel.find(",");
|
|
}
|
|
}
|
|
pwr_level->range(min, max);
|
|
xmlrig.use_pwrlevel = true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Parse IOS (serial stream format) definitions
|
|
//---------------------------------------------------------------------
|
|
|
|
void parseIOSsize(size_t &p0)
|
|
{
|
|
iosTemp.size = getInt(p0);
|
|
}
|
|
|
|
void parseIOSbytes(size_t &p0)
|
|
{
|
|
if (iosTemp.data.size == 0)
|
|
iosTemp.str1.append(getBytes(p0));
|
|
else
|
|
iosTemp.str2.append(getBytes(p0));
|
|
}
|
|
|
|
void parseIOSbyte(size_t &p0)
|
|
{
|
|
if (iosTemp.data.size == 0)
|
|
iosTemp.str1 += getByte(p0);
|
|
else
|
|
iosTemp.str2 += getByte(p0);
|
|
}
|
|
|
|
void parseIOSstring(size_t &p0)
|
|
{
|
|
if (iosTemp.data.size == 0)
|
|
iosTemp.str1 += getElement(p0);
|
|
else
|
|
iosTemp.str2 += getElement(p0);
|
|
}
|
|
|
|
void parseIOSint(size_t &p0)
|
|
{
|
|
if (iosTemp.data.size == 0)
|
|
iosTemp.str1 += (char)(getInt(p0) & 0xFF);
|
|
else
|
|
iosTemp.str2 += (char)(getInt(p0) & 0xFF);
|
|
}
|
|
|
|
void parseDTYPE(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.dtype = getElement(p1);
|
|
}
|
|
|
|
void parseDSIZE(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.size = getInt(p1);
|
|
}
|
|
|
|
void parseDMAX(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.max = getInt(p1);
|
|
}
|
|
|
|
void parseDMIN(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.min = getInt(p1);
|
|
}
|
|
|
|
void parseDRESOL(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.resolution = getFloat(p1);
|
|
}
|
|
|
|
void parseDREV(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.reverse = getBool(p1);
|
|
}
|
|
|
|
void parseDMAKS(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.andmask = getInt(p1);
|
|
}
|
|
|
|
void parseDSHIFT(size_t &p1)
|
|
{
|
|
print(p1,2);
|
|
iosTemp.data.shiftbits = getInt(p1);
|
|
}
|
|
|
|
void parseIOSdata(size_t &p0)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
size_t p1;
|
|
TAGS *pv;
|
|
|
|
p1 = nextTag(p0);
|
|
while (p1 < pend) {
|
|
pv = datatags;
|
|
while (pv->tag) {
|
|
if (strXML.find(pv->tag, p1) == p1)
|
|
break;
|
|
pv++;
|
|
}
|
|
if (pv->fp) {
|
|
print(p1, 1);
|
|
(pv->fp)(p1);
|
|
p1 = tagEnd(p1);
|
|
} else {
|
|
LOG_ERROR("Invalid tag: %s", strXML.substr(p1, 10).c_str());
|
|
parseDISCARD(p1);
|
|
}
|
|
p1 = nextTag(p1);
|
|
}
|
|
}
|
|
|
|
void parseIOSinfo(size_t &p0)
|
|
{
|
|
string strR = getElement(p0);
|
|
if (strR.empty()) return;
|
|
iosTemp.info = strR;
|
|
}
|
|
|
|
void parseIOSok(size_t &p0)
|
|
{
|
|
string strR = getElement(p0);
|
|
if (strR.empty()) return;
|
|
iosTemp.ok = strR;
|
|
}
|
|
|
|
void parseIOSbad(size_t &p0)
|
|
{
|
|
string strR = getElement(p0);
|
|
if (strR.empty()) return;
|
|
iosTemp.bad = strR;
|
|
}
|
|
|
|
void parseIOSsymbol(size_t &p0)
|
|
{
|
|
string strR = getElement(p0);
|
|
if (strR.empty()) return;
|
|
iosTemp.SYMBOL = strR;
|
|
}
|
|
|
|
void parseIOSfill(size_t &p0)
|
|
{
|
|
if (iosTemp.data.size == 0)
|
|
iosTemp.fill1 = getInt(p0);
|
|
else
|
|
iosTemp.fill2 = getInt(p0);
|
|
}
|
|
|
|
//=======================================================================
|
|
|
|
bool parseIOS(size_t &p0, TAGS *valid)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
size_t p1;
|
|
TAGS *pv;
|
|
|
|
print(p0,0);
|
|
|
|
iosTemp.clear();
|
|
p1 = nextTag(p0);
|
|
while (p1 < pend) {
|
|
pv = valid;
|
|
while (pv->tag) {
|
|
if (strXML.find(pv->tag, p1) == p1)
|
|
break;
|
|
pv++;
|
|
}
|
|
if (pv->fp) {
|
|
print(p1, 1);
|
|
(pv->fp)(p1);
|
|
p1 = tagEnd(p1);
|
|
} else {
|
|
LOG_ERROR("Invalid tag: %s", strXML.substr(p1, 10).c_str());
|
|
parseDISCARD(p1);
|
|
}
|
|
p1 = nextTag(p1);
|
|
}
|
|
p0 = pend;
|
|
return (!iosTemp.SYMBOL.empty());
|
|
}
|
|
|
|
void parseCOMMAND(size_t &p0)
|
|
{
|
|
if (parseIOS(p0, commandtags))
|
|
commands.push_back(iosTemp);
|
|
}
|
|
|
|
void parseREPLY(size_t &p0)
|
|
{
|
|
if (parseIOS(p0, replytags))
|
|
reply.push_back(iosTemp);
|
|
}
|
|
|
|
void parseRIGDEF(size_t &p0)
|
|
{
|
|
print(p0,0);
|
|
size_t p1 = tagEnd(p0);
|
|
if (p1 != string::npos)
|
|
strXML.erase(p1);
|
|
}
|
|
|
|
void parseDISCARD(size_t &p0)
|
|
{
|
|
size_t pend = tagEnd(p0);
|
|
if (pend == string::npos) p0++;
|
|
else p0 = pend;
|
|
}
|
|
|
|
void parseXML()
|
|
{
|
|
size_t p0 = 0;
|
|
TAGS *pValid = rigdeftags;
|
|
|
|
p0 = strXML.find("<");
|
|
while (p0 != string::npos) {
|
|
pValid = rigdeftags;
|
|
while (pValid->tag) {
|
|
if (strXML.find(pValid->tag, p0) == p0)
|
|
break;
|
|
pValid++;
|
|
}
|
|
if (pValid->tag) {
|
|
(pValid->fp)(p0);
|
|
} else {
|
|
LOG_ERROR("Invalid tag: %s", strXML.substr(p0, 10).c_str());
|
|
parseDISCARD(p0);
|
|
}
|
|
p0 = nextTag(p0);
|
|
}
|
|
}
|
|
|
|
bool remove_comments()
|
|
{
|
|
size_t p0 = 0;
|
|
size_t p1 = 0;
|
|
|
|
// remove comments from xml text
|
|
while ((p0 = strXML.find("<!--")) != string::npos) {
|
|
p1 = strXML.find("-->", p0);
|
|
if (p1 == string::npos) {
|
|
fl_alert2("Corrupt rig XML defintion file\nMismatched comment tags!");
|
|
return false;
|
|
}
|
|
strXML.erase(p0, p1 - p0 + 3);
|
|
}
|
|
if (strXML.find("-->") != string::npos) {
|
|
fl_alert2("Corrupt rig XML defintion file\nMismatched comment tags!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool testXML()
|
|
{
|
|
if (!remove_comments()) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool readRigXML()
|
|
{
|
|
char szLine[256];
|
|
int lines = 0;
|
|
|
|
commands.clear();
|
|
reply.clear();
|
|
lmodes.clear();
|
|
lmodeCMD.clear();
|
|
lmodeREPLY.clear();
|
|
lbws.clear();
|
|
lbwCMD.clear();
|
|
lbwREPLY.clear();
|
|
LSBmodes.clear();
|
|
strXML = "";
|
|
|
|
ifstream xmlfile(progdefaults.XmlRigFilename.c_str(), ios::in);
|
|
if (xmlfile) {
|
|
while (!xmlfile.eof()) {
|
|
lines++;
|
|
memset(szLine, 0, sizeof(szLine));
|
|
xmlfile.getline(szLine,255);
|
|
strXML.append(szLine);
|
|
}
|
|
xmlfile.close();
|
|
if (testXML()) {
|
|
parseXML();
|
|
xmlrig.xmlok = true;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void selectRigXmlFilename()
|
|
{
|
|
string deffilename;
|
|
deffilename = progdefaults.XmlRigFilename;
|
|
const char *p = FSEL::select(_("Open rig xml file"), _("Fldigi rig xml definition file\t*.xml"), deffilename.c_str());
|
|
if (!p) return;
|
|
if (!*p) return;
|
|
|
|
progdefaults.XmlRigFilename = p;
|
|
txtXmlRigFilename->value(fl_filename_name(p));
|
|
loadRigXmlFile();
|
|
}
|
|
|
|
void loadRigXmlFile(void)
|
|
{
|
|
rigCAT_close();
|
|
readRigXML();
|
|
rigCAT_defaults();
|
|
}
|