diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/pic16/graph.c | |
| download | sdcc-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.c | 180 |
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; +} |
