diff --git a/src/include/66/66.h b/src/include/66/66.h index 80c7a54681b42888f04c63523587859cdb1e9794..661d2d7c17a9a0e633e5fdc7ef4078a77152f05c 100644 --- a/src/include/66/66.h +++ b/src/include/66/66.h @@ -20,6 +20,7 @@ #include <66/constants.h> #include <66/db.h> #include <66/enum.h> +#include <66/graph.h> #include <66/parser.h> #include <66/svc.h> #include <66/tree.h> diff --git a/src/include/66/graph.h b/src/include/66/graph.h new file mode 100644 index 0000000000000000000000000000000000000000..7577e93dc8bd5a1af3c47ba301b522b9f032181b --- /dev/null +++ b/src/include/66/graph.h @@ -0,0 +1,104 @@ +/* + * graph.h + * + * Copyright (c) 2018 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./ + */ + +#ifndef GRAPH_H +#define GRAPH_H + +extern stralloc SAGRAPH ; + +typedef enum visit_e visit ; +enum visit_e +{ + WHITE = 0, + GRAY, + BLACK +} ; + +typedef struct vertex_graph_s vertex_graph_t, *vertex_graph_t_ref ; +struct vertex_graph_s +{ + unsigned int type ; //type of the service + unsigned int idx ; //idx of the service + unsigned int name ; //pos in associated stralloc, name of the service + unsigned int ndeps ; //number of dependencies + unsigned int gaidx ; //pos of deps in genalloc dps + genalloc dps ; // type vertex_graph_t +} ; + +typedef struct graph_s graph_t, *graph_t_ref ; +struct graph_s +{ + unsigned int nvertex ; //number of vertex + unsigned int nedge ; //number of edge + char *string ; // associated stralloc + genalloc vertex ; //type vertex_graph_t + genalloc stack ; //vertex_graph_t, topological sorted +} ; + +#define VERTEX_GRAPH_ZERO { 0, 0, 0, 0, 0, GENALLOC_ZERO } +#define GRAPH_ZERO { 0, 0, 0, GENALLOC_ZERO, GENALLOC_ZERO } + +static vertex_graph_t const vertex_graph_zero = VERTEX_GRAPH_ZERO ; +static graph_t const graph_zero = GRAPH_ZERO ; + + +typedef struct tdepth_s tdepth ; +struct tdepth_s +{ + tdepth *prev; + tdepth *next; + int level; + unsigned int cndeps ; + unsigned int pndeps ; +} ; + +typedef struct graph_style_s graph_style ; +struct graph_style_s +{ + const char *tip; + const char *last; + const char *limb; + int indent; +} ; + +#define UTF_V "\342\224\202" /* U+2502, Vertical line drawing char */ +#define UTF_VR "\342\224\234" /* U+251C, Vertical and right */ +#define UTF_H "\342\224\200" /* U+2500, Horizontal */ +#define UTF_UR "\342\224\224" /* U+2514, Up and right */ + +extern unsigned int MAXDEPTH ; +extern graph_style *STYLE ; +extern graph_style graph_utf8 ; +extern graph_style graph_default ; + +/** what = 0 -> only classic + * what = 1 -> only atomic + * what = 2 -> both*/ +extern int graph_type_src(genalloc *ga,char const *tree,unsigned int what) ; + +extern int graph_build(graph_t *g, stralloc *sagraph, genalloc *tokeep,char const *tree) ; + +extern int graph_rdepends(genalloc *ga,graph_t *g, char const *name, char const *src) ; + +extern int graph_master(genalloc *ga, graph_t *g) ; + +extern int graph_sort(graph_t *g) ; + +extern int graph_search(graph_t *g, char const *name) ; + +extern int graph_tree(graph_t *g, char const *name, char const *tree) ; + +extern void stack_reverse(genalloc *st) ; + +#endif diff --git a/src/lib66/graph.c b/src/lib66/graph.c new file mode 100644 index 0000000000000000000000000000000000000000..c81852a0fde51b345913cfe300f04c83b8df727d --- /dev/null +++ b/src/lib66/graph.c @@ -0,0 +1,636 @@ +/* + * graph.c + * + * Copyright (c) 2018 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 <string.h> +#include <stdlib.h> +#include <dirent.h> + +#include <oblibs/string.h> +#include <oblibs/error2.h> +#include <oblibs/stralist.h> +#include <oblibs/strakeyval.h> +#include <oblibs/directory.h> +#include <oblibs/files.h> + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/direntry.h> +#include <skalibs/unix-transactional.h>//stat_at +#include <skalibs/lolstdio.h> + +#include <66/graph.h> +#include <66/enum.h> +#include <66/utils.h> +#include <66/constants.h> + +#include <stdio.h> + +graph_style graph_utf8 = { + UTF_VR UTF_H, + UTF_UR UTF_H, + UTF_V " ", + 2 +} ; + +graph_style graph_default = { + "|-", + "`-", + "|", + 2 +} ; + +static void print_text(const char *pkg, const char *info, tdepth *depth, int last) +{ + const char *tip = "" ; + int level = 1 ; + if(!pkg) + return ; + + if(depth->level > 0) + { + tip = last ? STYLE->last : STYLE->tip; + + while(depth->prev) + depth = depth->prev; + + + while(depth->next) + { + if (!bprintf(buffer_1," %*s%-*s",STYLE->indent * (depth->level - level), "", STYLE->indent, STYLE->limb)) return ; + level = depth->level + 1; + depth = depth->next; + } + } + + if(depth->level > 0) + { + if (!bprintf(buffer_1," %*s%s%s ",STYLE->indent * (depth->level - level),"",tip,pkg)) return ; + } + else if (!bprintf(buffer_1," %s%s ",tip,pkg)) return ; + + if(info) + if (!bprintf(buffer_1," %s%s", ":",info)) return ; + + if (buffer_putsflush(buffer_1,"\n") < 0) return ; + + +} + +static void print(const char *pkgname, const char *depname, tdepth *depth, int last) +{ + print_text(pkgname, depname, depth, last); + +} +/* +static void print_start(const char *pkgname, const char *provname) +{ + + tdepth d = { + NULL, + NULL, + 0 , + 0 , + 0 + }; + print_text(pkgname, provname, &d, 0); + +} +*/ +static void graph_walk(graph_t *g,genalloc *ga,unsigned int src,unsigned int nlen, tdepth *depth) +{ + + unsigned int last, i, newdata ; + + unsigned int stacklen = genalloc_len(vertex_graph_t,ga) ; + + if(!stacklen || ((MAXDEPTH >= 0) && (depth->level > MAXDEPTH))) + return ; + + char *string = g->string ; + + i = src ; + last = newdata = 0 ; + + for(; i < stacklen && i < nlen ; i++ ) + { + for (unsigned int d = 0 ; d < genalloc_len(vertex_graph_t,&g->stack) ; d++) + { + if (genalloc_s(vertex_graph_t,ga)[i].idx == genalloc_s(vertex_graph_t,&g->stack)[d].idx) + { + newdata = genalloc_s(vertex_graph_t,&g->stack)[d].gaidx ; + break ; + } + else + { + newdata = genalloc_s(vertex_graph_t,ga)[i].gaidx ; + } + } + + int idx = genalloc_s(vertex_graph_t,&g->vertex)[newdata].name ; + char *name = string + idx ; + char const *type = get_keybyid(genalloc_s(vertex_graph_t,&g->vertex)[newdata].type) ; + unsigned int dplen = genalloc_s(vertex_graph_t,&g->vertex)[newdata].ndeps ; + + last = i + 1 < depth->pndeps ? 0 : 1 ; + + + print(name, type, depth, last) ; + + if (dplen) + { + genalloc data = genalloc_s(vertex_graph_t,&g->vertex)[newdata].dps ; + + tdepth d = + { + depth, + NULL, + depth->level + 1 , + depth->cndeps , + dplen + + } ; + depth->next = &d; + + if(last) + { + if(depth->prev) + { + depth->prev->next = &d; + d.prev = depth->prev; + depth = &d; + depth->cndeps = 0 ; + + } + else + d.prev = NULL; + } + + graph_walk(g,&data,0,dplen,&d); + depth->next = NULL; + depth->cndeps = 0 ; + } + + } + + +} + +int graph_tree(graph_t *g, char const *name, char const *tree) +{ + unsigned int a = 0 ; + unsigned int first = 0 ; + unsigned int ndeps = g->nvertex ; + + //print_start(tree, 0) ; + + if (name) + { + char *string = g->string ; + + for (; a < g->nvertex ; a++) + { + char *gname = string + genalloc_s(vertex_graph_t,&g->stack)[a].name ; + + if (obstr_equal(name,gname)) + { + first = a ; + ndeps = first + 1 ; + break ; + } + } + } + tdepth d = { + NULL, + NULL, + 1 , + 0 , + ndeps + } ; + + graph_walk(g,&g->stack,first,ndeps,&d); + + return 1 ; +} + +int stack_init(genalloc *st, unsigned int len) +{ + *st = genalloc_zero ; + return genalloc_ready(vertex_graph_t,st,len) ; +} + +int stack_push_at(genalloc *st,genalloc *data,unsigned int len, unsigned int idx) +{ + return genalloc_insertb(vertex_graph_t,st,idx,&genalloc_s(vertex_graph_t,data)[len],1) ; +} + +int stack_push_start(genalloc *st, genalloc *data,unsigned int len) +{ + return stack_push_at(st,data,len,0) ; +} + +void stack_reverse(genalloc *st) +{ + for (unsigned int i = 0 ; i < genalloc_len(vertex_graph_t,st) ; i++) + { + genalloc_reverse(vertex_graph_t,&genalloc_s(vertex_graph_t,st)[i].dps) ; + } + genalloc_reverse(vertex_graph_t,st) ; +} + +int stack_push(genalloc *st,genalloc *data,unsigned int len) +{ + return genalloc_append(vertex_graph_t,st,&genalloc_s(vertex_graph_t,data)[len]) ; +} + +int dfs(graph_t *g, unsigned int idx, genalloc *stack, visit *c) +{ + int cycle = 0 ; + unsigned int i, data ; + unsigned int len = genalloc_s(vertex_graph_t,&g->vertex)[idx].ndeps ; + + if (c[idx] == GRAY) return 1 ; + if (c[idx] == WHITE) + { + c[idx] = GRAY ; + for (i = 0 ; i < len ; i++) + { + data = genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[idx].dps)[i].gaidx ; + cycle = (cycle || dfs(g,data, stack, c)) ; + } + c[idx] = BLACK ; + stack_push_start(stack,&g->vertex,idx) ; + } + return cycle ; +} + +int graph_sort(graph_t *g) +{ + unsigned int len = g->nvertex ; + unsigned int color = g->nedge ; + visit c[color] ; + for (unsigned int i = 0 ; i < color; i++) c[i] = WHITE ; + if (!len) return 0 ; + if (!stack_init(&g->stack,color)) + { + VERBO3 strerr_warnwu1x("iniate stack") ; + return 0; + } + for (unsigned int i = 0 ; i < len ; i++) + { + if ( c[i] == WHITE && dfs(g,i,&g->stack,c)) + { + genalloc_free(vertex_graph_t,&g->stack) ; + return -1 ; + } + } + return 1 ; +} + +int graph_master(genalloc *ga, graph_t *g) +{ + unsigned int data, ddata,a,b,w ; + unsigned int color = g->nedge ; + visit c[color] ; + for (unsigned int i = 0 ; i < color; i++) c[i] = WHITE ; + char *string = g->string ; + for (a = 0 ; a < genalloc_len(vertex_graph_t,&g->stack) ; a++) + { + data = genalloc_s(vertex_graph_t,&g->stack)[a].idx ; + for (b = 0 ; b < genalloc_len(vertex_graph_t,&g->stack) ; b++) + { + for (unsigned int d = 0 ; d < genalloc_s(vertex_graph_t,&g->stack)[b].ndeps ; d++) + { + ddata = genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->stack)[b].dps)[d].idx ; + if (data == ddata) c[a] = BLACK ; + } + } + } + + for (w = 0 ; w < g->nvertex ; w++) + if (c[w] == WHITE) + if (!stra_add(ga,string + genalloc_s(vertex_graph_t,&g->stack)[w].name)) + return 0 ; + + return 1 ; +} + +int graph_rdepends(genalloc *ga,graph_t *g, char const *name, char const *src) +{ + unsigned int i,k ; + int r ; + + char *string = g->string ; + + unsigned int type = graph_search(g,name) ; + /** bundle , we need to check every service set onto it*/ + if (genalloc_s(vertex_graph_t,&g->vertex)[type].type == BUNDLE) + { + + for (k = 0; k < genalloc_s(vertex_graph_t,&g->vertex)[type].ndeps; k++) + { + char *depname = g->string + genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[type].dps)[k].name ; + + if (!stra_cmp(ga,depname)) + { + if (!stra_add(ga,depname)) + { + VERBO3 strerr_warnwu3x("add: ",depname," as dependency to remove") ; + return 0 ; + } + if (!find_logger(ga,depname,src)) + { + VERBO3 strerr_warnwu3x("add: ",gaistr(ga,genalloc_len(stralist,ga)-1)," as dependency to remove") ; + return 0 ; + } + } + r = graph_rdepends(ga,g,depname,src) ; + if (!r) + { + VERBO3 strerr_warnwu2x("find services depending on: ",name) ; + return 0 ; + } + if(r == 2) + { + VERBO3 strerr_warnt2x("any services don't depends on: ",name) ; + return 2 ; + } + } + } + + for (i = 0 ; i < g->nvertex ; i++) + { + + char *master = string + genalloc_s(vertex_graph_t,&g->vertex)[i].name ; + if (obstr_equal(name,master)) continue ; + + if (genalloc_s(vertex_graph_t,&g->vertex)[i].ndeps) + { + for (k = 0; k < genalloc_s(vertex_graph_t,&g->vertex)[i].ndeps; k++) + { + char *depname = string + genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[k].name ; + + if (obstr_equal(name,depname)) + { + /* if (genalloc_s(vertex_graph_t,&g->vertex)[i].type == BUNDLE) + continue ;*/ + + if (!stra_cmp(ga,master)) + { + if (!stra_add(ga,master)) + { + VERBO3 strerr_warnwu3x("add: ",depname," as dependency to remove") ; + return 0 ; + } + if (!find_logger(ga,master,src)) + { + VERBO3 strerr_warnwu3x("add: ",gaistr(ga,genalloc_len(stralist,ga)-1)," as dependency to remove") ; + return 0 ; + } + + r = graph_rdepends(ga,g,master,src) ; + if (!r) return 0 ; + } + } + } + } + } + + if (!genalloc_len(stralist,ga)) + { + genalloc_deepfree(stralist,ga,stra_free) ; + return 2 ; + } + return 1 ; +} +/** what = 0 -> only classic + * what = 1 -> only atomic + * what = 2 -> both + * @Return 0 on fail + * @Return -1 for empty graph*/ +int graph_type_src(genalloc *ga,char const *dir,unsigned int what) +{ + size_t dirlen = strlen(dir) ; + char solve[dirlen + SS_DB_LEN + SS_SRC_LEN + 1] ; + memcpy(solve,dir,dirlen) ; + + memcpy(solve + dirlen, SS_SVC, SS_SVC_LEN) ; + solve[dirlen + SS_SVC_LEN] = 0 ; + + if (!what || what == 2) + if (!dir_get(ga,solve,SS_MASTER + 1,S_IFDIR)) return 0 ; + + + memcpy(solve + dirlen, SS_DB, SS_DB_LEN) ; + memcpy(solve + dirlen + SS_DB_LEN, SS_SRC, SS_SRC_LEN) ; + solve[dirlen + SS_DB_LEN + SS_SRC_LEN] = 0 ; + + if (what) + if (!dir_get(ga,solve,SS_MASTER + 1,S_IFDIR)) return 0 ; + + if (!genalloc_len(stralist,ga)) return -1 ; + + return 1 ; +} + +int graph_build(graph_t *g, stralloc *sagraph, genalloc *tokeep,char const *dir) +{ + + + size_t dirlen = strlen(dir) ; + size_t newlen = 0 ; + char solve[dirlen + SS_RESOLVE_LEN + 1 + 1] ; + memcpy(solve,dir,dirlen) ; + memcpy(solve + dirlen, SS_RESOLVE,SS_RESOLVE_LEN) ; + solve[dirlen + SS_RESOLVE_LEN] = '/' ; + newlen = dirlen + SS_RESOLVE_LEN + 1 ; + solve[newlen] = 0 ; + + genalloc gatmp = GENALLOC_ZERO ;//stralist + stralloc res = STRALLOC_ZERO ; + + graph_t gtmp = GRAPH_ZERO ; + vertex_graph_t gsv = VERTEX_GRAPH_ZERO ; + vertex_graph_t gdeps = VERTEX_GRAPH_ZERO ; + + unsigned int nvertex = 0 ; + unsigned int nedge = 0 ; + + for (unsigned int i = 0 ; i < genalloc_len(stralist,tokeep) ; i++) + { + char *file = "deps" ; + char const *name = gaistr(tokeep,i) ; + size_t namelen = gaistrlen(tokeep,i) ; + char namesrc[newlen + namelen + 1] ; + memcpy(namesrc,solve,newlen) ; + memcpy(namesrc + newlen,name,namelen) ; + namesrc[newlen + namelen] = 0 ; + + res = stralloc_zero ; + if (!file_readputsa(&res,namesrc,"type")) + { + VERBO3 strerr_warnwu2x("read type of: ",name) ; + goto err ; + }else gsv.type = get_enumbyid(res.s,key_enum_el) ; + res = stralloc_zero ; + if (file_readputsa(&res,namesrc,file)) + { + + if (!clean_val(&gatmp,res.s)) + { + VERBO3 strerr_warnwu2x("clean val: ",res.s) ; + goto err ; + } + } + /*file = "logger" ; + res = stralloc_zero ; + if(file_readputsa(&res,namesrc,file)) + { + if (!clean_val(&gatmp,res.s)) + { + VERBO3 strerr_warnwu2x("clean val: ",res.s) ; + goto err ; + } + }*/ + + gsv.idx = nedge ; + nedge++ ; + gsv.gaidx = genalloc_len(vertex_graph_t, >mp.vertex) ; + gsv.name = sagraph->len ; + if (!stralloc_catb(sagraph,name,namelen + 1)) goto err ; + + if (genalloc_len(stralist,&gatmp)) + { + + gsv.ndeps = genalloc_len(stralist,&gatmp) ; + for (unsigned int i = 0 ; i < genalloc_len(stralist,&gatmp);i++) + { + gdeps.idx = nedge++ ; + gdeps.name = sagraph->len ; + if (!stralloc_catb(sagraph,gaistr(&gatmp,i),gaistrlen(&gatmp,i) + 1)) goto err ; + gdeps.gaidx = genalloc_len(vertex_graph_t,&gsv.dps) ; + gdeps.ndeps = 0 ; + gdeps.dps = genalloc_zero ; + if (!genalloc_append(vertex_graph_t,&gsv.dps,&gdeps)) goto err ; + + } + } + gtmp.nedge = nedge ; + gtmp.nvertex = ++nvertex ; + if (!genalloc_append(vertex_graph_t,>mp.vertex,&gsv)) goto err ; + gsv = vertex_graph_zero ; + gdeps = vertex_graph_zero ; + gatmp = genalloc_zero ; + } + + stralloc_free(&res) ; + genalloc_deepfree(stralist,&gatmp,stra_free) ; + + /** second pass */ + + char *string = sagraph->s ; + for (unsigned int a = 0 ; a < gtmp.nvertex ; a++) + { + + int idxa = genalloc_s(vertex_graph_t,>mp.vertex)[a].idx ; + gsv.idx = idxa ; + gsv.type = genalloc_s(vertex_graph_t,>mp.vertex)[a].type ; + gsv.name = genalloc_s(vertex_graph_t,>mp.vertex)[a].name ; + gsv.ndeps = genalloc_s(vertex_graph_t,>mp.vertex)[a].ndeps ; + gsv.gaidx = genalloc_s(vertex_graph_t,>mp.vertex)[a].gaidx ; + + for (unsigned int b = 0 ; b < genalloc_s(vertex_graph_t,>mp.vertex)[a].ndeps ; b++) + { + int idxb = genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,>mp.vertex)[a].dps)[b].idx ; + int nb = genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,>mp.vertex)[a].dps)[b].name ; + char *nameb = string + nb ; + gdeps.gaidx = genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,>mp.vertex)[a].dps)[b].gaidx ; + gdeps.ndeps = 0 ; + gdeps.dps = genalloc_zero ; + gdeps.idx = idxb ; + gdeps.name = nb ; + for (unsigned int c = 0 ; c < gtmp.nvertex ; c++) + { + int idxc = genalloc_s(vertex_graph_t,>mp.vertex)[c].idx ; + if (idxa == idxc) continue ; + int nc = genalloc_s(vertex_graph_t,>mp.vertex)[c].name ; + char *namec = string + nc ; + + if (obstr_equal(namec,nameb)) + { + gdeps.idx = idxc ; + gdeps.name = nc ; + gdeps.gaidx = genalloc_s(vertex_graph_t,>mp.vertex)[c].gaidx ; + gdeps.ndeps = genalloc_s(vertex_graph_t,>mp.vertex)[c].ndeps ; + gdeps.type = genalloc_s(vertex_graph_t,>mp.vertex)[c].type ; + break ; + } + } + if (!genalloc_append(vertex_graph_t,&gsv.dps,&gdeps)) goto err ; + + } + if (!genalloc_append(vertex_graph_t,&g->vertex,&gsv)) goto err ; + gsv = vertex_graph_zero ; + gdeps = vertex_graph_zero ; + } + g->string = sagraph->s ; + g->nvertex = gtmp.nvertex ; + g->nedge = gtmp.nedge ; + + genalloc_free(vertex_graph_t,&gsv.dps) ; + genalloc_free(vertex_graph_t,&gdeps.dps) ; + + /*for (unsigned int i = 0 ; i < genalloc_len(vertex_graph_t,&g->vertex) ; i++) + { + char *string = g->string ; + //int idx = genalloc_s(unsigned int,&g->vertex)[i] ; + printf("i::%i::type::%s\n",i,get_keybyid(genalloc_s(vertex_graph_t,&g->vertex)[i].type)) ; + //printf("i::%i::idx::%i\n",i,genalloc_s(vertex_graph_t,&g->vertex)[i].idx) ; + printf("i::%i::name::%s\n",i,string + genalloc_s(vertex_graph_t,&g->vertex)[i].name) ; + //printf("i::%i::ndeps::%i\n",i,genalloc_s(vertex_graph_t,&g->vertex)[i].ndeps) ; + //printf("i::%i::gaidx::%i\n",i,genalloc_s(vertex_graph_t,&g->vertex)[i].gaidx) ; + for (unsigned int d = 0 ; d < genalloc_s(vertex_graph_t,&g->vertex)[i].ndeps ; d++) + { + printf(" deps type::%s\n", get_keybyid(genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[d].type)) ; + //printf(" deps idx::%i\n", genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[d].idx) ; + printf(" deps name::%s\n", string + genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[d].name) ; + //printf(" deps ndeps::%i\n", genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[d].ndeps) ; + // printf(" deps gaidx::%i\n---\n", genalloc_s(vertex_graph_t,&genalloc_s(vertex_graph_t,&g->vertex)[i].dps)[d].gaidx) ; + } + + + } */ + return 1 ; + + err: + genalloc_deepfree(stralist,&gatmp,stra_free) ; + stralloc_free(&res) ; + genalloc_free(vertex_graph_t,&gsv.dps) ; + genalloc_free(vertex_graph_t,&gdeps.dps) ; + return 0 ; +} + +/** return idx of @name in @g + * @Return -1 if not found*/ +int graph_search(graph_t *g, char const *name) +{ + unsigned int i ; + char *string = g->string ; + for (i = 0 ; i < g->nvertex ; i++) + { + char *master = string + genalloc_s(vertex_graph_t,&g->vertex)[i].name ; + if (obstr_equal(name,master)) return i ; + } + + return -1 ; +}