home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / DMAKE37S.ZIP / DMAKE / PARSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  5.1 KB  |  158 lines

  1. /* RCS      -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/parse.c,v 1.1 91/05/06 15:23:20 dvadura Exp $
  2. -- SYNOPSIS -- parse the input, and perform semantic analysis
  3. -- 
  4. -- DESCRIPTION
  5. --     This file contains the routines that parse the input makefile and
  6. --    call the appropriate routines to perform the semantic analysis and
  7. --    build the internal dag.
  8. --
  9. -- AUTHOR
  10. --      Dennis Vadura, dvadura@watdragon.uwaterloo.ca
  11. --      CS DEPT, University of Waterloo, Waterloo, Ont., Canada
  12. --
  13. -- COPYRIGHT
  14. --      Copyright (c) 1990 by Dennis Vadura.  All rights reserved.
  15. -- 
  16. --      This program is free software; you can redistribute it and/or
  17. --      modify it under the terms of the GNU General Public License
  18. --      (version 1), as published by the Free Software Foundation, and
  19. --      found in the file 'LICENSE' included with this distribution.
  20. -- 
  21. --      This program is distributed in the hope that it will be useful,
  22. --      but WITHOUT ANY WARRANTY; without even the implied warrant of
  23. --      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  24. --      GNU General Public License for more details.
  25. -- 
  26. --      You should have received a copy of the GNU General Public License
  27. --      along with this program;  if not, write to the Free Software
  28. --      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  29. --
  30. -- LOG
  31. --     $Log:    parse.c,v $
  32.  * Revision 1.1  91/05/06  15:23:20  dvadura
  33.  * dmake Release Version 3.7
  34.  * 
  35. */
  36.  
  37. #include "extern.h"
  38.  
  39.  
  40. PUBLIC void
  41. Parse( fil )/*
  42. ==============  Parse the makefile input */
  43. FILE *fil;
  44. {
  45.    int  rule  = FALSE;                 /* have seen a recipe line        */
  46.    char *p;                   /* termporary pointer into Buffer */
  47.  
  48.    DB_ENTER( "Parse" );
  49.  
  50.    State = NORMAL_SCAN;
  51.    Group = FALSE;                 /* true if scanning a group rcpe  */
  52.    while( TRUE ) {
  53.       if( Get_line( Buffer, fil ) ) {
  54.      if( fil != NIL( FILE ) )               /* end of parsable input */
  55.         Closefile();
  56.  
  57.      Bind_rules_to_targets( F_DEFAULT );
  58.          if( Group )  Fatal( "Incomplete rule recipe group detected" );
  59.  
  60.      DB_VOID_RETURN;
  61.       }
  62.       else {
  63.          switch( State ) {
  64.         case RULE_SCAN:
  65.  
  66.            /* Check for the `[' that starts off a group rule definition.  It
  67.             * must appear as the first non-white space
  68.         * character in the line. */
  69.  
  70.            p = _strspn( Buffer, " \t\r\n" );
  71.                if( Set_group_attributes( p ) ) {
  72.                   if( rule && Group )
  73.                      Fatal( "Cannot mix single and group recipe lines" );
  74.                   else
  75.                      Group = TRUE;
  76.  
  77.                   rule = TRUE;
  78.  
  79.                   break;                     /* ignore the group start  */
  80.                }
  81.  
  82.                if( Group ) {
  83.                   if( *p != ']' ) {
  84.                      Add_recipe_to_list( Buffer, TRUE, TRUE );
  85.                      rule = TRUE;
  86.                   }
  87.                   else
  88.                      State = NORMAL_SCAN;
  89.                }
  90.                else {
  91.                   if( *Buffer == '\t' ) {
  92.                      Add_recipe_to_list( Buffer, FALSE, FALSE );
  93.                      rule = TRUE;
  94.                   }
  95.                   else if( *p == ']' )
  96.                      Fatal( "Found unmatched ']'" );
  97.                   else if( *Buffer && *p )
  98.              State = NORMAL_SCAN;
  99.                }
  100.  
  101.                if( State == RULE_SCAN ) break;     /* ie. keep going    */
  102.                
  103.            Bind_rules_to_targets( (Group) ? F_GROUP: F_DEFAULT );
  104.  
  105.                rule = FALSE;
  106.                if( Group ) {
  107.                   Group = FALSE;
  108.                   break;
  109.                }
  110.            /*FALLTRHOUGH*/
  111.  
  112.                /* In this case we broke out of the rule scan because we do not
  113.                 * have a recipe line that begins with a <TAB>, so lets
  114.         * try to scan the thing as a macro or rule definition. */
  115.                
  116.  
  117.         case NORMAL_SCAN:
  118.            if( !*Buffer ) continue;         /* we have null input line */
  119.  
  120.            /* STUPID AUGMAKE uses "include" at the start of a line as
  121.             * a signal to include a new file, so let's look for it.
  122.         * if we see it replace it by .INCLUDE: and stick this back
  123.         * into the buffer. */
  124.            if( !strncmp( "include", Buffer, 7 ) &&
  125.            (Buffer[7] == ' ' || Buffer[7] == '\t') )
  126.            {
  127.           char *tmp;
  128.  
  129.           tmp = _strjoin( ".INCLUDE:", Buffer+7, -1, FALSE );
  130.           strcpy( Buffer, tmp );
  131.           FREE( tmp );
  132.            }
  133.  
  134.                /* look for a macro definition, they all contain an = sign
  135.             * if we fail to recognize it as a legal macro op then try to
  136.         * parse the same line as a rule definition, it's one or the
  137.         * other */
  138.         
  139.            if( Parse_macro(Buffer, M_DEFAULT) ) break;/* it's a macro def */
  140.            if( Parse_rule_def( &State ) )         break;/* it's a rule def  */
  141.  
  142.            /* if just blank line then ignore it */
  143.            if( *_strspn( Buffer, " \t\r\n" ) == '\0' ) break;
  144.            
  145.            /* otherwise assume it was a line of unrecognized input, or a
  146.             * recipe line out of place so print a message */
  147.         
  148.            Fatal( "Expecting macro or rule defn, found neither" );
  149.            break;
  150.  
  151.         default:
  152.            Fatal( "Internal -- UNKNOWN Parser state %d", State );
  153.      }
  154.       }
  155.    }
  156. }
  157.  
  158.