4 -- Parse the input, and perform semantic analysis
7 -- This file contains the routines that parse the input makefile and
8 -- call the appropriate routines to perform the semantic analysis and
9 -- build the internal dag.
12 -- Dennis Vadura, dvadura@dmake.wticorp.com
15 -- http://dmake.wticorp.com/
18 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
20 -- This program is NOT free software; you can redistribute it and/or
21 -- modify it under the terms of the Software License Agreement Provided
22 -- in the file <distribution-root>/readme/license.txt.
25 -- Use cvs log to obtain detailed change logs.
33 ============== Parse the makefile input */
36 int rule
= FALSE
; /* have seen a recipe line */
37 char *p
; /* termporary pointer into Buffer */
43 Group
= FALSE
; /* true if scanning a group rcpe */
45 if( Get_line( Buffer
, fil
) ) {
46 if( Group
) Fatal( "Incomplete rule recipe group detected" );
48 /* If we are still in RULE_SCAN mode there might be unbound recipes. */
49 if( State
== RULE_SCAN
)
50 Bind_rules_to_targets( F_DEFAULT
);
52 if( fil
!= NIL( FILE ) ) /* end of parsable input */
60 if ( Buffer
[0] == 10 )
79 /* Check for the `[' that starts off a group recipe definition.
80 * It must appear as the first non-white space
81 * character in the line. */
83 p
= DmStrSpn( Buffer
, " \t\r\n" );
84 if( Set_group_attributes( p
) ) {
86 Fatal( "New group recipe begin found within group recipe." );
88 Fatal( "Cannot mix single and group recipe lines." );
94 break; /* ignore the group start */
99 Add_recipe_to_list( pTmpBuf
, TRUE
, TRUE
);
107 || (Notabs
&& *pTmpBuf
== ' ') ) {
108 Add_recipe_to_list( pTmpBuf
, FALSE
, FALSE
);
112 Fatal( "Found unmatched ']'" );
113 else if( *pTmpBuf
) /* Something that was no recipe. */
115 /* The only thing that was not handled was an empty line. */
118 if( State
== RULE_SCAN
) break; /* ie. keep going */
120 Bind_rules_to_targets( (Group
) ? F_GROUP
: F_DEFAULT
);
129 /* In this case we broke out of the rule scan because we do not
130 * have a recipe line that begins with a <TAB>, so lets
131 * try to scan the thing as a macro or rule definition. */
135 if( !*pTmpBuf
) continue; /* we have null input line */
137 /* STUPID AUGMAKE uses "include" at the start of a line as
138 * a signal to include a new file, so let's look for it.
139 * if we see it replace it by .INCLUDE: and stick this back
140 * into the buffer. */
141 if( !strncmp( "include", pTmpBuf
, 7 ) &&
142 (pTmpBuf
[7] == ' ' || pTmpBuf
[7] == '\t') )
146 tmp
= DmStrJoin( ".INCLUDE:", pTmpBuf
+7, -1, FALSE
);
147 strcpy( pTmpBuf
, tmp
);
151 /* look for a macro definition, they all contain an = sign
152 * if we fail to recognize it as a legal macro op then try to
153 * parse the same line as a rule definition, it's one or the
156 if( Parse_macro(pTmpBuf
, M_DEFAULT
) ) break;/* it's a macro def*/
157 if( Parse_rule_def( &State
) ) break;/* it's a rule def */
159 /* if it is an empty or blank line then ignore it */
160 if( !*Buffer
|| *DmStrSpn( Buffer
, " \t\r\n" ) == '\0' ) break;
162 /* otherwise assume it was a line of unrecognized input, or a
163 * recipe line out of place so print a message */
165 Fatal( "Expecting macro or rule defn, found neither" );
169 Fatal( "Internal -- UNKNOWN Parser state %d", State
);