/*
 *  program p88cfg
 *  creates or modifies the configuration-file p88.env
 *
{*  last modification:  02.01.92  17:24   }
 *  uli 29.07.91: write error detection
 *  uli 30.07.91: on_sysrts and sysenv added.
 *  uli 09.08.91: showsetting: output screen modified.
 *  uli 26.08.91 : on_handling added.
 *  uli 17.09.91 : new style headers.
 *  uli 17.12.91 : namelength added.
 *  uli 02.01.92 : on_sysrts default true.
 *  uli 02.01.92 : ov_handling and on_fastfor added.
 *  PJ  06.04.95 : on_print_check and os_print_check added ( however,they
                   are not included in the environment file )
*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "defs.h"
/* #include "depend.h" */
#include "p88hlp.h"
#include "p88cfg.h"           /* contains names of the variables in p88.env */
			      /* which are also used by sysutil.c */


	int     namelength  = NAMElength ;
local   FILE  * envfile     = (FILE*)0;
local   int changed = false ;       /* flag: "configuration modified!" */
#define      HLPfnam     "cxsc.hlp"   /* help file of p88cfg */

   /* in order to correct the clearscreen action                 */
   /* delete the following 3 lines and link depend.o to p88cfg.o */
char * clearstr = "\n" ;
char * clearcmd = NULL ;      /* not available ==> use clearstr */

/*--------------------------------------------------------------------------*/
/*  following variables are the same as declared in option.h (as external)  */
/*  and are not used by sysutil.c (has already included option.h)           */

local   char    on_verbose   = 1;
local   char    on_list      = 0;
local   char    on_warning   = 1;
local   char    on_merge     = 0;
local   char    on_code      = 0;
local   char    on_rename    = 1;
local   char    on_index     = 1;
local   char    on_number    = 1;
local   char    on_fastfor   = 0;
local   char    on_include   = 0;
local   char    on_terminal  = 0;
local   char    on_handling  = 0;
local   char    on_dump      = 0;
local   char    on_srcdir    = 0;
local   char    on_remove    = 1;
local   char    on_prototyp  = 0;
local   char    on_stdmodule = 0;
local   char    on_reverse   = 1;
local   char    on_sysrts    = 1;
local   char    on_print_check = 0;

local   char    os_code      = 0;
local   char    os_verbose   = 0;
local   char    os_print_check = 0;

local   char *  ov_rename    = "";
local   char *  ov_include   = "";

local   int     ov_handling  = 7;
local   int     ov_abort     = 0;

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


#ifdef LINT_ARGS

local  void   envopen  (void);
local  void   envread  (void);            /* same as setdefault in sysutil.c */
local  void   display  (char * nam, char * *val) ;
local  int    envwrite (void);

local  int    getnext  (void);
local  void   setmark  (char);
local  int    getflag (char*);
local  char * b_fgets  (void);
local  void   b_fputs  (char*);

local  void   showsetting (void);

#else

local  void   envopen  ( );
local  void   envread  ( );
local  void   display  ( ) ;
local  int    envwrite ( );

local  int    getnext  ( );
local  void   setmark  ( );
local  int    getflag  ( );
local  char * b_fgets  ( );
local  void   b_fputs  ( );

local  void   showsetting ( );

#endif

							 /*-----------------*/
#ifdef LINT_ARGS
local  void  envopen  ( void)
#else
local  void  envopen ()                                  /*  e n v o p e n  */
  /* searches directories for the environment file to be read */
#endif
BEGIN (envopen)
  local  char  envname [256] ;
		   /* holds the path and filename of the environment file */
		   /* used only to report it */
  char * p ;

  sysenv = getenv (P88SYS) ;            /* system environment variable */

  strcpy (envname, envfnam) ;           /* search in current directory */
  envfile = fopen (envname, "rb");
  if (envfile)  {
    printf("Local environment file found.   ");
    printf("Modifying file %s.\n", envname);
    return ;
   }

  p = getenv (P88USR) ;                 /* user environment variable */
  if  (p)    {
    strcat (strcpy (envname, p), envfnam) ;
    envfile = fopen(envname,"rb");      /* search in user directory */
    if  (envfile)  goto exitlab ;
  }

  p = getenv (HOME) ;                   /* users home directory */
  if  (p)
     strcat (strcpy (envname, p), usrdir) ;
  else
     strcpy (envname, usrdir);
  strcat (envname, envfnam);
  envfile = fopen(envname,"rb");        /* search in user directory */
  if (envfile)  goto exitlab ;

  if  (sysenv)    {
    strcat (strcpy (envname, sysenv), envfnam) ;
    envfile = fopen(envname,"rb");      /* search in system directory */
    if  (envfile)  goto exitlab ;
  }

  strcpy (envname, sysdir);
  strcat (envname, envfnam);
  envfile = fopen(envname,"rb");        /* search in system directory */
  if  (not envfile)    {
      printf("Environment file %s not found.  ", envname);
      printf("Initializing file %s\n", envfnam);
      return ;
   }

exitlab:
  printf("Environment file %s found.  ", envname);
  printf("Copying to file %s", envfnam);
  return ;
END  /* envopen */                                      /*  e n v o p e n  */
							/*-----------------*/

/**********************/
/*  reading env file  */
/**********************/

local  char  nullstring [1] = "" ;  /* constant nullstring */

							/*-----------------*/
#ifdef LINT_ARGS
local  char * b_fgets  ( void)
#else
local  char * b_fgets ()                                /*  b _ f g e t s  */
  /* reads a string from the env-file and allocates the string */
#endif
BEGIN (b_fgets)
  int    len;
  char * str;

  len=fgetc(envfile) ;
  if (len == EOF or len <= 1)   return (nullstring);
  str = (char*) malloc (len);
  if (str) {
    fgets (str, len, envfile);
    return (str);
  } else {
    printf ("\n Error: Insufficient memory\n\n");
    exit (-999);
  }
  return (str);  /* never reached! */
END  /* b_fgets */                                      /*  b _ f g e t s  */
							/*-----------------*/


							/*-----------------*/
#ifdef LINT_ARGS
local  int getnext  ( void)
#else
local  int getnext ()                                    /*  g e t n e x t  */
  /* searches for the next delimiter in the env-file */
#endif
BEGIN (getnext)
  int  c;

  while  ((c=fgetc(envfile)) != delimiter  and  c!=EOF) ;
  if (c==delimiter)
    c = fgetc(envfile);
  else
    printf ("invalid environment-file\n\n");

  return (c);

END  /* getnext */                                      /*  g e t n e x t  */
							/*-----------------*/

							/*-----------------*/
#ifdef LINT_ARGS
local  int  getflag  ( char * flag )
#else
local  int  getflag (flag)                              /*  g e t f l a g  */
  char * flag ;
#endif
BEGIN(getflag)
  int c = fgetc(envfile) ;
  if ((c) != delimiter)
		   * flag = (char)c;
		 else
		   ungetc (c, envfile);
  return c ;
END /* getflag */                                       /*  g e t f l a g  */
							/*-----------------*/

							/*-----------------*/
#ifdef LINT_ARGS
local  void envread  ( void)
#else
local  void envread ()                                  /*  e n v r e a d  */
#endif
BEGIN (envread)
  int c;

  while ((c=getnext())!=options and c!=EOF) ;           /* default options */
  if (c!=EOF) {
    c = getflag (&on_verbose  );
    c = getflag (&on_list     );
    c = getflag (&on_warning  );
    c = getflag (&on_merge    );
    c = getflag (&os_code     );
    c = getflag (&on_code     );
    c = getflag (&on_index    );
    c = getflag (&on_number   );
    c = getflag (&on_dump     );
    c = getflag (&on_terminal );
    c = getflag (&on_rename   );
    c = getflag (&on_include  );
    c = getflag (&on_srcdir   );
    c = getflag (&on_remove   );
    c = getflag (&on_prototyp );
    c = getflag (&on_reverse  );
    c = getflag (&os_verbose  );
    c = getflag (&on_sysrts   );
    c = getflag (&on_handling );
    c = getflag (&on_fastfor  );
  }
/*
Check :
20 Flags werden aus dem envfile ausgelesen.
Vergleiche Anzahl und Reihenfolge beim Schreiben der Flags : fputc(flag,envfile));
*/

  while ((c=getnext())!=includes and c!=EOF) ;           /* include <files> */
  ov_rename  = b_fgets ();
  ov_include = b_fgets ();

  while ((c=getnext())!=extensions and c!=EOF) ;         /* file extensions */
  codfext = b_fgets ();
  dclfext = b_fgets ();
  intfext = b_fgets ();
  srcfext = b_fgets ();
  lstfext = b_fgets ();
  objfext = b_fgets ();
  libfext = b_fgets ();
  exefext = b_fgets ();

  while ((c=getnext())!=paths and c!=EOF) ;
  findmod = b_fgets ();                         /* path for interface-files */
  runtime = b_fgets ();                         /* path for runtime-routine */

  while ((c=getnext())!='n' && c!=EOF) ;
  if (c=='n')  namelength = fgetc (envfile) ;  /* max. length of C names */

  fclose (envfile);

END  /* envread */                                      /*  e n v r e a d  */
							/*-----------------*/


						/*-------------------------*/
#ifdef LINT_ARGS
local  void showsetting ( void)
#else
local  void showsetting()                        /*  s h o w s e t t i n g  */
#endif
BEGIN (showsetting)

  printf ("\n\nO = command line Options:");
  if (os_verbose) {
   if (on_verbose) printf (" +v");
	      else printf (" -v");
  }
  else             printf ("  v");  /* not specified */
  if (on_list    ) printf (" +l");
	      else printf (" -l");
  if (on_warning ) printf (" +w");
	      else printf (" -w");
  if (on_merge   ) printf (" +m");
	      else printf (" -m");
  if (os_code) {
    if (on_code  ) printf (" +c");
	      else printf (" -c");
  }
  else             printf ("  c");  /* not specified */
  if (on_index   ) printf (" +x");
	      else printf (" -x");
  if (on_number  ) printf (" +n");
	      else printf (" -n");
  if (on_fastfor ) printf (" +f");
	      else printf (" -f");
  if (on_dump    ) printf (" +d");
	      else printf (" -d");
  if (on_handling) printf (" +h");
	      else printf (" -h");
  if (on_terminal) printf (" +t");
	      else printf (" -t");
  if (on_rename  ) printf (" +r");
	      else printf (" -r");
  if (on_srcdir  ) printf (" +s");
	      else printf (" -s");
  /* if (on_remove  ) printf (" +rm");
		 else printf (" -rm"); */

  if  (ov_include and *ov_include)
    printf ("\nI = include file name:  %s", ov_include);

  printf ("\nN = Non command line options:");
  if (on_srcdir  ) printf (" +src");
	      else printf (" -src");
  if (on_remove  ) printf (" +rm");
	      else printf (" -rm");
  if (on_prototyp) printf (" +proto");
	      else printf (" -proto");
  if (on_reverse ) printf (" +lv");
	      else printf (" -lv");
  if (on_sysrts  ) printf (" +y");
	      else printf (" -y");
  if (os_code) {
    if (on_code  ) printf (" +c");
	      else printf (" -c");
  }
  else             printf ("  c");  /* not specified */
  if (os_verbose) {
    if (on_verbose) printf (" +v");
	      else  printf (" -v");
  }
  else             printf ("  v");  /* not specified */

  printf ("\n\nT =  filename-extensions, file Types :  \n");
  printf ("  Source   : %-9s", srcfext);
  printf ("  C-code   : %-9s", codfext);
  printf ("  Dump     : %-9s", lstfext);
  printf("\n");
  printf ("  Interface: %-9s", intfext);
  printf ("  Header   : %-9s", dclfext);
  printf ("  Object   : %-9s", objfext);
  printf ("\n");
  printf ("  Library  : %-9s", libfext);
  printf ("  Execute  : %-9s", exefext);
  printf ("\n");

  printf ("\nI = pathname of interface-files: %s", findmod);
  printf ("\nR = pathname of runtime interface ");
  if (on_sysrts)
    printf ("is system directory %s", sysenv ? sysenv : sysdir) ;
  else
    printf (": %s", runtime);
  printf ("\nL = length of C identifiers ") ;
  if  (namelength == 0)   printf ("is unlimited") ;
  else                    printf ("= %d", namelength);
  printf ("\n");

  helpon ('D') ;
END  /* showsetting */                          /*  s h o w s e t t i n g  */
						/*-------------------------*/

/**********************/
/*  writing env file  */
/**********************/

							/*-----------------*/
#ifdef LINT_ARGS
local  void setmark  ( char c)
#else
local  void setmark (c)                                  /*  s e t m a r k  */
char c;
#endif
BEGIN (setmark)

  fputc (delimiter, envfile);
  fputc (c, envfile);

END  /* setmark */                                      /*  s e t m a r k  */
							/*-----------------*/

							/*-----------------*/
#ifdef LINT_ARGS
local  void b_fputs  ( char * str)
#else
local  void b_fputs (str)                                /*  b _ f p u t s  */
char * str;
#endif
BEGIN (b_fputs)

  fputc (strlen(str)+1, envfile);
  fputs (str,  envfile);
/*  fputc ('\n', envfile); */

END  /* b_fputs */                                      /*  b _ f p u t s  */
							/*-----------------*/


							/*-------------------*/
#ifdef LINT_ARGS
local  int  envwrite  ( void)
#else
local  int  envwrite ()                                 /*  e n v w r i t e  */
  /* returns zero, if successful */
#endif
BEGIN (envwrite)

  envfile = fopen(envfnam, "wb");
  if  (not envfile) {
    return 1 ;
  }
  setmark (options);
  fputc (on_verbose ,envfile);
  fputc (on_list    ,envfile);
  fputc (on_warning ,envfile);
  fputc (on_merge   ,envfile);
  fputc (os_code    ,envfile);
  fputc (on_code    ,envfile);
  fputc (on_index   ,envfile);
  fputc (on_number  ,envfile);
  fputc (on_dump    ,envfile);
  fputc (on_terminal,envfile);
  fputc (on_rename  ,envfile);
  fputc (on_include ,envfile);
  fputc (on_srcdir  ,envfile);
  fputc (on_remove  ,envfile);
  fputc (on_prototyp,envfile);
  fputc (on_reverse ,envfile);
  fputc (os_verbose ,envfile);
  fputc (on_sysrts  ,envfile);
  fputc (on_handling,envfile);
  fputc (on_fastfor ,envfile);
/*
Check :
20 Flags werden auf das envfile geschrieben.
Vergleiche Anzahl und Reihenfolge beim Einlesen der Flags : getflag (flag);
*/

  setmark (includes);
  b_fputs (ov_rename );
  b_fputs (ov_include);
  b_fputs ("\0");
  b_fputs ("\0");

  setmark (extensions);
  b_fputs (codfext);
  b_fputs (dclfext);
  b_fputs (intfext);
  b_fputs (srcfext);
  b_fputs (lstfext);
  b_fputs (objfext);
  b_fputs (libfext);
  b_fputs (exefext);

/* Dummy-output;
   update : strings may be added without loosing the contents
   of not updated files. If envread is invoked with more extensions then
   declared in old enviroment-file, no reading error occures. previous
   contents are read without any fault.
*/
  b_fputs ("\0");
  b_fputs ("\0");


  setmark (paths);
  b_fputs (findmod);
  b_fputs (runtime);
  b_fputs ("\0");
  b_fputs ("\0");

  setmark ('n');
  fputc (namelength, envfile);

  setmark('c');         /* Language 'C' - Interface */
  b_fputs ("\0");
  b_fputs ("\0");

/* Dummy marks;
   if any updates are made, these marks can be used.
*/
  setmark('u');
  setmark('v');
  setmark('w');
  setmark('x');
  setmark('y');
  setmark('z');

  return   fclose(envfile);

END  /* envwrite */                                   /*  e n v w r i t e  */
						      /*-------------------*/

/*****************/
/*  user dialog  */
/*****************/
							/*---------------*/
#ifdef LINT_ARGS
local  void  display (char * nam, char * * val)         /*  d i p l a y  */
#else
local  void  display (nam, val)
  char * nam, * *val ;
#endif
BEGIN(display)
  if  (*val == NULL  or  **val == '\0')
    printf ("%s set empty\n", nam) ;
  else
    printf ("%s set to \"%s\"\n", nam, *val) ;

						 /* fieser Trick!!! */
  if  (val != &runtime and val != &findmod and val != &ov_include  and
       **val != '\0' and **val != point)
    printf ("An extension should start with a \"%c\".\n", (char)point) ;
END /* display */



/******************/
/*  main program  */
/******************/
							/*-----------------*/
int main ()                                             /*   m  a  i  n    */
{
local  char * mainprompt =
	      "Command (o/n/t/i/r/h/d/u/e/q/k/+/-) or ? for help : " ;
local  char * normalstatus =
       " Note: Use the 'n' command to set this option to normal status.\n" ;
int cmd, subcmd ;   /* command chars */
int on ;            /* "+" or "-" */

  hlpinit (HLPfnam) ;

  envopen ();
  if (envfile) envread ();

  showsetting ();
  prompt (mainprompt);
  while(true) {
    cmd = readtty () ;
    switch (cmd) {

    case    '+':  case    '-':
      on = (cmd == '+') ;
      do   {
	if  (on)
	 prompt("Which option to turn on (v/l/w/m/c/x/n/d/t/r/s/rm) or ? for help : ");
	else
	 prompt("Which option to turn off (v/l/w/m/c/x/n/d/t/r/s/rm) or ? for help : ");
	subcmd = readtty () ;
	if  (subcmd != '?')   break ;
	if  (on)    helpon ('&') ;    else    helpon ('_') ;
      } while  (subcmd == '?') ;

      switch (subcmd) {
	case    'v':
	  on_verbose = on ;
	  os_verbose = 1 ;
	  printf("verbose switched o%s.\n", on ? "n" : "ff");
	  printf(normalstatus);
	break;
	case    'w':
	  on_warning = on ;
	  printf("warning switched o%s.\n", on ? "n" : "ff");
	break;
	case    'l':
	  on_list    = on ;
	  printf("listing switched o%s.\n", on ? "n" : "ff");
	break;
	case    'm':
	  on_merge   = on ;
	  printf("merge switched o%s.\n", on ? "n" : "ff");
	break;
	case    'c':
	  on_code    = on ;
	  os_code=1;
	  printf("code switched o%s.\n", on ? "n" : "ff");
	  printf(normalstatus);
	break;
	case    'x':
	  on_index  = on ;
	  printf("index switched o%s.\n", on ? "n" : "ff");
	break;
	case    'n':
	  on_number = on ;
	  printf("number switched o%s.\n", on ? "n" : "ff");
	break;
	case    'd':
	  on_dump   = on ;
	  printf("dump switched o%s.\n", on ? "n" : "ff");
	break;
	case    't':
	  on_terminal = on;
	  printf("terminal switched o%s.\n", on ? "n" : "ff");
	break;
	case    'h':
	  on_handling = on;
	  printf("handling switched o%s.\n", on ? "n" : "ff");
	break;
	case    'f':
	  on_fastfor = on;
	  printf("fastfor switched o%s.\n", on ? "n" : "ff");
	break;
	case    's':
	  on_srcdir = on ;
	  printf("srcdir switched o%s.\n", on ? "n" : "ff");
	break;
	case    'r':
	  on_rename = on ;
	  printf("rename switched o%s.\n", on ? "n" : "ff");
	break;
	case    'i':
	  on_include = on ;
	  ask (" Include file name ", &ov_include ) ;
	  display (" Include file name ", &ov_include ) ;
	break;
	case    'q':
	  READLN ;
	break;
	default:
	  READLN ;
	  printf("undefined option: %c = 0x%x\n", (char)subcmd, subcmd);
      } /* end of option switch */
      changed = true ;
    break;

    case    'o':
      do   {
	prompt("Which option to change (v/l/w/m/c/x/n/d/t/r/s/rm) or ? for help : ");
	subcmd = readtty () ;
	if  (subcmd != '?')   break ;
	helpon ('O') ;
      } while  (subcmd == '?') ;

      switch (subcmd) {
	case    'v':
	  on_verbose = ! on_verbose ;
	  os_verbose = 1;
	  printf("verbose toggled to %c\n", on_verbose? '+' : '-');
	  printf(normalstatus);
	break;
	case    'w':
	  on_warning = ! on_warning ;
	  printf("warning toggled to %c\n",on_warning? '+' : '-');
	break;
	case    'l':
	  on_list    = ! on_list ;
	  printf("listing toggled to %c\n",on_list? '+' : '-');
	break;
	case    'm':
	  on_merge   = ! on_merge ;
	  printf("merge toggled to %c\n",on_merge? '+' : '-');
	break;
	case    'c':
	  on_code    = ! on_code ;
	  os_code=1;
	  printf("code toggled to %c\n",on_code? '+' : '-');
	  printf(normalstatus);
	break;
	case    'x':
	  on_index  = ! on_index;
	  printf("index toggled to %c\n",on_index? '+' : '-');
	break;
	case    'n':
	  on_number = ! on_number ;
	  printf("number toggled to %c\n",on_number? '+' : '-');
	break;
	case    'd':
	  on_dump   = ! on_dump ;
	  printf("dump toggled to %c\n",on_dump? '+' : '-');
	break;
	case    't':
	  on_terminal = ! on_terminal;
	  printf("terminal toggled to %c\n",on_terminal? '+' : '-');
	break;
	case    'h':
	  on_handling = ! on_handling;
	  printf("handling toggled to %c\n",on_handling? '+' : '-');
	break;
	case    'f':
	  on_fastfor = ! on_fastfor;
	  printf("fastfor toggled to %c\n",on_fastfor? '+' : '-');
	break;
	case    's':
	  on_srcdir = ! on_srcdir ;
	  printf("srcdir toggled to %c\n",on_srcdir? '+' : '-');
	break;
	case    'r':
	  on_rename = ! on_rename ;
	  printf("rename toggled to %c\n",on_rename? '+' : '-');
	break;
	case    'i':
	  on_include = ! on_include ;
	  ask (" include file name ", &ov_include) ;
	  display (" include file name ", &ov_include) ;
	break;
	case    'q':
	  READLN ;
	break;
	default:
	  READLN ;
	  printf("undefined option: %c = 0x%x\n", (char)subcmd, subcmd);
      } /* end of option switch */
      changed = true ;
    break;

    case    'n':
      do   {
	prompt("Which option to change (s/r/p/c/l/y/c/v) or ? for help : ");
	subcmd = readtty () ;
	if  (subcmd != '?')   break ;
	helpon ('N') ;
      } while  (subcmd == '?') ;

      switch (subcmd) {
	case    'v':
	  os_verbose = 0;
	  printf("verbose changed to not specified\n");
	break;
	case    'c':
	  os_code = 0;
	  printf("code changed to not specified\n");
	break;
	case    's':
	  on_srcdir = ! on_srcdir ;
	  printf("srcdir toggled to %c\n",on_srcdir? '+' : '-');
	break;
	case    'r':
	  on_remove = ! on_remove ;
	  printf("remove toggled to %c\n",on_remove? '+' : '-');
	break;
	case    'p':
	  on_prototyp = ! on_prototyp ;
	  printf("prototyping toggled to %c\n",on_prototyp? '+' : '-');
	break;
	case    'l':
	  on_reverse  = ! on_reverse  ;
	  printf("link reverse toggled to %c\n",on_reverse? '+' : '-');
	break;
	case    'y':
	  on_sysrts   = ! on_sysrts   ;
	  if  (on_sysrts)
	    printf("runtime command disabled, system directory in use\n");
	  else
	    printf("runtime command enabled, 'r' specification in use\n");
	break;
	case    'q':
	  READLN ;
	break;
	default:
	  READLN ;
	  printf("undefined option: %c = 0x%x\n", (char)subcmd, subcmd);
      } /* end of option switch */
      changed = true ;
    break;

    case    't':  case    '.':
      do   {
	prompt ("Enter first character (s/c/d/i/h/o/l/e) or ? for help : ");
	subcmd = readtty () ;
	if  (subcmd != '?')   break ;
	helpon ('T') ;
      } while  (subcmd == '?') ;

      switch (tolower(subcmd)) {
	case    's':
	  ask ("Source extension", &srcfext) ;
	  display ("Source extension", &srcfext) ;
	break;
	case    'c':
	  ask (" C-code extension ", &codfext);
	  display (" C-code extension ", &codfext);
	break;
	case    'i':
	  ask (" Interface extension ", &intfext) ;
	  display (" Interface extension ", &intfext) ;
	break;
	case    'd':
	  ask (" Dump extension ", &lstfext) ;
	  display (" Dump extension ", &lstfext) ;
	break;
	case    'h':
	  ask (" Header extension ", &dclfext) ;
	  display (" Header extension ", &dclfext) ;
	break;
	case    'o':
	  ask (" Object extension ", &objfext) ;
	  display (" Object extension ", &objfext) ;
	break;
	case    'l':
	  ask (" Library extension ", &libfext) ;
	  display (" Library extension ", &libfext) ;
	break;
	case    'e':
	  ask (" Executable extension ", &exefext) ;
	  display (" Executable extension ", &exefext) ;
	break;
	case    'q':
	  READLN ;
	break;
	default:
	  READLN ;
	  printf("Unknown typ: %c = 0x%x\n", (char)subcmd, subcmd);
      }  /* end of extension switch */
      changed = true ;
      break;

    case    'i':
      ask (" Interface path ", &findmod) ;
      display (" Interface path ", &findmod) ;
      if  (*findmod!='\0' and findmod[strlen(findmod)-1]!=pathchar)
	printf ("A pathname should end with a \"%c\".\n", (char)pathchar) ;
      changed = true ;
    break;

    case    'r':
      ask (" Runtime path ", &runtime) ;
      display (" Runtime path ", &runtime) ;
      on_sysrts = false ;
      printf(" Note: Use the 'ny' command to switch to normal usage.\n") ;
      if  (*runtime!='\0' and runtime[strlen(runtime)-1]!=pathchar)
	printf ("A pathname should end with a \"%c\".\n", (char)pathchar) ;
      changed = true ;
    break;

    case    'l':
	{ char s [64], *p = s ;

	  sprintf (s, "%d", namelength) ;
	  ask (" Namelength ", &p) ;
	  if  (p  and  *p )
	   { int n = atoi (p) ;
	     if  (n != 0  and  (n < 6  or  n > 255))   {
		printf ("Specify a value between 6 and 255\n") ;
		break ;
	     }
	     else namelength = n ;
	   }
	  else   namelength = 0 ;
	}
	printf ("Namelength set to ") ;
	if  (namelength==0)   printf ("unlimited\n") ;
	else                  printf ("%d\n", namelength) ;
	changed = true ;
    break;

    case    'd':
      showsetting ();
    break;

    case    'u':
    case    'e':
      changed =   envwrite () != 0 ;
      if  (changed) {   /* not yet updated */
	printf ("Error: Write failed on file  %s\n", envfnam) ;
	cmd = 'u' ;  /* do not quit */
	}
      else
	printf ("File %s updated\n", envfnam);
    break;

    case    'q':
      if  (changed) {
	prompt("Do you really want to discard all changes  (y/n)? ");
	subcmd = readtty () ;
	if  (subcmd != 'y' and subcmd != 'Y')
	 { cmd = 'h' ; /* no longer 'q' */
	   printf ("   Use the e command to quit with update.\n") ;
	 }
      } /* changed */
      break;

    case    'k':
      printf ("Be sure, that the current directory is not the system directory!!!\n\n") ;
      prompt("Do you really want to discard the configuration in the current directory? ");
      subcmd = readtty () ;
      if  (subcmd == 'y' or subcmd == 'Y')
       { if  (remove (envfnam))
	   printf ("Error: Remove failed! \n") ;
	 else
	   cmd = 'q' ; /* delete and quit */
       }
      break;

    case    '?':
      helpon ('?') ;
      break;

    case    'h':
      if (tty == '\n')   helpon ('H') ;
      do   {
	prompt ("Help on (o/n/t/i/r/h/d/u/e/q/+/-) or ? for help : ");
	subcmd = readtty () ;
	if  (subcmd != '?')   break ;
	helpon ('H') ;
      } while  (subcmd == '?') ;
      helpon (subcmd) ;
      printf ("\nNow you are back in the main menu.\n") ;
      break;

    default:
	while  (tty != '\n'  and  tty != EOF)  tty = getchar ();
	printf("Unknown command: %c = 0x%x\n", (char)cmd, cmd);
    }  /* switch */
  if(cmd=='e') break;
  if(cmd=='q') break;
  if(tty==EOF) break;

  prompt(mainprompt);
  }  /* until quit or exit */

  return (0) ;
END /* main */
