Logo Search packages:      
Sourcecode: vcg version File versions  Download package

animation2.c

/* SCCS-info %W% %E% */

/*--------------------------------------------------------------------*/
/*                                                                    */
/*              VCG : Visualization of Compiler Graphs                */
/*              --------------------------------------                */
/*                                                                    */
/*   file:         animation2.c                                       */
/*   version:      1.00.00                                            */
/*   creation:     12.11.93                                           */
/*   author:       G. Sander (Version 1.00.00-...)                    */  
/*                 Universitaet des Saarlandes, 66041 Saarbruecken    */
/*                 ESPRIT Project #5399 Compare                       */
/*   description:  Animation demo 2 for VCG                           */
/*   status:       in work                                            */
/*                                                                    */
/*--------------------------------------------------------------------*/

/* $Id: animation2.c,v 1.7 1995/02/08 11:21:41 sander Exp $ */

/*
 *   Copyright (C) 1993, 1994 by Georg Sander, Iris Lemke, and
 *                               the Compare Consortium 
 *
 *  This program and documentation is free software; you can redistribute 
 *  it under the terms of the  GNU General Public License as published by
 *  the  Free Software Foundation;  either version 2  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,  write  to  the  Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  The software is available per anonymous ftp at ftp.cs.uni-sb.de.
 *  Contact  sander@cs.uni-sb.de  for additional information.
 */


/* $Log: animation2.c,v $
 * Revision 1.7  1995/02/08  11:21:41  sander
 * Distribution Version 1.3
 *
 * Revision 1.6  1994/03/04  20:03:15  sander
 * Small bug "-a 1" should be "-a -1" in call of vcg.
 *
 * Revision 1.5  1994/03/02  14:29:05  sander
 * Gnu License message added.
 * Call of VCG improved by first looking for local vcg's.
 *
 * Revision 1.4  1994/01/21  20:05:00  sander
 * Signal handling adapted for Sys V.
 * Some portability problems solved for Silicon Graphics IRIS and IBM R6000.
 *
 * Revision 1.3  1994/01/05  20:07:42  sander
 * X11 bug: open xvcg with -geometry, fixed
 *
 * Revision 1.2  1994/01/03  17:43:24  sander
 * Remarks added.
 *
 * Revision 1.1  1993/12/06  11:23:59  sander
 * Initial revision
 *
 */


/*--------------------------------------------------------------------*
 * This is a small example how to program a animation. The protocol
 * used here is the following:
 *
 * The client (this program) sends signals to the server (VCG) when
 * the server should display the graph.
 * The server send a signal SIGUSR1 back to the client, when it is
 * ready with displaying. Thus the server need not the have write
 * access to the file.
 *--------------------------------------------------------------------*/

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <signal.h> 
#include "../src/globals.h"


/* Prototypes
 * ----------
 */

void main         _PP((void));
void next_state         _PP((void));
void call_vcg           _PP((void));
void signal_vcg         _PP((int k));
void set_signal         _PP((void));
int  signal_handler     _PP((int signl));

void create_graph _PP((int x,int y));
void open_graph         _PP((void));
void close_graph  _PP((void));
void create_node  _PP((char *title,int x,int y));
void create_edge  _PP((char *so,char *ta));
char *get_color         _PP((void));


/* This must be an absolute path to the vcg-tool !
 * No ~, .. or similar trash allowed.
 */

#ifndef VCGCALL
#define VCGCALL "/RW/esprit/users/sander/ABC/vcg"
#endif

#ifndef VCGTOOL
#define VCGTOOL "vcg"
#endif



/* Global Variables
 * ----------------
 */

FILE *f = NULL;
char filename[] = "animfile2.vcg";

/* Flag, indicates that the animation is still ongoing and that 
 * we should wait for the next signal.
 */

int not_ready;    


/* Counter, indicates which instance of the graph should be generated.
 */

int act_state;

/*--------------------------------------------------------------------*/

/* Main Routine
 * ------------
 * The main program consists of a small sequence of pictures.
 * Each picture is generated by create_graph and reloaded into
 * the vcg by signal_vcg. The problem with synchronizing by
 * signals is, that we cannot write down the animation process
 * in a sequential manner. Each time a synchronizing signal
 * comes in, we have to generate a new state of the graph
 * and signal this to vcg, i.e. the process is event driven. 
 * Pause causes the driver program to sleep until the next signal 
 * event comes in.
 */


#ifdef ANSI_C
void main(void)
#else
void main()
#endif
{
      set_signal();
      create_graph(20,20);
      call_vcg(); 
      not_ready = 1;
      act_state = 0;
      while (not_ready) pause();  /* wait for signal */
      signal_vcg(- SIGUSR2);      /* close vcg (does not work with X11 */
      pause();              /* wait for signal */
      sleep(3);
      signal_vcg(- SIGQUIT);      /* exit vcg  */
}

/* Create the next state of the graph 
 * ----------------------------------
 */ 

#ifdef ANSI_C
void next_state(void)
#else
void next_state()
#endif
{
      act_state++;
      if (act_state > 12) { not_ready=0; return; }
      if (act_state > 6) create_graph(20+(12-act_state)*40,20); 
      else create_graph(20+act_state*40,20);          
      sleep(1);
      signal_vcg(- SIGUSR1);  /* reload file */
}


/*--------------------------------------------------------------------*/
/*   Communication with vcg                                           */
/*--------------------------------------------------------------------*/

/* Call the vcg-tool
 * -----------------
 * Calling means fork a child process that is the vcg-tool.
 */

int   pid;      /* Process Id of the vcg process */

#ifdef ANSI_C
void call_vcg(void)
#else
void call_vcg()
#endif
{
      pid = fork();
      switch (pid) {
      case -1: /* this is an error */
             FPRINTF(stderr,"Cannot fork process vcg\n");
             exit(-1);
             /* NEVER REACHED */ 
             
      case 0:  /* this is the child process: call vcg   */

                { char toolname[1024];

                  strcpy(toolname,"../src/");
                  strcat(toolname,VCGTOOL);
                  if ((f = fopen(toolname,"r")) != NULL) {
                        fclose(f);
                  }
                  else if ((f = fopen(VCGCALL,"r")) != NULL) {
                        fclose(f);
                        strcpy(toolname,VCGCALL);
                  }     
                  else  strcpy(toolname,VCGTOOL);


                  PRINTF("Call %s\n",toolname);
                  execl(toolname,toolname,
                        "-a","-1",
#ifdef X11
                        "-geometry","200x200-30+30",
#endif
                        filename,0L);
                }
                 /* NEVER REACHED */

      default: /* this is the father process:            */
             /* pid is now the ID of the child process */
            ;
      }
}


/* Send a signal to the vcg-tool
 * -----------------------------
 */

char cmdline[1024];  /* Buffer for the kill-command */

#ifdef ANSI_C
void signal_vcg(int k)
#else
void signal_vcg(k)
int k;
#endif
{
      SPRINTF(cmdline,"kill %d %d \n",k,pid);
      system(cmdline);
}



/*--------------------------------------------------------------------*/
/*   Signal handling                                                  */
/*--------------------------------------------------------------------*/

/*
 *  Initialisation of Signal Handler
 *  --------------------------------
 *  This has to be done before the first signal is recognized.
 */


#ifdef ANSI_C
void set_signal(void)
#else
void set_signal()
#endif
{
        if ( (int)signal(SIGUSR1,(void (*)())signal_handler) == -1 ) {
                FPRINTF(stderr,"Can't set USR1 process signal.\n");
                exit(-1);  
        }
}

/*
 *  Signal Handler for Signal USR1
 *  ------------------------------
 */

#ifdef ANSI_C
int signal_handler(int signl)
#else
int signal_handler(signl)
int     signl;
#endif
{
      set_signal();
      next_state();
        return(0);
}

 

/*--------------------------------------------------------------------*/
/*   Create an instance of the graph                                  */
/*--------------------------------------------------------------------*/

/* Write a graph to the file
 * -------------------------
 * After writing, we synchronize the file system to be sure that
 * writing is finished before the vcg starts loading.
 * Our simple graph consists of two nodes titled `A' and `B'.
 * The position of node `A' is fixed, but the position of node
 * `B' depends on x,y of this graph instance.
 */

#ifdef ANSI_C
void create_graph(int x,int y)
#else
void create_graph(x,y)
int x, y;
#endif
{
      f = fopen(filename,"w");
      if (!f) return;

      open_graph();
      create_node("A",100,100);
      create_node("B",x,y);
      create_edge("A","B");
      close_graph();

      fsync(fileno(f));       /* Assert that the file is written */
      if (f) fclose(f);
}


/* Sequence to start a graph
 * -------------------------
 */

#ifdef ANSI_C
void open_graph(void)
#else
void open_graph()
#endif
{
            FPRINTF(f,"graph: { title:\"test\"\n"); 
      FPRINTF(f,"         x: 30 y: 30\n");
      FPRINTF(f,"         xmax: 300 ymax: 300\n");
      FPRINTF(f,"         display_edge_labels: yes\n");
}


/* Sequence to complete a graph
 * ----------------------------
 */

#ifdef ANSI_C
void close_graph(void)
#else
void close_graph()
#endif
{
      FPRINTF(f,"}\n");
}


/* Write a node of title `title' and position `x',`y' to the file
 * --------------------------------------------------------------
 */

#ifdef ANSI_C
void create_node(char *title,int x,int y)
#else
void create_node(title,x,y)
char *title;
int x,y;
#endif
{
            FPRINTF(f,"         node: { title: \"%s\" label: \"%s\" ", 
            title, title); 
      FPRINTF(f,"loc: { x: %d y: %d } ", x, y);
            FPRINTF(f,"color: %s ",get_color()); 
            FPRINTF(f,"textcolor: %s ",get_color()); 
            FPRINTF(f,"bordercolor: %s ",get_color()); 
      FPRINTF(f,"}\n");
}


/* Write an edge
 * -------------
 * between nodes of sourcetitle `so' and targettitle `ta'.
 */

#ifdef ANSI_C
void create_edge(char *so,char *ta)
#else
void create_edge(so,ta)
char *so,*ta;
#endif
{
            FPRINTF(f,"         edge: { sourcename: \"%s\" targetname: \"%s\" ", 
              so, ta); 
            FPRINTF(f,"label: \"demo\" "); 
            FPRINTF(f,"color: %s ",get_color()); 
            FPRINTF(f,"class: 1 "); 
      FPRINTF(f,"}\n");
}



/* Get an arbitrary color
 * ----------------------
 * Colors except white are returned.
 * Consecutive calls of this function will return different colors.
 */
 
int color_cntr = 0;

#ifdef ANSI_C
char *get_color(void)
#else
char *get_color()
#endif
{
      color_cntr++;
      if (color_cntr>30) color_cntr = 0;
      switch (color_cntr) {
        case  0: return("blue");
        case  1: return("red");
        case  2: return("green");
        case  3: return("yellow");
        case  4: return("magenta");
        case  5: return("cyan");
        case  6: return("darkgrey");
        case  7: return("darkblue");
        case  8: return("darkred");
        case  9: return("darkgreen");
        case 10: return("darkyellow");
        case 11: return("darkmagenta");
        case 12: return("darkcyan");
        case 13: return("gold");
        case 14: return("lightgrey");
        case 15: return("lightblue");
        case 16: return("lightred");
        case 17: return("lightgreen");
        case 18: return("lightyellow");
        case 19: return("lightmagenta");
        case 20: return("lightcyan");
        case 21: return("lilac");
        case 22: return("turquoise");
        case 23: return("aquamarine");
        case 24: return("khaki");
        case 25: return("purple");
        case 26: return("yellowgreen");
        case 27: return("pink");
        case 28: return("orange");
        case 29: return("orchid");
      }
        return("black");
}

/*--------------------------------------------------------------------*/


Generated by  Doxygen 1.6.0   Back to index