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