VarObj: Handle link lists.

This commit is contained in:
Ernie Pasveer
2022-08-28 14:03:10 -05:00
parent 572bd18a94
commit b1a076d967
12 changed files with 350 additions and 94 deletions
+2
View File
@@ -98,6 +98,7 @@ set(HEADER_FILES
QIndexTreeWidget.h
QStringPair.h
QHistoryLineEdit.h
QEditDelegate.h
)
set(SOURCE_FILES
@@ -178,6 +179,7 @@ set(SOURCE_FILES
QClearLineEdit.cpp
QIndexTreeWidget.cpp
QHistoryLineEdit.cpp
QEditDelegate.cpp
)
qt5_add_resources(SOURCE_FILES resource.qrc)
+31
View File
@@ -0,0 +1,31 @@
#include "QEditDelegate.h"
//
// QAllowEditDelegate enables a custom editor for a QTreeView column.
//
QAllowEditDelegate::QAllowEditDelegate(QObject* parent) : QStyledItemDelegate(parent) {
}
void QAllowEditDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
QStyledItemDelegate::setModelData(editor, model, index);
emit editingFinished(index);
}
//
// QNoEditDelegate disables editing in a QTreeView for a column.
// It does this by returning a 'null' editor when QTreeView calls QStyledItemDelegate::createEditor() for the cell.
//
QNoEditDelegate::QNoEditDelegate(QObject* parent) : QStyledItemDelegate(parent) {
}
QWidget* QNoEditDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
Q_UNUSED(parent);
Q_UNUSED(option);
Q_UNUSED(index);
return 0;
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include <QtWidgets/QItemDelegate>
#include <QtWidgets/QStyledItemDelegate>
#include <QtCore/QModelIndex>
class QAllowEditDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
QAllowEditDelegate(QObject* parent = nullptr);
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;
signals:
void editingFinished (const QModelIndex& ) const;
};
class QNoEditDelegate : public QStyledItemDelegate {
public:
QNoEditDelegate(QObject* parent = nullptr);
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const;
};
+10
View File
@@ -1545,6 +1545,15 @@ void SeerGdbWidget::handleGdbVarObjUpdate (int expressionid, QString objname) {
handleGdbCommand(QString("%1-var-update --all-values \"%2\"").arg(expressionid).arg(objname));
}
void SeerGdbWidget::handleGdbVarObjAssign (int expressionid, QString objname, QString value) {
if (executableLaunchMode() == "") {
return;
}
handleGdbCommand(QString("%1-var-assign \"%2\" %3").arg(expressionid).arg(objname).arg(value));
}
void SeerGdbWidget::handleGdbVarObjDelete (int expressionid, QString objname) {
if (executableLaunchMode() == "") {
@@ -1758,6 +1767,7 @@ void SeerGdbWidget::handleGdbVarAddExpression (QString expression) {
QObject::connect(w, &SeerVarVisualizerWidget::varObjCreate, this, &SeerGdbWidget::handleGdbVarObjCreate);
QObject::connect(w, &SeerVarVisualizerWidget::varObjListChildren, this, &SeerGdbWidget::handleGdbVarObjListChildren);
QObject::connect(w, &SeerVarVisualizerWidget::varObjUpdate, this, &SeerGdbWidget::handleGdbVarObjUpdate);
QObject::connect(w, &SeerVarVisualizerWidget::varObjAssign, this, &SeerGdbWidget::handleGdbVarObjAssign);
QObject::connect(w, &SeerVarVisualizerWidget::varObjDelete, this, &SeerGdbWidget::handleGdbVarObjDelete);
QObject::connect(w, &SeerVarVisualizerWidget::addMemoryVisualize, this, &SeerGdbWidget::handleGdbMemoryAddExpression);
QObject::connect(w, &SeerVarVisualizerWidget::addArrayVisualize, this, &SeerGdbWidget::handleGdbArrayAddExpression);
+1
View File
@@ -209,6 +209,7 @@ class SeerGdbWidget : public QWidget, protected Ui::SeerGdbWidgetForm {
void handleGdbVarObjCreate (int expressionid, QString expression);
void handleGdbVarObjListChildren (int expressionid, QString objname);
void handleGdbVarObjUpdate (int expressionid, QString objname);
void handleGdbVarObjAssign (int expressionid, QString objname, QString value);
void handleGdbVarObjDelete (int expressionid, QString objname);
void handleGdbDataListValues ();
void handleGdbDataListExpressions ();
+6 -7
View File
@@ -1,6 +1,7 @@
#include "SeerRegisterValuesBrowserWidget.h"
#include "SeerRegisterEditValueDialog.h"
#include "SeerUtl.h"
#include "QEditDelegate.h"
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItemIterator>
#include <QtWidgets/QApplication>
@@ -31,17 +32,17 @@ SeerRegisterValuesBrowserWidget::SeerRegisterValuesBrowserWidget (QWidget* paren
registerFormatComboBox->addItem("Raw", QVariant("r"));
// Create edit delegate.
MyEditingDelegate* editDelegate = new MyEditingDelegate(this);
QAllowEditDelegate* editDelegate = new QAllowEditDelegate(this);
registersTreeWidget->setItemDelegateForColumn(0, new MyNoEditDelegate(this));
registersTreeWidget->setItemDelegateForColumn(1, new MyNoEditDelegate(this));
registersTreeWidget->setItemDelegateForColumn(0, new QNoEditDelegate(this));
registersTreeWidget->setItemDelegateForColumn(1, new QNoEditDelegate(this));
registersTreeWidget->setItemDelegateForColumn(2, editDelegate);
registersTreeWidget->setItemDelegateForColumn(3, new MyNoEditDelegate(this));
registersTreeWidget->setItemDelegateForColumn(3, new QNoEditDelegate(this));
// Connect things.
QObject::connect(registersTreeWidget, &QTreeWidget::itemEntered, this, &SeerRegisterValuesBrowserWidget::handleItemEntered);
QObject::connect(registersTreeWidget, &QTreeWidget::customContextMenuRequested, this, &SeerRegisterValuesBrowserWidget::handleContextMenu);
QObject::connect(editDelegate, &MyEditingDelegate::editingFinished, this, &SeerRegisterValuesBrowserWidget::handleIndexEditingFinished);
QObject::connect(editDelegate, &QAllowEditDelegate::editingFinished, this, &SeerRegisterValuesBrowserWidget::handleIndexEditingFinished);
QObject::connect(registerFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SeerRegisterValuesBrowserWidget::handleFormatChanged);
}
@@ -208,8 +209,6 @@ void SeerRegisterValuesBrowserWidget::handleItemEntered (QTreeWidgetItem* item,
Q_UNUSED(column);
//qDebug() << item->text(0) << column;
item->setToolTip(0, item->text(1) + " : " + item->text(2));
for (int i=1; i<registersTreeWidget->columnCount(); i++) { // Copy tooltip to other columns.
-34
View File
@@ -2,43 +2,9 @@
#include "ui_SeerRegisterValuesBrowserWidget.h"
#include <QtWidgets/QWidget>
#include <QtWidgets/QItemDelegate>
#include <QtWidgets/QStyledItemDelegate>
#include <QtCore/QString>
#include <QtCore/QDebug>
class MyEditingDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
MyEditingDelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}
virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const {
QStyledItemDelegate::setModelData(editor, model, index);
emit editingFinished(index);
}
signals:
void editingFinished(const QModelIndex& ) const;
};
class MyNoEditDelegate: public QStyledItemDelegate {
public:
MyNoEditDelegate(QObject* parent = nullptr): QStyledItemDelegate(parent) {}
virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const {
Q_UNUSED(parent);
Q_UNUSED(option);
Q_UNUSED(index);
return 0;
}
};
class SeerRegisterValuesBrowserWidget : public QWidget, protected Ui::SeerRegisterValuesBrowserWidgetForm {
Q_OBJECT
+85 -22
View File
@@ -1,5 +1,6 @@
#include "SeerVarVisualizerWidget.h"
#include "SeerUtl.h"
#include "QEditDelegate.h"
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItemIterator>
#include <QtWidgets/QMenu>
@@ -24,10 +25,9 @@ SeerVarVisualizerWidget::SeerVarVisualizerWidget (QWidget* parent) : QWidget(par
setAttribute(Qt::WA_DeleteOnClose);
variableNameLineEdit->setFocus();
variableTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
variableTreeWidget->setMouseTracking(true);
variableTreeWidget->setSortingEnabled(false);
variableTreeWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
variableTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
variableTreeWidget->setRootIsDecorated(true);
variableTreeWidget->setItemsExpandable(true);
variableTreeWidget->resizeColumnToContents(0); // variable
@@ -40,21 +40,38 @@ SeerVarVisualizerWidget::SeerVarVisualizerWidget (QWidget* parent) : QWidget(par
variableTreeWidget->resizeColumnToContents(7); // has_more
variableTreeWidget->clear();
detailedCheckBox->setChecked(false);
debugCheckBox->setChecked(false);
// Create edit delegate.
// The value column will allow editing of the cell. However, some cells can then
// individually disable it again. ie: If the cell is for a node, not a value.
// See 'new QTreeWidgetItem'
QAllowEditDelegate* editDelegate = new QAllowEditDelegate(this);
variableTreeWidget->setItemDelegateForColumn(0, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(1, editDelegate);
variableTreeWidget->setItemDelegateForColumn(2, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(3, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(4, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(5, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(6, new QNoEditDelegate(this));
variableTreeWidget->setItemDelegateForColumn(6, new QNoEditDelegate(this));
// Connect things.
QObject::connect(expandAllToolButton, &QToolButton::clicked, this, &SeerVarVisualizerWidget::handleExpandAllButton);
QObject::connect(collapseAllToolButton, &QToolButton::clicked, this, &SeerVarVisualizerWidget::handleCollapseAllButton);
QObject::connect(refreshToolButton, &QToolButton::clicked, this, &SeerVarVisualizerWidget::handleRefreshButton);
QObject::connect(detailedCheckBox, &QCheckBox::clicked, this, &SeerVarVisualizerWidget::handleDetailedCheckBox);
QObject::connect(debugCheckBox, &QCheckBox::clicked, this, &SeerVarVisualizerWidget::handleDebugCheckBox);
QObject::connect(variableNameLineEdit, &QLineEdit::returnPressed, this, &SeerVarVisualizerWidget::handleVariableNameLineEdit);
QObject::connect(variableTreeWidget, &QTreeWidget::customContextMenuRequested, this, &SeerVarVisualizerWidget::handleContextMenu);
QObject::connect(variableTreeWidget, &QTreeWidget::itemEntered, this, &SeerVarVisualizerWidget::handleItemEntered);
QObject::connect(variableTreeWidget, &QTreeWidget::itemExpanded, this, &SeerVarVisualizerWidget::handleItemExpanded);
QObject::connect(variableTreeWidget, &QTreeWidget::itemCollapsed, this, &SeerVarVisualizerWidget::handleItemExpanded);
QObject::connect(editDelegate, &QAllowEditDelegate::editingFinished, this, &SeerVarVisualizerWidget::handleIndexEditingFinished);
// Show/hide columns.
handleDetailedCheckBox();
handleDebugCheckBox();
// Restore window settings.
readSettings();
@@ -87,6 +104,7 @@ void SeerVarVisualizerWidget::setVariableName (const QString& name) {
if (variableNameLineEdit->text() != "") {
QTreeWidgetItem* item = new QTreeWidgetItem;
item->setText(0, name);
item->setText(1, "");
item->setText(2, "");
@@ -119,12 +137,12 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
// "4^done,name=\"seer4\",numchild=\"1\",value=\"{...}\",type=\"Person\",thread-id=\"1\",has_more=\"0\""
// qDebug() << text;
QString id_text = text.section('^', 0,0);
if (id_text.toInt() == _variableId) {
//qDebug() << text;
QString name_text = Seer::parseFirst(text, "name=", '"', '"', false);
QString exp_text = Seer::parseFirst(text, "exp=", '"', '"', false);
QString numchild_text = Seer::parseFirst(text, "numchild=", '"', '"', false);
@@ -150,12 +168,26 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
topItem->setText(0, exp_text);
}
// Allow editing if the item has no children and has a value.
if (numchild_text == "0" && value_text != "") {
topItem->setFlags(topItem->flags() | Qt::ItemIsEditable);
}
// For now, always expand everything.
variableTreeWidget->expandAll();
// If there are children, get them.
//if (numchild_text != "0") {
// emit varObjListChildren(_variableId, name_text);
//}
if (numchild_text != "0") {
emit varObjListChildren(_variableId, name_text);
if (type_text.endsWith('*') && Seer::filterEscapes(value_text) == "0x0") {
// If it is a pointer that is not null, get the children.
// How universal is this for other languages?
}else{
emit varObjListChildren(_variableId, name_text);
}
}
// Save the VarObj name.
@@ -170,12 +202,12 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
// ],
// has_more="0"
// qDebug() << text;
QString id_text = text.section('^', 0,0);
if (id_text.toInt() == _variableId) {
//qDebug() << text;
QString children_text = Seer::parseFirst(text, "children=", '[', ']', false);
QStringList child_list = Seer::parse(children_text, "child=", '{', '}', false);
QString hasmore_text = Seer::parseFirst(text, "has_more=", '"', '"', false);
@@ -192,7 +224,6 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
// Do we have an existing item to add to?
QList<QTreeWidgetItem*> matches = variableTreeWidget->findItems(Seer::varObjParent(name_text), Qt::MatchExactly|Qt::MatchRecursive, 3);
// No, just add to the top level.
if (matches.size() == 0) {
@@ -219,14 +250,27 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
item->setText(0, exp_text);
}
// Allow editing if the item has no children and has a value.
if (numchild_text == "0" && value_text != "") {
item->setFlags(item->flags() | Qt::ItemIsEditable);
}
topItem->addChild(item);
}
// If there are children, get them.
if (numchild_text != "0") {
emit varObjListChildren(_variableId, name_text);
if (type_text.endsWith('*') && Seer::filterEscapes(value_text) == "0x0") {
// If it is a pointer that is not null, get the children.
// How universal is this for other languages?
}else{
emit varObjListChildren(_variableId, name_text);
}
}
}
// For now, always expand everything.
variableTreeWidget->expandAll();
}
@@ -241,12 +285,12 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
// {name=\"seer4.public.location.public.zip\", value=\"77063\", in_scope=\"true\", type_changed=\"false\", has_more=\"0\"}
// ]"
// qDebug() << text;
QString id_text = text.section('^', 0,0);
if (id_text.toInt() == _variableId) {
//qDebug() << text;
QString changelist_text = Seer::parseFirst(text, "changelist=", '[', ']', false);
QStringList child_list = Seer::parse(changelist_text, "", '{', '}', false);
@@ -260,9 +304,9 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
QString dynamic_text = Seer::parseFirst(child_text, "dynamic=", '"', '"', false);
QString hasmore_text = Seer::parseFirst(child_text, "has_more=", '"', '"', false);
// Do we have an existing item to add to?
QList<QTreeWidgetItem*> matches = variableTreeWidget->findItems(name_text, Qt::MatchExactly|Qt::MatchRecursive, 0);
// Do we have an existing item to add to?
QList<QTreeWidgetItem*> matches = variableTreeWidget->findItems(name_text, Qt::MatchExactly|Qt::MatchRecursive, 3);
// No, just add to the top level.
if (matches.size() == 0) {
@@ -276,6 +320,10 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
item->setText(1, Seer::filterEscapes(value_text));
item->setText(7, hasmore_text);
if (typechanged_text == "true") {
handleRefreshButton();
}
}
}
}
@@ -283,7 +331,7 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
}else if (text.contains(QRegExp("^([0-9]+)\\^error,msg="))) {
qDebug() << text;
//qDebug() << text;
QString id_text = text.section('^', 0,0);
QString msg_text = Seer::parseFirst(text, "msg=", '"', '"', false);
@@ -299,8 +347,8 @@ void SeerVarVisualizerWidget::handleText (const QString& text) {
foreach (auto item, topItem->takeChildren()) delete item;
// Set the error text.
topItem->setText(3, "");
topItem->setText(4, Seer::filterEscapes(msg_text));
topItem->setText(1, "");
topItem->setText(2, Seer::filterEscapes(msg_text));
}
@@ -582,7 +630,7 @@ void SeerVarVisualizerWidget::handleResizeColumns () {
variableTreeWidget->resizeColumnToContents(7);
}
void SeerVarVisualizerWidget::handleHideDetailedColumns (bool flag) {
void SeerVarVisualizerWidget::handleHideDebugColumns (bool flag) {
variableTreeWidget->setColumnHidden(0, false);
variableTreeWidget->setColumnHidden(1, false);
@@ -620,9 +668,9 @@ void SeerVarVisualizerWidget::handleRefreshButton () {
}
}
void SeerVarVisualizerWidget::handleDetailedCheckBox () {
void SeerVarVisualizerWidget::handleDebugCheckBox () {
handleHideDetailedColumns(!detailedCheckBox->isChecked());
handleHideDebugColumns(!debugCheckBox->isChecked());
}
void SeerVarVisualizerWidget::handleVariableNameLineEdit () {
@@ -634,6 +682,21 @@ void SeerVarVisualizerWidget::handleVariableNameLineEdit () {
setVariableName (variableNameLineEdit->text());
}
void SeerVarVisualizerWidget::handleIndexEditingFinished (const QModelIndex& index) {
QTreeWidgetItem* item = variableTreeWidget->getItemFromIndex(index);
if (item == 0) {
return;
}
// Get the new value;
QString value = item->text(1);
// Emit the signal to change the varobj to the new value.
emit varObjAssign(_variableId, item->text(3), value);
}
void SeerVarVisualizerWidget::writeSettings () {
QSettings settings;
+4 -2
View File
@@ -19,6 +19,7 @@ class SeerVarVisualizerWidget : public QWidget, protected Ui::SeerVarVisualizerW
void varObjListChildren (int expressionid, QString objname);
void varObjUpdate (int expressionid, QString objname);
void varObjDelete (int expressionid, QString objname);
void varObjAssign (int expressionid, QString objname, QString value);
void addMemoryVisualize (QString expression);
void addArrayVisualize (QString expression);
void addStructVisualize (QString expression);
@@ -30,13 +31,14 @@ class SeerVarVisualizerWidget : public QWidget, protected Ui::SeerVarVisualizerW
void handleExpandAllButton ();
void handleCollapseAllButton ();
void handleRefreshButton ();
void handleDetailedCheckBox ();
void handleDebugCheckBox ();
void handleVariableNameLineEdit ();
void handleIndexEditingFinished (const QModelIndex& index);
void handleContextMenu (const QPoint& pos);
void handleItemEntered (QTreeWidgetItem* item, int column);
void handleItemExpanded (QTreeWidgetItem* item);
void handleResizeColumns ();
void handleHideDetailedColumns (bool flag);
void handleHideDebugColumns (bool flag);
protected:
void writeSettings ();
+10 -3
View File
@@ -38,17 +38,17 @@
</widget>
</item>
<item row="0" column="6">
<widget class="QCheckBox" name="detailedCheckBox">
<widget class="QCheckBox" name="debugCheckBox">
<property name="toolTip">
<string>Show more variable details.</string>
</property>
<property name="text">
<string>Detailed</string>
<string>Debug</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="8">
<widget class="QTreeWidget" name="variableTreeWidget">
<widget class="QIndexTreeWidget" name="variableTreeWidget">
<column>
<property name="text">
<string>Variable</string>
@@ -151,12 +151,19 @@
<extends>QLineEdit</extends>
<header location="global">QHistoryLineEdit.h</header>
</customwidget>
<customwidget>
<class>QIndexTreeWidget</class>
<extends>QTreeWidget</extends>
<header location="global">QIndexTreeWidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>variableNameLineEdit</tabstop>
<tabstop>expandAllToolButton</tabstop>
<tabstop>collapseAllToolButton</tabstop>
<tabstop>refreshToolButton</tabstop>
<tabstop>autoRefreshCheckBox</tabstop>
<tabstop>debugCheckBox</tabstop>
<tabstop>variableTreeWidget</tabstop>
</tabstops>
<resources>
+81
View File
@@ -0,0 +1,81 @@
"4^done,name="seer4",
numchild="1",
value="{...}",
type="Node",
thread-id="1",
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.data",exp="data",numchild="0",value="1",type="int",thread-id="1"},
child={name="seer4.public.next",exp="next",numchild="1",value="0x613c40",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.next.public.data",exp="data",numchild="0",value="2",type="int",thread-id="1"},
child={name="seer4.public.next.public.next",exp="next",numchild="1",value="0x613c60",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.next.public.next.public.data",exp="data",numchild="0",value="3",type="int",thread-id="1"},
child={name="seer4.public.next.public.next.public.next",exp="next",numchild="1",value="0x0",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public.next.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.next.public.next.public.next.public.data",exp="data",numchild="0",value="",type="int",thread-id="1"},
child={name="seer4.public.next.public.next.public.next.public.next",exp="next",numchild="1",value="",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public.next.public.next.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.next.public.next.public.next.public.next.public.data",exp="data",numchild="0",value="",type="int",thread-id="1"},
child={name="seer4.public.next.public.next.public.next.public.next.public.next",exp="next",numchild="1",value="",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public.next.public.next.public.next.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
"4^done,numchild="2",
children=[
child={name="seer4.public.next.public.next.public.next.public.next.public.next.public.data",exp="data",numchild="0",value="",type="int",thread-id="1"},
child={name="seer4.public.next.public.next.public.next.public.next.public.next.public.next",exp="next",numchild="1",value="",type="Node *",thread-id="1"}
],
has_more="0""
"4^done,numchild="1",
children=[
child={name="seer4.public.next.public.next.public.next.public.next.public.next.public.next.public",exp="public",numchild="2",value="",thread-id="1"}
],
has_more="0""
+93 -26
View File
@@ -2,38 +2,105 @@
#include <iostream>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
// https://www.geeksforgeeks.org/linked-list-set-1-introduction/
//
// C program to implement a linked list
//
struct Location {
std::string city;
std::string state;
int zip;
struct Node {
int data;
struct Node* next;
};
struct Person {
std::string name;
int age;
float salary;
struct Location* location;
};
// Driver's code
int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;
// allocate 3 nodes in the heap
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
/* Three blocks have been allocated dynamically.
We have pointers to these three blocks as head,
second and third
head second third
| | |
| | |
+---+-----+ +----+----+ +----+----+
| # | # | | # | # | | # | # |
+---+-----+ +----+----+ +----+----+
# represents any random value.
Data is random because we havent assigned
anything yet
*/
head->data = 1; // assign data in first node
head->next = second; // Link first node with
// the second node
/* data has been assigned to the data part of the first
block (block pointed by the head). And next
pointer of first block points to second.
So they both are linked.
head second third
| | |
| | |
+---+---+ +----+----+ +-----+----+
| 1 | o----->| # | # | | # | # |
+---+---+ +----+----+ +-----+----+
*/
// assign data to second node
second->data = 2;
// Link second node with the third node
second->next = third;
/* data has been assigned to the data part of the second
block (block pointed by second). And next
pointer of the second block points to the third
block. So all three blocks are linked.
head second third
| | |
| | |
+---+---+ +---+---+ +----+----+
| 1 | o----->| 2 | o-----> | # | # |
+---+---+ +---+---+ +----+----+
*/
third->data = 3; // assign data to third node
third->next = NULL;
/* data has been assigned to data part of third
block (block pointed by third). And next pointer
of the third block is made NULL to indicate
that the linked list is terminated here.
We have the linked list ready.
head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | NULL |
+---+---+ +---+---+ +----+------+
int main (int argc, char** argv) {
Person me;
me.name = "Pasveer, Ernie";
me.age = 60;
me.salary = 0.25;
//me.location = (struct Location*)malloc(sizeof(struct Location));
me.location = new Location;
me.location->city = "Houston";
me.location->state = "Texas";
me.location->zip = 77063;
std::cout << "'" << me.name << "', from '" << me.location->city << "', is " << me.age << " years old and makes " << me.salary << " per year." << std::endl;
Note that only head is sufficient to represent
the whole list. We can traverse the complete
list by following next pointers.
*/
return 0;
}