
/* "WOL", an integrated circuit layout tool,
   Copyright (C) 1983, 1990 California Institute of Technology.
   Author: Massimo Sivilotti
   Thanks to: Glenn Gribble, Marty Sirkin, Sylvie Rychebusch
	      Maryann Mayer, Carver Mead, Rick Koshi, Torre Lande
   Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425/ CU Boulder/Boulder CO 91125. 
			  Send questions, bug fixes, to this address.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (Version 1, 1989).

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; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */

/* Output from p2c, the Pascal-to-C translator */
/* p2c: wolopt.text, line 9: Note: Range checking is OFF [216] */
/* p2c: wolopt.text, line 10: Note: Stack checking is OFF [217] */
/* p2c: wolopt.text, line 16: Note: Range checking is ON [216] */
/* From input file "layer_stuff.text" */


/* Change these for testing */



#include "global.h"


#define LAYER_STUFF_G
#include "layer_stuff.h"


/* Change the current display style and update deferred[] */
void set_disp_style(short new_style)
{
  short i;

  disp_style = new_style;
  for (i = min_layer; i <= max_layer; i++)
    deferred[i - min_layer] = layers[i - min_layer].styles[disp_style].deferred;
  /*write('deferred=');
  for i:=min_layer to max_layer do
     write(deferred[i]:1,' ');
  writeln;  */
}


void pat_fillbox(long x1, long y1, long x2, long y2, long pat)
{
  /* move to WOLGR?? */
  long t;

  if (x1 > x2) {
    t = x2;
    x2 = x1;
    x1 = t;
  }
  if (y1 > y2) {
    t = y2;
    y2 = y1;
    y1 = t;
  }
  if (x2 - x1 > 1 && y2 - y1 > 1) {   /* There is something inside. */
    t = m_curcolor();
    /*m_setpattern(patterns[pat]);
    m_color(m_pat);  */
    if (!intzoom || izoom < 2)
      m_grid(x1 + 1, y1 + 1, x2 - 1, y2 - 1, 2, 2, 0, 0);
    else
      m_grid(x1 + 1, y1 + 1, x2 - 1, y2 - 1, izoom, izoom, 0, 0);
    /*m_fillrect(x1+1,y1+1,x2-1,y2-1);   */
    /*m_color(t);*/
  }
  m_drawrect(x1, y1, x2, y2);
}


/* Mainly debugging.  Print the layer on a file. */
void show_layer(FILE **out, short num)
{
  short i;
  layer_info *WITH;
  short FORLIM;
  layer_disp_info *WITH1;
  plotter_disp_info *WITH2;

  WITH = &layers[num - min_layer];
  if (WITH->layer_on)
    fprintf(*out, "#  ON\n");
  else
    fprintf(*out, "# OFF\n");
  fprintf(*out, "layer: %2d %5s %5s\n", num, WITH->menu_name, WITH->cif_name);
  FORLIM = WITH->numstyles;
  for (i = 0; i < FORLIM; i++) {
    WITH1 = &WITH->styles[i];
    fprintf(*out, "  display: %d %5s %5s %2d %2d %2d %2d %2d\n",
	    i, WITH->menu_name, WITH1->deferred ? "TRUE" : "FALSE",
	    WITH1->color, WITH1->style, WITH1->fcolor, WITH1->fstyle,
	    WITH1->menu);
  }
  WITH2 = &WITH->plot;
  fprintf(*out, "  plotter: %5s %2d %2d %2d %2d \n",
	  WITH->menu_name, WITH2->color, WITH2->style, WITH2->fcolor,
	  WITH2->fstyle);
}


void dump_layers(FILE **out)
{
  long i, r, g, b;
  pattern *WITH;

  fprintf(*out, "# Layer table\n");
  fprintf(*out, "#\n");
  for (i = min_layer; i <= max_layer; i++)
    show_layer(out, i);
  for (i = 0; i <= 15; i++) {
    m_seecolor(i, (int *) &r, (int *) &g, (int *) &b);
    fprintf(*out, "cmap:%3ld%3ld%3ld%3ld\n", i, r, g, b);
  }
  for (i = 1; i <= max_patterns; i++) {
    if (patterns[i - 1] != NULL) {
      WITH = patterns[i - 1];
      fprintf(*out, "# pattern:%3ld%3d ????\n", i, WITH->xdim);
    }
  }
  fprintf(*out, "# That's all.\n");
}


void layers_show_all(void)
{
  FILE *TEMP;

  TEMP = stdout;
/* p2c: layer_stuff.text, line 189:
 * Note: Taking address of stdout; consider setting VarFiles = 0 [144] */
  dump_layers(&TEMP);
}


void reset_layer(void)
{
  /* call this to fix things up */
  set_layer(last_layer);
}


void set_layer(short newlayer)
{
  layer_disp_info *WITH;

  /*####things could probably be done to make editting/moving work out better */
  /* if (newlayer<min_layer) or (newlayer>max_layer) then newlayer:=min_layer;*/
  last_layer = newlayer;
  WITH = &layers[newlayer - min_layer].styles[disp_style];
  if (gstate.ref_in_black) {   /* black is boring, but has precedence */
    curr_color = 0;
    curr_style = 0;
    curr_fillp = -1;   /* curr_fillc does not matter */
  } else if (gstate.dotted) {
    curr_color = WITH->color;   /* layer color */
    curr_style = 1;   /* force dotted */
    curr_fillp = -1;   /* some question here??? */
  } else {
    curr_color = WITH->color;   /* boundary color */
    curr_style = WITH->style;   /* line style */
    curr_fillc = WITH->fcolor;   /* fill color */
    curr_fillp = WITH->fstyle;   /* fill pattern */
  }
  m_color(curr_color);
  m_linestyle(curr_style);

  /* dotted has next precedence */
}


/* Local variables for read_tech: */
struct LOC_read_tech {
  Char name[fidleng + 1];
  Char s[256];
  long p;
  short line;
  boolean errors;
} ;

Local void error(Char *err, struct LOC_read_tech *LINK)
{
  printf("\007technology file: \"%s\"  line %d\n", LINK->name, LINK->line);
  if (LINK->p >= 0) {
    printf(">>>%s\n", LINK->s);
    printf("%*s%s\n", (int)(LINK->p + 4), "^ ", err);
  } else
    printf("Error: %s\n", err);
  LINK->errors = true;
  _Escape(1);   /* get to end of loop */
}

Local void getstr(Char *st, struct LOC_read_tech *LINK)
{
  long q;

  while (LINK->p <= strlen(LINK->s) && LINK->s[LINK->p - 1] == ' ')
    LINK->p++;
  q = LINK->p;
  while (q <= strlen(LINK->s) && LINK->s[q - 1] != ' ')
    q++;
  sprintf(st, "%.*s", (int)(q - LINK->p), LINK->s + LINK->p - 1);
  LINK->p = q;
}

Local boolean testcmd(Char *cmd, struct LOC_read_tech *LINK)
{
  boolean b;

  b = strbegins(LINK->s, cmd);
  if (b)
    LINK->p = strlen(cmd) + 1;
  return b;
}

Local void readpattern(struct LOC_read_tech *LINK)
{
  /* Read a line starting "pattern:" */
  short dim, patnum, i, j;
  Char c;
  long TEMP;
  pattern *WITH;

  sscanf(LINK->s + LINK->p - 1, "%hd%hd%ln", &patnum, &dim, &TEMP);
  LINK->p += TEMP;
  /* writeln('patnum=',patnum:1,' dim=',dim:1); */
  if (patnum < 1 || patnum > max_patterns)
    error("Illegal pattern number.", LINK);

  if (patterns[patnum - 1] == NULL)
    patterns[patnum - 1] = Malloc(sizeof(pattern));

  WITH = patterns[patnum - 1];
  WITH->xdim = dim;
  WITH->ydim = dim;
  WITH->xsize = dim;
  WITH->ysize = dim;
  WITH->xoff = 0;
  WITH->yoff = 1 - dim;
  WITH->width = dim;
  WITH->height = dim;
  /* make it all transparent */
  for (i = 0; i <= 63; i++)
    WITH->UU.pica[i] = 255;
  for (i = 0; i < dim; i++) {
    /* skip spaces */
    while (LINK->p <= strlen(LINK->s) && LINK->s[LINK->p - 1] == ' ')
      LINK->p++;
    j = 0;
    while (LINK->p <= strlen(LINK->s) && LINK->s[LINK->p - 1] != ' ' &&
	   j < dim) {
      c = toupper(LINK->s[LINK->p - 1]);
      if (c == 'T') {
	c = 255;
/* p2c: layer_stuff.text, line 307:
 * Note: Character >= 128 encountered [281] */
      } else if (isdigit(c))
	c -= '0';
      else if (c >= 'A' && c <= 'F')
	c -= 55;
      else
	error("Bad character 0-9,A-F, or T", LINK);
      WITH->UU.pica[j + i * dim] = c;
      j++;
      LINK->p++;
    }
  }
}


/* Read technology file and setup LAYERS.  Does not mess with any of the */
/* menu stuff. */
void read_tech(Char *name_)
{
  struct LOC_read_tech V;
  FILE *infile;
  Char layer_name[81];
  short layer, display_number, check_layer, saveio;
  long c, r, g, b;
  layer_info *WITH;
  layer_disp_info *WITH1;
  Char *TEMP;
  Char STR1[256], STR2[256];
  long TEMP1;
  Char *STR3;
  Char STR4[100];
  plotter_disp_info *WITH2;

  strcpy(V.name, name_);
  infile = NULL;
  V.errors = false;
  if (infile != NULL)
    infile = freopen(V.name, "r", infile);
  else
    infile = fopen(V.name, "r");
  if (infile == NULL)
    _EscIO(FileNotFound);
  V.line = 0;

  /* Don't set all patterns to NIL, or we will lose memory. */
  /* nuke all layers */
  for (layer = min_layer; layer <= max_layer; layer++) {
    WITH = &layers[layer - min_layer];
    WITH->layer_on = false;
    WITH->menu_name[0] = '\0';
    WITH->cif_name[0] = '\0';
    WITH->numstyles = 0;
    for (V.p = 0; V.p <= max_styles; V.p++) {
      WITH1 = &WITH->styles[V.p];
      WITH1->color = 0;
      WITH1->style = 0;
      WITH1->fcolor = 0;
      WITH1->fstyle = -1;
    }
  }

  while (!P_eof(infile)) {
    TRY(try1);
      V.p = -1;
      V.line++;
      fgets(V.s, 256, infile);
      TEMP = strchr(V.s, '\n');
      if (TEMP != NULL)
	*TEMP = 0;
      V.p = 1;

      strcpy(STR1, strltrim(strrtrim(strcpy(STR2, V.s))));
      strcpy(V.s, STR1);
      if (!(*V.s == '\0' || testcmd("#", &V))) {   /* Comment, do nothing */
	if (testcmd("layer:", &V))
	{  /* layer: <layernumber> <menu_name> <cif name> */
	  layer = strtol(V.s + V.p - 1, &STR3, 10);
	  V.p = STR3 - V.s + 1;
	  if (layer < min_layer || layer > max_layer)
	    error("Illegal layer number.", &V);
	  WITH = &layers[layer - min_layer];
	  getstr(WITH->menu_name, &V);
	  if (!strcmp(WITH->menu_name, "ERROR"))
	    error_layer = layer;
	  WITH->layer_on = true;
	  getstr(WITH->cif_name, &V);
	} else if (testcmd("display:", &V)) {
	  display_number = strtol(V.s + V.p - 1, &STR3, 10);
	  V.p = STR3 - V.s + 1;
	  getstr(layer_name, &V);
	  check_layer = min_layer;
	  while (check_layer <= max_layer &&
		 strcmp(layers[check_layer - min_layer].menu_name, layer_name))
	    check_layer++;
	  if (check_layer > max_layer) {
	    sprintf(STR4, "Undeclared layer: %s", layer_name);
	    error(STR4, &V);
	  }
	  WITH = &layers[check_layer - min_layer];
	  if (WITH->numstyles <= display_number)
	    WITH->numstyles = display_number + 1;
	  WITH1 = &WITH->styles[display_number];
	  sscanf(V.s + V.p - 1, " %[a-zA-Z]%hd%hd%hd%hd%hd%ln", STR1,
		 &WITH1->color, &WITH1->style, &WITH1->fcolor, &WITH1->fstyle,
		 &WITH1->menu, &TEMP1);
	  WITH1->deferred = (*STR1 == 'T' || *STR1 == 't');
	  V.p += TEMP1;
	} else if (testcmd("plotter:", &V)) {
	  getstr(layer_name, &V);
	  check_layer = min_layer;
	  while (check_layer <= max_layer &&
		 strcmp(layers[check_layer - min_layer].menu_name, layer_name))
	    check_layer++;
	  if (check_layer > max_layer) {
	    sprintf(STR4, "Undeclared layer: %s", layer_name);
	    error(STR4, &V);
	  }
	  WITH2 = &layers[check_layer - min_layer].plot;
	  sscanf(V.s + V.p - 1, "%hd%hd%hd%hd%ln", &WITH2->color,
		 &WITH2->style, &WITH2->fcolor, &WITH2->fstyle, &TEMP1);
	  V.p += TEMP1;
	} else if (testcmd("pattern:", &V))
	  readpattern(&V);
	else if (testcmd("cmap:", &V)) {
	  sscanf(V.s + V.p - 1, "%ld%ld%ld%ld%ln", &c, &r, &g, &b, &TEMP1);
	  V.p += TEMP1;
	  m_setcolor(c, r, g, b);
	}
      }
    RECOVER(try1);
      if (P_escapecode == -20)
	_Escape(P_escapecode);
      if (P_escapecode != 1) {   /* already handled */
	saveio = P_ioresult;
	printf("\007technology file: \"%s\"  line %d\n", V.name, V.line);
	if (V.p >= 0)
	  printf(">>>%s\n", V.s);
	if (P_escapecode == 12)
	  strcpy(V.s, "Illegal layer number.");
	else
	  misc_getioerrmsg(V.s, saveio);
	if (V.p >= 0)
	  printf("%*s%s\n", (int)(V.p + 4), "^ ", V.s);
	else
	  printf("IOerror was \"%s\"\n", V.s);
	misc_printerror(0, 0);
	_Escape(10);
      }
    ENDTRY(try1);
  }
  if (infile != NULL)
    fclose(infile);
  infile = NULL;
  numstyles = 0;
  for (layer = min_layer; layer <= max_layer; layer++) {
    if (layers[layer - min_layer].numstyles > numstyles)
      numstyles = layers[layer - min_layer].numstyles;
  }
  if (infile != NULL)
    fclose(infile);
}


/* module LAYER_STUFF */




/* End. */
