1 /* RCS $Id: macparse.c,v 1.3 2007-10-15 15:40:02 ihi Exp $
4 -- Parse a macro definition
7 -- This file contains the code that parses a macro definition
8 -- stored in a buffer. If the string in buffer is not a valid
9 -- macro definition the routie Parse_macro returns 0, otherwise it
10 -- returns 1 to indicate success.
13 -- Dennis Vadura, dvadura@dmake.wticorp.com
16 -- http://dmake.wticorp.com/
19 -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved.
21 -- This program is NOT free software; you can redistribute it and/or
22 -- modify it under the terms of the Software License Agreement Provided
23 -- in the file <distribution-root>/readme/license.txt.
26 -- Use cvs log to obtain detailed change logs.
32 Parse_macro( buffer
, flag
)/*
33 =============================
34 Parse the string in buffer and define it as a macro if it is a valid macro.
35 Note especially the string .SETDIR= since it is an attribute, but looks a
36 lot like a macro definition. This would not be a problem if make used
37 white space as token separators, since this is not the case we must do
38 something about it. */
42 char *result
; /* temporary pointer for strings */
43 TKSTR input
; /* place to scan the buffer from */
44 HASHPTR hv
; /* pointer to hash table value */
45 int operator; /* what macro operator do we have */
46 char *tok1
; /* temporary place to keep a token */
47 char *tok2
; /* temporary place to keep a token */
48 int toklen
; /* length of a token */
50 DB_ENTER( "Parse_macro" );
52 SET_TOKEN( &input
, buffer
);
53 tok1
= Get_token( &input
, "=+:*!?", 0 );
55 operator=Macro_op(tok1
);
57 CLEAR_TOKEN( &input
);
58 Error( "Assignment without macro name: [%s].", buffer
);
62 tok1
= DmStrDup(tok1
);
63 tok2
= Get_token( &input
, "=+:*!?", 2 );
64 if( !(operator = Macro_op(tok2
)) || !strcmp(tok1
,".SETDIR") ) {
65 CLEAR_TOKEN( &input
);
70 tok2
= Expand(tok1
); FREE(tok1
); tok1
= tok2
;
71 if ( !(toklen
= strlen(tok1
)) ) {
72 Warning( "Empty macro name after expansion: [%s].", buffer
);
75 /* Catch illegal single character macro names. */
76 if ( toklen
== 1 && strchr("{()}", tok1
[0]) ) {
77 CLEAR_TOKEN( &input
);
78 Fatal( "Syntax error in macro assignment [%s]. The following characters cannot be used as single letter macro names: '{()}'.", buffer
);
81 /* Catch ':' in macro names. */
82 if ( strchr(tok1
, ':') ) {
83 CLEAR_TOKEN( &input
);
84 Fatal( "Syntax error in macro assignment [%s]. The character ':' is not allowed in macro names.", buffer
);
87 tok2
= Get_token(&input
, NIL( char ), FALSE
);
89 /* Make sure we can force the assignment. */
90 if ( operator & M_OP_SI
) {
91 flag
|= M_FORCE
|M_MULTI
;
97 tok2
= Expand( tok2
);
101 /* Add to an existing macro, if it is not defined, though, then
102 * just define a new macro */
104 if( (hv
= GET_MACRO(tok1
)) == NIL(HASH
) || hv
->ht_value
== NIL(char) )
105 Def_macro( tok1
, tok2
, flag
);
107 result
= DmStrAdd( hv
->ht_value
, tok2
, FALSE
);
108 Def_macro( tok1
, result
, flag
);
111 if( operator == M_OP_PLCL
) FREE(tok2
);
116 /* internal default macros or initialized empty macros set M_INIT. */
117 if( (hv
= GET_MACRO(tok1
)) != NIL(HASH
) && !(hv
->ht_flag
& M_INIT
) )
122 Def_macro( tok1
, tok2
, flag
);
127 /* internal default macros or initialized empty macros set M_INIT. */
128 if( (hv
= GET_MACRO(tok1
)) != NIL(HASH
) && !(hv
->ht_flag
& M_INIT
) )
133 tok2
= Expand( tok2
);
134 Def_macro( tok1
, tok2
, M_EXPANDED
| flag
);
143 Error("Nested conditional definition [%s ?= %s] ignored",
148 if (cp
->ce_flag
& F_MULTI
) {
150 for(lp
=cp
->ce_prq
; lp
->cl_next
; lp
=lp
->cl_next
);
154 sp
->st_string
= DmStrDup(tok2
);
155 sp
->st_next
= cp
->ce_cond
;
165 if ( LastMacName
!= NIL(char) )
179 Check the passed in op string and map it to one of the macro operators */
183 DB_ENTER( "macro_op" );
191 case '=': ret
|= M_OP_EQ
; break;
192 case ':': ret
|= M_OP_CL
; op
++; break;