1 /* $RCSfile: parse.c,v $
3 -- last change: $Author: ihi $ $Date: 2007-10-15 15:40:45 $
6 -- Parse the input, and perform semantic analysis
9 -- This file contains the routines that parse the input makefile and
10 -- call the appropriate routines to perform the semantic analysis and
11 -- build the internal dag.
14 -- Dennis Vadura, dvadura@dmake.wticorp.com
17 -- http://dmake.wticorp.com/
20 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
22 -- This program is NOT free software; you can redistribute it and/or
23 -- modify it under the terms of the Software License Agreement Provided
24 -- in the file <distribution-root>/readme/license.txt.
27 -- Use cvs log to obtain detailed change logs.
35 ============== Parse the makefile input */
38 int rule
= FALSE
; /* have seen a recipe line */
39 char *p
; /* termporary pointer into Buffer */
45 Group
= FALSE
; /* true if scanning a group rcpe */
47 if( Get_line( Buffer
, fil
) ) {
48 if( Group
) Fatal( "Incomplete rule recipe group detected" );
50 /* If we are still in RULE_SCAN mode there might be unbound recipes. */
51 if( State
== RULE_SCAN
)
52 Bind_rules_to_targets( F_DEFAULT
);
54 if( fil
!= NIL( FILE ) ) /* end of parsable input */
62 if ( Buffer
[0] == 10 )
81 /* Check for the `[' that starts off a group recipe definition.
82 * It must appear as the first non-white space
83 * character in the line. */
85 p
= DmStrSpn( Buffer
, " \t\r\n" );
86 if( Set_group_attributes( p
) ) {
88 Fatal( "New group recipe begin found within group recipe." );
90 Fatal( "Cannot mix single and group recipe lines." );
96 break; /* ignore the group start */
101 Add_recipe_to_list( pTmpBuf
, TRUE
, TRUE
);
109 || (Notabs
&& *pTmpBuf
== ' ') ) {
110 Add_recipe_to_list( pTmpBuf
, FALSE
, FALSE
);
114 Fatal( "Found unmatched ']'" );
115 else if( *pTmpBuf
) /* Something that was no recipe. */
117 /* The only thing that was not handled was an empty line. */
120 if( State
== RULE_SCAN
) break; /* ie. keep going */
122 Bind_rules_to_targets( (Group
) ? F_GROUP
: F_DEFAULT
);
131 /* In this case we broke out of the rule scan because we do not
132 * have a recipe line that begins with a <TAB>, so lets
133 * try to scan the thing as a macro or rule definition. */
137 if( !*pTmpBuf
) continue; /* we have null input line */
139 /* STUPID AUGMAKE uses "include" at the start of a line as
140 * a signal to include a new file, so let's look for it.
141 * if we see it replace it by .INCLUDE: and stick this back
142 * into the buffer. */
143 if( !strncmp( "include", pTmpBuf
, 7 ) &&
144 (pTmpBuf
[7] == ' ' || pTmpBuf
[7] == '\t') )
148 tmp
= DmStrJoin( ".INCLUDE:", pTmpBuf
+7, -1, FALSE
);
149 strcpy( pTmpBuf
, tmp
);
153 /* look for a macro definition, they all contain an = sign
154 * if we fail to recognize it as a legal macro op then try to
155 * parse the same line as a rule definition, it's one or the
158 if( Parse_macro(pTmpBuf
, M_DEFAULT
) ) break;/* it's a macro def*/
159 if( Parse_rule_def( &State
) ) break;/* it's a rule def */
161 /* if it is an empty or blank line then ignore it */
162 if( !*Buffer
|| *DmStrSpn( Buffer
, " \t\r\n" ) == '\0' ) break;
164 /* otherwise assume it was a line of unrecognized input, or a
165 * recipe line out of place so print a message */
167 Fatal( "Expecting macro or rule defn, found neither" );
171 Fatal( "Internal -- UNKNOWN Parser state %d", State
);