xref: /illumos-gate/usr/src/cmd/make/bin/macro.cc (revision e3ae4b35c024af1196582063ecee3ab79367227d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  *	macro.cc
28  *
29  *	Handle expansion of make macros
30  */
31 
32 /*
33  * Included files
34  */
35 #include <mk/defs.h>
36 #include <mksh/macro.h>		/* getvar(), expand_value() */
37 #include <mksh/misc.h>		/* getmem() */
38 
39 /*
40  * Defined macros
41  */
42 
43 /*
44  * typedefs & structs
45  */
46 
47 /*
48  * Static variables
49  */
50 
51 /*
52  * File table of contents
53  */
54 
55 void
56 setvar_append(Name name, Name value)
57 {
58 	Property	macro_apx = get_prop(name->prop, macro_append_prop);
59 	Property	macro = get_prop(name->prop, macro_prop);
60 	int			length;
61 	String_rec		destination;
62 	wchar_t			buffer[STRING_BUFFER_LENGTH];
63 	Chain		chain;
64 	Name			val = NULL;
65 
66 	if(macro_apx == NULL) {
67 		macro_apx = append_prop(name, macro_append_prop);
68 		if(macro != NULL) {
69 			macro_apx->body.macro_appendix.value = macro->body.macro.value;
70 		}
71 	}
72 
73 	val = macro_apx->body.macro_appendix.value_to_append;
74 
75 	INIT_STRING_FROM_STACK(destination, buffer);
76 	buffer[0] = 0;
77 	if (val != NULL) {
78 		APPEND_NAME(val,
79 			      &destination,
80 			      (int) val->hash.length);
81 		if (value != NULL) {
82 			MBTOWC(wcs_buffer, " ");
83 			append_char(wcs_buffer[0], &destination);
84 		}
85 	}
86 	if (value != NULL) {
87 		APPEND_NAME(value,
88 			      &destination,
89 			      (int) value->hash.length);
90 	}
91 	value = GETNAME(destination.buffer.start, FIND_LENGTH);
92 	if (destination.free_after_use) {
93 		retmem(destination.buffer.start);
94 	}
95 	macro_apx->body.macro_appendix.value_to_append = value;
96 
97 	SETVAR(name, empty_name, true);
98 }
99 
100 /*
101  *	setvar_envvar()
102  *
103  *	This function scans the list of environment variables that have
104  *	dynamic values and sets them.
105  *
106  *	Parameters:
107  *
108  *	Global variables used:
109  *		envvar		A list of environment vars with $ in value
110  */
111 void
112 setvar_envvar(void)
113 {
114 	wchar_t			buffer[STRING_BUFFER_LENGTH];
115 	int			length;
116 	char	*mbs, *tmp_mbs_buffer = NULL;
117 	char	*env, *tmp_mbs_buffer2 = NULL;
118 	Envvar			p;
119 	String_rec		value;
120 
121 	for (p = envvar; p != NULL; p = p->next) {
122 		if (p->already_put
123 		    ) {
124 			continue;
125 		}
126 		INIT_STRING_FROM_STACK(value, buffer);
127 		expand_value(p->value, &value, false);
128 		if ((length = wcslen(value.buffer.start)) >= MAXPATHLEN) {
129 			mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX);
130 			(void) wcstombs(mbs,
131 			                value.buffer.start,
132 			                (length + 1) * MB_LEN_MAX);
133 		} else {
134 			mbs = mbs_buffer;
135 			WCSTOMBS(mbs, value.buffer.start);
136 		}
137 		length = 2 + strlen(p->name->string_mb) + strlen(mbs);
138 		if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) {
139 			env = tmp_mbs_buffer2 = getmem(length);
140 		} else {
141 			env = mbs_buffer2;
142 		}
143 		(void) sprintf(env,
144 			       "%s=%s",
145 			       p->name->string_mb,
146 			       mbs);
147 		if (!p->already_put) {
148 			(void) putenv(env);
149 			p->already_put = true;
150 			if (p->env_string) {
151 				retmem_mb(p->env_string);
152 			}
153 			p->env_string = env;
154 			tmp_mbs_buffer2 = NULL; // We should not return this memory now
155 		}
156 		if (tmp_mbs_buffer2) {
157 			retmem_mb(tmp_mbs_buffer2);
158 			tmp_mbs_buffer2 = NULL;
159 		}
160 		if (tmp_mbs_buffer) {
161 			retmem_mb(tmp_mbs_buffer);
162 			tmp_mbs_buffer = NULL;
163 		}
164 	}
165 }
166 
167 
168