From bc6891859994c3c56fffbaa0f113fc717a36c882 Mon Sep 17 00:00:00 2001 From: erg <devnull@localhost> Date: Tue, 23 Jun 2009 16:16:16 +0000 Subject: [PATCH] Hook in gvpr library --- cmd/smyrna/gui/menucallbacks.c | 166 +++++++++++++-- cmd/smyrna/gvprpipe.c | 355 +++------------------------------ cmd/smyrna/gvprpipe.h | 2 +- 3 files changed, 180 insertions(+), 343 deletions(-) diff --git a/cmd/smyrna/gui/menucallbacks.c b/cmd/smyrna/gui/menucallbacks.c index 49ef7a4ea..7a2b50600 100755 --- a/cmd/smyrna/gui/menucallbacks.c +++ b/cmd/smyrna/gui/menucallbacks.c @@ -22,8 +22,11 @@ #include "gvprpipe.h" #include "topviewsettings.h" #include "gltemplate.h" +#include "memory.h" #include <const.h> #include <agxbuf.h> +#include <assert.h> +#include <ctype.h> //file char buf[255]; @@ -385,31 +388,154 @@ void mHelp(GtkWidget * widget, gpointer user_data) void change_cursor(GdkCursorType C) { - GdkCursor *cursor; - GdkWindow * w; - cursor = gdk_cursor_new(C); + GdkCursor *cursor; + GdkWindow * w; + cursor = gdk_cursor_new(C); w = (GdkWindow *) glade_xml_get_widget(xml, "frmMain"); - gdk_window_set_cursor((GdkWindow *) view->drawing_area->window, - cursor); + gdk_window_set_cursor((GdkWindow *) view->drawing_area->window, cursor); gdk_cursor_destroy(cursor); - return; } -float GetOGLDistance(int l); -void mTestgvpr(GtkWidget * widget, gpointer user_data) + +static const char* +endQuote (const char* args, agxbuf* xb, char endc) { -// apply_gvpr(view->g[view->activeGraph],"c:/graphviz-ms/bin/makered.g"); - int charcnt; - char* bf2; - GtkTextBuffer * gtkbuf; - GtkTextIter startit; - GtkTextIter endit; - gtkbuf=gtk_text_view_get_buffer((GtkTextView*) glade_xml_get_widget(xml,"gvprtextinput")); - charcnt=gtk_text_buffer_get_char_count (gtkbuf); - gtk_text_buffer_get_start_iter (gtkbuf,&startit); - gtk_text_buffer_get_end_iter (gtkbuf,&endit); + int more = 1; + char c; + + while (more) { + c = *args++; + if (c == endc) more = 0; + else if (c == '\0') { + more = 0; + args--; + } + else if (c == '\\') { + c = *args++; + if (c == '\0') args--; + else agxbputc (xb,c); + } + else + agxbputc (xb,c); + } + return args; +} + +static const char* +skipWS (const char* args) +{ + char c; + + while ((c = *args)) { + if (isspace(c)) args++; + else break; + } + return args; +} + +static const char* +getTok (const char* args, agxbuf* xb) +{ + char c; + int more = 1; + + args = skipWS(args); + if (*args == '\0') return 0; - bf2=gtk_text_buffer_get_text(gtkbuf,&startit,&endit,0); - run_gvpr (view->g[view->activeGraph], bf2); + while (more) { + c = *args++; + if (isspace(c)) more = 0; + else if (c == '\0') { + more = 0; + args--; + } + else if ((c == '"') || (c == '\'')) { + args = endQuote (args, xb, c); + } + else if (c == '\\') { + c = *args++; + if (c == '\0') args--; + else agxbputc (xb,c); + } + else + agxbputc (xb,c); + } + return args; +} + +static char** +splitArgs (const char* args, int* argcp) +{ + char** argv; + int argc; + int asize; + agxbuf xbuf; + unsigned char buf[SMALLBUF]; + + if (*args == '\0') { + *argcp = 0; + return 0; + } + + argc = 0; + asize = 0; + argv = 0; + agxbinit(&xbuf, SMALLBUF, buf); + while ((args = getTok (args, &xbuf))) { + if (asize <= argc) { + asize += 10; + argv = ALLOC(asize,argv,char*); + } + argv[argc++] = strdup(agxbuse(&xbuf)); + } + + agxbfree (&xbuf); + *argcp = argc; + return argv; +} + +void mTestgvpr(GtkWidget * widget, gpointer user_data) +{ + char* bf2; + GtkTextBuffer * gtkbuf; + GtkTextIter startit; + GtkTextIter endit; + const char* args; + int i, j, inargc, argc, writeGraph; + char** argv; + char** inargv; + + args = gtk_entry_get_text ((GtkEntry *)glade_xml_get_widget(xml, "gvprargs")); + gtkbuf=gtk_text_view_get_buffer((GtkTextView*) glade_xml_get_widget(xml,"gvprtextinput")); + gtk_text_buffer_get_start_iter (gtkbuf,&startit); + gtk_text_buffer_get_end_iter (gtkbuf,&endit); + bf2 = gtk_text_buffer_get_text(gtkbuf,&startit,&endit,0); + + inargv = splitArgs (args, &inargc); + + argc = inargc + 1; + if (*bf2 != '\0') argc++; + if (gtk_toggle_button_get_active((GtkToggleButton *) glade_xml_get_widget(xml, "gvprapplycb"))) { + writeGraph = 1; + argc++; + } + else + writeGraph = 0; + argv = N_NEW(argc+1, char*); + j = 0; + argv[j++] = "smyrna"; + if (writeGraph) + argv[j++] = strdup ("-c"); + for (i = 0; i < inargc; i++) + argv[j++] = inargv[i]; + free (inargv); + if (*bf2 != '\0') + argv[j++] = bf2; + assert (j == argc); + + run_gvpr (view->g[view->activeGraph], argc, argv); + for (i = 1; i < argc; i++) + free (argv[i]); + free (argv); } diff --git a/cmd/smyrna/gvprpipe.c b/cmd/smyrna/gvprpipe.c index a08444019..b83d8981f 100644 --- a/cmd/smyrna/gvprpipe.c +++ b/cmd/smyrna/gvprpipe.c @@ -17,349 +17,60 @@ #include "gvprpipe.h" #include <stdio.h> #include <stdlib.h> +#include <assert.h> #include <glade/glade.h> - - -#ifdef WIN32 -#include <windows.h> -#include <tchar.h> -#include <strsafe.h> -#else -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#endif - #include <viewport.h> -#include <const.h> -#include <agxbuf.h> extern GladeXML* xml; -#ifdef WIN32 - -/* two pipes - * 1 between smyrna and gvpr - * SmyrnaToGvprIn : write end of pipe , active graph's fread uses - * SmyrnaToGvprROut: read end of pipe , created process' std in uses - * 1 between gvpr and smyrna - * GvprToSmyrnaIn :write end of pipe, created process' stdout uses - * GvprToSmyrnaOut :read end of pipe, new graph's fread uses - */ - -static HANDLE GvprToSmyrnaWr; -static HANDLE GvprToSmyrnaWrErr; -static HANDLE GvprToSmyrnaRd; -static HANDLE GvprToSmyrnaErr; -static HANDLE SmyrnaToGvprWr; -static HANDLE SmyrnaToGvprRd; -static SECURITY_ATTRIBUTES saAttr; -static PROCESS_INFORMATION piProcInfo; - - -/*cgraph wrappers*/ -static int cgraph_write_wrapper(void *chan, char *str) -{ - DWORD dwWritten,lpExitCode; - BOOL bSuccess = FALSE; - GetExitCodeProcess( piProcInfo.hProcess,&lpExitCode); - if (lpExitCode!=259) /*still alive?*/ - return EOF; - - - bSuccess = WriteFile(SmyrnaToGvprWr, str, (DWORD)strlen(str), &dwWritten, NULL); - if ( ! bSuccess ) return EOF; - return 0; -} -static int cgraph_read_wrapper (void* ch,char* bf,int sz) -{ - DWORD dwRead; - BOOL bSuccess = FALSE; - int ind=0; - bSuccess=ReadFile( GvprToSmyrnaRd, bf, sz, &dwRead, NULL); - if ( ! bSuccess ) return EOF; - return dwRead; -} +#include <gvpr.h> +#include "topview.h" +#include "topviewsettings.h" -/* ErrorExit: - * Format a readable error message, display a message box, - * and exit from the application. - */ static void -ErrorExit(PTSTR lpszFunction) -{ - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); - StringCchPrintf((LPTSTR)lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s failed with error %d: %s"), - lpszFunction, dw, lpMsgBuf); - MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); - ExitProcess(1); -} - -static int dummyflush (void *chan) +refreshViewport () { - return 1; -} - -static Agraph_t* -ReadFromPipe() -{ - BOOL bSuccess = FALSE; - int totalbytes=0; - int ind=0; - Agiodisc_t a; - Agdisc_t disc; - Agraph_t* g=0; - - - if (!CloseHandle(SmyrnaToGvprWr)) - ErrorExit(TEXT("StdOutWr CloseHandle")); - - a.afread=cgraph_read_wrapper; - a.flush=dummyflush; - disc.io=&a; - disc.id = &AgIdDisc; - disc.mem = &AgMemDisc; - g=agread(NULL,&disc); -/* CloseHandle(piProcInfo.hProcess); - CloseHandle(piProcInfo.hThread);*/ - - return g; -} - -static void -CreateChildProcess(TCHAR* szCmdline,HANDLE g_hChildStd_IN_Rd,HANDLE g_hChildStd_OUT_Wr,HANDLE g_hChildStd_ERR_Wr) -{ - STARTUPINFO siStartInfo; - BOOL bSuccess = FALSE; - ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) ); - ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) ); - siStartInfo.cb = sizeof(STARTUPINFO); -// siStartInfo.hStdError = g_hChildStd_ERR_Wr; - siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; - siStartInfo.hStdInput = g_hChildStd_IN_Rd; - siStartInfo.dwFlags |= STARTF_USESTDHANDLES; - - bSuccess = CreateProcess(NULL, - szCmdline, // command line - NULL, // process security attributes - NULL, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - NULL, // use parent's environment - NULL, // use parent's current directory - &siStartInfo, // STARTUPINFO pointer - &piProcInfo); // receives PROCESS_INFORMATION - if ( ! bSuccess ) - { - - ErrorExit(TEXT("CreateProcess")); - - } - else - { -#if 0 - GetExitCodeProcess( piProcInfo.hProcess,&lpExitCode); - if (lpExitCode==259) /*still alive*/ -#endif - - } + update_graph_from_settings(view->g[view->activeGraph]); + set_viewport_settings_from_template(view, view->g[view->activeGraph]); + settvcolorinfo(view->g[view->activeGraph],view->Topview); + glexpose (); } -static void init_security_attr(SECURITY_ATTRIBUTES* Attr) +static ssize_t outfn (void* sp, const char *buf, size_t nbyte, void* dp) { - Attr->nLength = sizeof(SECURITY_ATTRIBUTES); - Attr->bInheritHandle = TRUE; - Attr->lpSecurityDescriptor = NULL; + return write (1, buf, nbyte); } -static void createpipes() +static ssize_t errfn (void* sp, const char *buf, size_t nbyte, void* dp) { - if ( ! CreatePipe(&GvprToSmyrnaRd, &GvprToSmyrnaWr, &saAttr, 0) ) - ErrorExit(TEXT("StdoutRd CreatePipe")); - if ( ! SetHandleInformation(GvprToSmyrnaRd, HANDLE_FLAG_INHERIT, 0) ) - ErrorExit(TEXT("Stdout SetHandleInformation")); - - - - if (! CreatePipe(&SmyrnaToGvprRd, &SmyrnaToGvprWr, &saAttr, 0)) - ErrorExit(TEXT("Stdin CreatePipe")); - - if ( ! SetHandleInformation(SmyrnaToGvprWr, HANDLE_FLAG_INHERIT, 0) ) - ErrorExit(TEXT("Stdin SetHandleInformation")); - + return write (2, buf, nbyte); } - - -#else - -#endif - -static Agraph_t* -exec_gvpr(Agraph_t* srcGraph, char* filename) -{ - Agraph_t* G; - unsigned char bf[SMALLBUF]; - agxbuf xbuf; -#ifdef WIN32 - DWORD lpExitCode; - Agiodisc_t* xio; - Agiodisc_t a; - init_security_attr(&saAttr); - createpipes(); -#else - FILE* pp; -#endif - - agxbinit (&xbuf, SMALLBUF, bf); - agxbput (&xbuf, "gvpr -c -f "); - agxbput (&xbuf, filename); - agxbput (&xbuf, " c:/tvgraph.gv"); - - -#ifdef WIN32 - CreateChildProcess (agxbuse (&xbuf), SmyrnaToGvprRd, GvprToSmyrnaWr,GvprToSmyrnaWr); - xio = srcGraph->clos->disc.io; - a.afread = srcGraph->clos->disc.io->afread; - a.putstr = cgraph_write_wrapper; - a.flush =xio->flush; - srcGraph->clos->disc.io = &a; - /*we need to check if there is still a pipe to write, iif child process is still alive?*/ - agwrite(srcGraph,NULL); - srcGraph->clos->disc.io = xio; - GetExitCodeProcess( piProcInfo.hProcess,&lpExitCode); - if (lpExitCode!=259) /*still alive?*/ - G=NULL; - else - G = ReadFromPipe() ; - CloseHandle(piProcInfo.hProcess); - CloseHandle(piProcInfo.hThread); -#else - pp = popen (agxbuse (&xbuf), "r+"); - if (!pp) { - fprintf (stderr, "error #:%d\n",errno); - exit(1); - } - - agwrite(srcGraph, pp); - G = agread(pp, NULL) ; - pclose (pp); - unlink (filename); -#endif - - return G; -} - -/* mkTemp: - */ -#ifdef WIN32 - -static char* -mkTempFile () +int run_gvpr (Agraph_t* srcGraph, int argc, char* argv[]) { - char buf[512]; - char buf2[512]; - - GetTempPath(512,buf); - if (GetTempFileName(buf,"gvpr",0,buf2)==0) - return NULL; - return strdup (buf2); -} - -#else -#define TMP_TEMPLATE "/tmp/_gvprXXXXXX" - -static char* -mkTempFile () -{ - char* name = strdup (TMP_TEMPLATE); + int i, rv = 1; + gvpropts opts; + Agraph_t* gs[2]; + + gs[0] = srcGraph; + gs[1] = 0; + opts.ingraphs = gs; + opts.out = outfn; + opts.err = errfn; + opts.flags = GV_USE_OUTGRAPH; - int rv = mkstemp (name); - if (rv < 0) { - free (name); - return NULL; - } - else { - close (rv); - return name; - } -} - -#endif - -/* - * saves a gvpr file as a temporary file, - * returns file name's full path or NULL on failure. - * Buffer is malloced, so must be freed. - */ -static char* -save_gvpr_program (char* prg) -{ - FILE *fp; - char* tmpname; + rv = gvpr (argc, argv, &opts); - tmpname = mkTempFile (); - fp = fopen(tmpname, "w"); - if (fp) { - fputs (prg, fp); - fclose (fp); - return tmpname; + if (rv) { /* error */ + fprintf (stderr, "Error in gvpr\n"); } - else { -#ifndef WIN32 - unlink (tmpname); -#endif - free (tmpname); - return NULL; + else if (opts.n_outgraphs) { + add_graph_to_viewport(opts.outgraphs[0]); + for (i = 1; i < opts.n_outgraphs; i++) + agclose (opts.outgraphs[i]); } -} - -extern Agraph_t* execGVPR(Agraph_t* srcG, char* prg); -static int -apply_gvpr(Agraph_t* g,char* prog) -{ -#ifdef WIN32 - Agraph_t* tempg = execGVPR (g, prog); -#else - Agraph_t* tempg = exec_gvpr (g, prog); -#endif - - if ((tempg) &&(gtk_toggle_button_get_active((GtkToggleButton *) glade_xml_get_widget(xml, "gvprapplycb")))) - { - add_graph_to_viewport(tempg); - return 1; - } - return 1; -} - -int run_gvpr (Agraph_t* srcGraph, char* script) -{ - char* tmpf; - int rv = 1; - - if ((tmpf = save_gvpr_program(script))) { - rv = apply_gvpr (srcGraph, tmpf); - free (tmpf); + else { + refreshViewport (); } return rv; } diff --git a/cmd/smyrna/gvprpipe.h b/cmd/smyrna/gvprpipe.h index 890e8cfcb..c9fe3f915 100644 --- a/cmd/smyrna/gvprpipe.h +++ b/cmd/smyrna/gvprpipe.h @@ -19,6 +19,6 @@ #include "cgraph.h" -extern int run_gvpr(Agraph_t* srcGraph, char* script); +extern int run_gvpr(Agraph_t* srcGraph, int, char**); #endif -- 2.40.0