LTP GCOV extension - code coverage report
Current view: directory - fcode-utils/toke - toke.c
Test: toke.info
Date: 2006-08-18 Instrumented lines: 103
Code covered: 92.2 % Executed lines: 95

       1                 : /*
       2                 :  *                     OpenBIOS - free your system! 
       3                 :  *                         ( FCode tokenizer )
       4                 :  *                          
       5                 :  *  toke.c - main tokenizer loop and parameter parsing.
       6                 :  *  
       7                 :  *  This program is part of a free implementation of the IEEE 1275-1994 
       8                 :  *  Standard for Boot (Initialization Configuration) Firmware.
       9                 :  *
      10                 :  *  Copyright (C) 2001-2006 by Stefan Reinauer <stepan@openbios.org>
      11                 :  *
      12                 :  *  This program is free software; you can redistribute it and/or modify
      13                 :  *  it under the terms of the GNU General Public License as published by
      14                 :  *  the Free Software Foundation; version 2 of the License.
      15                 :  *
      16                 :  *  This program is distributed in the hope that it will be useful,
      17                 :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :  *  GNU General Public License for more details.
      20                 :  *
      21                 :  *  You should have received a copy of the GNU General Public License
      22                 :  *  along with this program; if not, write to the Free Software
      23                 :  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
      24                 :  *
      25                 :  */
      26                 : 
      27                 : /* **************************************************************************
      28                 :  *         Modifications made in 2005 by IBM Corporation
      29                 :  *      (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
      30                 :  *      Modifications Author:  David L. Paktor    dlpaktor@us.ibm.com
      31                 :  **************************************************************************** */
      32                 : 
      33                 : #include <stdio.h>
      34                 : #include <stdlib.h>
      35                 : #include <string.h>
      36                 : #include <unistd.h>
      37                 : 
      38                 : #ifdef __GLIBC__
      39                 : #define _GNU_SOURCE
      40                 : #include <getopt.h>
      41                 : #endif
      42                 : 
      43                 : #include "types.h"
      44                 : #include "toke.h"
      45                 : #include "stream.h"
      46                 : #include "stack.h"
      47                 : #include "emit.h"
      48                 : 
      49                 : #define TOKE_VERSION "1.0.0"
      50                 : 
      51                 : #include "vocabfuncts.h"
      52                 : #include "scanner.h"
      53                 : #include "errhandler.h"
      54                 : #include "usersymbols.h"
      55                 : #include "clflags.h"
      56                 : #include "tracesyms.h"
      57                 : 
      58                 : #define CORE_COPYR   "(C) Copyright 2001-2006 Stefan Reinauer.\n" \
      59                 :                      "(C) Copyright 2006 coresystems GmbH <info@coresystems.de>"
      60                 : #define IBM_COPYR    "(C) Copyright 2005 IBM Corporation.  All Rights Reserved."
      61                 : 
      62                 : /*  Temporary hack during development...  See DATE_STAMP  line below... */
      63                 : #ifdef DEVEL
      64                 : #include "date_stamp.h"
      65                 : #endif /*  DEVEL  */
      66                 : 
      67                 : /* **************************************************************************
      68                 :  *
      69                 :  *     Global Variables Exported:
      70                 :  *        verbose          If true, enable optional messages.
      71                 :  *        noerrors         If true, create binary even if error(s) encountered.
      72                 :  *        fload_list       If true, create an "FLoad-List" file
      73                 :  *        dependency_list  If true, create a "Dependencies-List" file
      74                 :  *
      75                 :  **************************************************************************** */
      76                 : 
      77                 : bool verbose         = FALSE;
      78                 : bool noerrors        = FALSE;
      79                 : bool fload_list      = FALSE;
      80                 : bool dependency_list = FALSE;
      81                 : 
      82                 : /* **************************************************************************
      83                 :  *
      84                 :  *              Internal Static Variables
      85                 :  *         outputname    Name of output file supplied on command-line
      86                 :  *                           with the optional  -o  switch.
      87                 :  *              Internal System Variable
      88                 :  *         optind        Index into argv vector of first param after options,
      89                 :  *                           from which input file names will be taken.
      90                 :  *
      91                 :  **************************************************************************** */
      92                 : 
      93                 : static char *outputname = NULL;
      94                 : 
      95                 : /* **************************************************************************
      96                 :  *
      97                 :  *    Print the copyright message.
      98                 :  *
      99                 :  **************************************************************************** */
     100                 : static void print_copyright(void)
     101             161 : {
     102             161 :         printf( "Welcome to toke - OpenBIOS tokenizer v" TOKE_VERSION "\n"
     103                 :                 CORE_COPYR "\n" IBM_COPYR "\n"
     104                 :                 "This program is free software; you may redistribute it "
     105                 :                 "under the terms of\nthe GNU General Public License. This "
     106                 :                 "program has absolutely no warranty.\n\n");
     107                 : #ifdef DEVEL
     108                 :         /*  Temporary hack during development... */
     109                 :         printf( "\tTokenizer Compiled " DATE_STAMP "\n" );
     110                 : #endif /*  DEVEL  */
     111                 : 
     112             161 : }
     113                 : 
     114                 : /* **************************************************************************
     115                 :  *
     116                 :  *      Function name:    usage
     117                 :  *      Synopsis:         Print convenient usage-help message
     118                 :  *
     119                 :  **************************************************************************** */
     120                 : 
     121                 : static void usage(char *name)
     122               2 : {
     123               2 :         printf("usage: %s [-v] [-i] [-l] [-P] [-o target] <[-d name[=value]]> "
     124                 :                                 "<[-f [no]flagname]> <[-I dir-path]> "
     125                 :                                 "<[-T symbol]> <forth-file>\n\n",name);
     126               2 :         printf("  -v|--verbose          print Advisory messages\n");
     127               2 :         printf("  -i|--ignore-errors    don't suppress output after errors\n");
     128               2 :         printf("  -l|--load-list        create list of FLoaded file names\n");
     129               2 :         printf("  -P|--dependencies     create dePendency-list file\n");
     130               2 :         printf("  -o|--output-name      send output to filename given\n");
     131               2 :         printf("  -d|--define           create user-defined symbol\n");
     132               2 :         printf("  -f|--flag             set (or clear) Special-Feature flag\n");
     133               2 :         printf("  -I|--Include          add a directory to the Include-List\n");
     134               2 :         printf("  -T|--Trace            add a symbol to the Trace List\n");
     135               2 :         printf("  -h|--help             print this help message\n\n");
     136               2 :         printf("  -f|--flag    help     Help for Special-Feature flags\n");
     137               2 : }
     138                 : 
     139                 : /* **************************************************************************
     140                 :  *
     141                 :  *      Function name:    get_args
     142                 :  *      Synopsis:         Parse the Command-Line option switches
     143                 :  *      
     144                 :  *      Inputs:
     145                 :  *         Parameters:                  NONE
     146                 :  *         Global Variables:
     147                 :  *                    argc      Counter of command-line arguments
     148                 :  *                    argv      Vector pointing to command-line arguments
     149                 :  *         Command-Line Items:  The entire command-line will be parsed
     150                 :  *
     151                 :  *      Outputs:
     152                 :  *         Returned Value:              NONE
     153                 :  *         Global Variables:
     154                 :  *                verbose            set by "-v" switch
     155                 :  *                noerrors           set by "-i" switch
     156                 :  *                fload_list         set by "-l" switch
     157                 :  *                dependency_list    set by "-P" switch
     158                 :  *         Internal Static Variables
     159                 :  *                outputname         set by "-o" switch
     160                 :  *         Internal System Variable
     161                 :  *                optind             Index into argv vector of the position
     162                 :  *                                       from which to take input file names.
     163                 :  *         Printout:
     164                 :  *                (Copyright was already printed by the main body as a
     165                 :  *                    matter of course, rather than here depending on
     166                 :  *                    the Verbose flag, because  getopt()  prints its
     167                 :  *                    own error messages and we want to be sure to show
     168                 :  *                    the Copyright notice before any error messages.)
     169                 :  *                Rules for Usage and Flags-list or Flags-help display:
     170                 :  *                  Usage message on Help-Request or error.
     171                 :  *                  Ask for usage help, get Usage plus list of Flag Names.
     172                 :  *                  Ask for Flags-help alone, get Flags-help (names plus
     173                 :  *                      explanations)
     174                 :  *                  Ask for usage help and for Flags-help, get Usage plus
     175                 :  *                      Flags-help, without redundant list of Flag Names.
     176                 :  *                  Any help-request, exit Zero
     177                 :  *                  Error in Option switches, or missing input-file name,
     178                 :  *                      get error-description plus Usage
     179                 :  *                  Error in Flag Names, get list of Flag Names.
     180                 :  *                  Any error, exit One.
     181                 :  *         Behavior:
     182                 :  *                Exit (non-failure) after printing "Help" message
     183                 :  *
     184                 :  *      Error Detection:     Exit with failure status on:
     185                 :  *          Unknown Option switches or Flag Names
     186                 :  *          Missing input file name
     187                 :  *
     188                 :  *      Process Explanation:
     189                 :  *           The following switches are recognized:
     190                 :  *               v
     191                 :  *               h
     192                 :  *               ?
     193                 :  *               i
     194                 :  *               I
     195                 :  *               l
     196                 :  *               P
     197                 :  *               o
     198                 :  *               d
     199                 :  *               f
     200                 :  *               T
     201                 :  *           The conditions they set remain in effect through
     202                 :  *               the entire program run.
     203                 :  *
     204                 :  *      Revision History:
     205                 :  *          Updated Fri, 15 Jul 2005 by David L. Paktor
     206                 :  *              Don't bail on first invalid option.
     207                 :  *              Flags to control special features
     208                 :  *              Usage messages for "special-feature" flags
     209                 :  *          Updated Mon, 18 Jul 2005 by David L. Paktor
     210                 :  *              Fine-tune Usage and Flags-list or Flags-help display.
     211                 :  *          Updated Sun, 27 Nov 2005 by David L. Paktor
     212                 :  *              Add FLoad-List flag
     213                 :  *          Updated Wed, 29 Nov 2005 by David L. Paktor
     214                 :  *              Make getopt() case-insensitive
     215                 :  *          Updated Fri, 17 Mar 2006 by David L. O'Paktor
     216                 :  *              Make getopt() case-sensitive again,
     217                 :  *                  add include-list support and dePendency-list switch
     218                 :  *
     219                 :  *      Extraneous Remarks:
     220                 :  *          We were originally thinking about defining various classes
     221                 :  *              of "Warning" Messages and (somehow) controlling their
     222                 :  *              display, but now that we have "special-feature" flags
     223                 :  *              that control the generation of specific messages, that
     224                 :  *              step has become unnecessary...
     225                 :  *
     226                 :  **************************************************************************** */
     227                 : 
     228                 : static void get_args( int argc, char **argv )
     229             161 : {
     230             161 :         const char *optstring="vhilPo:d:f:I:T:?";
     231                 :         int c;
     232             161 :         int argindx = 0;
     233             161 :         bool inval_opt = FALSE;
     234             161 :         bool help_mssg = FALSE;
     235             161 :         bool cl_flag_error = FALSE;
     236                 : 
     237                 :         while (1) {
     238                 : #ifdef __GLIBC__
     239             700 :                 int option_index = 0;
     240                 :                 static struct option long_options[] = {
     241                 :                         { "verbose", 0, 0, 'v' },
     242                 :                         { "help", 0, 0, 'h' },
     243                 :                         { "ignore-errors", 0, 0, 'i' },
     244                 :                         { "load-list",     0, 0, 'l' },
     245                 :                         { "dependencies",  0, 0, 'P' },
     246                 :                         { "output-name",   1, 0, 'o' },
     247                 :                         { "define",        1, 0, 'd' },
     248                 :                         { "flag",          1, 0, 'f' },
     249                 :                         { "Include",       1, 0, 'I' },
     250                 :                         { "Trace",         1, 0, 'T' },
     251                 :                         { 0, 0, 0, 0 }
     252                 :                 };
     253                 : 
     254             700 :                 c = getopt_long (argc, argv, optstring,
     255                 :                                  long_options, &option_index);
     256                 : #else
     257                 :                 c = getopt (argc, argv, optstring);
     258                 : #endif
     259             700 :                 if (c == -1)
     260             161 :                         break;
     261                 : 
     262             539 :                 argindx++;
     263             539 :                 switch (c) {
     264                 :                 case 'v':
     265             159 :                         verbose=TRUE;
     266             159 :                         break;
     267                 :                 case 'o':
     268              59 :                         outputname = optarg;
     269              59 :                         break;
     270                 :                 case 'i':
     271              79 :                         noerrors = TRUE;
     272              79 :                         break;
     273                 :                 case 'l':
     274              60 :                         fload_list = TRUE;
     275              60 :                         break;
     276                 :                 case 'P':
     277               2 :                         dependency_list = TRUE;
     278               2 :                         break;
     279                 :                 case 'd':
     280                 :                         {
     281              29 :                             char *user_symb = optarg;
     282              29 :                             add_user_symbol(user_symb);
     283                 :                         }
     284              29 :                         break;
     285                 :                 case 'f':
     286              66 :                         cl_flag_error = set_cl_flag(optarg, FALSE) ;
     287              66 :                         break;
     288                 :                 case 'I':
     289                 :                         {
     290              75 :                             char *incl_list_elem = optarg;
     291              75 :                             add_to_include_list(incl_list_elem);
     292                 :                         }
     293              75 :                         break;
     294                 :                 case 'T':
     295               9 :                         add_to_trace_list(optarg);
     296               9 :                         break;
     297                 :                 case '?':
     298                 :                         /*  Distinguish between a '?' from the user
     299                 :                          *  and one  getopt()  returned
     300                 :                          */
     301               0 :                         if ( argv[argindx][1] != '?' )
     302                 :                         {
     303               0 :                             inval_opt = TRUE;
     304               0 :                             break;
     305                 :                         }
     306                 :                 case 'h':
     307                 :                 case 'H':
     308               1 :                          help_mssg = TRUE;              
     309               1 :                         break;
     310                 :                 default:
     311                 :                         /*  This is never executed
     312                 :                          *  because  getopt()  prints the
     313                 :                          *    "unknown option -- X"
     314                 :                          *  message and returns a '?'
     315                 :                          */
     316               0 :                         printf ("%s: unknown options.\n",argv[0]);
     317               0 :                         usage(argv[0]);
     318               0 :                         exit( 1 );
     319                 :                 }
     320                 :         }
     321                 : 
     322             161 :         if ( help_mssg )
     323                 :         {
     324               1 :             usage(argv[0]);
     325               1 :             if ( ! clflag_help )
     326                 :             {
     327               1 :                 list_cl_flag_names();
     328                 :             }
     329                 :         }
     330             161 :         if ( clflag_help )  cl_flags_help();
     331             161 :         if ( help_mssg || clflag_help )
     332                 :         {
     333               5 :             exit( 0 );
     334                 :         }
     335                 : 
     336             156 :         if ( inval_opt )      printf ("unknown options.\n");
     337             156 :         if (optind >= argc)   printf ("Input file name missing.\n");
     338             156 :         if ( inval_opt || (optind >= argc) )
     339                 :         {
     340               1 :                 usage(argv[0]);
     341                 :         }
     342             156 :         if ( cl_flag_error )  list_cl_flag_names();
     343                 : 
     344             156 :         if ( inval_opt || (optind >= argc) || cl_flag_error )
     345                 :         {
     346               2 :             exit( 1);
     347                 :         }
     348                 : 
     349             154 :         if (verbose)
     350                 :         {
     351             153 :             list_user_symbols();
     352             153 :             list_cl_flag_settings();
     353             153 :             display_include_list();
     354                 :         }
     355             154 :         save_cl_flags();
     356             154 : }
     357                 : 
     358                 : /* **************************************************************************
     359                 :  *
     360                 :  *      Main body of program.  Return 0 for success, 1 for failure.
     361                 :  *
     362                 :  *      Still to be done:
     363                 :  *          Devise a syntax to allow the command-line to specify multiple
     364                 :  *              input files together with an output file name for each.
     365                 :  *          Currently, the syntax allows only one output file name to be
     366                 :  *              specified; when multiple input file names are specified,
     367                 :  *              the specification of an output file name is disallowed,
     368                 :  *              and only the default output file names are permitted.
     369                 :  *              While this works around the immediate problem, a more
     370                 :  *              elegant solution could be devised...
     371                 :  *
     372                 :  **************************************************************************** */
     373                 : 
     374                 : int main(int argc, char **argv)
     375             161 : {
     376             161 :         int retval = 0;
     377                 : 
     378             161 :         print_copyright();
     379             161 :         get_args( argc, argv );
     380                 : 
     381             154 :         init_stack();
     382             154 :         init_dictionary();
     383                 : 
     384             154 :         init_scanner();
     385                 :         
     386             154 :         if ( outputname != NULL )
     387                 :         {
     388              54 :             if ( argc > optind + 1 )
     389                 :             {
     390                 :             /*  Multiple input file names w/ single output file name  */
     391                 :                 /*  Work-around  */
     392               0 :                 printf( "Cannot specify single output file name "
     393                 :                         "with multiple input file names.\n"
     394                 :                         "Please either remove output-file-name specification,\n"
     395                 :                         "or use multiple commands.\n");
     396               0 :                 exit ( -2 );
     397                 :             }
     398                 :                 }
     399                 : 
     400             170 :         for ( ; optind < argc ; optind++ )
     401                 :         {
     402                 :             bool stream_ok ;
     403                 : 
     404             171 :             printf("\nTokenizing  %s   ", argv[optind]);
     405             171 :             init_error_handler();
     406             171 :             stream_ok = init_stream( argv[optind]);
     407             171 :             if ( stream_ok )
     408                 :             {
     409             165 :                 init_output(argv[optind], outputname);
     410                 : 
     411             165 :                 init_scan_state();
     412                 : 
     413             165 :                 reset_vocabs();
     414             165 :                 reset_cl_flags();
     415                 : 
     416             165 :                 tokenize();
     417             164 :                 finish_headers();
     418                 :                 
     419             164 :                 close_stream( NULL);
     420             164 :                 if ( close_output() )  retval = 1;
     421                 :             }
     422                 :         }
     423                 :         
     424             153 :         exit_scanner();
     425             153 :         return retval;
     426                 : }
     427                 : 

Generated by: LTP GCOV extension version 1.5