123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947 |
- /*
- * Copyright 2021
- *
- * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
- *
- * SPDX-License-Identifier: GPL-3.0+
- * License-Filename: LICENSE
- */
- /*
- To improve this C there are guides for mission-critical software
- and similar guides collected at
- https://github.com/abougouffa/awesome-coding-standards
- This are few rules from nasa at
- https://en.wikipedia.org/wiki/The_Power_of_10:_Rules_for_Developing_Safety-Critical_Code
- Avoid complex flow constructs, such as goto and recursion.
- All loops must have fixed bounds. This prevents runaway code.
- Avoid heap memory allocation.
- Restrict functions to a single printed page.
- Use a minimum of two runtime assertions per function.
- Restrict the scope of data to the smallest possible.
- Check the return value of all non-void functions, or cast to void to indicate the return value is useless.
- Use the preprocessor sparingly.
- Limit pointer use to a single dereference, and do not use function pointers.
- Compile with all possible warnings active; all warnings should then be addressed before release of the software.
- */
- #include "config.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <strings.h>
- #include <zlib.h>
- #include "splay-tree.h"
- #include "main.h"
- #include "dp.h"
- #include "dpus.h"
- #include "dpun.h"
- #include "dpmisc.h"
- #include "dpcolor.h"
- #include "lex.yy.h"
- #include "dot.tab.h"
- #include "dpn.h"
- #include "dpe.h"
- #include "dpg.h"
- #include "dpmem.h"
- char dp_errmsg[256];
- int dp_cclass = 0;
- int dp_sgnr = 0; /* uniq graph number */
- /* all nodes */
- struct dpnlink *dp_anodes = NULL;
- static struct dpnlink *dp_anodesend = NULL;
- /* all edges */
- struct dpelink *dp_aedges = NULL;
- static struct dpelink *dp_aedgesend = NULL;
- /* all edge points */
- static struct dpeplink *dp_epl = NULL;
- static struct dpeplink *dp_eplend = NULL;
- /* all head edge points */
- static struct dpeplink *dp_headepl = NULL;
- static struct dpeplink *dp_headeplend = NULL;
- /* all subgraphs but not rootgraph */
- static struct dpglink *dp_asubg = NULL;
- static struct dpglink *dp_asubgend = NULL;
- /* tmp edges during edge building */
- static struct dptelink *dp_tmpe = NULL;
- static struct dptelink *dp_tmpeend = NULL;
- /* edge nesting */
- static int dp_enest = 0;
- /* node id number */
- static int dp_nodenum = 0;
- /* edge numbers */
- static int dp_edgenum = 0;
- /* splay tree with nested graphs */
- static splay_tree dpgraphs = NULL;
- /* the root graph */
- struct dpgraph *dp_groot = NULL;
- /* the current graph */
- struct dpgraph *dp_curgraph = NULL;
- struct dpnode *dp_curnode = NULL;
- struct dpedge *dp_curedge = NULL;
- static void dp_nodelink(struct dpnode *node, int mode);
- static void dp_eplink(struct dpepoint *epoint);
- static void dp_endel_n2n(struct dpepoint *fn, struct dpepoint *tn);
- static void dp_endel_n2g(struct dpepoint *fn, struct dpepoint *tn);
- static void dp_endel_g2n(struct dpepoint *fn, struct dpepoint *tn);
- static void dp_endel_g2g(struct dpepoint *fn, struct dpepoint *tn);
- static void dp_clredges(void);
- /* return 0 if no errors, >0 at error */
- int dp_chkerr(void)
- {
- return ((int)strlen(dp_errmsg));
- }
- /* */
- static void dp_pushgraph(struct dpgraph *g)
- {
- int ix = 0;
- splay_tree_node spn;
- spn = splay_tree_max(dpgraphs);
- if (spn == NULL) {
- ix = 0;
- } else {
- ix = (int)spn->key;
- ix++;
- }
- splay_tree_insert(dpgraphs, (splay_tree_key) ix, (splay_tree_value) g);
- dp_curgraph = g;
- return;
- }
- /* */
- static struct dpgraph *dp_pullgraph(void)
- {
- struct dpgraph *ret = NULL;
- int ix = 0;
- splay_tree_node spn = NULL;
- spn = splay_tree_max(dpgraphs);
- if (spn == NULL) {
- printf("dot %s(): shouldnothappen near line %d\n", __func__, yylineno);
- return (NULL);
- }
- ix = (int)spn->key;
- if ((ix - 1) < 0) {
- /* remove last element ix=0 */
- splay_tree_remove(dpgraphs, (splay_tree_key) ix);
- printf("dot %s(): removed last element near line %d\n", __func__, yylineno);
- return (NULL);
- }
- spn = splay_tree_lookup(dpgraphs, (splay_tree_key) (ix - 1));
- if (spn == NULL) {
- /* shouldnothappen */
- printf("dot %s(): could not find %d element near line %d\n", __func__, (ix - 1), yylineno);
- ret = NULL;
- } else {
- ret = (struct dpgraph *)spn->value;
- splay_tree_remove(dpgraphs, (splay_tree_key) ix);
- }
- dp_curgraph = ret;
- return (ret);
- }
- /* at start of graph, etype is -- or -> */
- void dp_sg(char *etype, char *gname)
- {
- memset(dp_errmsg, 0, 256);
- /* node id number */
- dp_nodenum = 0;
- /* edge numbers */
- dp_edgenum = 0;
- /* graph numbers */
- dp_sgnr = 0;
- /* edge nesting */
- dp_enest = 0;
- dpgraphs = splay_tree_new(splay_tree_compare_ints, NULL, NULL);
- /* fresh root graph */
- dp_groot = (struct dpgraph *)dp_calloc(1, sizeof(struct dpgraph));
- /* root graph has uniq number 0 */
- dp_groot->nr = dp_sgnr;
- dp_sgnr++;
- dp_groot->type = DP_SG_ROOT;
- /* set factory defaults */
- dp_graphfdef(dp_groot);
- if (gname == NULL) {
- /* no graphname, make it "" */
- dp_groot->graphname = dp_uniqstr((char *)"");
- } else {
- dp_groot->graphname = gname;
- }
- /* type of edge, -- or -> */
- dp_groot->yylineno = yylineno;
- dp_groot->etype = etype;
- dp_groot->rootedon = NULL;
- dp_groot->tag = DP_TGRAPH;
- /* splay with node/edge/graph parsed settings */
- dp_groot->gattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- dp_groot->nattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- dp_groot->eattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- /* node with default settings */
- dp_groot->defnode = (struct dpnode *)dp_calloc(1, sizeof(struct dpnode));
- /* set factory defaults */
- dp_nodefdef(dp_groot->defnode);
- dp_groot->defnode->name = dp_uniqstr((char *)"default");
- dp_groot->defnode->label = dp_uniqstr((char *)"default");
- /* edge with default settings */
- dp_groot->defedge = (struct dpedge *)dp_calloc(1, sizeof(struct dpedge));
- /* set factory defaults */
- dp_edgefdef(dp_groot->defedge);
- /* add root to array of graphs */
- dp_pushgraph(dp_groot);
- dp_cclass = DP_TGRAPH;
- return;
- }
- /* subgraph with optional name
- * types of subgraphs:
- * #define DP_SG_ROOT 0 * root graph type
- * #define DP_SG_CO 1 * compound subgraph {}
- * #define DP_SG_NM 2 * named subgrph
- * #define DP_SG_CL 3 * cluster subgraph
- * #define DP_SG_NN 4 * no name subgraph
- */
- void dp_nsubg(struct dpgraph *sg, char *gname, int type)
- {
- if (sg == NULL) {
- /* shouldnothappen */
- return;
- }
- if (gname == NULL) {
- /* type is now DP_SG_CO (compound) or DP_SG_NN (no-name) */
- sg->type = type;
- /* no graphname, make it "" */
- sg->graphname = NULL;
- } else {
- /* name or "" */
- sg->graphname = gname;
- sg->type = DP_SG_NM;
- /*
- * when subgraph name starts with cluster
- * it gets special meaning in dot language
- */
- if (strncmp(sg->graphname, "cluster", 7) == 0) {
- sg->cluster = 1;
- sg->type = DP_SG_CL;
- }
- }
- /* type of edge, -- or -> */
- sg->etype = dp_groot->etype;
- sg->rootedon = dp_curgraph;
- sg->tag = DP_TGRAPH;
- /* splay with node/edge/graph parsed settings */
- sg->gattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- sg->nattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- sg->eattr = splay_tree_new(splay_tree_compare_strings, NULL, NULL);
- /* node with default settings */
- sg->defnode = (struct dpnode *)dp_calloc(1, sizeof(struct dpnode));
- sg->defnode->name = dp_uniqstr((char *)"default");
- sg->defnode->label = dp_uniqstr((char *)"default");
- /* set factory defaults */
- dp_nodefdef(sg->defnode);
- dp_nodegdef(dp_curgraph->defnode, sg->defnode);
- /* edge with default settings */
- sg->defedge = (struct dpedge *)dp_calloc(1, sizeof(struct dpedge));
- /* set factory defaults */
- dp_edgefdef(sg->defedge);
- dp_edgegdef(dp_curgraph->defedge, sg->defedge);
- /* set factory defaults */
- sg->yylineno = yylineno;
- /* factory defaults */
- dp_graphfdef(sg);
- /* get data from rooted on subgraph */
- /* set graph default */
- dp_graphgdef(sg->rootedon, sg);
- return;
- }
- /* end graph */
- void dp_eg(void)
- {
- return;
- }
- void dp_atype_graph(void)
- {
- dp_cclass = DP_TGRAPH;
- return;
- }
- void dp_atype_sgraph(void)
- {
- dp_cclass = DP_SGRAPH;
- return;
- }
- void dp_atype_node(void)
- {
- dp_cclass = DP_TNODE;
- return;
- }
- void dp_atype_edge(void)
- {
- dp_cclass = DP_TEDGE;
- return;
- }
- void dp_atype_graphdef(void)
- {
- dp_cclass = DP_TGRAPHDEF;
- return;
- }
- void dp_atype_nodedef(void)
- {
- dp_cclass = DP_TNODEDEF;
- return;
- }
- void dp_atype_edgedef(void)
- {
- dp_cclass = DP_TEDGEDEF;
- return;
- }
- /* set attribute with last arg set to 1 if r is a <html-label>, otherwise r="a-string" */
- void dp_aset(char *l, char *r, int ishtml)
- {
- char *dval = NULL;
- splay_tree_node spn = NULL;
- int htmllabel = 0;
- /* safety */
- if (l == NULL) {
- printf("%s(): dot shouldnothappen l is nil\n", __func__);
- return;
- }
- if (yydebug || 0) {
- printf("%s(): attribute \"%s\" has arg \"%s\" ishtml=%d\n", __func__, l, r, ishtml);
- }
- htmllabel = 0;
- if (ishtml) {
- if (strcmp(l, "label") == 0) {
- htmllabel = 1;
- } else {
- printf("%s(): html-label only supported for label attribute but not for \"%s=%s\" attribute\n", __func__, l, r);
- return;
- }
- }
- if (r) {
- dval = r;
- } else {
- dval = dp_uniqstr((char *)"");
- }
- switch (dp_cclass) {
- /* example : "aa"[color=red] */
- case DP_TNODE:
- {
- dp_do_nattr(l, r, ishtml);
- }
- break;
- /* example: node[color=red] */
- case DP_TNODEDEF:
- {
- spn = splay_tree_lookup(dp_curgraph->nattr, (splay_tree_key) l);
- if (spn == NULL) {
- splay_tree_insert(dp_curgraph->nattr, (splay_tree_key) l, (splay_tree_value) dval);
- } else {
- /*
- if (0)
- {
- printf
- ("dot %s(): attempt to redefine node attribute `%s=%s' with value `%s' near line %d\n",
- __func__, l, (char *) spn->value, r, yylineno);
- fflush (stdout);
- }
- */
- spn->value = (splay_tree_value) dval;
- }
- dp_do_nattr(l, r, ishtml);
- }
- break;
- case DP_TEDGE:
- {
- if (htmllabel == 0) {
- dp_do_eattr(l, r);
- } else {
- printf("%s(): html-label not supported for edge attributes\n", __func__);
- }
- }
- break;
- case DP_TEDGEDEF:
- {
- spn = splay_tree_lookup(dp_curgraph->eattr, (splay_tree_key) l);
- if (spn == NULL) {
- splay_tree_insert(dp_curgraph->eattr, (splay_tree_key) l, (splay_tree_value) dval);
- } else {
- /*
- if (0)
- {
- printf
- ("dot %s(): attempt to redefine edge attribute `%s=%s' with value `%s' near line %d\n",
- __func__, l, (char *) spn->value, r, yylineno);
- fflush (stdout);
- }
- */
- spn->value = (splay_tree_value) dval;
- }
- if (htmllabel == 0) {
- dp_do_eattr(l, r);
- } else {
- printf("%s(): html-label not supported for edge attributes\n", __func__);
- }
- }
- break;
- case DP_TGRAPHDEF:
- case DP_TGRAPH:
- {
- spn = splay_tree_lookup(dp_curgraph->gattr, (splay_tree_key) l);
- if (spn == NULL) {
- splay_tree_insert(dp_curgraph->gattr, (splay_tree_key) l, (splay_tree_value) dval);
- } else {
- /*
- if (0)
- {
- printf
- ("dot %s(): attempt to redefine graph attribute `%s=%s' with value `%s' near line %d\n",
- __func__, l, (char *) spn->value, r, yylineno);
- fflush (stdout);
- }
- */
- spn->value = (splay_tree_value) dval;
- }
- if (htmllabel == 0) {
- dp_do_gattr(l, r);
- } else {
- /* todo */
- printf("%s(): html-label not supported for graph attributes\n", __func__);
- }
- }
- break;
- case DP_SGRAPH:
- /* attribute after subgraph */
- break;
- default:
- {
- printf("dot %s(): shouldnothappen dp_cclass=%d\n", __func__, dp_cclass);
- fflush(stdout);
- }
- break;
- }
- return;
- }
- /* add node as global node and to subgraph nodelist if mode is 0 */
- static void dp_nodelink(struct dpnode *node, int mode)
- {
- struct dpnlink *nl = NULL;
- if (0) {
- printf("%s(): add node \"%s\" \"%s\"\n", __func__, node->name, node->label);
- }
- /* if mode is 1, do not add as global node. */
- if (mode == 0) {
- /* add node to global nodelist */
- nl = (struct dpnlink *)dp_calloc(1, sizeof(struct dpnlink));
- nl->n = node;
- if (dp_anodes == NULL) {
- dp_anodes = nl;
- dp_anodesend = nl;
- } else {
- dp_anodesend->next = nl;
- dp_anodesend = nl;
- }
- }
- /* add node to current subgraph */
- nl = (struct dpnlink *)dp_calloc(1, sizeof(struct dpnlink));
- nl->n = node;
- if (dp_curgraph->dpnodes == NULL) {
- dp_curgraph->dpnodes = nl;
- dp_curgraph->dpnodesend = nl;
- } else {
- dp_curgraph->dpnodesend->next = nl;
- dp_curgraph->dpnodesend = nl;
- }
- return;
- }
- /* add edge point */
- static void dp_eplink(struct dpepoint *epoint)
- {
- struct dpeplink *el = NULL;
- /* add point to global pointlist */
- el = (struct dpeplink *)dp_calloc(1, sizeof(struct dpeplink));
- el->ep = epoint;
- if (dp_epl == NULL) {
- dp_epl = el;
- dp_eplend = el;
- } else {
- dp_eplend->next = el;
- dp_eplend = el;
- }
- /* add point to global pointlist */
- el = (struct dpeplink *)dp_calloc(1, sizeof(struct dpeplink));
- el->ep = epoint;
- if (dp_curgraph->dpeplist == NULL) {
- dp_curgraph->dpeplist = el;
- dp_curgraph->dpeplistend = el;
- } else {
- dp_curgraph->dpeplistend->next = el;
- dp_curgraph->dpeplistend = el;
- }
- return;
- }
- /* recursive clear all eppoint's */
- static void dp_clrep_r(struct dpgraph *gr)
- {
- struct dpglink *ng = NULL;
- struct dpeplink *el = NULL;
- struct dpeplink *elnext = NULL;
- if (gr == NULL) {
- return;
- }
- ng = gr->dpsubg;
- while (ng) {
- dp_clrep_r(ng->sg);
- ng = ng->next;
- }
- el = gr->dpeplist;
- while (el) {
- elnext = el->next;
- el = (struct dpeplink *)dp_free(el);
- if (el) {
- }
- el = elnext;
- }
- gr->dpeplist = NULL;
- gr->dpeplistend = NULL;
- return;
- }
- /* clear all eppoint's */
- void dp_clrep(void)
- {
- struct dpeplink *el = NULL;
- struct dpeplink *elnext = NULL;
- /* recursive clear in subgraphs */
- dp_clrep_r(dp_groot);
- /* clear epl itself */
- el = dp_epl;
- while (el) {
- elnext = el->next;
- if (el->ep) {
- el->ep = (struct dpepoint *)dp_free((void *)el->ep);
- }
- el = (struct dpeplink *)dp_free((void *)el);
- if (el) {
- }
- el = elnext;
- }
- dp_epl = NULL;
- dp_eplend = NULL;
- return;
- }
- /* free nodes in subgraphs and rootgraph */
- static void dp_clrnodes_r(struct dpgraph *gr)
- {
- struct dpglink *ng = NULL;
- struct dpnlink *nl = NULL;
- struct dpnlink *nlnext = NULL;
- if (gr == NULL) {
- return;
- }
- ng = gr->dpsubg;
- while (ng) {
- dp_clrnodes_r(ng->sg);
- ng = ng->next;
- }
- nl = gr->dpnodes;
- while (nl) {
- nlnext = nl->next;
- nl = (struct dpnlink *)dp_free((void *)nl);
- if (nl) {
- }
- nl = nlnext;
- }
- gr->dpnodes = NULL;
- gr->dpnodesend = NULL;
- return;
- }
- /* clear all nodes */
- static void dp_clrnodesli(struct dppart *info)
- {
- int i = 0;
- struct dppart *info2 = NULL;
- if (info == NULL) {
- return;
- }
- for (i = 0; i < info->ndpparts; i++) {
- if (info->parts[i]) {
- dp_clrnodesli(info->parts[i]);
- }
- }
- if (info->parts) {
- info->parts = (struct dppart **)dp_free((void *)info->parts);
- }
- info2 = (struct dppart *)dp_free(info);
- if (info2) {
- }
- return;
- }
- /* free ilist */
- static void dp_freememil(struct tdldata *td)
- {
- struct ilist *ilptr = NULL; /* text items in td or 0 */
- struct ilist *ilptrnext = NULL; /* text items in td or 0 */
- if (td == NULL) {
- return;
- }
- if (td->tdd == NULL) {
- return;
- }
- if (td->tdd->il) {
- ilptr = td->tdd->il;
- while (ilptr) {
- ilptrnext = ilptr->next;
- if (ilptr->items) {
- ilptr->items = (struct item *)dp_free((void *)ilptr->items);
- }
- ilptr = (struct ilist *)dp_free((void *)ilptr);
- if (ilptr) {
- }
- ilptr = ilptrnext;
- }
- td->tdd->il = NULL;
- td->tdd->ilend = NULL;
- }
- return;
- }
- /* free <tr> */
- static void dp_freememtr(struct trlist *tr)
- {
- struct tdldata *tdlptr = NULL; /* td items in tr */
- struct tdldata *tdlptrnext = NULL;
- if (tr == NULL) {
- return;
- }
- if (tr->tritem == NULL) {
- return;
- }
- /* <td> data */
- tdlptr = tr->tritem->td;
- while (tdlptr) {
- tdlptrnext = tdlptr->next;
- /* tdptr is free'ed later */
- /* free il data in <td> */
- if (tdlptr->tdd) {
- dp_freememil(tdlptr);
- tdlptr->tdd = (struct tddata *)dp_free((void *)tdlptr->tdd);
- }
- tdlptr = (struct tdldata *)dp_free((void *)tdlptr);
- if (tdlptr) {
- }
- tdlptr = tdlptrnext;
- }
- tr->tritem->td = NULL;
- tr->tritem->tdend = NULL;
- tr->tritem = (struct trdata *)dp_free((void *)tr->tritem);
- if (tr->tritem) {
- }
- return;
- }
- static void dp_freememt_r(struct tlist *tl)
- {
- struct tlist *tlptr = NULL; /* list of table items */
- struct tlist *tlptrnext = NULL; /* list of table items */
- struct trlist *trptr = NULL; /* tr items */
- struct trlist *trptrnext = NULL; /* end tr items */
- if (tl == NULL) {
- /* shouldnothappen */
- return;
- }
- if (tl->titem == NULL) {
- /* shouldnothappen */
- return;
- }
- if (tl->titem->tabdata) {
- /* clear sub tables if any */
- if (tl->titem->tabdata->tl) {
- tlptr = tl->titem->tabdata->tl;
- while (tlptr) {
- tlptrnext = tlptr->next;
- dp_freememt_r(tlptr);
- if (tlptr->titem) {
- tlptr->titem = (struct tableldata *)dp_free((void *)tlptr->titem);
- }
- tlptr = (struct tlist *)dp_free((void *)tlptr);
- if (tlptr) {
- }
- tlptr = tlptrnext;
- }
- tl->titem->tabdata->tl = NULL;
- tl->titem->tabdata->tlend = NULL;
- }
- /* <tr> data */
- if (tl->titem->tabdata->tr) {
- trptr = tl->titem->tabdata->tr;
- while (trptr) {
- trptrnext = trptr->next;
- dp_freememtr(trptr);
- if (trptr->tritem) {
- trptr->tritem = (struct trdata *)dp_free((void *)trptr->tritem);
- }
- trptr = (struct trlist *)dp_free((void *)trptr);
- if (trptr) {
- }
- trptr = trptrnext;
- }
- tl->titem->tabdata->tr = NULL;
- tl->titem->tabdata->trend = NULL;
- }
- if (tl->titem->tabdata) {
- tl->titem->tabdata = (struct tabledata *)dp_free((void *)tl->titem->tabdata);
- }
- }
- if (tl->titem) {
- tl->titem = (struct tableldata *)dp_free((void *)tl->titem);
- }
- return;
- }
- /* clear hlinfo of one node */
- static void dp_clearhlinfonode(struct dpnode *node)
- {
- struct tlist *tlptr = NULL; /* list of table items */
- struct tlist *tlptrnext = NULL; /* list of table items */
- struct ilist *pil = NULL;
- struct ilist *pilnext = NULL;
- if (node == NULL) { /* shoudlothappen */
- return;
- }
- if (node->hlinfo == NULL) { /* shouldnothappen */
- return;
- }
- /* item data to free */
- if (node->hlinfo->il) {
- pil = node->hlinfo->il;
- while (pil) {
- pilnext = pil->next;
- if (pil->items) {
- pil->items = (struct item *)dp_free((void *)pil->items);
- }
- pil = (struct ilist *)dp_free((void *)pil);
- if (pil) {
- }
- pil = pilnext;
- }
- node->hlinfo->il = NULL;
- node->hlinfo->ilend = NULL;
- }
- /* table data to free */
- if (node->hlinfo->tl) {
- /* */
- tlptr = node->hlinfo->tl;
- while (tlptr) {
- tlptrnext = tlptr->next;
- dp_freememt_r(tlptr);
- if (tlptr->titem) {
- tlptr->titem = (struct tableldata *)dp_free((void *)tlptr->titem);
- }
- tlptr = (struct tlist *)dp_free((void *)tlptr);
- if (tlptr) {
- }
- tlptr = tlptrnext;
- }
- /* ready */
- node->hlinfo->tl = NULL;
- node->hlinfo->tlend = NULL;
- }
- return;
- }
- static void dp_clrnodes(void)
- {
- struct dpnlink *nl = NULL;
- struct dpnlink *nlnext = NULL;
- dp_clrnodes_r(dp_groot);
- nl = dp_anodes;
- while (nl) {
- nlnext = nl->next;
- if (nl->n->labelinfo) {
- dp_clrnodesli(nl->n->labelinfo);
- }
- if (nl->n->hlinfo) {
- dp_clearhlinfonode(nl->n);
- nl->n->hlinfo = (struct hlpart *)dp_free(nl->n->hlinfo);
- if (nl->n->hlinfo) {
- }
- }
- if (nl->n) {
- nl->n = (struct dpnode *)dp_free((void *)nl->n);
- }
- nl = (struct dpnlink *)dp_free((void *)nl);
- if (nl) {
- }
- nl = nlnext;
- }
- dp_anodes = NULL;
- dp_anodesend = NULL;
- return;
- }
- static void dp_clrgraph_r(struct dpgraph *gr)
- {
- struct dpglink *ng = NULL;
- struct dpglink *gl = NULL;
- struct dpglink *glnext = NULL;
- if (gr == NULL) {
- return;
- }
- ng = gr->dpsubg;
- while (ng) {
- dp_clrgraph_r(ng->sg);
- ng = ng->next;
- }
- gl = gr->dpsubg;
- while (gl) {
- glnext = gl->next;
- if (gl->sg->defnode) {
- gl->sg->defnode = (struct dpnode *)dp_free((void *)gl->sg->defnode);
- }
- if (gl->sg->defedge) {
- gl->sg->defedge = (struct dpedge *)dp_free((void *)gl->sg->defedge);
- }
- gl->sg->gattr = splay_tree_delete(gl->sg->gattr);
- gl->sg->nattr = splay_tree_delete(gl->sg->nattr);
- gl->sg->eattr = splay_tree_delete(gl->sg->eattr);
- gl = (struct dpglink *)dp_free((void *)gl);
- if (gl) {
- }
- gl = glnext;
- }
- gr->dpsubg = NULL;
- gr->dpsubgend = NULL;
- return;
- }
- /* clear all garphs */
- static void dp_clrgraphs(void)
- {
- struct dpglink *dpl = NULL;
- struct dpglink *dplnext = NULL;
- dp_clrgraph_r(dp_groot);
- if (dp_asubg) {
- dpl = dp_asubg;
- while (dpl) {
- dplnext = dpl->next;
- if (dpl->sg) {
- dpl->sg = (struct dpgraph *)dp_free((void *)dpl->sg);
- }
- dpl = (struct dpglink *)dp_free((void *)dpl);
- if (dpl) {
- }
- dpl = dplnext;
- }
- }
- dp_asubg = NULL;
- dp_asubgend = NULL;
- return;
- }
- /* free edges in subgraphs and rootgraph */
- static void dp_clredges_r(struct dpgraph *gr)
- {
- struct dpglink *ng = NULL;
- struct dpelink *el = NULL;
- struct dpelink *elnext = NULL;
- if (gr == NULL) {
- return;
- }
- ng = gr->dpsubg;
- while (ng) {
- dp_clredges_r(ng->sg);
- ng = ng->next;
- }
- el = gr->dpedges;
- while (el) {
- elnext = el->next;
- /* edge ->e is free()'ed in dp_clredges() */
- el = (struct dpelink *)dp_free((void *)el);
- if (el) {
- }
- el = elnext;
- }
- gr->dpedges = NULL;
- gr->dpedgesend = NULL;
- return;
- }
- /* clear all edges */
- static void dp_clredges(void)
- {
- struct dpelink *el = NULL;
- struct dpelink *elnext = NULL;
- dp_clredges_r(dp_groot);
- el = dp_aedges;
- while (el) {
- elnext = el->next;
- if (el->e) {
- el->e = (struct dpedge *)dp_free((void *)el->e);
- }
- el = (struct dpelink *)dp_free((void *)el);
- if (el) {
- }
- el = elnext;
- }
- dp_aedges = NULL;
- dp_aedgesend = NULL;
- return;
- }
- /* clear edge head nodes */
- void dp_clrheade(void)
- {
- struct dpeplink *el = NULL;
- struct dpeplink *elnext = NULL;
- el = dp_headepl;
- while (el) {
- elnext = el->next;
- if (el->ep) {
- el->ep = (struct dpepoint *)dp_free((void *)el->ep);
- }
- el = (struct dpeplink *)dp_free((void *)el);
- if (el) {
- }
- el = elnext;
- }
- dp_headepl = NULL;
- dp_headeplend = NULL;
- return;
- }
- /* clear tmp edges during edge building */
- static void dp_clrtmpe(void)
- {
- struct dptelink *te = NULL;
- struct dptelink *tenext = NULL;
- te = dp_tmpe;
- while (te) {
- tenext = te->next;
- if (te->e) {
- te->e = (struct dptmpe *)dp_free((void *)te->e);
- }
- te = (struct dptelink *)dp_free((void *)te);
- if (te) {
- }
- te = tenext;
- }
- dp_tmpe = NULL;
- dp_tmpeend = NULL;
- return;
- }
- /* add graph to lists */
- static void dp_graphlink(struct dpgraph *sg)
- {
- struct dpglink *ng = NULL;
- /* add node to global nodelist */
- ng = (struct dpglink *)dp_calloc(1, sizeof(struct dpglink));
- ng->sg = sg;
- /* all subgraphs in one list */
- if (dp_asubg == NULL) {
- dp_asubg = ng;
- dp_asubgend = ng;
- } else {
- dp_asubgend->next = ng;
- dp_asubgend = ng;
- }
- /* add node to current subgraph */
- ng = (struct dpglink *)dp_calloc(1, sizeof(struct dpglink));
- ng->sg = sg;
- if (dp_curgraph->dpsubg == NULL) {
- dp_curgraph->dpsubg = ng;
- dp_curgraph->dpsubgend = ng;
- } else {
- dp_curgraph->dpsubgend->next = ng;
- dp_curgraph->dpsubgend = ng;
- }
- return;
- }
- /* create node at nodestatement
- * dot allows to redefine a node.
- * node name can be ""
- * node label can be ""
- */
- void dp_mknode0(char *name)
- {
- struct dpnode *n = NULL;
- /* check if node is in database */
- n = dpuniqnode(name);
- if (n) {
- /* node exist and being redefined now */
- /* only if earlier defined by a node statement */
- /* todo this does not work */
- if (n->bitflags0.defbynode == 1 || 0) {
- if (0) {
- printf("dot %s(): node `%s' line %d is redefined at line %d\n", __func__, n->name, n->yylineno, yylineno);
- fflush(stdout);
- }
- }
- if (dp_groot != dp_curgraph) {
- dp_nodegdef(dp_curgraph->defnode, n);
- }
- dp_curnode = n;
- /* add node to curgraph but not in nodelist */
- dp_nodelink(n, 1);
- } else {
- /* fresh new node */
- n = (struct dpnode *)dp_calloc(1, sizeof(struct dpnode));
- n->name = name; /* uniq node name */
- n->label = name; /* label text \N */
- /* set factory defaults */
- dp_nodefdef(n);
- /* set node defaults for this graph */
- dp_nodegdef(dp_groot->defnode, n);
- if (dp_groot != dp_curgraph || 0) {
- dp_nodegdef(dp_curgraph->defnode, n);
- }
- /* setparams */
- n->root = dp_curgraph;
- dp_nodenum++;
- n->nr = dp_nodenum; /* uniq node number */
- n->yylineno = yylineno; /* line where node is defined */
- dp_groot->nnodes++; /* number of nodes in graph */
- if (dp_groot != dp_curgraph) {
- dp_curgraph->nnodes++; /* number of nodes in sub graph */
- }
- n->bitflags0.defbynode = 1;
- /* add as uniqnode */
- dpuniqnode_add(n);
- /* add node as global node and to subgraph nodelist */
- dp_nodelink(n, 0);
- /* set current node being parsed */
- dp_curnode = n;
- }
- return;
- }
- /* edge point with node name and port/compass */
- struct dpepoint *dp_mknid(char *name, char *port, char *compass)
- {
- struct dpnode *n = NULL;
- struct dpepoint *nid = NULL;
- char *compass2 = NULL;
- char *port2 = NULL;
- int yes = 0;
- port2 = port;
- compass2 = compass;
- if (compass) {
- yes = dp_iscompass(compass);
- if (yes == 0) {
- memset(dp_errmsg, 0, 256);
- snprintf(dp_errmsg, (256 - 1),
- "dot %s(): syntax error invalid compass point `%s' at node `%s' near line %dexpected one of these compass points: n,ne,e,se,s,sw,w,nw,c,_\n\n",
- __func__, compass, name, yylineno);
- /* continue and error message will soon appear */
- }
- }
- if (compass == NULL) {
- if (port) {
- yes = dp_iscompass(port);
- if (yes == 1) {
- /* turn port into compass */
- compass2 = port;
- port2 = NULL;
- }
- }
- }
- /* check if node is in database */
- n = dpuniqnode(name);
- if (n == NULL) {
- /* node in edge did not exist and create now */
- /* fresh new node */
- n = (struct dpnode *)dp_calloc(1, sizeof(struct dpnode));
- /* setparams */
- n->name = name; /* uniq node name */
- n->label = name; /* label text \N */
- /* set factory defaults */
- dp_nodefdef(n);
- /* set node defaults for this graph */
- dp_nodegdef(dp_groot->defnode, n);
- if (dp_groot != dp_curgraph || 0) {
- dp_nodegdef(dp_curgraph->defnode, n);
- }
- n->root = dp_curgraph; /* subgraph where node is defined */
- dp_nodenum++;
- n->nr = dp_nodenum; /* uniq node number */
- n->yylineno = yylineno; /* line where node is defined */
- dp_groot->nnodes++; /* number of nodes in graph */
- if (dp_groot != dp_curgraph) {
- dp_curgraph->nnodes++; /* number of nodes in sub graph */
- }
- /* add as uniqnode */
- dpuniqnode_add(n);
- /* add node as global node and to subgraph nodelist */
- dp_nodelink(n, 0);
- }
- nid = (struct dpepoint *)dp_calloc(1, sizeof(struct dpepoint));
- nid->n = n;
- nid->port = port2; /* port or compass point */
- nid->compass = compass2;
- nid->type = 0; /* type 0: this is a node */
- nid->root = n->root;
- return (nid);
- }
- /* start edge at nid */
- void dp_starte1(struct dpepoint *ep)
- {
- struct dpepoint *epnew = NULL;
- struct dpeplink *el = NULL;
- dp_enest++;
- dp_curgraph->enest++;
- /* add point to global pointlist */
- el = (struct dpeplink *)dp_calloc(1, sizeof(struct dpeplink));
- epnew = (struct dpepoint *)dp_calloc(1, sizeof(struct dpepoint));
- epnew->port = ep->port;
- epnew->compass = ep->compass;
- epnew->type = ep->type;
- epnew->root = ep->root;
- epnew->n = ep->n;
- el->ep = epnew;
- dp_eplink(ep);
- if (dp_headepl == NULL) {
- dp_headepl = el;
- dp_headeplend = el;
- } else {
- dp_headeplend->next = el;
- dp_headeplend = el;
- }
- return;
- }
- /* start edge at sstatements */
- void dp_starte2(struct dpepoint *ep)
- {
- struct dpepoint *epnew = NULL;
- struct dpeplink *el = NULL;
- dp_enest++;
- dp_curgraph->enest++;
- /* add point to global pointlist */
- el = (struct dpeplink *)dp_calloc(1, sizeof(struct dpeplink));
- epnew = (struct dpepoint *)dp_calloc(1, sizeof(struct dpepoint));
- epnew->port = ep->port;
- epnew->compass = ep->compass;
- epnew->type = ep->type;
- epnew->root = ep->root;
- epnew->n = ep->n;
- el->ep = epnew;
- dp_eplink(ep);
- if (dp_headepl == NULL) {
- dp_headepl = el;
- dp_headeplend = el;
- } else {
- dp_headeplend->next = el;
- dp_headeplend = el;
- }
- return;
- }
- /* inside edge statement */
- void dp_ine(struct dpepoint *ep)
- {
- dp_eplink(ep);
- return;
- }
- /* setup new edge for edge attribute */
- void dp_newe(void)
- {
- dp_curedge = (struct dpedge *)dp_calloc(1, sizeof(struct dpedge));
- dp_curedge->yylineno = yylineno;
- dp_edgegdef(dp_curgraph->defedge, dp_curedge);
- dp_atype_edge();
- return;
- }
- static void dp_endeprlink(struct dpeplink *el)
- {
- struct dpgraph *g = NULL;
- struct dpeplink *eptr = NULL;
- struct dpnlink *nodes = NULL;
- int ltype = 0;
- eptr = el;
- while (eptr) {
- ltype = eptr->ep->type;
- printf("\tltype=%d", ltype);
- if (eptr->ep->type == 0) {
- /* type 0: this is a node */
- printf("`%s' %p ", eptr->ep->n->name, (void *)eptr->ep->root);
- } else if (eptr->ep->type == 1) {
- printf("`subgraph-%p' : ", (void *)eptr->ep->root);
- /* type 1: this is a subgraph */
- g = eptr->ep->root;
- nodes = g->dpnodes;
- if (nodes) {
- while (nodes) {
- printf("`%s' ", nodes->n->name);
- nodes = nodes->next;
- }
- } else {
- printf("no-nodes");
- }
- } else {
- printf("dp_endeprlink()-unknown-ep->type");
- }
- printf("\n");
- eptr = eptr->next;
- }
- return;
- }
- /* make edges edges */
- static void dp_mkedges(void)
- {
- struct dpelink *nel = NULL;
- struct dpedge *newedge = NULL;
- struct dptelink *tl = NULL;
- tl = dp_tmpe;
- while (tl) {
- newedge = (struct dpedge *)dp_calloc(1, sizeof(struct dpedge));
- dp_edgenum++;
- newedge->nr = dp_edgenum;
- newedge->rootedon = dp_curgraph;
- newedge->fn = tl->e->fn;
- newedge->fport = tl->e->fport;
- newedge->fcompass = tl->e->fcompass;
- newedge->tn = tl->e->tn;
- newedge->tport = tl->e->tport;
- newedge->tcompass = tl->e->tcompass;
- newedge->yylineno = yylineno;
- /* copy edge attributes */
- dp_edgegdef(dp_curedge, newedge);
- nel = (struct dpelink *)dp_calloc(1, sizeof(struct dpelink));
- nel->e = newedge;
- if (dp_aedges == NULL) {
- dp_aedges = nel;
- dp_aedgesend = nel;
- } else {
- dp_aedgesend->next = nel;
- dp_aedgesend = nel;
- }
- nel = (struct dpelink *)dp_calloc(1, sizeof(struct dpelink));
- nel->e = newedge;
- /* */
- if (tl->e->fn->root->dpedges == NULL) {
- tl->e->fn->root->dpedges = nel; /* edges starting in this graph */
- tl->e->fn->root->dpedgesend = nel; /* edges starting in this graph */
- } else {
- tl->e->fn->root->dpedgesend->next = nel; /* edges starting in this graph */
- tl->e->fn->root->dpedgesend = nel; /* edges starting in this graph */
- }
- tl = tl->next;
- }
- return;
- }
- /* print all edges */
- static void dp_prtae(void)
- {
- struct dpelink *nel = NULL;
- printf("dot %s(): all edges:\n", __func__);
- nel = dp_aedges;
- while (nel) {
- printf(" `%s'->`%s'\n", nel->e->fn->name, nel->e->tn->name);
- nel = nel->next;
- }
- printf("dot %s(): end all edges\n", __func__);
- return;
- }
- /* print tmp edges */
- static void dp_prte(void)
- {
- struct dptelink *tl = NULL;
- tl = dp_tmpe;
- while (tl) {
- printf("dot %s(): `%s'->`%s' %p->%p\n", __func__, tl->e->fn->name,
- tl->e->tn->name, (void *)tl->e->fn->root, (void *)tl->e->tn->root);
- tl = tl->next;
- } return;
- }
- /* create tmp edges */
- static void dp_addte(struct dpnode *fn, char *fport, char *fcompass, struct dpnode *tn, char *tport, char *tcompass)
- {
- struct dptmpe *te = NULL;
- struct dptelink *tl = NULL;
- te = (struct dptmpe *)dp_calloc(1, sizeof(struct dptmpe));
- te->fn = fn;
- te->fport = fport;
- te->fcompass = fcompass;
- te->tn = tn;
- te->tport = tport;
- te->tcompass = tcompass;
- tl = (struct dptelink *)dp_calloc(1, sizeof(struct dptelink));
- tl->e = te;
- if (dp_tmpe == NULL) {
- dp_tmpe = tl;
- dp_tmpeend = tl;
- } else {
- dp_tmpeend->next = tl;
- dp_tmpeend = tl;
- }
- return;
- }
- static void dp_endel_n2n(struct dpepoint *fn, struct dpepoint *tn)
- {
- if (yydebug) {
- printf("%s(1): `%s'->`%s'\n", __func__, fn->n->name, tn->n->name);
- }
- dp_addte(fn->n, fn->port, fn->compass, tn->n, tn->port, tn->compass);
- return;
- }
- static void dp_endel_n2g(struct dpepoint *fn, struct dpepoint *tn)
- {
- struct dpgraph *g = NULL;
- struct dpnlink *nodes = NULL;
- g = tn->root;
- nodes = g->dpnodes;
- while (nodes) {
- if (yydebug) {
- printf("%s(1): `%s'->`%s'\n", __func__, fn->n->name, nodes->n->name);
- }
- dp_addte(fn->n, fn->port, fn->compass, nodes->n, NULL, NULL);
- nodes = nodes->next;
- }
- return;
- }
- /* subgraph to node as in {}->x */
- static void dp_endel_g2n(struct dpepoint *fn, struct dpepoint *tn)
- {
- struct dpgraph *g = NULL;
- struct dpnlink *nodes = NULL;
- g = fn->root;
- nodes = g->dpnodes;
- while (nodes) {
- if (yydebug || 0) {
- printf("%s(1): `%s'->`%s'\n", __func__, nodes->n->name, tn->n->name);
- }
- dp_addte(nodes->n, NULL, NULL, tn->n, tn->port, tn->compass);
- nodes = nodes->next;
- }
- return;
- }
- static void dp_endel_g2g(struct dpepoint *fn, struct dpepoint *tn)
- {
- struct dpgraph *g = NULL;
- struct dpnlink *nodes = NULL;
- struct dpgraph *g2 = NULL;
- struct dpnlink *nodes2 = NULL;
- g = fn->root;
- nodes = g->dpnodes;
- while (nodes) {
- g2 = tn->root;
- nodes2 = g2->dpnodes;
- while (nodes2) {
- if (yydebug) {
- printf("%s(1): `%s'->`%s'\n", __func__, nodes->n->name, nodes2->n->name);
- }
- dp_addte(nodes->n, NULL, NULL, nodes2->n, NULL, NULL);
- nodes2 = nodes2->next;
- }
- nodes = nodes->next;
- }
- return;
- }
- /* main */
- static void dp_endel(struct dpeplink *el)
- {
- struct dpeplink *eptr = NULL;
- struct dpepoint *fn = NULL;
- struct dpepoint *tn = NULL;
- int ltype = 0;
- int rtype = 0;
- eptr = el;
- if (yydebug || 0) {
- printf("%s(start): dp_enest=%d eptr=%p eptr->next=%p\n", __func__, dp_enest, (void *)eptr, (void *)eptr->next);
- }
- if (dp_enest > 1) {
- printf("dot %s(): nested edges not supported at line %d\n", __func__, yylineno);
- fflush(stdout);
- }
- if (eptr && eptr->next == NULL) {
- if (dp_headepl == NULL) {
- /* shouldnothappen */
- return;
- }
- /* from and to node */
- fn = dp_headepl->ep;
- tn = eptr->ep;
- ltype = fn->type;
- rtype = tn->type;
- /* check type of from and to node */
- if (ltype == 0 && rtype == 0) {
- dp_endel_n2n(fn, tn);
- } else if (ltype == 0 && rtype == 1) {
- dp_endel_n2g(fn, tn);
- } else if (ltype == 1 && rtype == 0) {
- dp_endel_g2n(fn, tn);
- } else if (ltype == 1 && rtype == 1) {
- dp_endel_g2g(fn, tn);
- } else {
- printf("%s(1): ltype=%d rtype=%d shouldnothappen\n", __func__, ltype, rtype);
- }
- } else {
- while (eptr) {
- if (eptr->next == NULL) {
- break;
- }
- fn = eptr->ep;
- tn = eptr->next->ep;
- fflush(stdout);
- ltype = fn->type;
- rtype = tn->type;
- if (dp_enest) {
- if (fn->root == tn->root) {
- if (ltype == 0 && rtype == 0) {
- dp_endel_n2n(fn, tn);
- } else if (ltype == 0 && rtype == 1) {
- dp_endel_n2g(fn, tn);
- } else if (ltype == 1 && rtype == 0) {
- dp_endel_g2n(fn, tn);
- } else if (ltype == 1 && rtype == 1) {
- dp_endel_g2g(fn, tn);
- } else {
- printf("%s(2): ltype=%d rtype=%d shouldnothappen\n", __func__, ltype, rtype);
- }
- }
- } else {
- /* nest is 0 */
- if (ltype == 0 && rtype == 0) {
- dp_endel_n2n(fn, tn);
- } else if (ltype == 0 && rtype == 1) {
- dp_endel_n2g(fn, tn);
- } else if (ltype == 1 && rtype == 0) {
- dp_endel_g2n(fn, tn);
- } else if (ltype == 1 && rtype == 1) {
- dp_endel_g2g(fn, tn);
- } else {
- printf
- ("%s(3): ltype=%d rtype=%d fn=%s tn=%s shouldnothappen\n",
- __func__, ltype, rtype, fn->n->name, tn->n->name);
- }
- }
- eptr = eptr->next;
- }
- }
- if (yydebug || 0) {
- printf("%s(end):\n", __func__);
- }
- return;
- }
- /* end edge statement */
- void dp_ende(void)
- {
- struct dpgraph *g = NULL;
- struct dpglink *sg = NULL;
- int en = 0;
- en = dp_curgraph->enest;
- if (yydebug || 0) {
- printf
- ("dot %s(): curgraph=%p now dp_curgraph->enest from %d to %d and enest from %d to %d\n",
- __func__, (void *)dp_curgraph, en, en - 1, dp_enest, dp_enest - 1);
- }
- dp_enest--;
- if (dp_enest < 0) {
- dp_enest = 0;
- }
- dp_curgraph->enest--;
- if (dp_curgraph->enest < 0) {
- dp_curgraph->enest = 0;
- }
- if (yydebug || 0) {
- printf("dot %s(): dp_epl list:\n", __func__);
- dp_endeprlink(dp_epl);
- g = dp_groot;
- printf(" root graph:\n");
- dp_endeprlink(g->dpeplist);
- sg = g->dpsubg;
- while (sg) {
- printf(" subgraph:\n");
- dp_endeprlink(sg->sg->dpeplist);
- sg = sg->next;
- }
- printf("dot %s(): end dp_epl list\n", __func__);
- printf("dot %s(): dp_headepl list:\n", __func__);
- dp_endeprlink(dp_headepl);
- printf("dot %s(): end dp_headepl list\n", __func__);
- fflush(stdout);
- }
- dp_endel(dp_epl);
- /* and full end of edge statement, handle the rest */
- if (dp_enest == 0) {
- if (yydebug || 0) {
- printf("dot %s(): Wipe headepl\n", __func__);
- /* print tmp edges */
- dp_prte();
- }
- /* make real edges */
- dp_mkedges();
- if (yydebug || 0) { /* print all edges */
- dp_prtae();
- }
- dp_curedge = (struct dpedge *)dp_free((void *)dp_curedge);
- if (dp_curedge) {
- }
- dp_clrheade();
- dp_clrtmpe();
- dp_enest = 0;
- }
- dp_atype_graph();
- fflush(stdout);
- return;
- }
- /* subg without name, also in edge like a->{b->c}
- * or with a name as in subgraph "ho" { }
- * or with empty name as in subgraph { }
- * or with nil name as in { }
- * types of subgraphs:
- * #define DP_SG_ROOT 0 * root graph type
- * #define DP_SG_CO 1 * compound subgraph {}
- * #define DP_SG_NM 2 * named subgrph
- * #define DP_SG_CL 3 * cluster subgraph
- * #define DP_SG_NN 4 * no name subgraph
- */
- void dp_namedsubg(char *sgname, int type)
- {
- struct dpgraph *nsg = NULL;
- nsg = (struct dpgraph *)dp_calloc(1, sizeof(struct dpgraph));
- /* uniq graph number */
- nsg->nr = dp_sgnr;
- dp_sgnr++;
- /* set factory defaults */
- dp_graphfdef(nsg);
- dp_nsubg(nsg, sgname, type);
- dp_graphlink(nsg);
- dp_pushgraph(nsg);
- return;
- }
- /* end ssatement in edge */
- struct dpepoint *dp_endss(void)
- {
- struct dpepoint *newe = NULL;
- struct dpgraph *g = NULL;
- newe = (struct dpepoint *)dp_calloc(1, sizeof(struct dpepoint));
- newe->type = 1; /* type 1: this is a subgraph edge point */
- newe->root = dp_curgraph;
- g = dp_pullgraph();
- if (g) {
- }
- return (newe);
- }
- void dp_cke(char *edgetype)
- {
- if (strcmp(edgetype, dp_groot->etype)) {
- memset(dp_errmsg, 0, 256);
- snprintf(dp_errmsg, (256 - 1),
- "dot %s(): syntax error edgetype `%s' but expected `%s' near line %d\n",
- __func__, edgetype, dp_groot->etype, yylineno);
- }
- return;
- }
- /* 'add' strings in a new string */
- char *dp_ccat(char *a, char *b)
- {
- size_t lena = 0;
- size_t lenb = 0;
- char *tmpp = NULL;
- char *res = NULL;
- /* add safety */
- if (a == NULL) {
- return (dp_uniqstr((char *)""));
- }
- /* add safety */
- if (b == NULL) {
- return (dp_uniqstr((char *)""));
- }
- lena = strlen(a);
- lenb = strlen(b);
- tmpp = (char *)dp_calloc(1, (lena + lenb + 1));
- strcpy(tmpp, a);
- strcat(tmpp, b);
- res = dp_uniqstr(tmpp);
- tmpp = (char *)dp_free((void *)tmpp);
- if (tmpp) {
- }
- return (res);
- }
- /* clear all memory in use zzz */
- void dp_clearall(void)
- {
- dp_clrep();
- dp_clrheade();
- dp_clrtmpe();
- /* clear all edges in graph */
- dp_clredges();
- dp_clrnodes();
- dp_clrgraphs();
- if (dp_groot) {
- dp_groot->gattr = splay_tree_delete(dp_groot->gattr);
- dp_groot->nattr = splay_tree_delete(dp_groot->nattr);
- dp_groot->eattr = splay_tree_delete(dp_groot->eattr);
- if (dp_groot->defnode) {
- dp_groot->defnode = (struct dpnode *)dp_free((void *)dp_groot->defnode);
- }
- if (dp_groot->defedge) {
- dp_groot->defedge = (struct dpedge *)dp_free((void *)dp_groot->defedge);
- }
- dp_groot = (struct dpgraph *)dp_free((void *)dp_groot);
- if (dp_groot) {
- }
- }
- dpgraphs = splay_tree_delete(dpgraphs);
- dp_curgraph = NULL;
- dp_groot = NULL;
- clear_dpuniqnode();
- dp_colorcode_clear();
- dp_clear_uniqstr();
- return;
- }
- /* end */
|