2021-06-26 15:24:07 +02:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
/*
|
2022-11-06 18:33:43 +01:00
|
|
|
* Copyright (C) 2019-2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
|
|
|
|
* Copyright (C) 2022 phdussud
|
|
|
|
|
*
|
2021-06-26 15:24:07 +02:00
|
|
|
*/
|
2022-11-06 18:33:43 +01:00
|
|
|
|
|
|
|
|
#include "svf_jtag.hpp"
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2022-10-25 19:55:02 +02:00
|
|
|
#include <algorithm>
|
2019-09-26 18:29:20 +02:00
|
|
|
#include <iostream>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
2020-03-06 09:05:57 +01:00
|
|
|
#include "jtag.hpp"
|
2019-09-26 18:29:20 +02:00
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
void SVF_jtag::split_str(string const &str, vector<string> &vparse)
|
|
|
|
|
{
|
|
|
|
|
string token;
|
2022-10-25 19:55:02 +02:00
|
|
|
istringstream tokenStream(str);
|
|
|
|
|
while (getline(tokenStream, token, ' '))
|
2019-09-26 18:29:20 +02:00
|
|
|
vparse.push_back(token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SVF_jtag::clear_XYR(svf_XYR &t)
|
|
|
|
|
{
|
|
|
|
|
t.len = 0;
|
|
|
|
|
t.tdo.clear();
|
|
|
|
|
t.tdi.clear();
|
|
|
|
|
t.mask.clear();
|
|
|
|
|
t.smask.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-06 18:33:43 +01:00
|
|
|
static unsigned char *parse_hex(string const &in, size_t byte_length,
|
|
|
|
|
bool default_value)
|
2022-10-25 19:55:02 +02:00
|
|
|
{
|
|
|
|
|
unsigned char *txbuf = new unsigned char[byte_length];
|
|
|
|
|
char c;
|
2022-11-11 00:01:21 +01:00
|
|
|
ssize_t last_iter = in.size() - (2 * byte_length);
|
|
|
|
|
for (ssize_t i = (in.size() - 1), pos = 0; i >= last_iter; i--, pos++) {
|
2022-11-06 18:33:43 +01:00
|
|
|
if (i < 0) {
|
2022-10-25 19:55:02 +02:00
|
|
|
c = default_value ? 0x0f : 0x00;
|
2022-11-06 18:33:43 +01:00
|
|
|
} else {
|
2022-10-25 19:55:02 +02:00
|
|
|
if (in[i] <= '9')
|
|
|
|
|
c = 0x0f & (in[i] - '0');
|
|
|
|
|
else
|
|
|
|
|
c = 0x0f & (in[i] - 'A' + 10);
|
|
|
|
|
}
|
|
|
|
|
if (!(pos & 1))
|
|
|
|
|
txbuf[pos / 2] = c;
|
|
|
|
|
else
|
|
|
|
|
txbuf[pos / 2] |= c << 4;
|
|
|
|
|
}
|
|
|
|
|
return txbuf;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
|
|
|
|
|
/* pas clair:
|
2022-10-25 19:55:02 +02:00
|
|
|
* si length != previous length : tout est remis a zero
|
|
|
|
|
* tdi, mask et smask sont memorises. Si pas present c'est la memoire
|
|
|
|
|
* qui est utilise
|
|
|
|
|
* tdo si absent on s'en fout
|
|
|
|
|
* TODO: ameliorer l'analyse des chaines de caracteres
|
|
|
|
|
*/
|
2019-09-26 18:29:20 +02:00
|
|
|
void SVF_jtag::parse_XYR(vector<string> const &vstr, svf_XYR &t)
|
|
|
|
|
{
|
2022-10-25 19:55:02 +02:00
|
|
|
if (_verbose)
|
|
|
|
|
cout << endl;
|
2019-09-26 18:29:20 +02:00
|
|
|
int mode = 0;
|
|
|
|
|
string s;
|
|
|
|
|
string full_line;
|
|
|
|
|
full_line.reserve(1276);
|
|
|
|
|
int write_data = -1;
|
|
|
|
|
|
|
|
|
|
if (vstr[0][0] == 'S')
|
|
|
|
|
write_data = ((vstr[0][1] == 'I') ? 0 : 1);
|
|
|
|
|
|
2022-10-25 19:55:02 +02:00
|
|
|
uint32_t new_length = stoul(vstr[1]);
|
2022-10-26 18:16:04 +02:00
|
|
|
if (new_length != t.len) {
|
2019-09-26 18:29:20 +02:00
|
|
|
clear_XYR(t);
|
|
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
t.len = new_length;
|
|
|
|
|
t.tdo.clear();
|
|
|
|
|
if (t.len == 0)
|
|
|
|
|
return;
|
2022-11-06 18:33:43 +01:00
|
|
|
for (size_t pos = 2; pos < vstr.size(); pos++) {
|
2019-09-26 18:29:20 +02:00
|
|
|
s = vstr[pos];
|
|
|
|
|
|
|
|
|
|
if (!s.compare("TDO")) {
|
|
|
|
|
mode = 1;
|
|
|
|
|
continue;
|
|
|
|
|
} else if (!s.compare("TDI")) {
|
|
|
|
|
mode = 2;
|
|
|
|
|
continue;
|
|
|
|
|
} else if (!s.compare("MASK")) {
|
|
|
|
|
mode = 3;
|
|
|
|
|
continue;
|
|
|
|
|
} else if (!s.compare("SMASK")) {
|
|
|
|
|
mode = 4;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (s.front() == '(')
|
|
|
|
|
s = s.substr(1);
|
|
|
|
|
if (s.front() == '\t')
|
|
|
|
|
s = s.substr(1);
|
|
|
|
|
if (s.back() == ')')
|
2022-10-25 19:55:02 +02:00
|
|
|
s = s.substr(0, s.size() - 1);
|
2019-09-26 18:29:20 +02:00
|
|
|
|
|
|
|
|
/* faut analyser et convertir le string ici
|
|
|
|
|
* quand s.back() == ')'
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
full_line += s;
|
|
|
|
|
s.clear();
|
|
|
|
|
|
|
|
|
|
if (vstr[pos].back() == ')') {
|
|
|
|
|
switch (mode) {
|
|
|
|
|
case 1:
|
|
|
|
|
t.tdo.clear();
|
|
|
|
|
t.tdo = full_line;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
t.tdi = full_line;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
t.mask.clear();
|
2022-10-25 19:55:02 +02:00
|
|
|
t.mask = full_line;
|
2019-09-26 18:29:20 +02:00
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
t.smask.clear();
|
2022-10-25 19:55:02 +02:00
|
|
|
t.smask = full_line;
|
2019-09-26 18:29:20 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
full_line.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (write_data != -1) {
|
2022-10-25 19:55:02 +02:00
|
|
|
size_t byte_len = (t.len + 7) / 8;
|
|
|
|
|
unsigned char *write_buffer = parse_hex(t.tdi, byte_len, 0);
|
|
|
|
|
if (!t.smask.empty()) {
|
|
|
|
|
unsigned char *smaskbuff = parse_hex(t.smask, byte_len, 0);
|
|
|
|
|
for (unsigned int b = 0; b < byte_len; b++) {
|
|
|
|
|
write_buffer[b] &= smaskbuff[b];
|
|
|
|
|
}
|
|
|
|
|
delete smaskbuff;
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
unsigned char *read_buffer = NULL;
|
|
|
|
|
if (!t.tdo.empty()) {
|
|
|
|
|
read_buffer = new unsigned char[byte_len];
|
2022-11-06 18:33:43 +01:00
|
|
|
read_buffer[byte_len - 1] = 0; // clear the last byte which may not be full;
|
|
|
|
|
} else {
|
2022-10-25 19:55:02 +02:00
|
|
|
read_buffer = NULL;
|
2022-11-06 18:33:43 +01:00
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
if (write_data == 0)
|
2022-10-25 19:55:02 +02:00
|
|
|
_jtag->shiftIR(write_buffer, read_buffer, t.len, _endir);
|
2019-09-26 18:29:20 +02:00
|
|
|
else
|
2022-10-25 19:55:02 +02:00
|
|
|
_jtag->shiftDR(write_buffer, read_buffer, t.len, _enddr);
|
|
|
|
|
if (!t.tdo.empty()) {
|
|
|
|
|
unsigned char *tdobuf = parse_hex(t.tdo, byte_len, 0);
|
|
|
|
|
unsigned char *maskbuf = parse_hex(t.mask, byte_len, t.mask.empty() ? 1 : 0);
|
2022-10-26 18:16:04 +02:00
|
|
|
for (size_t i = 0; i < byte_len; i++) {
|
|
|
|
|
if ((read_buffer[i] ^ tdobuf[i]) & maskbuf[i]) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cerr << "TDO value ";
|
2022-10-26 18:16:04 +02:00
|
|
|
for (int j = byte_len - 1; j >= 0; j--) {
|
|
|
|
|
cerr << uppercase << hex << int(read_buffer[j]);
|
2022-10-25 19:55:02 +02:00
|
|
|
}
|
|
|
|
|
cerr << " isn't the one expected: " << uppercase << t.tdo << endl;
|
|
|
|
|
throw exception();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete tdobuf;
|
|
|
|
|
delete maskbuf;
|
|
|
|
|
}
|
|
|
|
|
delete write_buffer;
|
|
|
|
|
delete read_buffer;
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Implementation partielle de la spec */
|
|
|
|
|
void SVF_jtag::parse_runtest(vector<string> const &vstr)
|
|
|
|
|
{
|
2022-10-25 19:55:02 +02:00
|
|
|
unsigned int pos = 1;
|
2019-09-26 18:29:20 +02:00
|
|
|
int nb_iter = 0;
|
|
|
|
|
int run_state = -1;
|
|
|
|
|
int end_state = -1;
|
2022-10-25 19:55:02 +02:00
|
|
|
double min_duration = -1;
|
|
|
|
|
// 0 => RUNTEST
|
|
|
|
|
// 1 => Ca depend
|
2022-11-06 18:33:43 +01:00
|
|
|
if (isalpha(vstr[pos][0])) {
|
2019-09-26 18:29:20 +02:00
|
|
|
run_state = fsm_state[vstr[1]];
|
|
|
|
|
pos++;
|
|
|
|
|
}
|
2022-10-26 18:16:04 +02:00
|
|
|
if (!vstr[pos + 1].compare("SEC")) {
|
2022-10-25 19:55:02 +02:00
|
|
|
min_duration = atof(vstr[pos].c_str());
|
|
|
|
|
pos++;
|
2022-11-06 18:33:43 +01:00
|
|
|
pos++;
|
2022-10-25 19:55:02 +02:00
|
|
|
} else {
|
|
|
|
|
nb_iter = atoi(vstr[pos].c_str());
|
2019-09-26 18:29:20 +02:00
|
|
|
pos++;
|
2022-11-06 18:33:43 +01:00
|
|
|
pos++; // run_clk field, ignored.
|
2022-10-25 19:55:02 +02:00
|
|
|
if (((pos + 1) < vstr.size()) &&
|
|
|
|
|
(!vstr[pos + 1].compare("SEC"))) {
|
|
|
|
|
min_duration = atof(vstr[pos].c_str());
|
|
|
|
|
pos++;
|
|
|
|
|
pos++;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
auto res = find(begin(vstr) + pos, end(vstr), "ENDSTATE");
|
2022-11-06 18:33:43 +01:00
|
|
|
if (res != end(vstr)) {
|
2022-10-25 19:55:02 +02:00
|
|
|
res++;
|
|
|
|
|
end_state = fsm_state[*res];
|
|
|
|
|
}
|
2022-11-06 18:33:43 +01:00
|
|
|
if (run_state != -1) {
|
2019-09-26 18:29:20 +02:00
|
|
|
_run_state = run_state;
|
|
|
|
|
}
|
2022-11-06 18:33:43 +01:00
|
|
|
if (end_state != -1) {
|
2019-09-26 18:29:20 +02:00
|
|
|
_end_state = end_state;
|
2022-11-06 18:33:43 +01:00
|
|
|
} else if (run_state != -1) {
|
2019-09-26 18:29:20 +02:00
|
|
|
_end_state = run_state;
|
2022-11-06 18:33:43 +01:00
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
_jtag->set_state(_run_state);
|
|
|
|
|
_jtag->toggleClk(nb_iter);
|
2022-11-06 18:33:43 +01:00
|
|
|
if (min_duration > 0) {
|
2022-10-25 19:55:02 +02:00
|
|
|
usleep((useconds_t)(min_duration * 1.0E6));
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
_jtag->set_state(_end_state);
|
2022-10-25 19:55:02 +02:00
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
|
|
|
|
|
void SVF_jtag::handle_instruction(vector<string> const &vstr)
|
|
|
|
|
{
|
|
|
|
|
if (!vstr[0].compare("FREQUENCY")) {
|
|
|
|
|
_freq_hz = atof(vstr[1].c_str());
|
|
|
|
|
if (_verbose) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << "frequency value " << vstr[1] << " unit " << vstr[2];
|
2019-09-26 18:29:20 +02:00
|
|
|
cout << _freq_hz << endl;
|
|
|
|
|
}
|
|
|
|
|
_jtag->setClkFreq(_freq_hz);
|
|
|
|
|
} else if (!vstr[0].compare("TRST")) {
|
|
|
|
|
if (_verbose) cout << "trst value : " << vstr[1] << endl;
|
|
|
|
|
} else if (!vstr[0].compare("ENDDR")) {
|
|
|
|
|
if (_verbose) cout << "enddr value : " << vstr[1] << endl;
|
|
|
|
|
_enddr = fsm_state[vstr[1]];
|
|
|
|
|
} else if (!vstr[0].compare("ENDIR")) {
|
|
|
|
|
if (_verbose) cout << "endir value : " << vstr[1] << endl;
|
|
|
|
|
_endir = fsm_state[vstr[1]];
|
|
|
|
|
} else if (!vstr[0].compare("STATE")) {
|
|
|
|
|
if (_verbose) cout << "state value : " << vstr[1] << endl;
|
|
|
|
|
_jtag->set_state(fsm_state[vstr[1]]);
|
|
|
|
|
} else if (!vstr[0].compare("RUNTEST")) {
|
|
|
|
|
parse_runtest(vstr);
|
|
|
|
|
} else if (!vstr[0].compare("HIR")) {
|
|
|
|
|
parse_XYR(vstr, hir);
|
2022-10-25 19:55:02 +02:00
|
|
|
if (hir.len > 0) {
|
|
|
|
|
cerr << "HIR length supported is only 0 " << endl;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
if (_verbose) {
|
|
|
|
|
cout << "HIR" << endl;
|
|
|
|
|
cout << "\tlen : " << hir.len << endl;
|
|
|
|
|
cout << "\ttdo : " << hir.tdo.size()*4 << endl;
|
|
|
|
|
cout << "\ttdi : " << hir.tdi.size()*4 << endl;
|
|
|
|
|
cout << "\tmask : " << hir.mask.size()*4 << endl;
|
|
|
|
|
cout << "\tsmask : " << hir.smask.size()*4 << endl;
|
|
|
|
|
}
|
|
|
|
|
} else if (!vstr[0].compare("HDR")) {
|
|
|
|
|
parse_XYR(vstr, hdr);
|
2022-11-06 18:33:43 +01:00
|
|
|
if (hdr.len > 0) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cerr << "HDR length supported is only 0" << endl;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
if (_verbose) {
|
|
|
|
|
cout << "HDR" << endl;
|
|
|
|
|
cout << "\tlen : " << hdr.len << endl;
|
|
|
|
|
cout << "\ttdo : " << hdr.tdo.size()*4 << endl;
|
|
|
|
|
cout << "\ttdi : " << hdr.tdi.size()*4 << endl;
|
|
|
|
|
cout << "\tmask : " << hdr.mask.size()*4 << endl;
|
|
|
|
|
cout << "\tsmask : " << hdr.smask.size()*4 << endl;
|
|
|
|
|
}
|
|
|
|
|
} else if (!vstr[0].compare("SIR")) {
|
|
|
|
|
parse_XYR(vstr, sir);
|
|
|
|
|
if (_verbose) {
|
2022-11-06 18:33:43 +01:00
|
|
|
for (auto &&t : vstr)
|
2019-09-26 18:29:20 +02:00
|
|
|
cout << t << " ";
|
|
|
|
|
cout << endl;
|
|
|
|
|
cout << "\tlen : " << sir.len << endl;
|
|
|
|
|
cout << "\ttdo : " << sir.tdo.size()*4 << endl;
|
|
|
|
|
cout << "\ttdi : " << sir.tdi.size()*4 << endl;
|
|
|
|
|
cout << "\tmask : " << sir.mask.size()*4 << endl;
|
|
|
|
|
cout << "\tsmask : " << sir.smask.size()*4 << endl;
|
|
|
|
|
}
|
|
|
|
|
} else if (!vstr[0].compare("SDR")) {
|
|
|
|
|
parse_XYR(vstr, sdr);
|
|
|
|
|
if (_verbose) {
|
|
|
|
|
cout << "SDR" << endl;
|
|
|
|
|
cout << "\tlen : " << sdr.len << endl;
|
|
|
|
|
cout << "\ttdo : " << sdr.tdo.size()*4 << endl;
|
|
|
|
|
cout << "\ttdi : " << sdr.tdi.size()*4 << endl;
|
|
|
|
|
cout << "\tmask : " << sdr.mask.size()*4 << endl;
|
|
|
|
|
cout << "\tsmask : " << sdr.smask.size()*4 << endl;
|
|
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
} else if (!vstr[0].compare("TDR")) {
|
|
|
|
|
parse_XYR(vstr, tdr);
|
|
|
|
|
if (tdr.len > 0) {
|
|
|
|
|
cerr << "TDR length supported is only 0" << endl;
|
|
|
|
|
}
|
2022-10-26 18:16:04 +02:00
|
|
|
if (_verbose) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << "TDR" << endl;
|
|
|
|
|
cout << "\tlen : " << tdr.len << endl;
|
|
|
|
|
cout << "\ttdo : " << tdr.tdo.size() * 4 << endl;
|
|
|
|
|
cout << "\ttdi : " << tdr.tdi.size() * 4 << endl;
|
|
|
|
|
cout << "\tmask : " << tdr.mask.size() * 4 << endl;
|
|
|
|
|
cout << "\tsmask : " << tdr.smask.size() * 4 << endl;
|
|
|
|
|
}
|
|
|
|
|
} else if (!vstr[0].compare("TIR")) {
|
|
|
|
|
parse_XYR(vstr, tir);
|
|
|
|
|
if (tir.len > 0) {
|
|
|
|
|
cerr << "TIR length supported is only 0" << endl;
|
|
|
|
|
}
|
2022-10-26 18:16:04 +02:00
|
|
|
if (_verbose) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << "TIR" << endl;
|
|
|
|
|
cout << "\tlen : " << tir.len << endl;
|
|
|
|
|
cout << "\ttdo : " << tir.tdo.size() * 4 << endl;
|
|
|
|
|
cout << "\ttdi : " << tir.tdi.size() * 4 << endl;
|
|
|
|
|
cout << "\tmask : " << tir.mask.size() * 4 << endl;
|
|
|
|
|
cout << "\tsmask : " << tir.smask.size() * 4 << endl;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
} else {
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << "error: unhandled instruction " << vstr[0] << endl;
|
|
|
|
|
throw exception();
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-06 09:05:57 +01:00
|
|
|
SVF_jtag::SVF_jtag(Jtag *jtag, bool verbose):_verbose(verbose), _freq_hz(0),
|
2019-09-26 18:29:20 +02:00
|
|
|
_enddr(fsm_state["IDLE"]), _endir(fsm_state["IDLE"]),
|
|
|
|
|
_run_state(fsm_state["IDLE"]), _end_state(fsm_state["IDLE"])
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
_jtag = jtag;
|
|
|
|
|
_jtag->go_test_logic_reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SVF_jtag::~SVF_jtag() {}
|
|
|
|
|
|
2022-11-06 18:33:43 +01:00
|
|
|
bool is_space(char x) {
|
2022-10-25 19:55:02 +02:00
|
|
|
return !!isspace(x);
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
/* Read SVF file line by line
|
|
|
|
|
* concat continuous lines
|
|
|
|
|
* and pass instruction to handle_instruction
|
|
|
|
|
*/
|
2022-11-06 18:33:43 +01:00
|
|
|
void SVF_jtag::parse(string filename)
|
2019-09-26 18:29:20 +02:00
|
|
|
{
|
|
|
|
|
string str;
|
|
|
|
|
vector<string> vstr;
|
|
|
|
|
bool is_complete;
|
|
|
|
|
ifstream fs;
|
|
|
|
|
|
|
|
|
|
fs.open(filename);
|
|
|
|
|
if (!fs.is_open()) {
|
2022-10-25 19:55:02 +02:00
|
|
|
cerr << "Error opening svf file " << filename << endl;
|
2019-09-26 18:29:20 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
unsigned int lineno = 0;
|
|
|
|
|
try {
|
|
|
|
|
while (getline(fs, str)) {
|
|
|
|
|
/* sanity check: DOS CR */
|
|
|
|
|
if (str.back() == '\r')
|
|
|
|
|
str.pop_back();
|
|
|
|
|
lineno++;
|
|
|
|
|
is_complete = false;
|
2022-11-06 18:33:43 +01:00
|
|
|
if (str[0] == '!') // comment
|
2022-10-25 19:55:02 +02:00
|
|
|
continue;
|
|
|
|
|
if (str.back() == ';') {
|
|
|
|
|
str.pop_back();
|
|
|
|
|
is_complete = true;
|
|
|
|
|
}
|
|
|
|
|
replace_if(begin(str), end(str), is_space, ' ');
|
|
|
|
|
split_str(str, vstr);
|
|
|
|
|
if (is_complete) {
|
|
|
|
|
if (_verbose) {
|
|
|
|
|
if (vstr[0].compare("HDR") && vstr[0].compare("HIR")
|
|
|
|
|
&& vstr[0].compare("SDR") && vstr[0].compare("SIR")) {
|
2022-11-06 18:33:43 +01:00
|
|
|
for (auto &&word : vstr)
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << word << " ";
|
|
|
|
|
cout << endl;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
handle_instruction(vstr);
|
|
|
|
|
vstr.clear();
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-25 19:55:02 +02:00
|
|
|
catch (exception &e)
|
|
|
|
|
{
|
|
|
|
|
cerr << "Cannot proceed because of error(s) at line " << lineno << endl;
|
|
|
|
|
throw;
|
|
|
|
|
}
|
2019-09-26 18:29:20 +02:00
|
|
|
|
2022-10-25 19:55:02 +02:00
|
|
|
cout << "end of SVF file" << endl;
|
2019-09-26 18:29:20 +02:00
|
|
|
}
|