Logo Search packages:      
Sourcecode: vcg version File versions

main.c

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

/*--------------------------------------------------------------------*/
/*                                                                    */
/*              VCG : Visualization of Compiler Graphs                */
/*              --------------------------------------                */
/*                                                                    */
/*   file:         main.c                                             */
/*   version:      1.00.00                                            */
/*   creation:     1.4.1993                                           */
/*   author:       I. Lemke  (...-Version 0.99.99)                    */
/*                 G. Sander (Version 1.00.00-...)                    */  
/*                 Universitaet des Saarlandes, 66041 Saarbruecken    */
/*                 ESPRIT Project #5399 Compare                       */
/*   description:  Top level program                                  */
/*   status:       in work                                            */
/*                                                                    */
/*--------------------------------------------------------------------*/

#ifndef lint
static char *id_string="$Id: main.c,v 3.17 1995/02/08 11:11:14 sander Exp $";
#endif


/*
 *   Copyright (C) 1993--1995 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: main.c,v $
 * Revision 3.17  1995/02/08  11:11:14  sander
 * Distribution version 1.3.
 *
 * Revision 3.16  1994/12/23  18:12:45  sander
 * Manhatten layout added.
 * Option interface cleared.
 *
 * Revision 3.15  1994/11/25  15:43:29  sander
 * Printer interface added to allow to use VCG as a converter.
 *
 * Revision 3.14  1994/11/23  14:50:47  sander
 * Input behaviour changed. Better behaviour in the case that we have no
 * input file.
 * Option -nocopt added.
 *
 * Revision 3.13  1994/08/08  16:01:47  sander
 * Attributes xraster, xlraster, yraster added.
 *
 * Revision 3.12  1994/08/05  12:13:25  sander
 * Treelayout added. Attributes "treefactor" and "spreadlevel" added.
 * Scaling as abbreviation of "stretch/shrink" added.
 *
 * Revision 3.11  1994/08/03  14:03:59  sander
 * Version Number to 1.1 changed.
 *
 * Revision 3.10  1994/08/02  15:36:12  sander
 * Local crossing unwinding implemented.
 *
 * Revision 3.9  1994/06/07  14:09:59  sander
 * Splines implemented.
 * HP-UX, Linux, AIX, Sun-Os, IRIX compatibility tested.
 * The tool is now ready to be distributed.
 *
 * Revision 3.8  1994/05/17  16:35:59  sander
 * attribute node_align added to allow nodes to be centered in the levels.
 *
 * Revision 3.7  1994/05/16  08:56:03  sander
 * shape attribute (boxes, rhombs, ellipses, triangles) added.
 *
 * Revision 3.6  1994/05/05  08:20:30  sander
 * Algorithm late labels added: If labels are inserted
 * after partitioning, this may yield a better layout.
 *
 * Revision 3.5  1994/04/27  16:05:19  sander
 * Some general changes for the PostScript driver.
 * Horizontal order added. Bug fixes of the folding phases:
 * Folding of nested graphs works now.
 *
 * Revision 3.4  1994/03/04  19:11:24  sander
 * Specification of levels per node added.
 * X11 geometry behaviour (option -geometry) changed such
 * that the window is now opened automatically.
 *
 * Revision 3.3  1994/03/03  14:12:21  sander
 * median centering heuristics added to reduce crossings.
 *
 * Revision 3.2  1994/03/02  11:48:54  sander
 * Layoutalgoritms mindepthslow, maxdepthslow, minindegree, ... mandegree
 * added.
 * Anchors and nearedges are not anymore allowed to be intermixed.
 * Escapes in strings are now allowed.
 *
 * Revision 3.1  1994/03/01  10:59:55  sander
 * Copyright and Gnu Licence message added.
 * Problem with "nearedges: no" and "selfloops" solved.
 *
 * Revision 2.4  1994/01/21  19:33:46  sander
 * VCG Version tested on Silicon Graphics IRIX, IBM R6000 AIX and Sun 3/60.
 * Option handling improved. Option -grabinputfocus installed.
 * X11 Font selection scheme implemented. The user can now select a font
 * during installation.
 * Sun K&R C (a nonansi compiler) tested. Some portabitility problems solved.
 *
 * Revision 2.3  1994/01/03  15:29:06  sander
 * First complete X11 version.
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "globals.h"
#include "grammar.h"
#include "alloc.h"
#include "usrsignal.h"
#include "folding.h"
#include "steps.h"
#include "timelim.h"
#include "main.h"
#include "options.h"
#include "grprint.h"
#include "PSdev.h"
#include "timing.h"

#ifdef X11

#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Xproto.h>
#include <ctype.h>
#include <math.h>
#include "main.h"
#include "X11devpb.h"

#endif

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

/* Prototypes
 * ==========
 */

/*  These functions are device dependent. Instead including all external
 *  device dependent h-files, we declare them here as external. This
 *  simplifies the selection of the device.
 *  Depending on the device, these functions are implemented in sunvdev.c 
 *  or X11dev.c.
 */

extern void display_part      _PP((void));
extern void setScreenSpecifics  _PP((void));
extern void gs_exit             _PP((int x));

static int   f_is_writable    _PP((char *fname));


/* Global variables
 * ================
 */


char short_banner[128];
char version_str[24]  = "V.1.3";
char date_str[48]     = "$Date: 1995/02/08 11:11:14 $";
char revision_str[48] = "$Revision: 3.17 $";



/*--------------------------------------------------------------------*/
/*  Main routines                                           */
/*--------------------------------------------------------------------*/


/*  The main program
 *  ================
 */


#ifdef ANSI_C
int main(int argc, char *argv[])
#else
int main(argc, argv)
int   argc;
char  *argv[];
#endif
{
      int i;

#ifdef NEVER
      printf("%d %d\n",sizeof(struct gnode),sizeof(struct gedge));
#endif

      for (i=0; i<48; i++) {
            if (date_str[i]=='$')     date_str[i]=' ';      
            if (revision_str[i]=='$') revision_str[i]=' ';  
      }
      
      SPRINTF(short_banner,"USAAR Visualization Tool VCG/XVCG %s %s", 
                  version_str, revision_str);

      set_signal();

      G_xmax = G_ymax = -1;

      if ( argc <= 1) {
            PRINTF("Filename: "); fflush(stdout);
            for (i=0; i<800; i++) {
                  Dataname[i] = (char)fgetc(stdin);
                  if (Dataname[i]==0) break;
                  if (Dataname[i]==10) { Dataname[i] = 0; break; }
                  if (Dataname[i]==13) { Dataname[i] = 0; break; }
            }
      }
      else {  /* Get arguments from the command line */

            if (!scanOptions(argc, argv)) print_basic_help(); /* and exit */
      }

      print_version_copyright();
      print_help(); 

      if (!Dataname[0]) {
            PRINTF("Filename: "); fflush(stdout);
            for (i=0; i<800; i++) {
                  Dataname[i] = (char)fgetc(stdin);
                  if (Dataname[i]==0) break;
                  if (Dataname[i]==10) { Dataname[i] = 0; break; }
                  if (Dataname[i]==13) { Dataname[i] = 0; break; }
            }
      }
      for (i=0; i<800; i++) { if (Dataname[i]!=' ') break; }
      strncpy(filename,&(Dataname[i]),  800-i);
      filename[ 800] = 0;
      
      for (i=0; i<800; i++) { if (filename[i]!=' ') break; }
      if (i==800)         print_basic_help(); /* and exit */ 
      if (filename[i]==0) print_basic_help(); /* and exit */ 

      if (fastflag) {
            min_baryiterations = 0;
            max_baryiterations = 2;
            min_mediumshifts = 0;
            max_mediumshifts = 2;
            min_centershifts = 0;
            max_centershifts = 2;
            max_edgebendings = 2;
            max_straighttune = 2;
      }

      if (!silent) { FPRINTF(stdout,"Wait "); FFLUSH(stdout); }
      parse_part();
      visualize_part();

      if (exfile) {

            /* Batch conversion mode is called: We initialize the format paramters
             * and the produce the printout file.
             */

            set_of_region(0L, 0L, 
                  maximal_xpos + (long)G_xbase, 
                  maximal_ypos + (long)G_ybase);
            act_output_type = extype; 
            act_paper_type  = expaper; 
            act_paper_num   = expapernum; 
            act_color_type  = excolor; 
            act_ori_type    = exori; 
            act_bbox        = exbbox; 
            set_of_xdpi(exxdpi);
            set_of_ydpi(exydpi);

            if (exscaling>0.0) 
                  set_of_scaling(exscaling);
            else if ((exwidth>0.0) && (exheight>0.0))
                  fit_of_heightwidth(exheight, exwidth);
            else if (exwidth>0.0)
                  set_of_width(exwidth);
            else if (exheight>0.0)
                  set_of_height(exheight);
            else set_of_maxspect();

            set_of_centerx();
            set_of_centery();

            if (exleftm >-0.5)   set_of_leftmargin  (exleftm);
            if (exrightm>-0.5)   set_of_rightmargin (exrightm);
            if (extopm >-0.5)    set_of_topmargin   (extopm);
            if (exbottomm >-0.5) set_of_topmargin   (exbottomm);

            if (f_is_writable(exfilename)) {
                  switch (act_output_type) {
                  case 0: (void)print_graph(exfilename);
                        break;
                  case 1:
                  case 2: (void)print_pbm_or_ppm(
                              exfilename, 0, 0,
                              maximal_xpos + (long)G_xbase, 
                              maximal_ypos + (long)G_ybase);
                        break;
                  case 3: (void)print_all_ps(
                              exfilename, 0, 0,
                              maximal_xpos + (long)G_xbase, 
                              maximal_ypos + (long)G_ybase);
                        break;
                  }
            }
            else {
                  FPRINTF(stderr,"Error on writing file %s.", exfilename);
                  FPRINTF(stderr," Illegal file name, or");
                  FPRINTF(stderr," file may exist or is unwriteable.\n");
            } 
      }
      else {  /* Display part calls the display device driver. This is a 
             * device dependent function !!!
             * The device driver is basically a loop that draws the graph and
             * reacts on interaction, until the FINISHING interaction is 
             * selected.
             */
            display_part(); 
      }

      return(0);
}


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

/* Check whether file is writable
 * ==============================
 * Returns 1 if yes. .
 */

#ifdef ANSI_C
static int f_is_writable(char *fname)
#else
static int f_is_writable(fname)
char *fname;
#endif
{
        FILE *f;
        char *c;

        f = NULL;
        c = fname;
        while (*c) c++;
        if (c>fname) c--;
        if (*c=='/')  return(0); 
        if (( strcmp(fname,"-")==0 ) || (*fname==0))  return(0); 
        f = fopen(fname,"r");
        if (f != NULL) { fclose(f); return(0); }
        return(1);
}


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

/*  Fatal Errors 
 *  ============
 *  Note: the parser uses internally the function fatal_error which is
 *  different.
 */


#ifdef ANSI_C
void Fatal_error(char *x,char *y)
#else
void Fatal_error(x,y)
char *x;
char *y;
#endif
{
            FPRINTF(stderr,"Fatal error: %s %s !\n",x,y);
            FPRINTF(stderr,"Aborted !\n");
        gs_exit(-1);
}



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

/*  Call of the parser
 *  ==================
 */

#ifdef ANSI_C
void  parse_part(void)
#else
void  parse_part()
#endif
{
      int   errs,i;

      start_time();
      debugmessage("parse_part","");

      /* We start from the scratch */

      info_name_available = 0;
      for (i=0; i<3; i++) info_names[i]=NULL;

      free_memory();
      yyin = NULL;

      if ( strcmp(Dataname,"-")==0 ) yyin = stdin;
      else {
            yyin = fopen(Dataname,"r");
            if (yyin == NULL) Fatal_error("Cannot open",Dataname);
            }

      free_timelimit();
      if (G_timelimit>0) init_timelimit(G_timelimit);
        errs = parse();

        if ((yyin)&&(yyin!=stdin)) fclose(yyin);

        if (errs>0) Fatal_error("Syntax error","");
      assert((Syntax_Tree!=NULL));

      stop_time("parse_part");
}


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

/*  Call of the visualizer 
 *  ======================
 */

#ifdef X11
static char geom_buffer[128];
#endif

#ifdef ANSI_C
void  visualize_part(void)
#else
void  visualize_part()
#endif
{
      debugmessage("visualize_part","");

      /* Init of the default values */

        G_title         = myalloc(256);
            strncpy(G_title,Dataname,254);
      G_title[255] = 0;
        G_x             = -1L;
        G_y             = -1L;

      /* Check the output device */
      if (!exfile) {
            setScreenSpecifics();   /* this sets G_width, G_height */
      }
      else {
            G_width = G_height = 700;
      }
      G_width_set  = 0; /* because they are not set by */
      G_height_set = 0; /* the specification           */
      if (!G_xymax_final) G_xmax = G_width+10;
        if (!G_xymax_final) G_ymax = G_height+10;
        G_xbase         = 5;
        G_ybase         = 5;
        G_dspace        = 0;
        G_xspace        = 20;
        G_yspace        = 70;
        G_orientation   = TOP_TO_BOTTOM;
        G_folding       = 0;
        G_color         = WHITE;
        G_displayel     = NO;
        G_dirtyel       = NO;
        G_shrink        = 1;
        G_stretch       = 1;
      G_yalign        = AL_CENTER;
      G_portsharing   = YES;
      G_arrowmode     = AMFIXED;
      G_xraster   = 1;
      G_yraster   = 1;
      G_dxraster  = 1;

      /* No edge class is hidden: initialize this */

      clear_hide_class();

      /* Check colors */

      if (colored== -1) {
#ifdef VMS
            if (RootWinMaxDepth ==1) colored = 0;
#else
            if (maxDepth == 1)       colored = 0;
#endif
            else /* maxDepth == 8 */ colored = 1;
      }

      /*  Analyze specification and allocate graph */

      step0_main();
      if (nr_errors!=0) Fatal_error("Wrong specification","");
      check_graph_consistency();

#ifdef X11
      if (!Xmygeometry) {
            if ((G_width_set)&&(G_height_set)) {
                  if ((G_x != -1L) && (G_y != -1L)) 
                        SPRINTF(geom_buffer,"%dx%d+%ld+%ld",
                              G_width,G_height,G_x,G_y);
                  else  SPRINTF(geom_buffer,"%dx%d",G_width,G_height);
                  Xmygeometry   = geom_buffer;
            }
            else if ((G_x != -1) && (G_y != -1)) {
                        SPRINTF(geom_buffer,"+%ld+%ld",
                              G_x,G_y);
                  Xmygeometry   = geom_buffer;
            }
      }
#endif

      /* Set drawing area */

      G_xymax_final = 1;
        V_xmin = V_xmin_initial;
        V_xmax = V_xmin + (long)G_xmax;
        V_ymin = V_ymin_initial;
        V_ymax = V_ymin + (long)(G_ymax + COFFSET);

      relayout();
}


/* Relayout the graph 
 * ------------------
 */


#ifdef ANSI_C
void relayout(void)
#else
void relayout()
#endif
{
      debugmessage("relayout","");
        start_time();

      if (G_timelimit>0) init_timelimit(G_timelimit);
      free_all_lists();
        if (nr_errors==0) folding();
        stop_time("folding");

        if (!locFlag) {

            if (min_mediumshifts>max_mediumshifts)
                  max_mediumshifts = min_mediumshifts;
            if (min_centershifts>max_centershifts)
                  max_centershifts = min_centershifts;
            if (min_baryiterations>max_baryiterations)
                  max_baryiterations = min_baryiterations;
            if (one_line_manhatten==1) manhatten_edges = 1;
            if ((manhatten_edges==1)&&(prio_phase==0)) prio_phase = 1;
            if ((prio_phase==1)&&(straight_phase==0)) straight_phase = 1;
            if ((prio_phase==0)&&(straight_phase==1)) prio_phase = 1;
            if (prio_phase==1)     {
                  min_centershifts = 0;
                  max_centershifts = 0;
            }
            if (G_dxraster<=0) G_dxraster = 1;
            if (G_xraster<=0)  G_xraster  = 1;
            if (G_xraster % G_dxraster) {
                  G_xraster = (G_xraster/G_dxraster) * G_dxraster;
            }
      
            /* Calculate new layout */

                step1_main();
            if (nr_errors!=0) Fatal_error("Wrong specification","");

            /* step1_main calls tree_main, if TREE_LAYOUT.
             */

            if (layout_flag != TREE_LAYOUT) {
                  step2_main();
                  if (nr_errors!=0) Fatal_error("Wrong specification","");
                  step3_main();
                  if (nr_errors!=0) Fatal_error("Wrong specification","");
            }
            step4_main();
            if (nr_errors!=0) Fatal_error("Wrong specification","");
      }
      else {
            /* Prepare given layout: calculate co-ordinate of edges 
             * width and height of nodes etc.
             */ 

            prepare_nodes();
      }
      free_timelimit();
}
      
/*--------------------------------------------------------------------*/

Generated by  Doxygen 1.6.0   Back to index