summaryrefslogtreecommitdiff
path: root/src/pic16/graph.c
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/pic16/graph.c
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/pic16/graph.c')
-rw-r--r--src/pic16/graph.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/src/pic16/graph.c b/src/pic16/graph.c
new file mode 100644
index 0000000..be59017
--- /dev/null
+++ b/src/pic16/graph.c
@@ -0,0 +1,180 @@
+/*-------------------------------------------------------------------------
+
+ graph.c - implementation of general graphs
+
+ Written By - Raphael Neider <rneider AT web.de> (2005)
+
+ This program 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 2, or (at your option) any
+ later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+-------------------------------------------------------------------------*/
+
+/* $Id: graph.c 9490 2016-01-31 11:44:32Z molnarkaroly $ */
+
+#include "graph.h"
+
+/* === helpers ====================================================== */
+
+int default_compare (void *data1, void *data2)
+{
+ return (data1 == data2);
+}
+
+/* === GraphEdge ==================================================== */
+
+GraphEdge *newGEdge (GraphNode *src, GraphNode *dest, unsigned int weight) {
+ GraphEdge *edge = (GraphEdge *)Safe_alloc(sizeof(GraphEdge));
+ edge->src = src;
+ edge->node = dest;
+ edge->weight = weight;
+ return edge;
+}
+
+GraphEdge *deleteGEdge (GraphEdge *edge) {
+ GraphEdge *head;
+ // remove edge from list
+ if (edge->next) edge->next->prev = edge->prev;
+ if (edge->prev) edge->prev->next = edge->next;
+
+ if (edge->prev) head = edge->prev; else head = edge->next;
+ Safe_free (edge);
+ return head;
+}
+
+/* === GraphNode ==================================================== */
+
+GraphNode *newGNode (void *data, hash_t hash) {
+ GraphNode *node = (GraphNode*)Safe_alloc(sizeof(GraphNode));
+ node->data = data;
+ node->hash = hash;
+ return node;
+}
+
+GraphNode * deleteGNode (GraphNode *node) {
+ GraphNode *head;
+
+ if (!node) return NULL;
+
+ // delete all edges
+ while (node->edge) {
+ node->edge = deleteGEdge (node->edge);
+ } // while
+
+ // remove node from list
+ if (node->next) node->next->prev = node->prev;
+ if (node->prev) node->prev->next = node->next;
+
+ if (node->prev) head = node->prev; else head = node->next;
+ Safe_free (node);
+ return head;
+}
+
+GraphEdge *addGEdge (GraphNode *from, GraphNode *to, unsigned int weight) {
+ GraphEdge *edge = getGEdge (from, to);
+ if (edge == NULL) {
+ edge = newGEdge (from, to, weight);
+ // insert edge into list
+ if (from->edge) from->edge->prev = edge;
+ edge->next = from->edge;
+ from->edge = edge;
+ } else
+ edge->weight += weight;
+
+ assert (edge->src == from && edge->node == to);
+ return edge;
+}
+
+void addGEdge2 (GraphNode *from, GraphNode *to, unsigned int weight, unsigned int weight_back) {
+ addGEdge (from, to, weight);
+ addGEdge (to, from, weight_back);
+}
+
+void remGEdge (GraphNode *from, GraphNode *to) {
+ GraphEdge *curr = from->edge;
+ while (curr && curr->node != to) curr = curr->next;
+
+ if (!curr) return;
+
+ if (from->edge == curr)
+ from->edge = deleteGEdge (curr);
+ else
+ deleteGEdge (curr);
+}
+
+GraphEdge *getGEdge (GraphNode *from, GraphNode *to) {
+ GraphEdge *curr = from->edge;
+ while (curr && curr->node != to) {
+ assert (curr->src == from);
+ curr = curr->next;
+ }
+ return curr;
+}
+
+/* === Graph ======================================================== */
+
+Graph *newGraph (Graph_compareData *compare) {
+ Graph *graph = (Graph*)Safe_alloc(sizeof(Graph));
+ graph->compare = compare;
+ if (!compare) graph->compare = default_compare;
+
+ return graph;
+}
+
+void deleteGraph (Graph *graph) {
+ // remove all nodes
+ while (graph->node) {
+ graph->node = deleteGNode (graph->node);
+ } // while
+
+ Safe_free (graph);
+}
+
+GraphNode *addGNode (Graph *graph, void *data, hash_t hash) {
+ GraphNode *node = newGNode (data, hash);
+ if (graph->node) graph->node->prev = node;
+ node->next = graph->node;
+ graph->node = node;
+ return node;
+}
+
+void remGNode (Graph *graph, void *data, hash_t hash) {
+ GraphNode *curr = graph->node;
+ while (curr && ((curr->hash != hash) || (!graph->compare(curr->data, data)))) {
+ curr = curr->next;
+ } // while
+
+ if (!curr) return;
+
+ if (graph->node == curr)
+ graph->node = deleteGNode (curr);
+ else
+ deleteGNode (curr);
+}
+
+GraphNode *getGNode (Graph *graph, void *data, hash_t hash) {
+ GraphNode *curr = graph->node;
+ while (curr && ((curr->hash != hash) || (!graph->compare(curr->data, data)))) {
+ curr = curr->next;
+ } // while
+
+ return curr;
+}
+
+GraphNode *getOrAddGNode (Graph *graph, void *data, hash_t hash) {
+ GraphNode *curr = getGNode (graph, data, hash);
+ if (!curr)
+ curr = addGNode (graph, data, hash);
+
+ assert (curr != NULL);
+ return curr;
+}