File mttroot/mtt/bin/trans/awk/rbg_fig2m.awk artifact 3ec50668e6 part of check-in 158fedb6ad


###################################### 
##### Model Transformation Tools #####
######################################

# gawk script: rbg_fig2m.awk
# Raw  bond-graph conversion from fig to matlab
# P.J.Gawthrop June 1996
# Copyright (c) P.J.Gawthrop, 1996.

###############################################################
## Version control history
###############################################################
## $Id$
## $Log$
## Revision 1.1  1996/08/04 20:01:58  peter
## Initial revision
##
###############################################################


##############################################################
# This (g)awk script reads a fig file in fig 3.1 format.
# It interprets the picture as: bonds, arrows and components
# as follows:
#
# Bonds are firm (not dashed etc) polylines with 2 line segments - 
#  fig represents this by  a firstline record where
#    field 1 = 2 (always 2)
#    field 2 = 1 (polyline)
#    field 3 = 0 (style is a firm line)
#    field 14 = 0 (no forward arrow)
#    field 15 = 0 (backward arrow) 
#  a data field starting with a tab followed by 3 (x,y) cordinates
#
# Arrows are polylines with 1 line segment and an arrow 
#  fig represents this by  a firstline record where
#    field 1 = 2 (always 2)
#    field 2 = 1 (polyline)
#    field 3 = 0 (style is a firm line)
#    field 14 = 1 for a forward arrow  
#    field 15 = 1 for a backward arrow 
#  an additional data files
#  a data field starting with a tab followed by 2(x,y) cordinates
#
#
# Strokes are polylines with 1 line segment and and no arrow 
#  fig represents this by  a firstline record where
#    field 1 = 2 (always 2)
#    field 2 = 1 (polyline)
#    field 3 = 0 (style is a firm line)
#    field 14 = 0 (no forward arrow)
#    field 15 = 0 (backward arrow) 
#  a data field starting with a tab followed by 2(x,y) cordinates
#
# Components appear in two files -- the fig file and the lbl file
# these two files are concatenated with the lbl file first
#  	The lbl file represents components by 3 fields
#		field  1 is the name
#		field  2 is the CR name
#		field  3 is the CR arguments
#  	The fig file represents components by 14 fields
#             field 1 = 4
#		fields 12 and 13 are the coordinates
#		field 14 is the type:name string terminated by \001
# To prevent text being confused with components, components consist
# of alphanumeric characters and : and _ only.
# The lbl file is used to sort the components.
##############################################################

function exact_match(name1, name2) {
  return ((match(name1,name2)>0)&&(length(name1)==length(name2)))
    }

function process_lbl() {
# This puts the components in the lable file at the top of the list
# and saves up the corresponding CR and arguments
# note that there may be more than one component per label
  if ((match($1,"%")==0)&&(NF>0))
    { 
      i_label++;
      name = $1;
      CR   = $2;
      args = $3;
      label[i_label,1] = name; 
      label[i_label,2] = CR;
      label[i_label,3] = args
	}
}

function process_text() {
# The text string is field 14 onwards
  str = $14; 
  for (i=15; i<=NF; i++) {
    str = sprintf("%s %s", str, $i)
      }
# It is terminated by /001 - so delete this termination
  str = substr(str,1,length(str)-4);

# A component string contain only alphanumeric  _ and :
  isa_plain_component = match(str, component_regexp)==0;

# A port is an integer within []
  isa_port = match(str, port_regexp)>0;

# A port component is SS followed by : followed by a port string
  isa_port_component = 0;
  if (match(str, delimiter)) {
    split(str,a,delimiter);
    isa_port_component = (exact_match(a[1], "SS"))&&
      (match(a[2], port_regexp)>0)
      }
    
# A component is a plain or a port component
  isa_component = isa_plain_component||isa_port_component;

print str, isa_component;

# Coordinates in fields 12 & 13
  x_coord = $12;
  y_coord = $13;

  if (isa_component) {
    i_text++;

    named_component = (match(str,delimiter) > 0);
    if (named_component) {
      split(str,a,delimiter);
      type = a[1];
      name = a[2];

# Check  if name is in label file and if used already
      found = 0; name_used = 0;
      for (i=1; i<=i_label; i++) {
	lname = label[i,1];
	if ( exact_match(name,lname) ) {
	  found = 1;
	  if (name in used) {
	    name_used = 1;
	    CR = label[i,2];
	    args = label[i,3];
	  }
	  else {
	    used[name] = 1
	      }
	  break
	    }
      }

	if (!found) {
	  if (isa_plain_component) {
	    printf(warning_f, name)
	  }
	  i_label++;
	  CR = default_cr;
	  args = "";
	  label[i_label,1] = name; 
	  label[i_label,2] = CR;
	  label[i_label,3] = args
	    }

# Give it a new entry if already used
      if (name_used) {
	i_label++;
	i_name++;
	name = sprintf("%1.0f", i_name);
	label[i_label,1] = name; 
	label[i_label,2] = CR;
	label[i_label,3] = args
	  }
    }

# Unnamed component
    if (named_component==0) {
      i_name++;
      name = sprintf("%1.0f", i_name);
      type = str;
      i_label++;
      label[i_label,1] = name;
      label[i_label,2] = default_cr;
      label[i_label,3] = default_args
	}

# Save in associative arrays by name	
    comp_type[name] = type;
    x[name] = x_coord;
    y[name] = y_coord;
    info[name] =  sprintf("%s %s %s %s %s %s %s %s %s %s %s ", \
			  $1, $2, $3, $4, $5, $6, $7, \
			  $8, $9, $10, $11);
  }    

  if (isa_port) {
    i_port++;
    port_index = substr(str,2,length(str)-2);
    ports[i_port] = sprintf("%s %s %s", x_coord, y_coord, port_index);
  }
}

function process_bond() {

  arg_count++;
  if ( (arg_count-arrow)==1 ) 
    {

#Save up bond coords
      if (NF == (2*bond_coords+1) ) {
	i_bond++;
	bonds[i_bond] = sprintf("%s %s %s %s %s %s", \
				$2, $3, $4, $5, $6, $7);
      }
      
#Save up arrow coords
      if ( (arrow)&&(NF==(2*arrow_coords+1)) ) {
	i_arrow++;
	arrows[i_arrow] = sprintf("%s %s %s %s",  $2, $3, $4, $5);
      }
      
#Save up stroke coords
      if ( (!arrow)&&(NF==(2*stroke_coords+1)) ) {
	i_stroke++;
	strokes[i_stroke] = sprintf("%s %s %s %s",  $2, $3, $4, $5);
      }
    }
}

function write_cbg() {
# Create _cbg.fig file from _abg file - not components
  if ( (fig_file)&&((object!=text)||(isa_component==0))) {
    printf $1 >> cbg_file
      for (i=2; i<=NF; i++)
	printf(" %s", $i) >> cbg_file;
    printf("\n") >> cbg_file
      }
}

function process_fig() {
# Test for the fig format first line and data line
  data_line = (match($1,data_symbol)>0);
  first_line = (data_line==0)&&(NF>min_line_length);

#Process firstline
  if (first_line) {
    object = $1;
    sub_type = $2;
    style = $3;
    f_arrow = ($14==1)&&(object=polyline);
    b_arrow = ($15==1)&&(object=polyline);
    arrow = f_arrow||b_arrow;
    arg_count = 0;
  }

#Process text
  if (object==text) {
    process_text()
      }

# Process bond
  if ( \
(data_line)&& \
       (object==polyline)&& \
       (sub_type==sub_polyline)&& \
       (style==firm_style) \
       ) {
    process_bond()
      }   

  write_cbg()

    }

BEGIN {
  sys_name = ARGV[1];
  delete ARGV[1];
  b_file = sprintf("%s_rbg.m", sys_name);
  c_file = sprintf("%s_cmp.m", sys_name);
  cbg_file = sprintf("%s_cbg1.fig", sys_name);
  warning_f = "WARNING %s \t in fig file but not lbl file  - using\n";
  warning_l = "WARNING %s \t in lbl file but not fig file  - ignoring\n";
  data_symbol = "----";
  default_cr = "";
  default_args = "";
  delimiter = ":";
  q = "\047";
  terminator = "\\001";
  component_regexp = "[^0-9a-zA-Z_:]";
  port_regexp = "\[[0-9]*\]";
    
  fig_file = 0;
  min_line_length = 10;
  object = 0;
  polyline = 2;
  sub_polyline=1; 
  firm_style = 0;
  text = 4;
  bond_coords = 3;
  stroke_coords = 2;
  arrow_coords = 2;

  i_bond = 0;
  i_port = 0;
  i_stroke = 0;
  i_arrow = 0;
  i_label = 0;
  i_text = 0;
  i_name = 0;
}
{
# Start of .fig file?
  if ( (NF>0) && (match("#FIG", $1) > 0) ) {
    fig_file=1;
  }

  if (fig_file==0) {
    process_lbl()    
      }
  else {
    process_fig()
      }
}

END {
#Print out the matlab functions
  print  sprintf("function [rbonds, rstrokes,rcomponents,rports] = %s_rbg", sys_name) > b_file;
  print  sprintf("%%[rbonds,rstrokes,rcomponents,rports] = %s_rbg", sys_name) > b_file;
  print  sprintf("%%Generated by MTT") > b_file;

  print  sprintf("function [comp_type, name, cr, arg] = %s_cmp(i)",\
		 sys_name) > c_file;
  print  sprintf("%%[comp_type, name, cr, arg] = %s_cmp", sys_name) > c_file;
  print  sprintf("%%Generated by MTT") > c_file;

  print  sprintf("rbonds = [") >> b_file;
  for (i = 1; i <= i_bond; i++)
    print  bonds[i] >> b_file;
  for (i = 1; i <= i_arrow; i++)
    print  arrows[i], "-1 -1" >> b_file;
  print  sprintf("];") >> b_file;
  
  print  sprintf("rstrokes = [") >> b_file;
  for (i = 1; i <= i_stroke; i++)
    print  strokes[i] >> b_file;
  print  sprintf("];") >> b_file;

  print  sprintf("rcomponents = [") >> b_file;
  j = 0;
  for (i = 1; i <= i_label; i++) {
    name = label[i,1];
    cr   = label[i,2];
    arg  = label[i,3];
    
    if (length(x[name])==0)
      printf(warning_l, name);
    else {
      j++;
      print x[name], y[name], info[name] >> b_file;
      printf("if i==%1.0f\n", j) 	>> c_file;
      printf("\tcomp_type = %s%s%s;\n", q, comp_type[name], q) >> c_file;
      printf("\tname = %s%s%s;\n", q, name, q) >> c_file;
      printf("\tcr = %s%s%s;\n", q, cr, q) >> c_file;
      printf("\targ = %s%s%s;\n", q, arg, q) >> c_file;
      print "end" >> c_file
	}
  }
  print sprintf("];") >> b_file;

  print  sprintf("rports = [") >> b_file;
  for (i = 1; i <= i_port; i++)
    print  ports[i] >> b_file;
  print  sprintf("];") >> b_file;

}




MTT: Model Transformation Tools
GitHub | SourceHut | Sourceforge | Fossil RSS ]