1 /* $Id$ $Revision$ */
2 /* vim:set shiftwidth=4 ts=8: */
3 
4 /*************************************************************************
5  * Copyright (c) 2011 AT&T Intellectual Property
6  * All rights reserved. This program and the accompanying materials
7  * are made available under the terms of the Eclipse Public License v1.0
8  * which accompanies this distribution, and is available at
9  * http://www.eclipse.org/legal/epl-v10.html
10  *
11  * Contributors: See CVS logs. Details at http://www.graphviz.org/
12  *************************************************************************/
13 
14 
15 /* avoid compiler warnings with template changes in Tcl8.4 */
16 /*    specifically just the change to Tcl_CmdProc */
17 #define USE_NON_CONST
18 #include <tcl.h>
19 #include "render.h"
20 #include "gvc.h"
21 #include "gvio.h"
22 #include "tclhandle.h"
23 
24 #ifndef CONST84
25 #define CONST84
26 #endif
27 
28 /* ******* not ready yet
29 #if (TCL_MAJOR_VERSION > 7)
30 #define TCLOBJ
31 #if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION == 0)
32 char *
33 Tcl_GetString(Tcl_Obj *obj) {
34     int len;
35 	return (Tcl_GetStringFromObj(obj, &len));
36 }
37 #else
38 #define UTF8
39 #endif
40 #endif
41 ********* */
42 
43 /*
44  * ictx - one per tcl interpreter, may support multiple graph namespaces
45  */
46 typedef struct {
47     Agdisc_t mydisc;    /* must be first to allow casting mydisc to ictx */
48     Agiodisc_t myioDisc;
49     uint64_t ctr;  /* odd number counter for anon objects over all g's in interp */
50     Tcl_Interp *interp;
51     GVC_t *gvc;
52 } ictx_t;
53 
54 /*
55  * gctx - one for each graph in a tcl interp
56  */
57 typedef struct {
58     Agraph_t *g;        /* the graph */
59     ictx_t *ictx;
60     uint64_t idx;
61 } gctx_t;
62 
63 #if HAVE_LIBGD
64 extern void *GDHandleTable;
65 extern int Gdtclft_Init(Tcl_Interp *);
66 #endif
67 
68 extern int graphcmd(ClientData clientData, Tcl_Interp * interp,
69 #ifndef TCLOBJ
70 		    int argc, char *argv[]
71 #else
72 		    int argc, Tcl_Obj * CONST objv[]
73 #endif
74     );
75 extern int nodecmd(ClientData clientData, Tcl_Interp * interp,
76 #ifndef TCLOBJ
77 		    int argc, char *argv[]
78 #else
79 		    int argc, Tcl_Obj * CONST objv[]
80 #endif
81     );
82 extern int edgecmd(ClientData clientData, Tcl_Interp * interp,
83 #ifndef TCLOBJ
84 		    int argc, char *argv[]
85 #else
86 		    int argc, Tcl_Obj * CONST objv[]
87 #endif
88     );
89 
90 /* rdr_t isn't exposed by cgraph/io.c */
91 typedef struct {
92     const char *data;
93     int len;
94     int cur;
95 } rdr_t;
96 
97 extern int myiodisc_afread(void* channel, char *ubuf, int n);
98 extern int myiodisc_memiofread(void *chan, char *buf, int bufsize);
99 extern Agiddisc_t myiddisc;
100 extern Agraph_t *agread_usergets (ictx_t *ictx, FILE * fp, int (*usergets)(void *chan, char *buf, int bufsize));
101 extern Agraph_t *cmd2g(char *cmd);
102 extern Agnode_t *cmd2n(char *cmd);
103 extern Agedge_t *cmd2e(char *cmd);
104 extern char *obj2cmd(void *obj);
105 extern void deleteEdge(gctx_t *gctx, Agraph_t * g, Agedge_t * e);
106 extern void deleteNode(gctx_t *gctx, Agraph_t * g, Agnode_t * n);
107 extern void deleteGraph(gctx_t *gctx, Agraph_t * g);
108 extern void listGraphAttrs (Tcl_Interp * interp, Agraph_t* g);
109 extern void listNodeAttrs (Tcl_Interp * interp, Agraph_t* g);
110 extern void listEdgeAttrs (Tcl_Interp * interp, Agraph_t* g);
111 
112 extern void setgraphattributes(Agraph_t * g, char *argv[], int argc);
113 extern void setedgeattributes(Agraph_t * g, Agedge_t * e, char *argv[], int argc);
114 extern void setnodeattributes(Agraph_t * g, Agnode_t * n, char *argv[], int argc);
115 
116 extern size_t Tcldot_string_writer(GVJ_t *job, const char *s, size_t len);
117 extern size_t Tcldot_channel_writer(GVJ_t *job, const char *s, size_t len);
118 
119 extern void tcldot_layout(GVC_t *gvc, Agraph_t * g, char *engine);
120 
121 /* Check whether string str corresponds to option opname.
122  * opname: literal string.
123  * str: the string to check.
124  * str0: first character of str.
125  * strn: length of str. */
126 #define MATCHES_OPTION(opname, str, str0, strn) \
127 	(opname[0] == str0) && (sizeof(opname)-1 == strn) && (strncmp(opname, str, sizeof(opname)) == 0)
128