
/* "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 "name_stuff.text" */


/* Change these for testing */


/* A bunch of stuff for displaying text menus and getting names */

#include "global.h"


#define NAME_STUFF_G
#include "name_stuff.h"


#ifndef NEWCRT_H
#include <p2c/newcrt.h>
#endif


/* constants for text attributes */
/* add these constants together in the text fields to get the desired effect */
/* attributes for text should be chosen as follows: */
/* colors - choose 1 only */

#define crt_green       0
#define crt_yellow      4096
#define crt_black       8192
#define crt_red         12288
#define crt_cyan        16384
#define crt_white       20480
#define crt_blue        24576
#define crt_purple      28672
/* other attributes - choose as many as wanted */
#define crt_inv         256
#define crt_blink       512
#define crt_under       1024
#define crt_half        2048

#define saMax           300   /* Max things in a StrArray */

#define saMaxStr        "300"   /* Same thing as a string */


/* special records and arrays for alpha menu stuff */

typedef struct strrecord {
  short color;
  Char name[41];
} strrecord;

typedef strrecord strarray[saMax + 1];   /* data strings for pen text menu */

typedef struct kprecord {
  Char str[31];   /* actual text */
  short xp, yp;   /* position on screen */
  short wid;   /* width of select field */
  short col;   /* color */
} kprecord;

typedef kprecord kparray[10001];   /* only for use in ANYVAR statements */
typedef kprecord kparr3[3];


#define my_cursor       (crt_white + 252)   /* A white 'ü' */


Static short acursorx, acursory;   /* last position of alpha cursor */
Static short acursorold;   /* last anything at alpha cursor position */


/*******************************************************************************/

/* If cursor position is over a plain space, then put a 'ü' */
/* there as a cursor. */
Static void acursor(short x, short y)
{
  CRTWORD *WITH;

  if (strcmp(m_machine, "9836C")) {
    nk_gotoxy(x, y);   /* At least update the silly underline */
    return;
  }
  /*$if false$
   { Use mod 4096 to test character and highlight bits, but not color bits }
   if acursorold mod 4096=ord(' ') { plain space }
      then screen^[acursorx+acursory*screenwidth].wholeword:=252+crt_white { 'ü' }
      else screen^[acursorx+acursory*screenwidth].wholeword:=crt_white+acursorold mod 4096;
$end$*/
  if (acursorx >= 0) {   /* remove old cursor */
    WITH = &nk_screen[acursorx + acursory * nk_screenwidth];
    if (WITH->WHOLEWORD == my_cursor)
      WITH->WHOLEWORD = acursorold;
  }
  acursorx = x;
  acursory = y;
  WITH = &nk_screen[acursorx + acursory * nk_screenwidth];
  acursorold = WITH->WHOLEWORD;
  WITH->WHOLEWORD = my_cursor;

  /* We are on a large screen machine */
}


void acursoroff(void)
{
  CRTWORD *WITH;

  if (CURRENTCRT != ALPHATYPE)
    return;
  if (acursorx >= 0) {   /* remove old cursor */
    WITH = &nk_screen[acursorx + acursory * nk_screenwidth];
    if (WITH->WHOLEWORD == my_cursor)
      WITH->WHOLEWORD = acursorold;
  }
  acursorx = -1;
}


Static void crt_write_str(short x, short y, Char *s_, short field, short high)
{
  Char s[256];
  short l;
  Char STR2[256];

  strcpy(s, s_);
  l = abs(field) - strlen(s);
  if (l > 0) {
    if (field > 0)
      sprintf(s, "%*s%s", l, "", strcpy(STR2, s));
    else
      sprintf(s + strlen(s), "%*s", l, "");
  }
  nc_setHighlight(high);
  nc_putStr(x, y, s);
}


/* loop aborts */

#define maxfiles        35   /* should be a multiple of 7 */


Static boolean listdir_array(Char *dname_, strrecord *s)
{
  boolean Result;
  Char dname[fidleng + 1];
  fib dirfib;
  misc_catentry dirinfo;
  short numfiles;
  misc_catentry fileinfo[maxfiles];
  short i, num;   /* current position in array */
  short max;   /* Maximum number of files in a display */
  strrecord *WITH;

  strcpy(dname, dname_);
  Result = true;
  /* first 2 filenames are special (also illegal file names) */
  strcpy(s[0].name, " --abort-- ");
  s[0].color = crt_cyan;
  strcpy(s[1].name, " .. ");
  s[1].color = crt_red;
  num = 2;
  max = (nc_curWindow->height - 1) * (nc_curWindow->width / 20);

  TRY(try1);
    fp_open_dir(&dirfib, dname, &dirinfo);
    if (*dirfib.UU.ftitle != '\0') {
      printf("%s\007: not a directory\n", dname);
      P_escapecode = 10;
      goto _Ltry1;
    }
    do {
      numfiles = maxfiles;
      fp_cat_dir(&dirfib, &numfiles, (Anyptr)fileinfo);

      for (i = 0; i < numfiles; i++) {
	if (strpos2(fileinfo[i].cname, ".CIF", 1) != 0 ||
	    strpos2(fileinfo[i].cname, ".CFO", 1) != 0 ||
	    fileinfo[i].ckind == untypedfile) {
	  WITH = &s[num];
	  if (fileinfo[i].ckind == untypedfile)
	    WITH->color = crt_red;
	  else
	    WITH->color = crt_green;
	  strcpy(WITH->name, fileinfo[i].cname);
	  num++;
	  if (num >= max) {
	    printf("Too many files in DIR!!\n");
	    goto _L1;   /* abort FOR and WHILE loops now!! */
	  }
	}
      }
    } while (numfiles >= maxfiles);
_L1:   /* abort FOR and WHILE loops */
    fp_close_dir(&dirfib);
  RECOVER2(try1,_Ltry1);
    Result = false;
    if (P_escapecode != 10)
      show_error("directory", false);
    TRY(try2);
      fp_close_dir(&dirfib);
    RECOVER(try2);
      ;
    ENDTRY(try2);
  ENDTRY(try1);
  for (i = num; i <= saMax; i++) {
    WITH = &s[i];
    WITH->color = 0;
    *WITH->name = '\0';
  }
  return Result;
}

#undef maxfiles


/* Attacked by GEG 6/4 */
Static void show_strings(strrecord *s)
{
  short i, j, k, x;
  nc_windowRec *WITH;

  WITH = nc_curWindow;
  k = WITH->height - 1;

  for (j = 1; j <= k; j++) {
    nc_clearXY(0, j, WITH->width, 1);   /* clear current line */

    i = j - 1;
    x = 0;
    while (x + 20 <= WITH->width) {
      crt_write_str(x, j, s[i].name, 0, s[i].color);
      x += 20;
      i += k;
    }
  }
}


/* Local variables for getstrarray: */
struct LOC_getstrarray {
  strrecord *s;
  short last, c23;
} ;

Local void cursit(struct LOC_getstrarray *LINK)
{
  short x, y;
  strrecord *WITH;

  x = LINK->last / LINK->c23 * 20;
  y = LINK->last % LINK->c23 + 1;
  WITH = &LINK->s[LINK->last];
/* p2c: name_stuff.text, line 233:
 * Note: Using % for possibly-negative arguments [317] */
  if ((WITH->color / crt_inv) & 1)   /* toggle inverse mode */
    WITH->color -= crt_inv;
  else
    WITH->color += crt_inv;
  crt_write_str(x, y, WITH->name, 0, WITH->color);
}


Static short getstrarray(strrecord *s_)
{
#if 1
  struct LOC_getstrarray V;
  tablet_info ti;
  short cur;

  V.s = s_;
  V.c23 = 23;
  if (!strcmp(m_machine, "320") || !strcmp(m_machine, "700"))
    V.c23 = 46;
  nc_setWindow_(nc_defaultWindow);

  show_strings(V.s);
  if (!strcmp(m_machine, "Brain-Damaged-X"))
    return -1;
  else {
    ti = get_pena();   /* start where the pen is */
    if (ti.y < 1)
      ti.y = 1;
    V.last = ti.x / 20 * V.c23 + ti.y - 1;
    if (V.last > saMax)
      V.last = saMax;
    acursoroff();
    cursit(&V);
    debounce();
    do {
      ti = get_pena();
      if (ti.y < 1)
	ti.y = 1;
      acursor(ti.x, ti.y);
      cur = ti.x / 20 * V.c23 + ti.y - 1;
      if (cur > saMax)
	cur = saMax;
      /* cur := ti.x div 20+ti.y*4-4;   old */
      if (V.last != cur) {
	cursit(&V);
	V.last = cur;
	cursit(&V);
      }
    } while (!(ti.depressed || nk_keybufsize() > 0));
    cursit(&V);
    acursoroff();
    if (nk_keybufsize() > 0)
      return -1;
    else
      return V.last;
  }
#else
  struct LOC_getstrarray V;
  int i;
  char inputline[100];
  int num = 0;

  V.s = s_;
  printf("\n");
  for (i = 0; i < saMax; i++) {
    if (V.s != NULL && strlen(V.s[i].name)) {
      printf("%-20s", V.s[i].name);
      num++;
      if (num % 4 == 0) printf("\n");
    }
  }
  printf("\n");
  do {
    printf("? "); fflush(stdout);
    fgets(inputline, sizeof(inputline), stdin);
    inputline[strlen(inputline)-1] = '\0';

    for (i = 0; i < saMax; i++) 
      if (!strcmp(inputline, V.s[i].name)) return(i);
  } while (strlen(inputline));
  return -1;
#endif
}


Static void sortstrarray(strrecord *s)
{
  short i;
  strrecord t;
  boolean sorted;

  do {
    sorted = true;
    for (i = 0; i < saMax; i++) {
      if (strcmp(s[i].name, s[i + 1].name) > 0 && *s[i + 1].name != '\0') {
	t = s[i];
	s[i] = s[i + 1];
	s[i + 1] = t;
	sorted = false;
      }
    }
  } while (!sorted);
}


Char *getfname(Char *Result, Char *start_)
{
  Char start[fidleng + 1];
  strarray s;
  short n, i;
  boolean done;
  Char STR1[130];
  Char STR2[140];
  Char *TEMP;
  Char STR3[124];
  Char STR4[256];

  strcpy(start, start_);
  do {
    do {
      sprintf(STR1, "Reading: %s", start);
      crt_write_str(0, 0, STR1, -80, crt_green);
      done = listdir_array(start, s);
      if (!done) {
	printf("Directory read failed. New directory? ");
	fgets(start, fidleng + 1, stdin);
	TEMP = strchr(start, '\n');
	if (TEMP != NULL)
	  *TEMP = 0;
	n = 0;   /* in case we abort */
	if (*start == '\0')
	  goto _L1;
      }
    } while (!done);
    sortstrarray(s);
    sprintf(STR2, "Current directory: %s", start);
    crt_write_str(0, 0, STR2, -80, crt_cyan);
    n = getstrarray(s);
    if (n < 0) {
      printf("\001\tFile or ?directory: ");
      fgets(start, fidleng + 1, stdin);
      TEMP = strchr(start, '\n');
      if (TEMP != NULL)
	*TEMP = 0;
      done = true;
      if (*start != '\0' && start[0] == '?') {
	strcpy(start, start + 1);
	done = false;
      }
    } else {
      done = (s[n].color != crt_red);   /* red==directory */
      if (!done) {
	if (strcmp(s[n].name, " .. ")) {
	  if (start[strlen(start) - 1] != '/' &&
	      start[strlen(start) - 1] != ':')
	    sprintf(start + strlen(start), "/%s", s[n].name);
	  else
	    strcat(start, s[n].name);
	} else {
	  i = strlen(start);
	  while (i >= 1) {
	    if (start[i - 1] != ':' && start[i - 1] != '/') {
	      i--;
	      continue;
	    }
	    if (start[i - 1] == ':' ||
		!strcmp((sprintf(STR4, "%.3s", (sprintf(STR3, "%s  ", start),
						STR3) + i - 1), STR4), "/..")) {
	      i = 0;   /* This needs the /.. */
	      break;
	    }
	    if (i == 1)
	      strcpy(start, "/");
	    else {
	      start[i - 1] = '\0';
/* p2c: name_stuff.text, line 351:
 * Note: Modification of string length may translate incorrectly [146] */
	    }
	    i = -10;
	  }
	  if (i != -10) {
	    if (start[strlen(start) - 1] != ':')
	      strcat(start, "/..");
	    else
	      strcat(start, "..");
	  }
	}
      }
    }
  } while (!done);
_L1:
  if (n == 0)
    return strcpy(Result, "");
  else if (n < 0)
    return strcpy(Result, start);
  else if (start[strlen(start) - 1] != '/' && start[strlen(start) - 1] != ':') {
    sprintf(Result, "%s/%s", start, s[n].name);
    return Result;
  } else {
    sprintf(Result, "%s%s", start, s[n].name);
    return Result;
  }
}


/* Local variables for kbd_or_pen: */
struct LOC_kbd_or_pen {
  short num;
  kprecord *strs;
  tablet_info ti;
  short laststr;
} ;

Local short findit(struct LOC_kbd_or_pen *LINK)
{
  /* find which string we are in */
  short Result, i, FORLIM;
  kprecord *WITH;

  FORLIM = LINK->num;
  for (i = 0; i < FORLIM; i++) {
    WITH = &LINK->strs[i];
    if (LINK->ti.y == WITH->yp && LINK->ti.x >= WITH->xp &&
	LINK->ti.x < WITH->xp + WITH->wid) {
      Result = i;
      goto _L1;
    }
  }
  Result = -1;
_L1:
  return Result;
}

Local void cursit_(struct LOC_kbd_or_pen *LINK)
{
  kprecord *WITH;

  if (LINK->laststr < 0)
    return;
  WITH = &LINK->strs[LINK->laststr];
  if ((WITH->col / crt_inv) & 1)   /* toggle inverse mode */
    WITH->col -= crt_inv;
  else
    WITH->col += crt_inv;
  crt_write_str(WITH->xp, WITH->yp, WITH->str, 0, WITH->col);
}


/* return -1 if keyboard data becomes available before pen press */
Static short kbd_or_pen(short num_, kprecord *strs_)
{
  struct LOC_kbd_or_pen V;
  short Result, curstr;   /* last, current string in strs */
  short i, FORLIM;
  kprecord *WITH;

  V.num = num_;
  V.strs = strs_;
  FORLIM = V.num;
  for (i = 0; i < FORLIM; i++) {
    WITH = &V.strs[i];
    crt_write_str(WITH->xp, WITH->yp, WITH->str, 0, WITH->col);
  }
  if (nk_keybufsize() > 0) {   /* already typeahead!! */
    Result = -1;
    goto _L2;
  }
  V.ti = get_pena();   /* start where the pen is */
  V.laststr = findit(&V);
  acursoroff();
  cursit_(&V);
  debounce();
  V.ti.depressed = false;
  while (!(V.ti.depressed && V.laststr >= 0) && nk_keybufsize() == 0) {
    V.ti = get_pena();
    acursor(V.ti.x, V.ti.y);
    curstr = findit(&V);
    if (V.laststr == curstr)
      continue;
    acursoroff();
    cursit_(&V);
    V.laststr = curstr;
    cursit_(&V);
    acursor(V.ti.x, V.ti.y);
  }
  cursit_(&V);
  acursoroff();
  if (nk_keybufsize() > 0)
    Result = -1;
  else
    Result = V.laststr;
_L2:
  return Result;
}


typedef kprecord kparr2[2];


const kparr2 kpconst = {
  { " (Y", 0, 0, 3, crt_red },
  { "N)?", 4, 0, 3, crt_red }
};


boolean yes_no_quest(Char *pmpt)
{
#if 1
  boolean Result;
  kparr2 kp;
  long x, y;
  short i;
  Char resp;
  kprecord *WITH;

  memcpy(kp, kpconst, sizeof(kparr2));
  m_graphics_off();
  m_alpha_on();
  fputs(pmpt, stdout);
  nk_getxy(&x, &y);
  printf(" (Y/N)? ");
  for (i = 0; i <= 1; i++) {
    WITH = &kp[i];
    WITH->xp += x;
    WITH->yp += y;
  }
  do {
    i = kbd_or_pen(2, kp);
    if (i == 0)
      resp = 'Y';
    else if (i == 1)
      resp = 'N';
    else
      resp = nk_getkey();
  } while (resp != 'n' && resp != 'N' && resp != 'y' && resp != 'Y');

  Result = (resp == 'y' || resp == 'Y');
  m_graphics_on();
  m_alpha_off();
  /* reset green text, no underscore */
  return Result;
#else
#if 1
  int ch;
  int result;

  do {
    printf("%s (y/n)?\n", pmpt);
/*    ch = getchar();*/
    ch = nk_getkey();
    result = (toupper(ch) == 'Y');
  } while (toupper(ch) != 'N' && toupper(ch) != 'Y');
  return result;
#else
  char myprompt[100];

  sprintf(myprompt, "./test \"%s (y/n)?\"", pmpt);
  printf("calling >%s<\n", myprompt);
  return (system(myprompt));
#endif

#endif
}


Static Char *getnames_setup(Char *Result, Char *pmpt, Char *def, Char *pmpt2,
			    kprecord *kp_)
{
  kparr3 kp;
  Char resp[256];
  long x, y;
  short i;
  kprecord *WITH;

  memcpy(kp, kp_, sizeof(kparr3));
  m_graphics_off();
  m_alpha_on();
  fputs(pmpt, stdout);
  if (*def != '\0') {
    nk_getxy(&x, &y);
    strcpy(kp[2].str, def);
    kp[2].xp = x + 1;
    kp[2].yp = y;
    kp[2].wid = strlen(def);
    /* kp[2].color:=crt_red; color is decided by caller */
    printf("[%s]", def);
  }
  nk_getxy(&x, &y);
  fputs(pmpt2, stdout);
  for (i = 0; i <= 1; i++) {
    WITH = &kp[i];
    WITH->xp += x;
    WITH->yp += y;
  }
  i = kbd_or_pen(3, kp);
  if (i == 0)
    strcpy(resp, "?");
  else if (i == 1)
    strcpy(resp, "-ABORT");
  else if (i == 2)
    *resp = '\0';   /* default */
  else
    gets(resp);
  /* reset to green, no underline, etc.*/
  return strcpy(Result, resp);
}


const kparr3 kpconst_ = {
  { "?dir", 5, 0, 4, crt_red },
  { "-ABORT", 13, 0, 6, crt_red },
  { "", 0, 0, 0, crt_red }
};


Char *getfilename(Char *Result, Char *prompt_, Char *default__)
{
  Char prompt[81], default_[81];
  Char resp[fidleng + 1], STR2[fidleng + 1];

  strcpy(prompt, prompt_);
  strcpy(default_, default__);
  if (prompt_filename)
    getnames_setup(resp, prompt, default_, " (or ?dir or -ABORT) : ",
		   kpconst_);
  else {
    strcpy(resp, "?");
    m_graphics_off();
    m_alpha_on();
    printf("\001%s", prompt);
    if (*default_ != '\0')
      printf(" default would have been [%s]", default_);
  }
  if (*resp == '\0') {
    strcpy(resp, default_);
    /* else if strpos('-ABORT',resp)=1 then resp := '' leave as -ABORT */
  } else if (resp[0] == '?') {
    strcpy(resp, resp + 1);
    if (*resp == '\0')
      strcpy(resp, ":");
    strcpy(resp, getfname(STR2, resp));
    if (*resp != '\0' && resp[0] == ':')
      strcpy(resp, resp + 1);
    else if (*resp == '\0')
      strcpy(resp, default_);
    nk_gotoxy(0, 23);
    putchar('\t');
  }
  strcpy(Result, resp);
  m_graphics_on();
  return Result;
}


Static Char *getgcname(Char *Result)
{
  strarray s;
  short n, i, j;
  cell *gcells;
  Char name[81];
  strrecord *WITH;
  Char STR2[36];
  Char *TEMP;

  gcells = geom_cells;
  strcpy(s[0].name, " --abort-- ");   /* this must be first ! */
  s[0].color = crt_cyan;

  j = 1;
  do {
    if (gcells != geom_cells) {
      WITH = &s[j];
      strcpy(WITH->name, gcells->name);
      WITH->color = 0;
      if (gcells->modified)
	WITH->color += crt_under;
      j++;
    }
    gcells = gcells->next;
    if (j > saMax) {
      sprintf(STR2, "Too many cells (only showing %s)", saMaxStr);
      show_error(STR2, false);
      gcells = geom_cells;   /* get out of loop */
    }
  } while (gcells != geom_cells);
  for (i = j; i <= saMax; i++) {
    *s[i].name = '\0';   /* null out rest of fields */
    s[i].color = crt_green;
  }
  sortstrarray(s);
  n = getstrarray(s);
_L1:
  if (n == 0)
    return strcpy(Result, "-ABORT");
	/* used to be '', now leave as -ABORT */
  else if (n > 0)
    return strcpy(Result, s[n].name);
  else {
    printf("\001\tCell name? ");
    fgets(name, 81, stdin);
    TEMP = strchr(name, '\n');
    if (TEMP != NULL)
      *TEMP = 0;
    return strcpy(Result, name);
  }
}


const kparr3 kpconst__ = {
  { " ? ", 4, 0, 3, crt_red },
  { "-ABORT", 10, 0, 6, crt_red },
  { "", 0, 0, 0, crt_red }
};


Char *getgeomcellname(Char *Result, Char *prompt_, Char *default__)
{
  Char prompt[81], default_[81], resp[81];

  strcpy(prompt, prompt_);
  strcpy(default_, default__);
  if (prompt_cellname)
    getnames_setup(resp, prompt, default_, " (or ? or -ABORT) : ", kpconst__);
  else {
    strcpy(resp, "?");
    m_graphics_off();
    m_alpha_on();
    printf("%s", prompt);
    if (*default_ != '\0')
      printf(" default would have been [%s]", default_);
  }

  if (*resp == '\0') {
    strcpy(resp, default_);
    /* else if strpos('-ABORT',resp)=1 then resp := ''     leave as -ABORT */
  } else if (resp[0] == '?') {
    getgcname(resp);
    if (*resp == '\0')
      strcpy(resp, default_);
    nk_gotoxy(0, 23);
    putchar('\t');
  }
  strcpy(Result, resp);
  m_graphics_on();
  m_alpha_off();
  alpha_screen(CLR);
  /*writeln ('getgeomcellname returned name: ', resp);*/
  return Result;
}


Static Char *getcname(Char *Result)
{
  strarray s;
  short n, i, j;
  cell *gcells;
  comp_list *ccells;
  Char name[81];
  strrecord *WITH;
  Char STR2[36];
  Char *TEMP;

  ccells = comp_cells;
  gcells = geom_cells;
  strcpy(s[0].name, " --abort-- ");   /* this must be first ! */
  s[0].color = crt_cyan;

  j = 1;
  do {
    if (gcells != geom_cells) {
      WITH = &s[j];
      strcpy(WITH->name, gcells->name);
      WITH->color = 0;
      if (gcells->modified)
	WITH->color += crt_under;
      j++;
    }
    gcells = gcells->next;
    if (j > saMax) {
      sprintf(STR2, "Too many cells (only showing %s)", saMaxStr);
      show_error(STR2, false);
      gcells = geom_cells;   /* get out of loop */
    }
  } while (gcells != geom_cells);
  if (j <= saMax) {
    do {
      if (ccells != comp_cells) {
	WITH = &s[j];
	strcpy(WITH->name, ccells->name);
	WITH->color = crt_cyan;
	if (ccells->modified)
	  WITH->color += crt_under;
	j++;
      }
      ccells = ccells->next;
      if (j > saMax) {
	sprintf(STR2, "Too many cells (only showing %s)", saMaxStr);
	show_error(STR2, false);
	ccells = comp_cells;   /* get out of loop */
      }
    } while (ccells != comp_cells);
  }

  for (i = j; i <= saMax; i++) {
    *s[i].name = '\0';   /* null out rest of fields */
    s[i].color = 0;
  }
  sortstrarray(s);
  n = getstrarray(s);
_L1:
  if (n == 0)
    return strcpy(Result, "-ABORT");
	/* used to be '', now leave as -ABORT */
  else if (n > 0)
    return strcpy(Result, s[n].name);
  else {
    printf("\001\tCell name? ");
    fgets(name, 81, stdin);
    TEMP = strchr(name, '\n');
    if (TEMP != NULL)
      *TEMP = 0;
    return strcpy(Result, name);
  }
}


const kparr3 kpconst___ = {
  { " ? ", 4, 0, 3, crt_red },
  { "-ABORT", 10, 0, 6, crt_red },
  { "", 0, 0, 0, crt_red }
};


Char *getcellname(Char *Result, Char *prompt_, Char *default__)
{
  Char prompt[81], default_[81], resp[81];

  strcpy(prompt, prompt_);
  strcpy(default_, default__);
  if (prompt_cellname)
    getnames_setup(resp, prompt, default_, " (or ? or -ABORT) : ", kpconst___);
  else {
    strcpy(resp, "?");
    m_graphics_off();
    m_alpha_on();
    printf("\001%s", prompt);
    if (*default_ != '\0')
      printf(" default would have been [%s]", default_);
  }

  if (*resp == '\0') {
    strcpy(resp, default_);
    /* else if strpos('-ABORT',resp)=1 then resp := ''     leave -ABORT */
  } else if (resp[0] == '?') {
    getcname(resp);
    if (*resp == '\0')
      strcpy(resp, default_);
    nk_gotoxy(0, 23);
    putchar('\t');
  }
  strcpy(Result, resp);
  m_graphics_on();
  m_alpha_off();
  alpha_screen(CLR);
  /*writeln ('getcellname returned name: ', resp);*/
  return Result;
}


/* module NAME_STUFF */



/* End. */
