From 299055de1284a2020af60b38862361961f1ace7e Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Mon, 20 Jun 2022 11:43:24 +1100
Subject: [PATCH] add graph_build_service and
 graph_build_service_bytree_from_src function

---
 src/lib66/graph/graph_build_service.c         |  70 ++++++++++
 .../graph_build_service_bytree_from_src.c     | 124 ++++++++++++++++++
 2 files changed, 194 insertions(+)
 create mode 100644 src/lib66/graph/graph_build_service.c
 create mode 100644 src/lib66/graph/graph_build_service_bytree_from_src.c

diff --git a/src/lib66/graph/graph_build_service.c b/src/lib66/graph/graph_build_service.c
new file mode 100644
index 00000000..3900d006
--- /dev/null
+++ b/src/lib66/graph/graph_build_service.c
@@ -0,0 +1,70 @@
+/*
+ * graph_build_service.c
+ *
+ * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+#include <oblibs/sastr.h>
+
+#include <skalibs/stralloc.h>
+
+#include <66/constants.h>
+#include <66/tree.h>
+#include <66/resolve.h>
+#include <66/graph.h>
+
+/**
+ * @general has only effect for DATA_SERVICE type
+ * !general -> all services from @treename
+ * general -> all services from all trees of the system
+ *
+ * */
+int graph_build_service(graph_t *g, char const *base, char const *treename, uint8_t general)
+{
+    log_flow() ;
+
+    int e = 0 ;
+    size_t pos = 0, baselen = strlen(base) ;
+    stralloc sa = STRALLOC_ZERO ;
+
+    char solve[baselen + SS_SYSTEM_LEN + 1 + SS_MAX_TREENAME + SS_SVDIRS_LEN + 1] ;
+
+    if (general) {
+
+        if (!resolve_get_field_tosa_g(&sa, base, treename, treename, DATA_TREE_MASTER, TREE_ENUM_MASTER_CONTENTS))
+            goto err ;
+
+        FOREACH_SASTR(&sa, pos) {
+
+            auto_strings(solve + baselen + SS_SYSTEM_LEN + 1, sa.s + pos, SS_SVDIRS) ;
+
+            if (!graph_build_service_bytree(g, solve, 2))
+                goto err ;
+        }
+
+    } else {
+
+        auto_strings(solve, base, SS_SYSTEM, "/", treename, SS_SVDIRS) ;
+
+        if (!graph_build_service_bytree(g, solve, 2))
+                goto err ;
+    }
+
+    e = 1 ;
+    err:
+        stralloc_free(&sa) ;
+        return e ;
+}
diff --git a/src/lib66/graph/graph_build_service_bytree_from_src.c b/src/lib66/graph/graph_build_service_bytree_from_src.c
new file mode 100644
index 00000000..1b86df23
--- /dev/null
+++ b/src/lib66/graph/graph_build_service_bytree_from_src.c
@@ -0,0 +1,124 @@
+/*
+ * graph_build_service_bytree_from_src.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+#include <oblibs/sastr.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/constants.h>
+#include <66/enum.h>
+#include <66/graph.h>
+
+/** @tsrc: absolute path of the tree including SS_SVDIRS
+ * what = 0 -> classic
+ * what = 1 -> atomic and bundle
+ * what > 1 -> module */
+int graph_build_service_bytree_from_src(graph_t *g, char const *src, uint8_t what)
+{
+    log_flow() ;
+
+    int e = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+    resolve_service_t res = RESOLVE_SERVICE_ZERO ;
+    resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
+
+    size_t srclen = strlen(src), pos = 0 ;
+    char solve[srclen + SS_RESOLVE_LEN + 1] ;
+
+    auto_strings(solve, src, SS_RESOLVE) ;
+
+    char const *exclude[2] = { SS_MASTER + 1, 0 } ;
+
+    if (!sastr_dir_get(&sa,solve,exclude,S_IFREG))
+        goto err ;
+
+    solve[srclen] = 0 ;
+
+    /** can be needed for 66-inservice and 66-intree.
+     * TODO: try to avoid it
+     * */
+    if (!service_resolve_sort_bytype(&sa, solve))
+        goto err ;
+
+    FOREACH_SASTR(&sa, pos) {
+
+        char *service = sa.s + pos ;
+
+        if (!resolve_read(wres, solve, service))
+            goto err ;
+
+        char *str = res.sa.s ;
+
+        if (!graph_vertex_add(g, service)) {
+            log_warnu("add vertex: ", service) ;
+            goto err ;
+        }
+
+        if (res.ndepends) {
+
+            if (res.type == TYPE_MODULE || res.type == TYPE_BUNDLE) {
+
+                uint32_t depends = res.type == TYPE_MODULE ? what > 1 ? res.contents : res.depends : res.depends ;
+
+                if (!graph_add_deps(g, service, str + depends, 0)) {
+                    log_warnu("add dependencies of service: ",service) ;
+                    goto err ;
+                }
+
+            } else {
+
+                if (!graph_add_deps(g, service,str + res.depends, 0)) {
+                    log_warnu("add dependencies of service: ",service) ;
+                    goto err ;
+                }
+            }
+        }
+
+        if (res.nrequiredby) {
+
+            if (!graph_add_deps(g, service, str + res.requiredby, 1)) {
+                log_warnu("add requiredby of service: ", service) ;
+                goto err ;
+            }
+        }
+    }
+
+    if (!graph_matrix_build(g)) {
+        log_warnu("build the graph") ;
+        goto err ;
+    }
+
+    if (!graph_matrix_analyze_cycle(g)) {
+        log_warn("found cycle") ;
+        goto err ;
+    }
+
+    if (!graph_matrix_sort(g)) {
+        log_warnu("sort the graph") ;
+        goto err ;
+    }
+
+    e = 1 ;
+
+    err:
+        resolve_free(wres) ;
+        stralloc_free(&sa) ;
+        return e ;
+}
+
-- 
GitLab