diff options
Diffstat (limited to 'utils/regtools/qeditor/regtab.cpp')
-rw-r--r-- | utils/regtools/qeditor/regtab.cpp | 117 |
1 files changed, 109 insertions, 8 deletions
diff --git a/utils/regtools/qeditor/regtab.cpp b/utils/regtools/qeditor/regtab.cpp index e4adecf203..1e9846ef33 100644 --- a/utils/regtools/qeditor/regtab.cpp +++ b/utils/regtools/qeditor/regtab.cpp | |||
@@ -17,17 +17,100 @@ | |||
17 | #include "backend.h" | 17 | #include "backend.h" |
18 | #include "analyser.h" | 18 | #include "analyser.h" |
19 | 19 | ||
20 | RegTreeItem::RegTreeItem(const QString& string, int type) | 20 | SocFieldValidator::SocFieldValidator(QObject *parent) |
21 | :QTreeWidgetItem(QStringList(string), type) | 21 | :QValidator(parent) |
22 | { | 22 | { |
23 | m_field.first_bit = 0; | ||
24 | m_field.last_bit = 31; | ||
23 | } | 25 | } |
24 | 26 | ||
25 | void RegTreeItem::SetPath(int dev_idx, int dev_addr_idx, int reg_idx, int reg_addr_idx) | 27 | SocFieldValidator::SocFieldValidator(const soc_reg_field_t& field, QObject *parent) |
28 | :QValidator(parent), m_field(field) | ||
26 | { | 29 | { |
27 | m_dev_idx = dev_idx; | 30 | } |
28 | m_dev_addr_idx = dev_addr_idx; | 31 | |
29 | m_reg_idx = reg_idx; | 32 | void SocFieldValidator::fixup(QString& input) const |
30 | m_reg_addr_idx = reg_addr_idx; | 33 | { |
34 | input = input.trimmed(); | ||
35 | } | ||
36 | |||
37 | QValidator::State SocFieldValidator::validate(QString& input, int& pos) const | ||
38 | { | ||
39 | (void) pos; | ||
40 | soc_word_t val; | ||
41 | State state = parse(input, val); | ||
42 | qDebug() << "validate(" << input << "): " << state; | ||
43 | return state; | ||
44 | } | ||
45 | |||
46 | QValidator::State SocFieldValidator::parse(const QString& input, soc_word_t& val) const | ||
47 | { | ||
48 | // the empty string is all alwats intermediate | ||
49 | if(input.size() == 0) | ||
50 | return Intermediate; | ||
51 | // first check named values | ||
52 | State state = Invalid; | ||
53 | foreach(const soc_reg_field_value_t& value, m_field.value) | ||
54 | { | ||
55 | QString name = QString::fromLocal8Bit(value.name.c_str()); | ||
56 | // cannot be a substring if too long or empty | ||
57 | if(input.size() > name.size()) | ||
58 | continue; | ||
59 | // check equal string | ||
60 | if(input == name) | ||
61 | { | ||
62 | state = Acceptable; | ||
63 | val = value.value; | ||
64 | break; | ||
65 | } | ||
66 | // check substring | ||
67 | if(name.startsWith(input)) | ||
68 | state = Intermediate; | ||
69 | } | ||
70 | // early return for exact match | ||
71 | if(state == Acceptable) | ||
72 | return state; | ||
73 | // do a few special cases for convenience | ||
74 | if(input.compare("0x", Qt::CaseInsensitive) == 0 || | ||
75 | input.compare("0b", Qt::CaseInsensitive) == 0) | ||
76 | return Intermediate; | ||
77 | // try by parsing | ||
78 | unsigned basis, pos; | ||
79 | if(input.size() >= 2 && input.startsWith("0x", Qt::CaseInsensitive)) | ||
80 | { | ||
81 | basis = 16; | ||
82 | pos = 2; | ||
83 | } | ||
84 | else if(input.size() >= 2 && input.startsWith("0b", Qt::CaseInsensitive)) | ||
85 | { | ||
86 | basis = 2; | ||
87 | pos = 2; | ||
88 | } | ||
89 | else if(input.size() >= 2 && input.startsWith("0")) | ||
90 | { | ||
91 | basis = 8; | ||
92 | pos = 1; | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | basis = 10; | ||
97 | pos = 0; | ||
98 | } | ||
99 | bool ok = false; | ||
100 | unsigned long v = input.mid(pos).toULong(&ok, basis); | ||
101 | // if not ok, return result of name parsing | ||
102 | if(!ok) | ||
103 | return state; | ||
104 | // if ok, check if it fits in the number of bits | ||
105 | unsigned nr_bits = m_field.last_bit - m_field.first_bit + 1; | ||
106 | unsigned long max = nr_bits == 32 ? 0xffffffff : (1 << nr_bits) - 1; | ||
107 | if(v <= max) | ||
108 | { | ||
109 | val = v; | ||
110 | return Acceptable; | ||
111 | } | ||
112 | |||
113 | return state; | ||
31 | } | 114 | } |
32 | 115 | ||
33 | RegTab::RegTab(Backend *backend) | 116 | RegTab::RegTab(Backend *backend) |
@@ -167,6 +250,7 @@ void RegTab::OnDataSelChanged(int index) | |||
167 | OnDataSocActivated(m_io_backend->GetSocName()); | 250 | OnDataSocActivated(m_io_backend->GetSocName()); |
168 | } | 251 | } |
169 | Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); | 252 | Settings::Get()->setValue("regtab/loaddatadir", fd->directory().absolutePath()); |
253 | SetReadOnlyIndicator(); | ||
170 | } | 254 | } |
171 | #ifdef HAVE_HWSTUB | 255 | #ifdef HAVE_HWSTUB |
172 | else if(var == DataSelDevice) | 256 | else if(var == DataSelDevice) |
@@ -189,6 +273,10 @@ void RegTab::OnDataSelChanged(int index) | |||
189 | OnDataChanged(); | 273 | OnDataChanged(); |
190 | } | 274 | } |
191 | 275 | ||
276 | void RegTab::SetReadOnlyIndicator() | ||
277 | { | ||
278 | } | ||
279 | |||
192 | void RegTab::OnDataChanged() | 280 | void RegTab::OnDataChanged() |
193 | { | 281 | { |
194 | OnRegItemChanged(m_reg_tree->currentItem(), m_reg_tree->currentItem()); | 282 | OnRegItemChanged(m_reg_tree->currentItem(), m_reg_tree->currentItem()); |
@@ -230,6 +318,8 @@ void RegTab::DisplayRegister(const SocRegRef& ref) | |||
230 | { | 318 | { |
231 | delete m_right_content; | 319 | delete m_right_content; |
232 | 320 | ||
321 | bool read_only = m_io_backend->IsReadOnly(); | ||
322 | |||
233 | QVBoxLayout *right_layout = new QVBoxLayout; | 323 | QVBoxLayout *right_layout = new QVBoxLayout; |
234 | 324 | ||
235 | const soc_dev_addr_t& dev_addr = ref.GetDevAddr(); | 325 | const soc_dev_addr_t& dev_addr = ref.GetDevAddr(); |
@@ -286,9 +376,11 @@ void RegTab::DisplayRegister(const SocRegRef& ref) | |||
286 | QLabel *raw_val_name = new QLabel; | 376 | QLabel *raw_val_name = new QLabel; |
287 | raw_val_name->setText("Raw value:"); | 377 | raw_val_name->setText("Raw value:"); |
288 | QLineEdit *raw_val_edit = new QLineEdit; | 378 | QLineEdit *raw_val_edit = new QLineEdit; |
289 | raw_val_edit->setReadOnly(true); | 379 | raw_val_edit->setReadOnly(read_only); |
290 | raw_val_edit->setText(QString().sprintf("0x%08x", value)); | 380 | raw_val_edit->setText(QString().sprintf("0x%08x", value)); |
291 | raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); | 381 | raw_val_edit->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
382 | raw_val_edit->setValidator(new SocFieldValidator(raw_val_edit)); | ||
383 | connect(raw_val_edit, SIGNAL(returnPressed()), this, SLOT(OnRawRegValueReturnPressed())); | ||
292 | raw_val_layout = new QHBoxLayout; | 384 | raw_val_layout = new QHBoxLayout; |
293 | raw_val_layout->addStretch(); | 385 | raw_val_layout->addStretch(); |
294 | raw_val_layout->addWidget(raw_val_name); | 386 | raw_val_layout->addWidget(raw_val_name); |
@@ -445,3 +537,12 @@ void RegTab::OnSocChanged(const QString& soc) | |||
445 | FillRegTree(); | 537 | FillRegTree(); |
446 | FillAnalyserList(); | 538 | FillAnalyserList(); |
447 | } | 539 | } |
540 | |||
541 | void RegTab::OnRawRegValueReturnPressed() | ||
542 | { | ||
543 | QObject *obj = sender(); | ||
544 | QLineEdit *edit = dynamic_cast< QLineEdit* >(obj); | ||
545 | const SocFieldValidator *validator = dynamic_cast< const SocFieldValidator* >(edit->validator()); | ||
546 | soc_word_t val; | ||
547 | QValidator::State state = validator->parse(edit->text(), val); | ||
548 | } | ||