/*
 *  MODULE  : option.c
 *  command line scanner
 *
{*  last modification:  10.11.92  15:25   }

 *  uli 26.02.91: os_verbose handled
 *  uli 06.03.91 : new style headers.
 *  uli 06.03.91 : stdio.h added.
 *  uli 15.04.91 : default case added.
 *  uli 26.08.91 : on_handling added.
 *  uli 09.01.92 : ov_abort added.
 *  uli 14.02.92 : ov_handling added.
 *  uli 17.02.92 : on_fastfor added.
 *  LS  31.07.92 : non-option parameters will be gathered in a seperate
                   string and will be used as filenames ( for IBM-CMS ).
                   LS = Lutz Schmidt
 *  PJ  10.11.92 : on_print_check added.
 *  PJ  30.03.95 : string.h included (because of use of strcpy and strcat)
*/

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

#include           "impor.t"
#include "sysutil.h"

#include           "expor.t"
#include "option.h"

#include           "implemen.t"


#ifdef LINT_ARGS
local char * scanname (char *) ;
#endif

boolean
 /* initialize Compiler flags:
  user specified        on or off    default    comment
 +-------------------+-------------+---------+---------------------- */
  os_verbose = false ,  on_verbose = true ,  /* verbose compiler     */
  os_list    = false ,  on_list    = false,  /* listing to file      */
  os_warning = false ,  on_warning = true ,  /* report warnings      */
  os_merge   = false ,  on_merge   = false,  /* merge source in code */
  os_code    = false ,  on_code    = false,  /* code generation      */
  os_rename  = false ,  on_rename  = true ,  /* rename Pascal idents */
  os_index   = false ,  on_index   = true ,  /* index check          */
  os_number  = false ,  on_number  = true ,  /* linenumbers in code  */
  os_include = false ,  on_include = false,  /* include "filename"   */
  os_dump    = false ,  on_dump    = false,  /* structab dump        */
  os_terminal= false ,  on_terminal= false,  /* code to terminal     */
  os_handling= false ,  on_handling= false,  /* explain error hanndling */
  os_fastfor = false ,  on_fastfor = false,  /* for-loops for vector processors */
  os_bib     = false ,  on_bib     = false,  /* flags for library modules */
                        on_srcdir  = false,  /* output directory     */
                        on_remove  = true ,  /* remove output files  */
                        on_prototyp= false,  /* new style prototypes */
                        on_reverse = true ,  /* link modules in reverse */
  os_print_check = false, on_print_check = false, /* print check messages */
  /* . . . . . to be continued */
  os_dummy      ;
char
  *ov_real    = (char*)0 ,                  /* value of real option */
  *ov_include = (char*)0 ;                  /* value of include option */
int
   ov_idlength = 8 ,            /* identifier length accepted by linker */
   ov_abort = 0,                /* no abort compilation in case of error */
   ov_handling = 7;             /* length of lookahead queue */

                                                /*-------------------*/
#ifdef LINT_ARGS
local char * scanname  (  char * ch )           /*  s c a n n a m e  */
#else
local char * scanname (ch)
  /* returns the string specified behind '=', if not found then null */
  char * ch ;      /* pointer to scan option string */
#endif
BEGIN(scanname)
  /* ch points to the third char of option string */
  while (*ch != '=' and *ch != ':' and *ch != '\0') ch++ ; /* search for '=' */
  if (*ch != '\0')   return ( ch + 1 ) ;
  else return (0) ;
END/* scanname */


                                                /*-------------------*/
#ifdef LINT_ARGS
local void scanint (char * argv [],int * val)   /*  s c a n i n t    */
#else
local void scanint (argv, val)
  /* scans argv for a decimal integer value and assigns it to val. */
  char * argv []; int * val;
#endif
BEGIN(scanint)
   char * ch = (*argv)+2 ;
   /* ch points to the third char of option string */
   while (*ch != '=' and *ch != ':' and *ch != '\0' and
          *ch < '0'  and *ch > '9') ch++ ;      /* search value */
   if (*ch == '=' or *ch == ':')   ch++ ;
   if (*ch >= '0' and *ch <= '9')   *val = atoi (ch) ;
   /* if  (*ch == '\0')   /* nothing specified */
END/* scanint */


#define deflt(on,str) if (on) printf("+%s\n", str) ; else  printf("-%s\n", str)
/*
#ifdef LINT_ARGS
local void deflt  ( boolean on ,char * str )
#else
local void deflt (on, str)
  boolean on ;
  char * str ;
#endif
BEGIN(deflt)
  if (on)  printf ("+%s\n" ,str) ; else  printf ("-%s\n", str) ;
END /* deflt */


#ifdef LINT_ARGS
global char * readoptions  ( int argc ,char * argv [] )
#else
global char * readoptions (argc, argv)
  int argc ;
  char * argv [] ;
#endif
BEGIN(readoptions)
  static char fname[FILENAME_MAX]; /* LSchmidt. Buffer for specified
                                      file name */
  char * res ;     /* result, i.e. filename */
  boolean on ;     /* set option on/off */

  fname[0] = '\0'; /* LSchmidt. Initialize buffer and return pointer */
  res      = fname;

if (argc>1)
begin
  while (--argc > 0)
   if ( ( on = (*++argv) [0] == '+') or (*argv) [0] == '-')  then
     switch ((*argv)[1])  begin
       case 'A': case 'a':
           ov_abort = (on ? 1 : 0) ;
           scanint (argv, &ov_abort) ;       break ;
       case 'V': case 'v':
         os_verbose = true ; on_verbose = on ; break ;
       case 'L': case 'l':
         os_list    = true ; on_list    = on ; break ;
       case 'W': case 'w':
         os_warning = true ; on_warning = on ; break ;
       case 'M': case 'm':
         os_merge   = true ; on_merge   = on ; break ;
       case 'C': case 'c':
         os_code    = true ; on_code    = on ; break ;
       case 'X': case 'x':
         os_index   = true ; on_index   = on ; break ;
       case 'N': case 'n':
         os_number  = true ; on_number  = on ; break ;
       case 'F': case 'f':
         os_fastfor = true ; on_fastfor = on ; break ;

       case 'D': case 'd':

         os_dump = true ;
         on_dump = on ;
         break ;
       case 'B': case 'b':
         os_bib     = true ; on_bib     = on ; break ;
       case 'T': case 't':
         os_terminal= true ; on_terminal= on ; break ;
       case 'H': case 'h':
         os_handling= true ; on_handling= on ;
         scanint (argv, &ov_handling) ;        break ;
       case 'S': case 's':
                             on_srcdir  = on ; break ;
       case 'R': case 'r':
         ov_real    = scanname (&(*argv)[2]) ;
         os_rename  = true ; on_rename  = on ; break ;
       case 'I': case 'i':
         ov_include = scanname (&(*argv)[2]) ;
         os_include = true ; on_include = on ; break ;

       /*  PJ 10.11.92
              Print check error messages option
       */

       case 'K' : case 'k' :

         os_print_check = true;
         on_print_check = on;
         break;

       /* PJ 10.11.92  END */

       /* . . . . . to be continued */
       default :
         printf ("Unknown option  %c  ignored.\n", (*argv)[1]) ;
     end  /* switch option char */
   else   /* no option */
     if ( *res == '\0' ) strcpy( res, *argv );
     else
       strcat( strcat( res, " "), *argv );
  /* until command line read */
  return (res) ;
end
else         /* no file and no options specified */
begin
  printf ("Compiler options are:                                    default:\n"
        ) ;
  printf ("+v     verbose, Compiler reports, what he is doing         ") ;
  if  (os_verbose)
    deflt (on_verbose, "v") ;
  else
    printf ("\n") ;
  printf ("                No 'Compiling ...', but path & module info ") ;
  if  (os_verbose)
    deflt (on_verbose, "v") ;
  else
    printf ("\n") ;
  printf ("-v              Compiler is quiet                          ") ;
  if  (os_verbose)
    deflt (on_verbose, "v") ;
  else
    printf ("\n") ;

  printf ("+l     listing, direct messages to file *.lst              ") ;
  deflt (on_list   , "l") ;
  printf ("-l              display messages on terminal               ") ;
  deflt (on_list   , "l") ;
  printf ("+w     warning, report warnings                            ") ;
  deflt (on_warning, "w") ;
  printf ("-w              suppress warnings                          ") ;
  deflt (on_warning, "w") ;
  printf ("+m     merge,   merge source text into code                ") ;
  deflt (on_merge  , "m") ;
  printf ("-m              no source text in code                     ") ;
  deflt (on_merge  , "m") ;
  printf ("+a     abort,   abort compilation in case of error         ") ;
  deflt (ov_abort  , "a") ;
  printf ("-a              continue compilation in case of error      ") ;
  deflt (ov_abort  , "a") ;
  printf ("+f     fastfor, for-loops for vector processors            ") ;
  deflt (on_fastfor, "f") ;
  printf ("-f              standard conform for-loops                 ") ;
  deflt (on_fastfor, "f") ;
  printf ("+c     code,    code generation in any case                ") ;
  if  (os_code)
    deflt (on_code   , "c") ;
  else
    printf ("\n") ;
  printf ("                code generation only if error free         ") ;
  if  (os_code)
    deflt (on_code   , "c") ;
  else
    printf ("\n") ;
  printf ("-c              no code generation                         ") ;
  if  (os_code)
    deflt (on_code   , "c") ;
  else
    printf ("\n") ;
  printf ("+x     index,   generate index checks                      ") ;
  deflt (on_index  , "x") ;
  printf ("-x              no index checks                            ") ;
  deflt (on_index  , "x") ;
  printf ("+n     number,  generate line numbers into code            ") ;
  deflt (on_number , "n") ;
  printf ("-n              no line numbers in code                    ") ;
  deflt (on_number , "n") ;
  printf ("+d     dump,    internal dump, for debugging only          ") ;
  deflt (on_dump   , "d") ;
  printf ("-d              no dump                                    ") ;
  deflt (on_dump   , "d") ;
  printf ("+b     bibc,    generate module bibliothec file            ") ; /*nea
ga*/
  deflt (on_bib    , "b") ;
  printf ("-b              generate module object file                ") ;
  deflt (on_bib    , "b") ; /* neaga */
  printf ("+t     terminal,write code to stdout                       ") ;
  deflt (on_terminal, "t");
  printf ("-t              write code to file                         ") ;
  deflt (on_terminal, "t");
  printf ("+r     rename,  rename Pascal identifiers                  ") ;
  deflt (on_rename, "r");
  printf ("-r              preserve Pascal identifiers                ") ;
  deflt (on_rename, "r");
  printf ("+s     srcdir,  output to directory of source file         ") ;
  deflt (on_srcdir, "s");
  printf ("-s              output to current directory (working dir)  ") ;
  deflt (on_srcdir, "s");
  /* . . . . . to be continued */
#ifdef OLD
  printf ("-r=<filename>   -r and generate #include \"<filename>\"      ") ;
  printf ("unspec\n") ;
  printf ("-i=<filename>   generate #include \"<filename>\"             ") ;
  printf ("unspec\n") ;
#endif

  finish (0) ;
  return 0 ;  /* never reached */
end  /* options displayed */
END /* readoptions */
