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 * @(#)macro.cc 1.28 06/12/12
27 */
28
29 #pragma ident "@(#)macro.cc 1.28 06/12/12"
30
31 /*
32 * macro.cc
33 *
34 * Handle expansion of make macros
35 */
36
37 /*
38 * Included files
39 */
40 #ifdef DISTRIBUTED
41 #include <avo/strings.h> /* AVO_STRDUP() */
42 #include <dm/Avo_DoJobMsg.h>
43 #endif
44 #include <mk/defs.h>
45 #include <mksh/macro.h> /* getvar(), expand_value() */
46 #include <mksh/misc.h> /* getmem() */
47
48 /*
49 * Defined macros
50 */
51
52 /*
53 * typedefs & structs
54 */
55
56 /*
57 * Static variables
58 */
59
60 /*
61 * File table of contents
62 */
63
64 void
65 setvar_append(register Name name, register Name value)
66 {
67 register Property macro_apx = get_prop(name->prop, macro_append_prop);
68 register Property macro = get_prop(name->prop, macro_prop);
69 int length;
70 String_rec destination;
71 wchar_t buffer[STRING_BUFFER_LENGTH];
72 register Chain chain;
73 Name val = NULL;
74
75 if(macro_apx == NULL) {
76 macro_apx = append_prop(name, macro_append_prop);
77 if(macro != NULL) {
78 macro_apx->body.macro_appendix.value = macro->body.macro.value;
79 }
80 }
81
82 val = macro_apx->body.macro_appendix.value_to_append;
83
84 INIT_STRING_FROM_STACK(destination, buffer);
85 buffer[0] = 0;
86 if (val != NULL) {
87 APPEND_NAME(val,
88 &destination,
89 (int) val->hash.length);
90 if (value != NULL) {
91 MBTOWC(wcs_buffer, " ");
92 append_char(wcs_buffer[0], &destination);
93 }
94 }
95 if (value != NULL) {
96 APPEND_NAME(value,
97 &destination,
98 (int) value->hash.length);
99 }
100 value = GETNAME(destination.buffer.start, FIND_LENGTH);
101 if (destination.free_after_use) {
102 retmem(destination.buffer.start);
103 }
104 macro_apx->body.macro_appendix.value_to_append = value;
105
106 SETVAR(name, empty_name, true);
107 }
108
109 /*
110 * setvar_envvar()
111 *
112 * This function scans the list of environment variables that have
113 * dynamic values and sets them.
114 *
115 * Parameters:
116 *
117 * Global variables used:
118 * envvar A list of environment vars with $ in value
119 */
120 void
121 #ifdef DISTRIBUTED
122 setvar_envvar(Avo_DoJobMsg *dmake_job_msg)
123 #else
124 setvar_envvar(void)
125 #endif
126 {
127 wchar_t buffer[STRING_BUFFER_LENGTH];
128 int length;
129 #ifdef DISTRIBUTED
130 Property macro;
131 #endif
132 register char *mbs, *tmp_mbs_buffer = NULL;
133 register char *env, *tmp_mbs_buffer2 = NULL;
134 Envvar p;
135 String_rec value;
136
137 for (p = envvar; p != NULL; p = p->next) {
138 if (p->already_put
139 #ifdef DISTRIBUTED
140 && !dmake_job_msg
141 #endif
142 ) {
143 continue;
144 }
145 INIT_STRING_FROM_STACK(value, buffer);
146 expand_value(p->value, &value, false);
147 if ((length = wslen(value.buffer.start)) >= MAXPATHLEN) {
148 mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX);
149 (void) wcstombs(mbs,
150 value.buffer.start,
151 (length + 1) * MB_LEN_MAX);
152 } else {
153 mbs = mbs_buffer;
154 WCSTOMBS(mbs, value.buffer.start);
155 }
156 length = 2 + strlen(p->name->string_mb) + strlen(mbs);
157 if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) {
158 env = tmp_mbs_buffer2 = getmem(length);
159 } else {
160 env = mbs_buffer2;
161 }
162 (void) sprintf(env,
163 "%s=%s",
164 p->name->string_mb,
165 mbs);
166 if (!p->already_put) {
167 (void) putenv(env);
168 p->already_put = true;
169 if (p->env_string) {
170 retmem_mb(p->env_string);
171 }
172 p->env_string = env;
173 tmp_mbs_buffer2 = NULL; // We should not return this memory now
174 }
175 #ifdef DISTRIBUTED
176 if (dmake_job_msg) {
177 dmake_job_msg->appendVar(env);
178 }
179 #endif
180 if (tmp_mbs_buffer2) {
181 retmem_mb(tmp_mbs_buffer2);
182 tmp_mbs_buffer2 = NULL;
183 }
184 if (tmp_mbs_buffer) {
185 retmem_mb(tmp_mbs_buffer);
186 tmp_mbs_buffer = NULL;
187 }
188 }
189 #ifdef DISTRIBUTED
190 /* Append SUNPRO_DEPENDENCIES to the dmake_job_msg. */
191 if (keep_state && dmake_job_msg) {
192 macro = get_prop(sunpro_dependencies->prop, macro_prop);
193 length = 2 +
194 strlen(sunpro_dependencies->string_mb) +
195 strlen(macro->body.macro.value->string_mb);
196 if (length > (MAXPATHLEN * MB_LEN_MAX)) {
197 env = tmp_mbs_buffer2 = getmem(length);
198 } else {
199 env = mbs_buffer2;
200 }
201 (void) sprintf(env,
202 "%s=%s",
203 sunpro_dependencies->string_mb,
204 macro->body.macro.value->string_mb);
205 dmake_job_msg->appendVar(env);
206 if (tmp_mbs_buffer2) {
207 retmem_mb(tmp_mbs_buffer2);
208 tmp_mbs_buffer2 = NULL;
209 }
210 }
211 #endif
212 }
213
214