1*3625efb1SRichard Lowe /*
2*3625efb1SRichard Lowe * CDDL HEADER START
3*3625efb1SRichard Lowe *
4*3625efb1SRichard Lowe * The contents of this file are subject to the terms of the
5*3625efb1SRichard Lowe * Common Development and Distribution License (the "License").
6*3625efb1SRichard Lowe * You may not use this file except in compliance with the License.
7*3625efb1SRichard Lowe *
8*3625efb1SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3625efb1SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*3625efb1SRichard Lowe * See the License for the specific language governing permissions
11*3625efb1SRichard Lowe * and limitations under the License.
12*3625efb1SRichard Lowe *
13*3625efb1SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*3625efb1SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3625efb1SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*3625efb1SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*3625efb1SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*3625efb1SRichard Lowe *
19*3625efb1SRichard Lowe * CDDL HEADER END
20*3625efb1SRichard Lowe */
21*3625efb1SRichard Lowe /*
22*3625efb1SRichard Lowe * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*3625efb1SRichard Lowe * Use is subject to license terms.
24*3625efb1SRichard Lowe */
25*3625efb1SRichard Lowe
26*3625efb1SRichard Lowe
27*3625efb1SRichard Lowe /*
28*3625efb1SRichard Lowe * macro.cc
29*3625efb1SRichard Lowe *
30*3625efb1SRichard Lowe * Handle expansion of make macros
31*3625efb1SRichard Lowe */
32*3625efb1SRichard Lowe
33*3625efb1SRichard Lowe /*
34*3625efb1SRichard Lowe * Included files
35*3625efb1SRichard Lowe */
36*3625efb1SRichard Lowe #include <mksh/dosys.h> /* sh_command2string() */
37*3625efb1SRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */
38*3625efb1SRichard Lowe #include <mksh/macro.h>
39*3625efb1SRichard Lowe #include <mksh/misc.h> /* retmem() */
40*3625efb1SRichard Lowe #include <mksh/read.h> /* get_next_block_fn() */
41*3625efb1SRichard Lowe
42*3625efb1SRichard Lowe #include <libintl.h>
43*3625efb1SRichard Lowe
44*3625efb1SRichard Lowe /*
45*3625efb1SRichard Lowe * File table of contents
46*3625efb1SRichard Lowe */
47*3625efb1SRichard Lowe static void add_macro_to_global_list(Name macro_to_add);
48*3625efb1SRichard Lowe static void expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd);
49*3625efb1SRichard Lowe
50*3625efb1SRichard Lowe static void init_arch_macros(void);
51*3625efb1SRichard Lowe static void init_mach_macros(void);
52*3625efb1SRichard Lowe static Boolean init_arch_done = false;
53*3625efb1SRichard Lowe static Boolean init_mach_done = false;
54*3625efb1SRichard Lowe
55*3625efb1SRichard Lowe
56*3625efb1SRichard Lowe long env_alloc_num = 0;
57*3625efb1SRichard Lowe long env_alloc_bytes = 0;
58*3625efb1SRichard Lowe
59*3625efb1SRichard Lowe /*
60*3625efb1SRichard Lowe * getvar(name)
61*3625efb1SRichard Lowe *
62*3625efb1SRichard Lowe * Return expanded value of macro.
63*3625efb1SRichard Lowe *
64*3625efb1SRichard Lowe * Return value:
65*3625efb1SRichard Lowe * The expanded value of the macro
66*3625efb1SRichard Lowe *
67*3625efb1SRichard Lowe * Parameters:
68*3625efb1SRichard Lowe * name The name of the macro we want the value for
69*3625efb1SRichard Lowe *
70*3625efb1SRichard Lowe * Global variables used:
71*3625efb1SRichard Lowe */
72*3625efb1SRichard Lowe Name
getvar(register Name name)73*3625efb1SRichard Lowe getvar(register Name name)
74*3625efb1SRichard Lowe {
75*3625efb1SRichard Lowe String_rec destination;
76*3625efb1SRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
77*3625efb1SRichard Lowe register Name result;
78*3625efb1SRichard Lowe
79*3625efb1SRichard Lowe if ((name == host_arch) || (name == target_arch)) {
80*3625efb1SRichard Lowe if (!init_arch_done) {
81*3625efb1SRichard Lowe init_arch_done = true;
82*3625efb1SRichard Lowe init_arch_macros();
83*3625efb1SRichard Lowe }
84*3625efb1SRichard Lowe }
85*3625efb1SRichard Lowe if ((name == host_mach) || (name == target_mach)) {
86*3625efb1SRichard Lowe if (!init_mach_done) {
87*3625efb1SRichard Lowe init_mach_done = true;
88*3625efb1SRichard Lowe init_mach_macros();
89*3625efb1SRichard Lowe }
90*3625efb1SRichard Lowe }
91*3625efb1SRichard Lowe
92*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
93*3625efb1SRichard Lowe expand_value(maybe_append_prop(name, macro_prop)->body.macro.value,
94*3625efb1SRichard Lowe &destination,
95*3625efb1SRichard Lowe false);
96*3625efb1SRichard Lowe result = GETNAME(destination.buffer.start, FIND_LENGTH);
97*3625efb1SRichard Lowe if (destination.free_after_use) {
98*3625efb1SRichard Lowe retmem(destination.buffer.start);
99*3625efb1SRichard Lowe }
100*3625efb1SRichard Lowe return result;
101*3625efb1SRichard Lowe }
102*3625efb1SRichard Lowe
103*3625efb1SRichard Lowe /*
104*3625efb1SRichard Lowe * expand_value(value, destination, cmd)
105*3625efb1SRichard Lowe *
106*3625efb1SRichard Lowe * Recursively expands all macros in the string value.
107*3625efb1SRichard Lowe * destination is where the expanded value should be appended.
108*3625efb1SRichard Lowe *
109*3625efb1SRichard Lowe * Parameters:
110*3625efb1SRichard Lowe * value The value we are expanding
111*3625efb1SRichard Lowe * destination Where to deposit the expansion
112*3625efb1SRichard Lowe * cmd If we are evaluating a command line we
113*3625efb1SRichard Lowe * turn \ quoting off
114*3625efb1SRichard Lowe *
115*3625efb1SRichard Lowe * Global variables used:
116*3625efb1SRichard Lowe */
117*3625efb1SRichard Lowe void
expand_value(Name value,register String destination,Boolean cmd)118*3625efb1SRichard Lowe expand_value(Name value, register String destination, Boolean cmd)
119*3625efb1SRichard Lowe {
120*3625efb1SRichard Lowe Source_rec sourceb;
121*3625efb1SRichard Lowe register Source source = &sourceb;
122*3625efb1SRichard Lowe register wchar_t *source_p = NULL;
123*3625efb1SRichard Lowe register wchar_t *source_end = NULL;
124*3625efb1SRichard Lowe wchar_t *block_start = NULL;
125*3625efb1SRichard Lowe int quote_seen = 0;
126*3625efb1SRichard Lowe
127*3625efb1SRichard Lowe if (value == NULL) {
128*3625efb1SRichard Lowe /*
129*3625efb1SRichard Lowe * Make sure to get a string allocated even if it
130*3625efb1SRichard Lowe * will be empty.
131*3625efb1SRichard Lowe */
132*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, "");
133*3625efb1SRichard Lowe append_string(wcs_buffer, destination, FIND_LENGTH);
134*3625efb1SRichard Lowe destination->text.end = destination->text.p;
135*3625efb1SRichard Lowe return;
136*3625efb1SRichard Lowe }
137*3625efb1SRichard Lowe if (!value->dollar) {
138*3625efb1SRichard Lowe /*
139*3625efb1SRichard Lowe * If the value we are expanding does not contain
140*3625efb1SRichard Lowe * any $, we don't have to parse it.
141*3625efb1SRichard Lowe */
142*3625efb1SRichard Lowe APPEND_NAME(value,
143*3625efb1SRichard Lowe destination,
144*3625efb1SRichard Lowe (int) value->hash.length
145*3625efb1SRichard Lowe );
146*3625efb1SRichard Lowe destination->text.end = destination->text.p;
147*3625efb1SRichard Lowe return;
148*3625efb1SRichard Lowe }
149*3625efb1SRichard Lowe
150*3625efb1SRichard Lowe if (value->being_expanded) {
151*3625efb1SRichard Lowe fatal_reader_mksh(gettext("Loop detected when expanding macro value `%s'"),
152*3625efb1SRichard Lowe value->string_mb);
153*3625efb1SRichard Lowe }
154*3625efb1SRichard Lowe value->being_expanded = true;
155*3625efb1SRichard Lowe /* Setup the structure we read from */
156*3625efb1SRichard Lowe Wstring vals(value);
157*3625efb1SRichard Lowe sourceb.string.text.p = sourceb.string.buffer.start = wcsdup(vals.get_string());
158*3625efb1SRichard Lowe sourceb.string.free_after_use = true;
159*3625efb1SRichard Lowe sourceb.string.text.end =
160*3625efb1SRichard Lowe sourceb.string.buffer.end =
161*3625efb1SRichard Lowe sourceb.string.text.p + value->hash.length;
162*3625efb1SRichard Lowe sourceb.previous = NULL;
163*3625efb1SRichard Lowe sourceb.fd = -1;
164*3625efb1SRichard Lowe sourceb.inp_buf =
165*3625efb1SRichard Lowe sourceb.inp_buf_ptr =
166*3625efb1SRichard Lowe sourceb.inp_buf_end = NULL;
167*3625efb1SRichard Lowe sourceb.error_converting = false;
168*3625efb1SRichard Lowe /* Lift some pointers from the struct to local register variables */
169*3625efb1SRichard Lowe CACHE_SOURCE(0);
170*3625efb1SRichard Lowe /* We parse the string in segments */
171*3625efb1SRichard Lowe /* We read chars until we find a $, then we append what we have read so far */
172*3625efb1SRichard Lowe /* (since last $ processing) to the destination. When we find a $ we call */
173*3625efb1SRichard Lowe /* expand_macro() and let it expand that particular $ reference into dest */
174*3625efb1SRichard Lowe block_start = source_p;
175*3625efb1SRichard Lowe quote_seen = 0;
176*3625efb1SRichard Lowe for (; 1; source_p++) {
177*3625efb1SRichard Lowe switch (GET_CHAR()) {
178*3625efb1SRichard Lowe case backslash_char:
179*3625efb1SRichard Lowe /* Quote $ in macro value */
180*3625efb1SRichard Lowe if (!cmd) {
181*3625efb1SRichard Lowe quote_seen = ~quote_seen;
182*3625efb1SRichard Lowe }
183*3625efb1SRichard Lowe continue;
184*3625efb1SRichard Lowe case dollar_char:
185*3625efb1SRichard Lowe /* Save the plain string we found since */
186*3625efb1SRichard Lowe /* start of string or previous $ */
187*3625efb1SRichard Lowe if (quote_seen) {
188*3625efb1SRichard Lowe append_string(block_start,
189*3625efb1SRichard Lowe destination,
190*3625efb1SRichard Lowe source_p - block_start - 1);
191*3625efb1SRichard Lowe block_start = source_p;
192*3625efb1SRichard Lowe break;
193*3625efb1SRichard Lowe }
194*3625efb1SRichard Lowe append_string(block_start,
195*3625efb1SRichard Lowe destination,
196*3625efb1SRichard Lowe source_p - block_start);
197*3625efb1SRichard Lowe source->string.text.p = ++source_p;
198*3625efb1SRichard Lowe UNCACHE_SOURCE();
199*3625efb1SRichard Lowe /* Go expand the macro reference */
200*3625efb1SRichard Lowe expand_macro(source, destination, sourceb.string.buffer.start, cmd);
201*3625efb1SRichard Lowe CACHE_SOURCE(1);
202*3625efb1SRichard Lowe block_start = source_p + 1;
203*3625efb1SRichard Lowe break;
204*3625efb1SRichard Lowe case nul_char:
205*3625efb1SRichard Lowe /* The string ran out. Get some more */
206*3625efb1SRichard Lowe append_string(block_start,
207*3625efb1SRichard Lowe destination,
208*3625efb1SRichard Lowe source_p - block_start);
209*3625efb1SRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
210*3625efb1SRichard Lowe if (source == NULL) {
211*3625efb1SRichard Lowe destination->text.end = destination->text.p;
212*3625efb1SRichard Lowe value->being_expanded = false;
213*3625efb1SRichard Lowe return;
214*3625efb1SRichard Lowe }
215*3625efb1SRichard Lowe if (source->error_converting) {
216*3625efb1SRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_value()");
217*3625efb1SRichard Lowe }
218*3625efb1SRichard Lowe block_start = source_p;
219*3625efb1SRichard Lowe source_p--;
220*3625efb1SRichard Lowe continue;
221*3625efb1SRichard Lowe }
222*3625efb1SRichard Lowe quote_seen = 0;
223*3625efb1SRichard Lowe }
224*3625efb1SRichard Lowe retmem(sourceb.string.buffer.start);
225*3625efb1SRichard Lowe }
226*3625efb1SRichard Lowe
227*3625efb1SRichard Lowe /*
228*3625efb1SRichard Lowe * expand_macro(source, destination, current_string, cmd)
229*3625efb1SRichard Lowe *
230*3625efb1SRichard Lowe * Should be called with source->string.text.p pointing to
231*3625efb1SRichard Lowe * the first char after the $ that starts a macro reference.
232*3625efb1SRichard Lowe * source->string.text.p is returned pointing to the first char after
233*3625efb1SRichard Lowe * the macro name.
234*3625efb1SRichard Lowe * It will read the macro name, expanding any macros in it,
235*3625efb1SRichard Lowe * and get the value. The value is then expanded.
236*3625efb1SRichard Lowe * destination is a String that is filled in with the expanded macro.
237*3625efb1SRichard Lowe * It may be passed in referencing a buffer to expand the macro into.
238*3625efb1SRichard Lowe * Note that most expansions are done on demand, e.g. right
239*3625efb1SRichard Lowe * before the command is executed and not while the file is
240*3625efb1SRichard Lowe * being parsed.
241*3625efb1SRichard Lowe *
242*3625efb1SRichard Lowe * Parameters:
243*3625efb1SRichard Lowe * source The source block that references the string
244*3625efb1SRichard Lowe * to expand
245*3625efb1SRichard Lowe * destination Where to put the result
246*3625efb1SRichard Lowe * current_string The string we are expanding, for error msg
247*3625efb1SRichard Lowe * cmd If we are evaluating a command line we
248*3625efb1SRichard Lowe * turn \ quoting off
249*3625efb1SRichard Lowe *
250*3625efb1SRichard Lowe * Global variables used:
251*3625efb1SRichard Lowe * funny Vector of semantic tags for characters
252*3625efb1SRichard Lowe * is_conditional Set if a conditional macro is refd
253*3625efb1SRichard Lowe * make_word_mentioned Set if the word "MAKE" is mentioned
254*3625efb1SRichard Lowe * makefile_type We deliver extra msg when reading makefiles
255*3625efb1SRichard Lowe * query The Name "?", compared against
256*3625efb1SRichard Lowe * query_mentioned Set if the word "?" is mentioned
257*3625efb1SRichard Lowe */
258*3625efb1SRichard Lowe void
expand_macro(register Source source,register String destination,wchar_t * current_string,Boolean cmd)259*3625efb1SRichard Lowe expand_macro(register Source source, register String destination, wchar_t *current_string, Boolean cmd)
260*3625efb1SRichard Lowe {
261*3625efb1SRichard Lowe static Name make = (Name)NULL;
262*3625efb1SRichard Lowe static wchar_t colon_sh[4];
263*3625efb1SRichard Lowe static wchar_t colon_shell[7];
264*3625efb1SRichard Lowe String_rec string;
265*3625efb1SRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
266*3625efb1SRichard Lowe register wchar_t *source_p = source->string.text.p;
267*3625efb1SRichard Lowe register wchar_t *source_end = source->string.text.end;
268*3625efb1SRichard Lowe register int closer = 0;
269*3625efb1SRichard Lowe wchar_t *block_start = (wchar_t *)NULL;
270*3625efb1SRichard Lowe int quote_seen = 0;
271*3625efb1SRichard Lowe register int closer_level = 1;
272*3625efb1SRichard Lowe Name name = (Name)NULL;
273*3625efb1SRichard Lowe wchar_t *colon = (wchar_t *)NULL;
274*3625efb1SRichard Lowe wchar_t *percent = (wchar_t *)NULL;
275*3625efb1SRichard Lowe wchar_t *eq = (wchar_t *) NULL;
276*3625efb1SRichard Lowe Property macro = NULL;
277*3625efb1SRichard Lowe wchar_t *p = (wchar_t*)NULL;
278*3625efb1SRichard Lowe String_rec extracted;
279*3625efb1SRichard Lowe wchar_t extracted_string[MAXPATHLEN];
280*3625efb1SRichard Lowe wchar_t *left_head = NULL;
281*3625efb1SRichard Lowe wchar_t *left_tail = NULL;
282*3625efb1SRichard Lowe wchar_t *right_tail = NULL;
283*3625efb1SRichard Lowe int left_head_len = 0;
284*3625efb1SRichard Lowe int left_tail_len = 0;
285*3625efb1SRichard Lowe int tmp_len = 0;
286*3625efb1SRichard Lowe wchar_t *right_hand[128];
287*3625efb1SRichard Lowe int i = 0;
288*3625efb1SRichard Lowe enum {
289*3625efb1SRichard Lowe no_extract,
290*3625efb1SRichard Lowe dir_extract,
291*3625efb1SRichard Lowe file_extract
292*3625efb1SRichard Lowe } extraction = no_extract;
293*3625efb1SRichard Lowe enum {
294*3625efb1SRichard Lowe no_replace,
295*3625efb1SRichard Lowe suffix_replace,
296*3625efb1SRichard Lowe pattern_replace,
297*3625efb1SRichard Lowe sh_replace
298*3625efb1SRichard Lowe } replacement = no_replace;
299*3625efb1SRichard Lowe
300*3625efb1SRichard Lowe if (make == NULL) {
301*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, "MAKE");
302*3625efb1SRichard Lowe make = GETNAME(wcs_buffer, FIND_LENGTH);
303*3625efb1SRichard Lowe
304*3625efb1SRichard Lowe MBSTOWCS(colon_sh, ":sh");
305*3625efb1SRichard Lowe MBSTOWCS(colon_shell, ":shell");
306*3625efb1SRichard Lowe }
307*3625efb1SRichard Lowe
308*3625efb1SRichard Lowe right_hand[0] = NULL;
309*3625efb1SRichard Lowe
310*3625efb1SRichard Lowe /* First copy the (macro-expanded) macro name into string. */
311*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
312*3625efb1SRichard Lowe recheck_first_char:
313*3625efb1SRichard Lowe /* Check the first char of the macro name to figure out what to do. */
314*3625efb1SRichard Lowe switch (GET_CHAR()) {
315*3625efb1SRichard Lowe case nul_char:
316*3625efb1SRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
317*3625efb1SRichard Lowe if (source == NULL) {
318*3625efb1SRichard Lowe WCSTOMBS(mbs_buffer, current_string);
319*3625efb1SRichard Lowe fatal_reader_mksh(gettext("'$' at end of string `%s'"),
320*3625efb1SRichard Lowe mbs_buffer);
321*3625efb1SRichard Lowe }
322*3625efb1SRichard Lowe if (source->error_converting) {
323*3625efb1SRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_macro()");
324*3625efb1SRichard Lowe }
325*3625efb1SRichard Lowe goto recheck_first_char;
326*3625efb1SRichard Lowe case parenleft_char:
327*3625efb1SRichard Lowe /* Multi char name. */
328*3625efb1SRichard Lowe closer = (int) parenright_char;
329*3625efb1SRichard Lowe break;
330*3625efb1SRichard Lowe case braceleft_char:
331*3625efb1SRichard Lowe /* Multi char name. */
332*3625efb1SRichard Lowe closer = (int) braceright_char;
333*3625efb1SRichard Lowe break;
334*3625efb1SRichard Lowe case newline_char:
335*3625efb1SRichard Lowe fatal_reader_mksh(gettext("'$' at end of line"));
336*3625efb1SRichard Lowe default:
337*3625efb1SRichard Lowe /* Single char macro name. Just suck it up */
338*3625efb1SRichard Lowe append_char(*source_p, &string);
339*3625efb1SRichard Lowe source->string.text.p = source_p + 1;
340*3625efb1SRichard Lowe goto get_macro_value;
341*3625efb1SRichard Lowe }
342*3625efb1SRichard Lowe
343*3625efb1SRichard Lowe /* Handle multi-char macro names */
344*3625efb1SRichard Lowe block_start = ++source_p;
345*3625efb1SRichard Lowe quote_seen = 0;
346*3625efb1SRichard Lowe for (; 1; source_p++) {
347*3625efb1SRichard Lowe switch (GET_CHAR()) {
348*3625efb1SRichard Lowe case nul_char:
349*3625efb1SRichard Lowe append_string(block_start,
350*3625efb1SRichard Lowe &string,
351*3625efb1SRichard Lowe source_p - block_start);
352*3625efb1SRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
353*3625efb1SRichard Lowe if (source == NULL) {
354*3625efb1SRichard Lowe if (current_string != NULL) {
355*3625efb1SRichard Lowe WCSTOMBS(mbs_buffer, current_string);
356*3625efb1SRichard Lowe fatal_reader_mksh(gettext("Unmatched `%c' in string `%s'"),
357*3625efb1SRichard Lowe closer ==
358*3625efb1SRichard Lowe (int) braceright_char ?
359*3625efb1SRichard Lowe (int) braceleft_char :
360*3625efb1SRichard Lowe (int) parenleft_char,
361*3625efb1SRichard Lowe mbs_buffer);
362*3625efb1SRichard Lowe } else {
363*3625efb1SRichard Lowe fatal_reader_mksh(gettext("Premature EOF"));
364*3625efb1SRichard Lowe }
365*3625efb1SRichard Lowe }
366*3625efb1SRichard Lowe if (source->error_converting) {
367*3625efb1SRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_macro()");
368*3625efb1SRichard Lowe }
369*3625efb1SRichard Lowe block_start = source_p;
370*3625efb1SRichard Lowe source_p--;
371*3625efb1SRichard Lowe continue;
372*3625efb1SRichard Lowe case newline_char:
373*3625efb1SRichard Lowe fatal_reader_mksh(gettext("Unmatched `%c' on line"),
374*3625efb1SRichard Lowe closer == (int) braceright_char ?
375*3625efb1SRichard Lowe (int) braceleft_char :
376*3625efb1SRichard Lowe (int) parenleft_char);
377*3625efb1SRichard Lowe case backslash_char:
378*3625efb1SRichard Lowe /* Quote dollar in macro value. */
379*3625efb1SRichard Lowe if (!cmd) {
380*3625efb1SRichard Lowe quote_seen = ~quote_seen;
381*3625efb1SRichard Lowe }
382*3625efb1SRichard Lowe continue;
383*3625efb1SRichard Lowe case dollar_char:
384*3625efb1SRichard Lowe /*
385*3625efb1SRichard Lowe * Macro names may reference macros.
386*3625efb1SRichard Lowe * This expands the value of such macros into the
387*3625efb1SRichard Lowe * macro name string.
388*3625efb1SRichard Lowe */
389*3625efb1SRichard Lowe if (quote_seen) {
390*3625efb1SRichard Lowe append_string(block_start,
391*3625efb1SRichard Lowe &string,
392*3625efb1SRichard Lowe source_p - block_start - 1);
393*3625efb1SRichard Lowe block_start = source_p;
394*3625efb1SRichard Lowe break;
395*3625efb1SRichard Lowe }
396*3625efb1SRichard Lowe append_string(block_start,
397*3625efb1SRichard Lowe &string,
398*3625efb1SRichard Lowe source_p - block_start);
399*3625efb1SRichard Lowe source->string.text.p = ++source_p;
400*3625efb1SRichard Lowe UNCACHE_SOURCE();
401*3625efb1SRichard Lowe expand_macro(source, &string, current_string, cmd);
402*3625efb1SRichard Lowe CACHE_SOURCE(0);
403*3625efb1SRichard Lowe block_start = source_p;
404*3625efb1SRichard Lowe source_p--;
405*3625efb1SRichard Lowe break;
406*3625efb1SRichard Lowe case parenleft_char:
407*3625efb1SRichard Lowe /* Allow nested pairs of () in the macro name. */
408*3625efb1SRichard Lowe if (closer == (int) parenright_char) {
409*3625efb1SRichard Lowe closer_level++;
410*3625efb1SRichard Lowe }
411*3625efb1SRichard Lowe break;
412*3625efb1SRichard Lowe case braceleft_char:
413*3625efb1SRichard Lowe /* Allow nested pairs of {} in the macro name. */
414*3625efb1SRichard Lowe if (closer == (int) braceright_char) {
415*3625efb1SRichard Lowe closer_level++;
416*3625efb1SRichard Lowe }
417*3625efb1SRichard Lowe break;
418*3625efb1SRichard Lowe case parenright_char:
419*3625efb1SRichard Lowe case braceright_char:
420*3625efb1SRichard Lowe /*
421*3625efb1SRichard Lowe * End of the name. Save the string in the macro
422*3625efb1SRichard Lowe * name string.
423*3625efb1SRichard Lowe */
424*3625efb1SRichard Lowe if ((*source_p == closer) && (--closer_level <= 0)) {
425*3625efb1SRichard Lowe source->string.text.p = source_p + 1;
426*3625efb1SRichard Lowe append_string(block_start,
427*3625efb1SRichard Lowe &string,
428*3625efb1SRichard Lowe source_p - block_start);
429*3625efb1SRichard Lowe goto get_macro_value;
430*3625efb1SRichard Lowe }
431*3625efb1SRichard Lowe break;
432*3625efb1SRichard Lowe }
433*3625efb1SRichard Lowe quote_seen = 0;
434*3625efb1SRichard Lowe }
435*3625efb1SRichard Lowe /*
436*3625efb1SRichard Lowe * We got the macro name. We now inspect it to see if it
437*3625efb1SRichard Lowe * specifies any translations of the value.
438*3625efb1SRichard Lowe */
439*3625efb1SRichard Lowe get_macro_value:
440*3625efb1SRichard Lowe name = NULL;
441*3625efb1SRichard Lowe /* First check if we have a $(@D) type translation. */
442*3625efb1SRichard Lowe if ((get_char_semantics_value(string.buffer.start[0]) &
443*3625efb1SRichard Lowe (int) special_macro_sem) &&
444*3625efb1SRichard Lowe (string.text.p - string.buffer.start >= 2) &&
445*3625efb1SRichard Lowe ((string.buffer.start[1] == 'D') ||
446*3625efb1SRichard Lowe (string.buffer.start[1] == 'F'))) {
447*3625efb1SRichard Lowe switch (string.buffer.start[1]) {
448*3625efb1SRichard Lowe case 'D':
449*3625efb1SRichard Lowe extraction = dir_extract;
450*3625efb1SRichard Lowe break;
451*3625efb1SRichard Lowe case 'F':
452*3625efb1SRichard Lowe extraction = file_extract;
453*3625efb1SRichard Lowe break;
454*3625efb1SRichard Lowe default:
455*3625efb1SRichard Lowe WCSTOMBS(mbs_buffer, string.buffer.start);
456*3625efb1SRichard Lowe fatal_reader_mksh(gettext("Illegal macro reference `%s'"),
457*3625efb1SRichard Lowe mbs_buffer);
458*3625efb1SRichard Lowe }
459*3625efb1SRichard Lowe /* Internalize the macro name using the first char only. */
460*3625efb1SRichard Lowe name = GETNAME(string.buffer.start, 1);
461*3625efb1SRichard Lowe (void) wcscpy(string.buffer.start, string.buffer.start + 2);
462*3625efb1SRichard Lowe }
463*3625efb1SRichard Lowe /* Check for other kinds of translations. */
464*3625efb1SRichard Lowe if ((colon = (wchar_t *) wcschr(string.buffer.start,
465*3625efb1SRichard Lowe (int) colon_char)) != NULL) {
466*3625efb1SRichard Lowe /*
467*3625efb1SRichard Lowe * We have a $(FOO:.c=.o) type translation.
468*3625efb1SRichard Lowe * Get the name of the macro proper.
469*3625efb1SRichard Lowe */
470*3625efb1SRichard Lowe if (name == NULL) {
471*3625efb1SRichard Lowe name = GETNAME(string.buffer.start,
472*3625efb1SRichard Lowe colon - string.buffer.start);
473*3625efb1SRichard Lowe }
474*3625efb1SRichard Lowe /* Pickup all the translations. */
475*3625efb1SRichard Lowe if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
476*3625efb1SRichard Lowe replacement = sh_replace;
477*3625efb1SRichard Lowe } else if ((svr4) ||
478*3625efb1SRichard Lowe ((percent = (wchar_t *) wcschr(colon + 1,
479*3625efb1SRichard Lowe (int) percent_char)) == NULL)) {
480*3625efb1SRichard Lowe while (colon != NULL) {
481*3625efb1SRichard Lowe if ((eq = (wchar_t *) wcschr(colon + 1,
482*3625efb1SRichard Lowe (int) equal_char)) == NULL) {
483*3625efb1SRichard Lowe fatal_reader_mksh(gettext("= missing from replacement macro reference"));
484*3625efb1SRichard Lowe }
485*3625efb1SRichard Lowe left_tail_len = eq - colon - 1;
486*3625efb1SRichard Lowe if(left_tail) {
487*3625efb1SRichard Lowe retmem(left_tail);
488*3625efb1SRichard Lowe }
489*3625efb1SRichard Lowe left_tail = ALLOC_WC(left_tail_len + 1);
490*3625efb1SRichard Lowe (void) wcsncpy(left_tail,
491*3625efb1SRichard Lowe colon + 1,
492*3625efb1SRichard Lowe eq - colon - 1);
493*3625efb1SRichard Lowe left_tail[eq - colon - 1] = (int) nul_char;
494*3625efb1SRichard Lowe replacement = suffix_replace;
495*3625efb1SRichard Lowe if ((colon = (wchar_t *) wcschr(eq + 1,
496*3625efb1SRichard Lowe (int) colon_char)) != NULL) {
497*3625efb1SRichard Lowe tmp_len = colon - eq;
498*3625efb1SRichard Lowe if(right_tail) {
499*3625efb1SRichard Lowe retmem(right_tail);
500*3625efb1SRichard Lowe }
501*3625efb1SRichard Lowe right_tail = ALLOC_WC(tmp_len);
502*3625efb1SRichard Lowe (void) wcsncpy(right_tail,
503*3625efb1SRichard Lowe eq + 1,
504*3625efb1SRichard Lowe colon - eq - 1);
505*3625efb1SRichard Lowe right_tail[colon - eq - 1] =
506*3625efb1SRichard Lowe (int) nul_char;
507*3625efb1SRichard Lowe } else {
508*3625efb1SRichard Lowe if(right_tail) {
509*3625efb1SRichard Lowe retmem(right_tail);
510*3625efb1SRichard Lowe }
511*3625efb1SRichard Lowe right_tail = ALLOC_WC(wcslen(eq) + 1);
512*3625efb1SRichard Lowe (void) wcscpy(right_tail, eq + 1);
513*3625efb1SRichard Lowe }
514*3625efb1SRichard Lowe }
515*3625efb1SRichard Lowe } else {
516*3625efb1SRichard Lowe if ((eq = (wchar_t *) wcschr(colon + 1,
517*3625efb1SRichard Lowe (int) equal_char)) == NULL) {
518*3625efb1SRichard Lowe fatal_reader_mksh(gettext("= missing from replacement macro reference"));
519*3625efb1SRichard Lowe }
520*3625efb1SRichard Lowe if ((percent = (wchar_t *) wcschr(colon + 1,
521*3625efb1SRichard Lowe (int) percent_char)) == NULL) {
522*3625efb1SRichard Lowe fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
523*3625efb1SRichard Lowe }
524*3625efb1SRichard Lowe if (eq < percent) {
525*3625efb1SRichard Lowe fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
526*3625efb1SRichard Lowe }
527*3625efb1SRichard Lowe
528*3625efb1SRichard Lowe if (percent > (colon + 1)) {
529*3625efb1SRichard Lowe tmp_len = percent - colon;
530*3625efb1SRichard Lowe if(left_head) {
531*3625efb1SRichard Lowe retmem(left_head);
532*3625efb1SRichard Lowe }
533*3625efb1SRichard Lowe left_head = ALLOC_WC(tmp_len);
534*3625efb1SRichard Lowe (void) wcsncpy(left_head,
535*3625efb1SRichard Lowe colon + 1,
536*3625efb1SRichard Lowe percent - colon - 1);
537*3625efb1SRichard Lowe left_head[percent-colon-1] = (int) nul_char;
538*3625efb1SRichard Lowe left_head_len = percent-colon-1;
539*3625efb1SRichard Lowe } else {
540*3625efb1SRichard Lowe left_head = NULL;
541*3625efb1SRichard Lowe left_head_len = 0;
542*3625efb1SRichard Lowe }
543*3625efb1SRichard Lowe
544*3625efb1SRichard Lowe if (eq > percent+1) {
545*3625efb1SRichard Lowe tmp_len = eq - percent;
546*3625efb1SRichard Lowe if(left_tail) {
547*3625efb1SRichard Lowe retmem(left_tail);
548*3625efb1SRichard Lowe }
549*3625efb1SRichard Lowe left_tail = ALLOC_WC(tmp_len);
550*3625efb1SRichard Lowe (void) wcsncpy(left_tail,
551*3625efb1SRichard Lowe percent + 1,
552*3625efb1SRichard Lowe eq - percent - 1);
553*3625efb1SRichard Lowe left_tail[eq-percent-1] = (int) nul_char;
554*3625efb1SRichard Lowe left_tail_len = eq-percent-1;
555*3625efb1SRichard Lowe } else {
556*3625efb1SRichard Lowe left_tail = NULL;
557*3625efb1SRichard Lowe left_tail_len = 0;
558*3625efb1SRichard Lowe }
559*3625efb1SRichard Lowe
560*3625efb1SRichard Lowe if ((percent = (wchar_t *) wcschr(++eq,
561*3625efb1SRichard Lowe (int) percent_char)) == NULL) {
562*3625efb1SRichard Lowe
563*3625efb1SRichard Lowe right_hand[0] = ALLOC_WC(wcslen(eq) + 1);
564*3625efb1SRichard Lowe right_hand[1] = NULL;
565*3625efb1SRichard Lowe (void) wcscpy(right_hand[0], eq);
566*3625efb1SRichard Lowe } else {
567*3625efb1SRichard Lowe i = 0;
568*3625efb1SRichard Lowe do {
569*3625efb1SRichard Lowe right_hand[i] = ALLOC_WC(percent-eq+1);
570*3625efb1SRichard Lowe (void) wcsncpy(right_hand[i],
571*3625efb1SRichard Lowe eq,
572*3625efb1SRichard Lowe percent - eq);
573*3625efb1SRichard Lowe right_hand[i][percent-eq] =
574*3625efb1SRichard Lowe (int) nul_char;
575*3625efb1SRichard Lowe if (i++ >= VSIZEOF(right_hand)) {
576*3625efb1SRichard Lowe fatal_mksh(gettext("Too many %% in pattern"));
577*3625efb1SRichard Lowe }
578*3625efb1SRichard Lowe eq = percent + 1;
579*3625efb1SRichard Lowe if (eq[0] == (int) nul_char) {
580*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, "");
581*3625efb1SRichard Lowe right_hand[i] = (wchar_t *) wcsdup(wcs_buffer);
582*3625efb1SRichard Lowe i++;
583*3625efb1SRichard Lowe break;
584*3625efb1SRichard Lowe }
585*3625efb1SRichard Lowe } while ((percent = (wchar_t *) wcschr(eq, (int) percent_char)) != NULL);
586*3625efb1SRichard Lowe if (eq[0] != (int) nul_char) {
587*3625efb1SRichard Lowe right_hand[i] = ALLOC_WC(wcslen(eq) + 1);
588*3625efb1SRichard Lowe (void) wcscpy(right_hand[i], eq);
589*3625efb1SRichard Lowe i++;
590*3625efb1SRichard Lowe }
591*3625efb1SRichard Lowe right_hand[i] = NULL;
592*3625efb1SRichard Lowe }
593*3625efb1SRichard Lowe replacement = pattern_replace;
594*3625efb1SRichard Lowe }
595*3625efb1SRichard Lowe }
596*3625efb1SRichard Lowe if (name == NULL) {
597*3625efb1SRichard Lowe /*
598*3625efb1SRichard Lowe * No translations found.
599*3625efb1SRichard Lowe * Use the whole string as the macro name.
600*3625efb1SRichard Lowe */
601*3625efb1SRichard Lowe name = GETNAME(string.buffer.start,
602*3625efb1SRichard Lowe string.text.p - string.buffer.start);
603*3625efb1SRichard Lowe }
604*3625efb1SRichard Lowe if (string.free_after_use) {
605*3625efb1SRichard Lowe retmem(string.buffer.start);
606*3625efb1SRichard Lowe }
607*3625efb1SRichard Lowe if (name == make) {
608*3625efb1SRichard Lowe make_word_mentioned = true;
609*3625efb1SRichard Lowe }
610*3625efb1SRichard Lowe if (name == query) {
611*3625efb1SRichard Lowe query_mentioned = true;
612*3625efb1SRichard Lowe }
613*3625efb1SRichard Lowe if ((name == host_arch) || (name == target_arch)) {
614*3625efb1SRichard Lowe if (!init_arch_done) {
615*3625efb1SRichard Lowe init_arch_done = true;
616*3625efb1SRichard Lowe init_arch_macros();
617*3625efb1SRichard Lowe }
618*3625efb1SRichard Lowe }
619*3625efb1SRichard Lowe if ((name == host_mach) || (name == target_mach)) {
620*3625efb1SRichard Lowe if (!init_mach_done) {
621*3625efb1SRichard Lowe init_mach_done = true;
622*3625efb1SRichard Lowe init_mach_macros();
623*3625efb1SRichard Lowe }
624*3625efb1SRichard Lowe }
625*3625efb1SRichard Lowe /* Get the macro value. */
626*3625efb1SRichard Lowe macro = get_prop(name->prop, macro_prop);
627*3625efb1SRichard Lowe if ((macro != NULL) && macro->body.macro.is_conditional) {
628*3625efb1SRichard Lowe conditional_macro_used = true;
629*3625efb1SRichard Lowe /*
630*3625efb1SRichard Lowe * Add this conditional macro to the beginning of the
631*3625efb1SRichard Lowe * global list.
632*3625efb1SRichard Lowe */
633*3625efb1SRichard Lowe add_macro_to_global_list(name);
634*3625efb1SRichard Lowe if (makefile_type == reading_makefile) {
635*3625efb1SRichard Lowe warning_mksh(gettext("Conditional macro `%s' referenced in file `%ws', line %d"),
636*3625efb1SRichard Lowe name->string_mb, file_being_read, line_number);
637*3625efb1SRichard Lowe }
638*3625efb1SRichard Lowe }
639*3625efb1SRichard Lowe /* Macro name read and parsed. Expand the value. */
640*3625efb1SRichard Lowe if ((macro == NULL) || (macro->body.macro.value == NULL)) {
641*3625efb1SRichard Lowe /* If the value is empty, we just get out of here. */
642*3625efb1SRichard Lowe goto exit;
643*3625efb1SRichard Lowe }
644*3625efb1SRichard Lowe if (replacement == sh_replace) {
645*3625efb1SRichard Lowe /* If we should do a :sh transform, we expand the command
646*3625efb1SRichard Lowe * and process it.
647*3625efb1SRichard Lowe */
648*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
649*3625efb1SRichard Lowe /* Expand the value into a local string buffer and run cmd. */
650*3625efb1SRichard Lowe expand_value_with_daemon(name, macro, &string, cmd);
651*3625efb1SRichard Lowe sh_command2string(&string, destination);
652*3625efb1SRichard Lowe } else if ((replacement != no_replace) || (extraction != no_extract)) {
653*3625efb1SRichard Lowe /*
654*3625efb1SRichard Lowe * If there were any transforms specified in the macro
655*3625efb1SRichard Lowe * name, we deal with them here.
656*3625efb1SRichard Lowe */
657*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
658*3625efb1SRichard Lowe /* Expand the value into a local string buffer. */
659*3625efb1SRichard Lowe expand_value_with_daemon(name, macro, &string, cmd);
660*3625efb1SRichard Lowe /* Scan the expanded string. */
661*3625efb1SRichard Lowe p = string.buffer.start;
662*3625efb1SRichard Lowe while (*p != (int) nul_char) {
663*3625efb1SRichard Lowe wchar_t chr;
664*3625efb1SRichard Lowe
665*3625efb1SRichard Lowe /*
666*3625efb1SRichard Lowe * First skip over any white space and append
667*3625efb1SRichard Lowe * that to the destination string.
668*3625efb1SRichard Lowe */
669*3625efb1SRichard Lowe block_start = p;
670*3625efb1SRichard Lowe while ((*p != (int) nul_char) && iswspace(*p)) {
671*3625efb1SRichard Lowe p++;
672*3625efb1SRichard Lowe }
673*3625efb1SRichard Lowe append_string(block_start,
674*3625efb1SRichard Lowe destination,
675*3625efb1SRichard Lowe p - block_start);
676*3625efb1SRichard Lowe /* Then find the end of the next word. */
677*3625efb1SRichard Lowe block_start = p;
678*3625efb1SRichard Lowe while ((*p != (int) nul_char) && !iswspace(*p)) {
679*3625efb1SRichard Lowe p++;
680*3625efb1SRichard Lowe }
681*3625efb1SRichard Lowe /* If we cant find another word we are done */
682*3625efb1SRichard Lowe if (block_start == p) {
683*3625efb1SRichard Lowe break;
684*3625efb1SRichard Lowe }
685*3625efb1SRichard Lowe /* Then apply the transforms to the word */
686*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(extracted, extracted_string);
687*3625efb1SRichard Lowe switch (extraction) {
688*3625efb1SRichard Lowe case dir_extract:
689*3625efb1SRichard Lowe /*
690*3625efb1SRichard Lowe * $(@D) type transform. Extract the
691*3625efb1SRichard Lowe * path from the word. Deliver "." if
692*3625efb1SRichard Lowe * none is found.
693*3625efb1SRichard Lowe */
694*3625efb1SRichard Lowe if (p != NULL) {
695*3625efb1SRichard Lowe chr = *p;
696*3625efb1SRichard Lowe *p = (int) nul_char;
697*3625efb1SRichard Lowe }
698*3625efb1SRichard Lowe eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
699*3625efb1SRichard Lowe if (p != NULL) {
700*3625efb1SRichard Lowe *p = chr;
701*3625efb1SRichard Lowe }
702*3625efb1SRichard Lowe if ((eq == NULL) || (eq > p)) {
703*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, ".");
704*3625efb1SRichard Lowe append_string(wcs_buffer, &extracted, 1);
705*3625efb1SRichard Lowe } else {
706*3625efb1SRichard Lowe append_string(block_start,
707*3625efb1SRichard Lowe &extracted,
708*3625efb1SRichard Lowe eq - block_start);
709*3625efb1SRichard Lowe }
710*3625efb1SRichard Lowe break;
711*3625efb1SRichard Lowe case file_extract:
712*3625efb1SRichard Lowe /*
713*3625efb1SRichard Lowe * $(@F) type transform. Remove the path
714*3625efb1SRichard Lowe * from the word if any.
715*3625efb1SRichard Lowe */
716*3625efb1SRichard Lowe if (p != NULL) {
717*3625efb1SRichard Lowe chr = *p;
718*3625efb1SRichard Lowe *p = (int) nul_char;
719*3625efb1SRichard Lowe }
720*3625efb1SRichard Lowe eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
721*3625efb1SRichard Lowe if (p != NULL) {
722*3625efb1SRichard Lowe *p = chr;
723*3625efb1SRichard Lowe }
724*3625efb1SRichard Lowe if ((eq == NULL) || (eq > p)) {
725*3625efb1SRichard Lowe append_string(block_start,
726*3625efb1SRichard Lowe &extracted,
727*3625efb1SRichard Lowe p - block_start);
728*3625efb1SRichard Lowe } else {
729*3625efb1SRichard Lowe append_string(eq + 1,
730*3625efb1SRichard Lowe &extracted,
731*3625efb1SRichard Lowe p - eq - 1);
732*3625efb1SRichard Lowe }
733*3625efb1SRichard Lowe break;
734*3625efb1SRichard Lowe case no_extract:
735*3625efb1SRichard Lowe append_string(block_start,
736*3625efb1SRichard Lowe &extracted,
737*3625efb1SRichard Lowe p - block_start);
738*3625efb1SRichard Lowe break;
739*3625efb1SRichard Lowe }
740*3625efb1SRichard Lowe switch (replacement) {
741*3625efb1SRichard Lowe case suffix_replace:
742*3625efb1SRichard Lowe /*
743*3625efb1SRichard Lowe * $(FOO:.o=.c) type transform.
744*3625efb1SRichard Lowe * Maybe replace the tail of the word.
745*3625efb1SRichard Lowe */
746*3625efb1SRichard Lowe if (((extracted.text.p -
747*3625efb1SRichard Lowe extracted.buffer.start) >=
748*3625efb1SRichard Lowe left_tail_len) &&
749*3625efb1SRichard Lowe IS_WEQUALN(extracted.text.p - left_tail_len,
750*3625efb1SRichard Lowe left_tail,
751*3625efb1SRichard Lowe left_tail_len)) {
752*3625efb1SRichard Lowe append_string(extracted.buffer.start,
753*3625efb1SRichard Lowe destination,
754*3625efb1SRichard Lowe (extracted.text.p -
755*3625efb1SRichard Lowe extracted.buffer.start)
756*3625efb1SRichard Lowe - left_tail_len);
757*3625efb1SRichard Lowe append_string(right_tail,
758*3625efb1SRichard Lowe destination,
759*3625efb1SRichard Lowe FIND_LENGTH);
760*3625efb1SRichard Lowe } else {
761*3625efb1SRichard Lowe append_string(extracted.buffer.start,
762*3625efb1SRichard Lowe destination,
763*3625efb1SRichard Lowe FIND_LENGTH);
764*3625efb1SRichard Lowe }
765*3625efb1SRichard Lowe break;
766*3625efb1SRichard Lowe case pattern_replace:
767*3625efb1SRichard Lowe /* $(X:a%b=c%d) type transform. */
768*3625efb1SRichard Lowe if (((extracted.text.p -
769*3625efb1SRichard Lowe extracted.buffer.start) >=
770*3625efb1SRichard Lowe left_head_len+left_tail_len) &&
771*3625efb1SRichard Lowe IS_WEQUALN(left_head,
772*3625efb1SRichard Lowe extracted.buffer.start,
773*3625efb1SRichard Lowe left_head_len) &&
774*3625efb1SRichard Lowe IS_WEQUALN(left_tail,
775*3625efb1SRichard Lowe extracted.text.p - left_tail_len,
776*3625efb1SRichard Lowe left_tail_len)) {
777*3625efb1SRichard Lowe i = 0;
778*3625efb1SRichard Lowe while (right_hand[i] != NULL) {
779*3625efb1SRichard Lowe append_string(right_hand[i],
780*3625efb1SRichard Lowe destination,
781*3625efb1SRichard Lowe FIND_LENGTH);
782*3625efb1SRichard Lowe i++;
783*3625efb1SRichard Lowe if (right_hand[i] != NULL) {
784*3625efb1SRichard Lowe append_string(extracted.buffer.
785*3625efb1SRichard Lowe start +
786*3625efb1SRichard Lowe left_head_len,
787*3625efb1SRichard Lowe destination,
788*3625efb1SRichard Lowe (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len);
789*3625efb1SRichard Lowe }
790*3625efb1SRichard Lowe }
791*3625efb1SRichard Lowe } else {
792*3625efb1SRichard Lowe append_string(extracted.buffer.start,
793*3625efb1SRichard Lowe destination,
794*3625efb1SRichard Lowe FIND_LENGTH);
795*3625efb1SRichard Lowe }
796*3625efb1SRichard Lowe break;
797*3625efb1SRichard Lowe case no_replace:
798*3625efb1SRichard Lowe append_string(extracted.buffer.start,
799*3625efb1SRichard Lowe destination,
800*3625efb1SRichard Lowe FIND_LENGTH);
801*3625efb1SRichard Lowe break;
802*3625efb1SRichard Lowe case sh_replace:
803*3625efb1SRichard Lowe break;
804*3625efb1SRichard Lowe }
805*3625efb1SRichard Lowe }
806*3625efb1SRichard Lowe if (string.free_after_use) {
807*3625efb1SRichard Lowe retmem(string.buffer.start);
808*3625efb1SRichard Lowe }
809*3625efb1SRichard Lowe } else {
810*3625efb1SRichard Lowe /*
811*3625efb1SRichard Lowe * This is for the case when the macro name did not
812*3625efb1SRichard Lowe * specify transforms.
813*3625efb1SRichard Lowe */
814*3625efb1SRichard Lowe if (!strncmp(name->string_mb, "GET", 3)) {
815*3625efb1SRichard Lowe dollarget_seen = true;
816*3625efb1SRichard Lowe }
817*3625efb1SRichard Lowe dollarless_flag = false;
818*3625efb1SRichard Lowe if (!strncmp(name->string_mb, "<", 1) &&
819*3625efb1SRichard Lowe dollarget_seen) {
820*3625efb1SRichard Lowe dollarless_flag = true;
821*3625efb1SRichard Lowe dollarget_seen = false;
822*3625efb1SRichard Lowe }
823*3625efb1SRichard Lowe expand_value_with_daemon(name, macro, destination, cmd);
824*3625efb1SRichard Lowe }
825*3625efb1SRichard Lowe exit:
826*3625efb1SRichard Lowe if(left_tail) {
827*3625efb1SRichard Lowe retmem(left_tail);
828*3625efb1SRichard Lowe }
829*3625efb1SRichard Lowe if(right_tail) {
830*3625efb1SRichard Lowe retmem(right_tail);
831*3625efb1SRichard Lowe }
832*3625efb1SRichard Lowe if(left_head) {
833*3625efb1SRichard Lowe retmem(left_head);
834*3625efb1SRichard Lowe }
835*3625efb1SRichard Lowe i = 0;
836*3625efb1SRichard Lowe while (right_hand[i] != NULL) {
837*3625efb1SRichard Lowe retmem(right_hand[i]);
838*3625efb1SRichard Lowe i++;
839*3625efb1SRichard Lowe }
840*3625efb1SRichard Lowe *destination->text.p = (int) nul_char;
841*3625efb1SRichard Lowe destination->text.end = destination->text.p;
842*3625efb1SRichard Lowe }
843*3625efb1SRichard Lowe
844*3625efb1SRichard Lowe static void
add_macro_to_global_list(Name macro_to_add)845*3625efb1SRichard Lowe add_macro_to_global_list(Name macro_to_add)
846*3625efb1SRichard Lowe {
847*3625efb1SRichard Lowe Macro_list new_macro;
848*3625efb1SRichard Lowe Macro_list macro_on_list;
849*3625efb1SRichard Lowe char *name_on_list = (char*)NULL;
850*3625efb1SRichard Lowe char *name_to_add = macro_to_add->string_mb;
851*3625efb1SRichard Lowe char *value_on_list = (char*)NULL;
852*3625efb1SRichard Lowe const char *value_to_add = (char*)NULL;
853*3625efb1SRichard Lowe
854*3625efb1SRichard Lowe if (macro_to_add->prop->body.macro.value != NULL) {
855*3625efb1SRichard Lowe value_to_add = macro_to_add->prop->body.macro.value->string_mb;
856*3625efb1SRichard Lowe } else {
857*3625efb1SRichard Lowe value_to_add = "";
858*3625efb1SRichard Lowe }
859*3625efb1SRichard Lowe
860*3625efb1SRichard Lowe /*
861*3625efb1SRichard Lowe * Check if this macro is already on list, if so, do nothing
862*3625efb1SRichard Lowe */
863*3625efb1SRichard Lowe for (macro_on_list = cond_macro_list;
864*3625efb1SRichard Lowe macro_on_list != NULL;
865*3625efb1SRichard Lowe macro_on_list = macro_on_list->next) {
866*3625efb1SRichard Lowe
867*3625efb1SRichard Lowe name_on_list = macro_on_list->macro_name;
868*3625efb1SRichard Lowe value_on_list = macro_on_list->value;
869*3625efb1SRichard Lowe
870*3625efb1SRichard Lowe if (IS_EQUAL(name_on_list, name_to_add)) {
871*3625efb1SRichard Lowe if (IS_EQUAL(value_on_list, value_to_add)) {
872*3625efb1SRichard Lowe return;
873*3625efb1SRichard Lowe }
874*3625efb1SRichard Lowe }
875*3625efb1SRichard Lowe }
876*3625efb1SRichard Lowe new_macro = (Macro_list) malloc(sizeof(Macro_list_rec));
877*3625efb1SRichard Lowe new_macro->macro_name = strdup(name_to_add);
878*3625efb1SRichard Lowe new_macro->value = strdup(value_to_add);
879*3625efb1SRichard Lowe new_macro->next = cond_macro_list;
880*3625efb1SRichard Lowe cond_macro_list = new_macro;
881*3625efb1SRichard Lowe }
882*3625efb1SRichard Lowe
883*3625efb1SRichard Lowe /*
884*3625efb1SRichard Lowe * init_arch_macros(void)
885*3625efb1SRichard Lowe *
886*3625efb1SRichard Lowe * Set the magic macros TARGET_ARCH, HOST_ARCH,
887*3625efb1SRichard Lowe *
888*3625efb1SRichard Lowe * Parameters:
889*3625efb1SRichard Lowe *
890*3625efb1SRichard Lowe * Global variables used:
891*3625efb1SRichard Lowe * host_arch Property for magic macro HOST_ARCH
892*3625efb1SRichard Lowe * target_arch Property for magic macro TARGET_ARCH
893*3625efb1SRichard Lowe *
894*3625efb1SRichard Lowe * Return value:
895*3625efb1SRichard Lowe * The function does not return a value, but can
896*3625efb1SRichard Lowe * call fatal() in case of error.
897*3625efb1SRichard Lowe */
898*3625efb1SRichard Lowe static void
init_arch_macros(void)899*3625efb1SRichard Lowe init_arch_macros(void)
900*3625efb1SRichard Lowe {
901*3625efb1SRichard Lowe String_rec result_string;
902*3625efb1SRichard Lowe wchar_t wc_buf[STRING_BUFFER_LENGTH];
903*3625efb1SRichard Lowe char mb_buf[STRING_BUFFER_LENGTH];
904*3625efb1SRichard Lowe FILE *pipe;
905*3625efb1SRichard Lowe Name value;
906*3625efb1SRichard Lowe int set_host, set_target;
907*3625efb1SRichard Lowe const char *mach_command = "/bin/mach";
908*3625efb1SRichard Lowe
909*3625efb1SRichard Lowe set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
910*3625efb1SRichard Lowe set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
911*3625efb1SRichard Lowe
912*3625efb1SRichard Lowe if (set_host || set_target) {
913*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(result_string, wc_buf);
914*3625efb1SRichard Lowe append_char((int) hyphen_char, &result_string);
915*3625efb1SRichard Lowe
916*3625efb1SRichard Lowe if ((pipe = popen(mach_command, "r")) == NULL) {
917*3625efb1SRichard Lowe fatal_mksh(gettext("Execute of %s failed"), mach_command);
918*3625efb1SRichard Lowe }
919*3625efb1SRichard Lowe while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
920*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, mb_buf);
921*3625efb1SRichard Lowe append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
922*3625efb1SRichard Lowe }
923*3625efb1SRichard Lowe if (pclose(pipe) != 0) {
924*3625efb1SRichard Lowe fatal_mksh(gettext("Execute of %s failed"), mach_command);
925*3625efb1SRichard Lowe }
926*3625efb1SRichard Lowe
927*3625efb1SRichard Lowe value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
928*3625efb1SRichard Lowe
929*3625efb1SRichard Lowe if (set_host) {
930*3625efb1SRichard Lowe (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
931*3625efb1SRichard Lowe }
932*3625efb1SRichard Lowe if (set_target) {
933*3625efb1SRichard Lowe (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
934*3625efb1SRichard Lowe }
935*3625efb1SRichard Lowe }
936*3625efb1SRichard Lowe }
937*3625efb1SRichard Lowe
938*3625efb1SRichard Lowe /*
939*3625efb1SRichard Lowe * init_mach_macros(void)
940*3625efb1SRichard Lowe *
941*3625efb1SRichard Lowe * Set the magic macros TARGET_MACH, HOST_MACH,
942*3625efb1SRichard Lowe *
943*3625efb1SRichard Lowe * Parameters:
944*3625efb1SRichard Lowe *
945*3625efb1SRichard Lowe * Global variables used:
946*3625efb1SRichard Lowe * host_mach Property for magic macro HOST_MACH
947*3625efb1SRichard Lowe * target_mach Property for magic macro TARGET_MACH
948*3625efb1SRichard Lowe *
949*3625efb1SRichard Lowe * Return value:
950*3625efb1SRichard Lowe * The function does not return a value, but can
951*3625efb1SRichard Lowe * call fatal() in case of error.
952*3625efb1SRichard Lowe */
953*3625efb1SRichard Lowe static void
init_mach_macros(void)954*3625efb1SRichard Lowe init_mach_macros(void)
955*3625efb1SRichard Lowe {
956*3625efb1SRichard Lowe String_rec result_string;
957*3625efb1SRichard Lowe wchar_t wc_buf[STRING_BUFFER_LENGTH];
958*3625efb1SRichard Lowe char mb_buf[STRING_BUFFER_LENGTH];
959*3625efb1SRichard Lowe FILE *pipe;
960*3625efb1SRichard Lowe Name value;
961*3625efb1SRichard Lowe int set_host, set_target;
962*3625efb1SRichard Lowe const char *arch_command = "/bin/arch";
963*3625efb1SRichard Lowe
964*3625efb1SRichard Lowe set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
965*3625efb1SRichard Lowe set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
966*3625efb1SRichard Lowe
967*3625efb1SRichard Lowe if (set_host || set_target) {
968*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(result_string, wc_buf);
969*3625efb1SRichard Lowe append_char((int) hyphen_char, &result_string);
970*3625efb1SRichard Lowe
971*3625efb1SRichard Lowe if ((pipe = popen(arch_command, "r")) == NULL) {
972*3625efb1SRichard Lowe fatal_mksh(gettext("Execute of %s failed"), arch_command);
973*3625efb1SRichard Lowe }
974*3625efb1SRichard Lowe while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
975*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, mb_buf);
976*3625efb1SRichard Lowe append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
977*3625efb1SRichard Lowe }
978*3625efb1SRichard Lowe if (pclose(pipe) != 0) {
979*3625efb1SRichard Lowe fatal_mksh(gettext("Execute of %s failed"), arch_command);
980*3625efb1SRichard Lowe }
981*3625efb1SRichard Lowe
982*3625efb1SRichard Lowe value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
983*3625efb1SRichard Lowe
984*3625efb1SRichard Lowe if (set_host) {
985*3625efb1SRichard Lowe (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
986*3625efb1SRichard Lowe }
987*3625efb1SRichard Lowe if (set_target) {
988*3625efb1SRichard Lowe (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
989*3625efb1SRichard Lowe }
990*3625efb1SRichard Lowe }
991*3625efb1SRichard Lowe }
992*3625efb1SRichard Lowe
993*3625efb1SRichard Lowe /*
994*3625efb1SRichard Lowe * expand_value_with_daemon(name, macro, destination, cmd)
995*3625efb1SRichard Lowe *
996*3625efb1SRichard Lowe * Checks for daemons and then maybe calls expand_value().
997*3625efb1SRichard Lowe *
998*3625efb1SRichard Lowe * Parameters:
999*3625efb1SRichard Lowe * name Name of the macro (Added by the NSE)
1000*3625efb1SRichard Lowe * macro The property block with the value to expand
1001*3625efb1SRichard Lowe * destination Where the result should be deposited
1002*3625efb1SRichard Lowe * cmd If we are evaluating a command line we
1003*3625efb1SRichard Lowe * turn \ quoting off
1004*3625efb1SRichard Lowe *
1005*3625efb1SRichard Lowe * Global variables used:
1006*3625efb1SRichard Lowe */
1007*3625efb1SRichard Lowe static void
expand_value_with_daemon(Name,register Property macro,register String destination,Boolean cmd)1008*3625efb1SRichard Lowe expand_value_with_daemon(Name, register Property macro, register String destination, Boolean cmd)
1009*3625efb1SRichard Lowe {
1010*3625efb1SRichard Lowe register Chain chain;
1011*3625efb1SRichard Lowe
1012*3625efb1SRichard Lowe
1013*3625efb1SRichard Lowe switch (macro->body.macro.daemon) {
1014*3625efb1SRichard Lowe case no_daemon:
1015*3625efb1SRichard Lowe if (!svr4 && !posix) {
1016*3625efb1SRichard Lowe expand_value(macro->body.macro.value, destination, cmd);
1017*3625efb1SRichard Lowe } else {
1018*3625efb1SRichard Lowe if (dollarless_flag && tilde_rule) {
1019*3625efb1SRichard Lowe expand_value(dollarless_value, destination, cmd);
1020*3625efb1SRichard Lowe dollarless_flag = false;
1021*3625efb1SRichard Lowe tilde_rule = false;
1022*3625efb1SRichard Lowe } else {
1023*3625efb1SRichard Lowe expand_value(macro->body.macro.value, destination, cmd);
1024*3625efb1SRichard Lowe }
1025*3625efb1SRichard Lowe }
1026*3625efb1SRichard Lowe return;
1027*3625efb1SRichard Lowe case chain_daemon:
1028*3625efb1SRichard Lowe /* If this is a $? value we call the daemon to translate the */
1029*3625efb1SRichard Lowe /* list of names to a string */
1030*3625efb1SRichard Lowe for (chain = (Chain) macro->body.macro.value;
1031*3625efb1SRichard Lowe chain != NULL;
1032*3625efb1SRichard Lowe chain = chain->next) {
1033*3625efb1SRichard Lowe APPEND_NAME(chain->name,
1034*3625efb1SRichard Lowe destination,
1035*3625efb1SRichard Lowe (int) chain->name->hash.length);
1036*3625efb1SRichard Lowe if (chain->next != NULL) {
1037*3625efb1SRichard Lowe append_char((int) space_char, destination);
1038*3625efb1SRichard Lowe }
1039*3625efb1SRichard Lowe }
1040*3625efb1SRichard Lowe return;
1041*3625efb1SRichard Lowe }
1042*3625efb1SRichard Lowe }
1043*3625efb1SRichard Lowe
1044*3625efb1SRichard Lowe /*
1045*3625efb1SRichard Lowe * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
1046*3625efb1SRichard Lowe */
1047*3625efb1SRichard Lowe char *sunpro_dependencies_buf = NULL;
1048*3625efb1SRichard Lowe char *sunpro_dependencies_oldbuf = NULL;
1049*3625efb1SRichard Lowe int sunpro_dependencies_buf_size = 0;
1050*3625efb1SRichard Lowe
1051*3625efb1SRichard Lowe /*
1052*3625efb1SRichard Lowe * setvar_daemon(name, value, append, daemon, strip_trailing_spaces)
1053*3625efb1SRichard Lowe *
1054*3625efb1SRichard Lowe * Set a macro value, possibly supplying a daemon to be used
1055*3625efb1SRichard Lowe * when referencing the value.
1056*3625efb1SRichard Lowe *
1057*3625efb1SRichard Lowe * Return value:
1058*3625efb1SRichard Lowe * The property block with the new value
1059*3625efb1SRichard Lowe *
1060*3625efb1SRichard Lowe * Parameters:
1061*3625efb1SRichard Lowe * name Name of the macro to set
1062*3625efb1SRichard Lowe * value The value to set
1063*3625efb1SRichard Lowe * append Should we reset or append to the current value?
1064*3625efb1SRichard Lowe * daemon Special treatment when reading the value
1065*3625efb1SRichard Lowe * strip_trailing_spaces from the end of value->string
1066*3625efb1SRichard Lowe * debug_level Indicates how much tracing we should do
1067*3625efb1SRichard Lowe *
1068*3625efb1SRichard Lowe * Global variables used:
1069*3625efb1SRichard Lowe * makefile_type Used to check if we should enforce read only
1070*3625efb1SRichard Lowe * path_name The Name "PATH", compared against
1071*3625efb1SRichard Lowe * virtual_root The Name "VIRTUAL_ROOT", compared against
1072*3625efb1SRichard Lowe * vpath_defined Set if the macro VPATH is set
1073*3625efb1SRichard Lowe * vpath_name The Name "VPATH", compared against
1074*3625efb1SRichard Lowe * envvar A list of environment vars with $ in value
1075*3625efb1SRichard Lowe */
1076*3625efb1SRichard Lowe Property
setvar_daemon(register Name name,register Name value,Boolean append,Daemon daemon,Boolean strip_trailing_spaces,short debug_level)1077*3625efb1SRichard Lowe setvar_daemon(register Name name, register Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
1078*3625efb1SRichard Lowe {
1079*3625efb1SRichard Lowe register Property macro = maybe_append_prop(name, macro_prop);
1080*3625efb1SRichard Lowe register Property macro_apx = get_prop(name->prop, macro_append_prop);
1081*3625efb1SRichard Lowe int length = 0;
1082*3625efb1SRichard Lowe String_rec destination;
1083*3625efb1SRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
1084*3625efb1SRichard Lowe register Chain chain;
1085*3625efb1SRichard Lowe Name val;
1086*3625efb1SRichard Lowe wchar_t *val_string = (wchar_t*)NULL;
1087*3625efb1SRichard Lowe Wstring wcb;
1088*3625efb1SRichard Lowe
1089*3625efb1SRichard Lowe
1090*3625efb1SRichard Lowe if ((makefile_type != reading_nothing) &&
1091*3625efb1SRichard Lowe macro->body.macro.read_only) {
1092*3625efb1SRichard Lowe return macro;
1093*3625efb1SRichard Lowe }
1094*3625efb1SRichard Lowe /* Strip spaces from the end of the value */
1095*3625efb1SRichard Lowe if (daemon == no_daemon) {
1096*3625efb1SRichard Lowe if(value != NULL) {
1097*3625efb1SRichard Lowe wcb.init(value);
1098*3625efb1SRichard Lowe length = wcb.length();
1099*3625efb1SRichard Lowe val_string = wcb.get_string();
1100*3625efb1SRichard Lowe }
1101*3625efb1SRichard Lowe if ((length > 0) && iswspace(val_string[length-1])) {
1102*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
1103*3625efb1SRichard Lowe buffer[0] = 0;
1104*3625efb1SRichard Lowe append_string(val_string, &destination, length);
1105*3625efb1SRichard Lowe if (strip_trailing_spaces) {
1106*3625efb1SRichard Lowe while ((length > 0) &&
1107*3625efb1SRichard Lowe iswspace(destination.buffer.start[length-1])) {
1108*3625efb1SRichard Lowe destination.buffer.start[--length] = 0;
1109*3625efb1SRichard Lowe }
1110*3625efb1SRichard Lowe }
1111*3625efb1SRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
1112*3625efb1SRichard Lowe }
1113*3625efb1SRichard Lowe }
1114*3625efb1SRichard Lowe
1115*3625efb1SRichard Lowe if(macro_apx != NULL) {
1116*3625efb1SRichard Lowe val = macro_apx->body.macro_appendix.value;
1117*3625efb1SRichard Lowe } else {
1118*3625efb1SRichard Lowe val = macro->body.macro.value;
1119*3625efb1SRichard Lowe }
1120*3625efb1SRichard Lowe
1121*3625efb1SRichard Lowe if (append) {
1122*3625efb1SRichard Lowe /*
1123*3625efb1SRichard Lowe * If we are appending, we just tack the new value after
1124*3625efb1SRichard Lowe * the old one with a space in between.
1125*3625efb1SRichard Lowe */
1126*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
1127*3625efb1SRichard Lowe buffer[0] = 0;
1128*3625efb1SRichard Lowe if ((macro != NULL) && (val != NULL)) {
1129*3625efb1SRichard Lowe APPEND_NAME(val,
1130*3625efb1SRichard Lowe &destination,
1131*3625efb1SRichard Lowe (int) val->hash.length);
1132*3625efb1SRichard Lowe if (value != NULL) {
1133*3625efb1SRichard Lowe wcb.init(value);
1134*3625efb1SRichard Lowe if(wcb.length() > 0) {
1135*3625efb1SRichard Lowe MBTOWC(wcs_buffer, " ");
1136*3625efb1SRichard Lowe append_char(wcs_buffer[0], &destination);
1137*3625efb1SRichard Lowe }
1138*3625efb1SRichard Lowe }
1139*3625efb1SRichard Lowe }
1140*3625efb1SRichard Lowe if (value != NULL) {
1141*3625efb1SRichard Lowe APPEND_NAME(value,
1142*3625efb1SRichard Lowe &destination,
1143*3625efb1SRichard Lowe (int) value->hash.length);
1144*3625efb1SRichard Lowe }
1145*3625efb1SRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
1146*3625efb1SRichard Lowe wcb.init(value);
1147*3625efb1SRichard Lowe if (destination.free_after_use) {
1148*3625efb1SRichard Lowe retmem(destination.buffer.start);
1149*3625efb1SRichard Lowe }
1150*3625efb1SRichard Lowe }
1151*3625efb1SRichard Lowe
1152*3625efb1SRichard Lowe /* Debugging trace */
1153*3625efb1SRichard Lowe if (debug_level > 1) {
1154*3625efb1SRichard Lowe if (value != NULL) {
1155*3625efb1SRichard Lowe switch (daemon) {
1156*3625efb1SRichard Lowe case chain_daemon:
1157*3625efb1SRichard Lowe (void) printf("%s =", name->string_mb);
1158*3625efb1SRichard Lowe for (chain = (Chain) value;
1159*3625efb1SRichard Lowe chain != NULL;
1160*3625efb1SRichard Lowe chain = chain->next) {
1161*3625efb1SRichard Lowe (void) printf(" %s", chain->name->string_mb);
1162*3625efb1SRichard Lowe }
1163*3625efb1SRichard Lowe (void) printf("\n");
1164*3625efb1SRichard Lowe break;
1165*3625efb1SRichard Lowe case no_daemon:
1166*3625efb1SRichard Lowe (void) printf("%s= %s\n",
1167*3625efb1SRichard Lowe name->string_mb,
1168*3625efb1SRichard Lowe value->string_mb);
1169*3625efb1SRichard Lowe break;
1170*3625efb1SRichard Lowe }
1171*3625efb1SRichard Lowe } else {
1172*3625efb1SRichard Lowe (void) printf("%s =\n", name->string_mb);
1173*3625efb1SRichard Lowe }
1174*3625efb1SRichard Lowe }
1175*3625efb1SRichard Lowe /* Set the new values in the macro property block */
1176*3625efb1SRichard Lowe /**/
1177*3625efb1SRichard Lowe if(macro_apx != NULL) {
1178*3625efb1SRichard Lowe macro_apx->body.macro_appendix.value = value;
1179*3625efb1SRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
1180*3625efb1SRichard Lowe buffer[0] = 0;
1181*3625efb1SRichard Lowe if (value != NULL) {
1182*3625efb1SRichard Lowe APPEND_NAME(value,
1183*3625efb1SRichard Lowe &destination,
1184*3625efb1SRichard Lowe (int) value->hash.length);
1185*3625efb1SRichard Lowe if (macro_apx->body.macro_appendix.value_to_append != NULL) {
1186*3625efb1SRichard Lowe MBTOWC(wcs_buffer, " ");
1187*3625efb1SRichard Lowe append_char(wcs_buffer[0], &destination);
1188*3625efb1SRichard Lowe }
1189*3625efb1SRichard Lowe }
1190*3625efb1SRichard Lowe if (macro_apx->body.macro_appendix.value_to_append != NULL) {
1191*3625efb1SRichard Lowe APPEND_NAME(macro_apx->body.macro_appendix.value_to_append,
1192*3625efb1SRichard Lowe &destination,
1193*3625efb1SRichard Lowe (int) macro_apx->body.macro_appendix.value_to_append->hash.length);
1194*3625efb1SRichard Lowe }
1195*3625efb1SRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
1196*3625efb1SRichard Lowe if (destination.free_after_use) {
1197*3625efb1SRichard Lowe retmem(destination.buffer.start);
1198*3625efb1SRichard Lowe }
1199*3625efb1SRichard Lowe }
1200*3625efb1SRichard Lowe /**/
1201*3625efb1SRichard Lowe macro->body.macro.value = value;
1202*3625efb1SRichard Lowe macro->body.macro.daemon = daemon;
1203*3625efb1SRichard Lowe /*
1204*3625efb1SRichard Lowe * If the user changes the VIRTUAL_ROOT, we need to flush
1205*3625efb1SRichard Lowe * the vroot package cache.
1206*3625efb1SRichard Lowe */
1207*3625efb1SRichard Lowe if (name == path_name) {
1208*3625efb1SRichard Lowe flush_path_cache();
1209*3625efb1SRichard Lowe }
1210*3625efb1SRichard Lowe if (name == virtual_root) {
1211*3625efb1SRichard Lowe flush_vroot_cache();
1212*3625efb1SRichard Lowe }
1213*3625efb1SRichard Lowe /* If this sets the VPATH we remember that */
1214*3625efb1SRichard Lowe if ((name == vpath_name) &&
1215*3625efb1SRichard Lowe (value != NULL) &&
1216*3625efb1SRichard Lowe (value->hash.length > 0)) {
1217*3625efb1SRichard Lowe vpath_defined = true;
1218*3625efb1SRichard Lowe }
1219*3625efb1SRichard Lowe /*
1220*3625efb1SRichard Lowe * For environment variables we also set the
1221*3625efb1SRichard Lowe * environment value each time.
1222*3625efb1SRichard Lowe */
1223*3625efb1SRichard Lowe if (macro->body.macro.exported) {
1224*3625efb1SRichard Lowe static char *env;
1225*3625efb1SRichard Lowe
1226*3625efb1SRichard Lowe if (!reading_environment && (value != NULL)) {
1227*3625efb1SRichard Lowe Envvar p;
1228*3625efb1SRichard Lowe
1229*3625efb1SRichard Lowe for (p = envvar; p != NULL; p = p->next) {
1230*3625efb1SRichard Lowe if (p->name == name) {
1231*3625efb1SRichard Lowe p->value = value;
1232*3625efb1SRichard Lowe p->already_put = false;
1233*3625efb1SRichard Lowe goto found_it;
1234*3625efb1SRichard Lowe }
1235*3625efb1SRichard Lowe }
1236*3625efb1SRichard Lowe p = ALLOC(Envvar);
1237*3625efb1SRichard Lowe p->name = name;
1238*3625efb1SRichard Lowe p->value = value;
1239*3625efb1SRichard Lowe p->next = envvar;
1240*3625efb1SRichard Lowe p->env_string = NULL;
1241*3625efb1SRichard Lowe p->already_put = false;
1242*3625efb1SRichard Lowe envvar = p;
1243*3625efb1SRichard Lowe found_it:;
1244*3625efb1SRichard Lowe } if (reading_environment || (value == NULL) || !value->dollar) {
1245*3625efb1SRichard Lowe length = 2 + strlen(name->string_mb);
1246*3625efb1SRichard Lowe if (value != NULL) {
1247*3625efb1SRichard Lowe length += strlen(value->string_mb);
1248*3625efb1SRichard Lowe }
1249*3625efb1SRichard Lowe Property env_prop = maybe_append_prop(name, env_mem_prop);
1250*3625efb1SRichard Lowe /*
1251*3625efb1SRichard Lowe * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
1252*3625efb1SRichard Lowe */
1253*3625efb1SRichard Lowe if (!strncmp(name->string_mb, "SUNPRO_DEPENDENCIES", 19)) {
1254*3625efb1SRichard Lowe if (length >= sunpro_dependencies_buf_size) {
1255*3625efb1SRichard Lowe sunpro_dependencies_buf_size=length*2;
1256*3625efb1SRichard Lowe if (sunpro_dependencies_buf_size < 4096)
1257*3625efb1SRichard Lowe sunpro_dependencies_buf_size = 4096; // Default minimum size
1258*3625efb1SRichard Lowe if (sunpro_dependencies_buf)
1259*3625efb1SRichard Lowe sunpro_dependencies_oldbuf = sunpro_dependencies_buf;
1260*3625efb1SRichard Lowe sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size);
1261*3625efb1SRichard Lowe }
1262*3625efb1SRichard Lowe env = sunpro_dependencies_buf;
1263*3625efb1SRichard Lowe } else {
1264*3625efb1SRichard Lowe env = getmem(length);
1265*3625efb1SRichard Lowe }
1266*3625efb1SRichard Lowe env_alloc_num++;
1267*3625efb1SRichard Lowe env_alloc_bytes += length;
1268*3625efb1SRichard Lowe (void) sprintf(env,
1269*3625efb1SRichard Lowe "%s=%s",
1270*3625efb1SRichard Lowe name->string_mb,
1271*3625efb1SRichard Lowe value == NULL ?
1272*3625efb1SRichard Lowe "" : value->string_mb);
1273*3625efb1SRichard Lowe (void) putenv(env);
1274*3625efb1SRichard Lowe env_prop->body.env_mem.value = env;
1275*3625efb1SRichard Lowe if (sunpro_dependencies_oldbuf) {
1276*3625efb1SRichard Lowe /* Return old buffer */
1277*3625efb1SRichard Lowe retmem_mb(sunpro_dependencies_oldbuf);
1278*3625efb1SRichard Lowe sunpro_dependencies_oldbuf = NULL;
1279*3625efb1SRichard Lowe }
1280*3625efb1SRichard Lowe }
1281*3625efb1SRichard Lowe }
1282*3625efb1SRichard Lowe if (name == target_arch) {
1283*3625efb1SRichard Lowe Name ha = getvar(host_arch);
1284*3625efb1SRichard Lowe Name ta = getvar(target_arch);
1285*3625efb1SRichard Lowe Name vr = getvar(virtual_root);
1286*3625efb1SRichard Lowe int length;
1287*3625efb1SRichard Lowe wchar_t *new_value;
1288*3625efb1SRichard Lowe wchar_t *old_vr;
1289*3625efb1SRichard Lowe Boolean new_value_allocated = false;
1290*3625efb1SRichard Lowe
1291*3625efb1SRichard Lowe Wstring ha_str(ha);
1292*3625efb1SRichard Lowe Wstring ta_str(ta);
1293*3625efb1SRichard Lowe Wstring vr_str(vr);
1294*3625efb1SRichard Lowe
1295*3625efb1SRichard Lowe wchar_t * wcb_ha = ha_str.get_string();
1296*3625efb1SRichard Lowe wchar_t * wcb_ta = ta_str.get_string();
1297*3625efb1SRichard Lowe wchar_t * wcb_vr = vr_str.get_string();
1298*3625efb1SRichard Lowe
1299*3625efb1SRichard Lowe length = 32 +
1300*3625efb1SRichard Lowe wcslen(wcb_ha) +
1301*3625efb1SRichard Lowe wcslen(wcb_ta) +
1302*3625efb1SRichard Lowe wcslen(wcb_vr);
1303*3625efb1SRichard Lowe old_vr = wcb_vr;
1304*3625efb1SRichard Lowe MBSTOWCS(wcs_buffer, "/usr/arch/");
1305*3625efb1SRichard Lowe if (IS_WEQUALN(old_vr,
1306*3625efb1SRichard Lowe wcs_buffer,
1307*3625efb1SRichard Lowe wcslen(wcs_buffer))) {
1308*3625efb1SRichard Lowe old_vr = (wchar_t *) wcschr(old_vr, (int) colon_char) + 1;
1309*3625efb1SRichard Lowe }
1310*3625efb1SRichard Lowe if ( (ha == ta) || (wcslen(wcb_ta) == 0) ) {
1311*3625efb1SRichard Lowe new_value = old_vr;
1312*3625efb1SRichard Lowe } else {
1313*3625efb1SRichard Lowe new_value = ALLOC_WC(length);
1314*3625efb1SRichard Lowe new_value_allocated = true;
1315*3625efb1SRichard Lowe WCSTOMBS(mbs_buffer, old_vr);
1316*3625efb1SRichard Lowe (void) swprintf(new_value, length * SIZEOFWCHAR_T,
1317*3625efb1SRichard Lowe L"/usr/arch/%s/%s:%s",
1318*3625efb1SRichard Lowe ha->string_mb + 1,
1319*3625efb1SRichard Lowe ta->string_mb + 1,
1320*3625efb1SRichard Lowe mbs_buffer);
1321*3625efb1SRichard Lowe }
1322*3625efb1SRichard Lowe if (new_value[0] != 0) {
1323*3625efb1SRichard Lowe (void) setvar_daemon(virtual_root,
1324*3625efb1SRichard Lowe GETNAME(new_value, FIND_LENGTH),
1325*3625efb1SRichard Lowe false,
1326*3625efb1SRichard Lowe no_daemon,
1327*3625efb1SRichard Lowe true,
1328*3625efb1SRichard Lowe debug_level);
1329*3625efb1SRichard Lowe }
1330*3625efb1SRichard Lowe if (new_value_allocated) {
1331*3625efb1SRichard Lowe retmem(new_value);
1332*3625efb1SRichard Lowe }
1333*3625efb1SRichard Lowe }
1334*3625efb1SRichard Lowe return macro;
1335*3625efb1SRichard Lowe }
1336