#include "common.h" #include "util.h" SEXP Rgraphviz_buildNodeList(SEXP nodes, SEXP nodeAttrs, SEXP subGList, SEXP defAttrs) { SEXP pNodes; SEXP pnClass, curPN; SEXP attrs, attrNames, tmpStr; SEXP curSubG, subGNodes; int i, j, k, nSubG; nSubG = length(subGList); PROTECT(pnClass = MAKE_CLASS("pNode")); PROTECT(pNodes = allocVector(VECSXP, length(nodes))); PROTECT(attrNames = allocVector(STRSXP, 1)); SET_STRING_ELT(attrNames, 0, mkChar("label")); for (i = 0; i < length(nodes); i++) { PROTECT(tmpStr = allocVector(STRSXP, 1)); SET_STRING_ELT(tmpStr, 0, STRING_ELT(nodes, i)); PROTECT(curPN = NEW_OBJECT(pnClass)); SET_SLOT(curPN, Rf_install("name"), tmpStr); PROTECT(attrs = allocVector(VECSXP, 1)); setAttrib(attrs, R_NamesSymbol, attrNames); SET_VECTOR_ELT(attrs, 0, tmpStr); SET_SLOT(curPN, Rf_install("attrs"), attrs); SET_VECTOR_ELT(pNodes, i, curPN); for (j = 0; j < nSubG; j++) { curSubG = getListElement(VECTOR_ELT(subGList, j), "graph"); subGNodes = GET_SLOT(curSubG, Rf_install("nodes")); for (k = 0; k < length(subGNodes); k++) { if (strcmp(CHAR(STRING_ELT(subGNodes, k)), CHAR(STRING_ELT(nodes, i))) == 0) break; } if (k == length(subGNodes)) continue; SET_SLOT(curPN, Rf_install("subG"), Rf_ScalarInteger(j+1)); /* Only one subgraph per node */ break; } UNPROTECT(3); } setAttrib(pNodes, R_NamesSymbol, nodes); /* Put any attributes associated with this node list in */ pNodes = assignAttrs(nodeAttrs, pNodes, defAttrs); UNPROTECT(3); return(pNodes); }