110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe * CDDL HEADER START
310d63b7dSRichard Lowe *
410d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe *
810d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe * and limitations under the License.
1210d63b7dSRichard Lowe *
1310d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe *
1910d63b7dSRichard Lowe * CDDL HEADER END
2010d63b7dSRichard Lowe */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe * Use is subject to license terms.
2410d63b7dSRichard Lowe */
2510d63b7dSRichard Lowe
2610d63b7dSRichard Lowe
2710d63b7dSRichard Lowe /*
2810d63b7dSRichard Lowe * macro.cc
2910d63b7dSRichard Lowe *
3010d63b7dSRichard Lowe * Handle expansion of make macros
3110d63b7dSRichard Lowe */
3210d63b7dSRichard Lowe
3310d63b7dSRichard Lowe /*
3410d63b7dSRichard Lowe * Included files
3510d63b7dSRichard Lowe */
3610d63b7dSRichard Lowe #include <mksh/dosys.h> /* sh_command2string() */
3710d63b7dSRichard Lowe #include <mksh/i18n.h> /* get_char_semantics_value() */
3810d63b7dSRichard Lowe #include <mksh/macro.h>
3910d63b7dSRichard Lowe #include <mksh/misc.h> /* retmem() */
4010d63b7dSRichard Lowe #include <mksh/read.h> /* get_next_block_fn() */
4110d63b7dSRichard Lowe
4210d63b7dSRichard Lowe #include <libintl.h>
4310d63b7dSRichard Lowe
4410d63b7dSRichard Lowe /*
4510d63b7dSRichard Lowe * File table of contents
4610d63b7dSRichard Lowe */
4710d63b7dSRichard Lowe static void add_macro_to_global_list(Name macro_to_add);
48*e7afc443SToomas Soome static void expand_value_with_daemon(Name, Property macro, String destination, Boolean cmd);
4910d63b7dSRichard Lowe
5010d63b7dSRichard Lowe static void init_arch_macros(void);
5110d63b7dSRichard Lowe static void init_mach_macros(void);
5210d63b7dSRichard Lowe static Boolean init_arch_done = false;
5310d63b7dSRichard Lowe static Boolean init_mach_done = false;
5410d63b7dSRichard Lowe
5510d63b7dSRichard Lowe
5610d63b7dSRichard Lowe long env_alloc_num = 0;
5710d63b7dSRichard Lowe long env_alloc_bytes = 0;
5810d63b7dSRichard Lowe
5910d63b7dSRichard Lowe /*
6010d63b7dSRichard Lowe * getvar(name)
6110d63b7dSRichard Lowe *
6210d63b7dSRichard Lowe * Return expanded value of macro.
6310d63b7dSRichard Lowe *
6410d63b7dSRichard Lowe * Return value:
6510d63b7dSRichard Lowe * The expanded value of the macro
6610d63b7dSRichard Lowe *
6710d63b7dSRichard Lowe * Parameters:
6810d63b7dSRichard Lowe * name The name of the macro we want the value for
6910d63b7dSRichard Lowe *
7010d63b7dSRichard Lowe * Global variables used:
7110d63b7dSRichard Lowe */
7210d63b7dSRichard Lowe Name
getvar(Name name)73*e7afc443SToomas Soome getvar(Name name)
7410d63b7dSRichard Lowe {
7510d63b7dSRichard Lowe String_rec destination;
7610d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
77*e7afc443SToomas Soome Name result;
7810d63b7dSRichard Lowe
7910d63b7dSRichard Lowe if ((name == host_arch) || (name == target_arch)) {
8010d63b7dSRichard Lowe if (!init_arch_done) {
8110d63b7dSRichard Lowe init_arch_done = true;
8210d63b7dSRichard Lowe init_arch_macros();
8310d63b7dSRichard Lowe }
8410d63b7dSRichard Lowe }
8510d63b7dSRichard Lowe if ((name == host_mach) || (name == target_mach)) {
8610d63b7dSRichard Lowe if (!init_mach_done) {
8710d63b7dSRichard Lowe init_mach_done = true;
8810d63b7dSRichard Lowe init_mach_macros();
8910d63b7dSRichard Lowe }
9010d63b7dSRichard Lowe }
9110d63b7dSRichard Lowe
9210d63b7dSRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
9310d63b7dSRichard Lowe expand_value(maybe_append_prop(name, macro_prop)->body.macro.value,
9410d63b7dSRichard Lowe &destination,
9510d63b7dSRichard Lowe false);
9610d63b7dSRichard Lowe result = GETNAME(destination.buffer.start, FIND_LENGTH);
9710d63b7dSRichard Lowe if (destination.free_after_use) {
9810d63b7dSRichard Lowe retmem(destination.buffer.start);
9910d63b7dSRichard Lowe }
10010d63b7dSRichard Lowe return result;
10110d63b7dSRichard Lowe }
10210d63b7dSRichard Lowe
10310d63b7dSRichard Lowe /*
10410d63b7dSRichard Lowe * expand_value(value, destination, cmd)
10510d63b7dSRichard Lowe *
10610d63b7dSRichard Lowe * Recursively expands all macros in the string value.
10710d63b7dSRichard Lowe * destination is where the expanded value should be appended.
10810d63b7dSRichard Lowe *
10910d63b7dSRichard Lowe * Parameters:
11010d63b7dSRichard Lowe * value The value we are expanding
11110d63b7dSRichard Lowe * destination Where to deposit the expansion
11210d63b7dSRichard Lowe * cmd If we are evaluating a command line we
11310d63b7dSRichard Lowe * turn \ quoting off
11410d63b7dSRichard Lowe *
11510d63b7dSRichard Lowe * Global variables used:
11610d63b7dSRichard Lowe */
11710d63b7dSRichard Lowe void
expand_value(Name value,String destination,Boolean cmd)118*e7afc443SToomas Soome expand_value(Name value, String destination, Boolean cmd)
11910d63b7dSRichard Lowe {
12010d63b7dSRichard Lowe Source_rec sourceb;
121*e7afc443SToomas Soome Source source = &sourceb;
122*e7afc443SToomas Soome wchar_t *source_p = NULL;
123*e7afc443SToomas Soome wchar_t *source_end = NULL;
12410d63b7dSRichard Lowe wchar_t *block_start = NULL;
12510d63b7dSRichard Lowe int quote_seen = 0;
12610d63b7dSRichard Lowe
12710d63b7dSRichard Lowe if (value == NULL) {
12810d63b7dSRichard Lowe /*
12910d63b7dSRichard Lowe * Make sure to get a string allocated even if it
13010d63b7dSRichard Lowe * will be empty.
13110d63b7dSRichard Lowe */
13210d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "");
13310d63b7dSRichard Lowe append_string(wcs_buffer, destination, FIND_LENGTH);
13410d63b7dSRichard Lowe destination->text.end = destination->text.p;
13510d63b7dSRichard Lowe return;
13610d63b7dSRichard Lowe }
13710d63b7dSRichard Lowe if (!value->dollar) {
13810d63b7dSRichard Lowe /*
13910d63b7dSRichard Lowe * If the value we are expanding does not contain
14010d63b7dSRichard Lowe * any $, we don't have to parse it.
14110d63b7dSRichard Lowe */
14210d63b7dSRichard Lowe APPEND_NAME(value,
14310d63b7dSRichard Lowe destination,
14410d63b7dSRichard Lowe (int) value->hash.length
14510d63b7dSRichard Lowe );
14610d63b7dSRichard Lowe destination->text.end = destination->text.p;
14710d63b7dSRichard Lowe return;
14810d63b7dSRichard Lowe }
14910d63b7dSRichard Lowe
15010d63b7dSRichard Lowe if (value->being_expanded) {
15110d63b7dSRichard Lowe fatal_reader_mksh(gettext("Loop detected when expanding macro value `%s'"),
15210d63b7dSRichard Lowe value->string_mb);
15310d63b7dSRichard Lowe }
15410d63b7dSRichard Lowe value->being_expanded = true;
15510d63b7dSRichard Lowe /* Setup the structure we read from */
15610d63b7dSRichard Lowe Wstring vals(value);
15710d63b7dSRichard Lowe sourceb.string.text.p = sourceb.string.buffer.start = wcsdup(vals.get_string());
15810d63b7dSRichard Lowe sourceb.string.free_after_use = true;
15910d63b7dSRichard Lowe sourceb.string.text.end =
16010d63b7dSRichard Lowe sourceb.string.buffer.end =
16110d63b7dSRichard Lowe sourceb.string.text.p + value->hash.length;
16210d63b7dSRichard Lowe sourceb.previous = NULL;
16310d63b7dSRichard Lowe sourceb.fd = -1;
16410d63b7dSRichard Lowe sourceb.inp_buf =
16510d63b7dSRichard Lowe sourceb.inp_buf_ptr =
16610d63b7dSRichard Lowe sourceb.inp_buf_end = NULL;
16710d63b7dSRichard Lowe sourceb.error_converting = false;
16810d63b7dSRichard Lowe /* Lift some pointers from the struct to local register variables */
16910d63b7dSRichard Lowe CACHE_SOURCE(0);
17010d63b7dSRichard Lowe /* We parse the string in segments */
17110d63b7dSRichard Lowe /* We read chars until we find a $, then we append what we have read so far */
17210d63b7dSRichard Lowe /* (since last $ processing) to the destination. When we find a $ we call */
17310d63b7dSRichard Lowe /* expand_macro() and let it expand that particular $ reference into dest */
17410d63b7dSRichard Lowe block_start = source_p;
17510d63b7dSRichard Lowe quote_seen = 0;
17610d63b7dSRichard Lowe for (; 1; source_p++) {
17710d63b7dSRichard Lowe switch (GET_CHAR()) {
17810d63b7dSRichard Lowe case backslash_char:
17910d63b7dSRichard Lowe /* Quote $ in macro value */
18010d63b7dSRichard Lowe if (!cmd) {
18110d63b7dSRichard Lowe quote_seen = ~quote_seen;
18210d63b7dSRichard Lowe }
18310d63b7dSRichard Lowe continue;
18410d63b7dSRichard Lowe case dollar_char:
18510d63b7dSRichard Lowe /* Save the plain string we found since */
18610d63b7dSRichard Lowe /* start of string or previous $ */
18710d63b7dSRichard Lowe if (quote_seen) {
18810d63b7dSRichard Lowe append_string(block_start,
18910d63b7dSRichard Lowe destination,
19010d63b7dSRichard Lowe source_p - block_start - 1);
19110d63b7dSRichard Lowe block_start = source_p;
19210d63b7dSRichard Lowe break;
19310d63b7dSRichard Lowe }
19410d63b7dSRichard Lowe append_string(block_start,
19510d63b7dSRichard Lowe destination,
19610d63b7dSRichard Lowe source_p - block_start);
19710d63b7dSRichard Lowe source->string.text.p = ++source_p;
19810d63b7dSRichard Lowe UNCACHE_SOURCE();
19910d63b7dSRichard Lowe /* Go expand the macro reference */
20010d63b7dSRichard Lowe expand_macro(source, destination, sourceb.string.buffer.start, cmd);
20110d63b7dSRichard Lowe CACHE_SOURCE(1);
20210d63b7dSRichard Lowe block_start = source_p + 1;
20310d63b7dSRichard Lowe break;
20410d63b7dSRichard Lowe case nul_char:
20510d63b7dSRichard Lowe /* The string ran out. Get some more */
20610d63b7dSRichard Lowe append_string(block_start,
20710d63b7dSRichard Lowe destination,
20810d63b7dSRichard Lowe source_p - block_start);
20910d63b7dSRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
21010d63b7dSRichard Lowe if (source == NULL) {
21110d63b7dSRichard Lowe destination->text.end = destination->text.p;
21210d63b7dSRichard Lowe value->being_expanded = false;
21310d63b7dSRichard Lowe return;
21410d63b7dSRichard Lowe }
21510d63b7dSRichard Lowe if (source->error_converting) {
21610d63b7dSRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_value()");
21710d63b7dSRichard Lowe }
21810d63b7dSRichard Lowe block_start = source_p;
21910d63b7dSRichard Lowe source_p--;
22010d63b7dSRichard Lowe continue;
22110d63b7dSRichard Lowe }
22210d63b7dSRichard Lowe quote_seen = 0;
22310d63b7dSRichard Lowe }
22410d63b7dSRichard Lowe retmem(sourceb.string.buffer.start);
22510d63b7dSRichard Lowe }
22610d63b7dSRichard Lowe
22710d63b7dSRichard Lowe /*
22810d63b7dSRichard Lowe * expand_macro(source, destination, current_string, cmd)
22910d63b7dSRichard Lowe *
23010d63b7dSRichard Lowe * Should be called with source->string.text.p pointing to
23110d63b7dSRichard Lowe * the first char after the $ that starts a macro reference.
23210d63b7dSRichard Lowe * source->string.text.p is returned pointing to the first char after
23310d63b7dSRichard Lowe * the macro name.
23410d63b7dSRichard Lowe * It will read the macro name, expanding any macros in it,
23510d63b7dSRichard Lowe * and get the value. The value is then expanded.
23610d63b7dSRichard Lowe * destination is a String that is filled in with the expanded macro.
23710d63b7dSRichard Lowe * It may be passed in referencing a buffer to expand the macro into.
238*e7afc443SToomas Soome * Note that most expansions are done on demand, e.g. right
23910d63b7dSRichard Lowe * before the command is executed and not while the file is
240*e7afc443SToomas Soome * being parsed.
24110d63b7dSRichard Lowe *
24210d63b7dSRichard Lowe * Parameters:
24310d63b7dSRichard Lowe * source The source block that references the string
24410d63b7dSRichard Lowe * to expand
24510d63b7dSRichard Lowe * destination Where to put the result
24610d63b7dSRichard Lowe * current_string The string we are expanding, for error msg
24710d63b7dSRichard Lowe * cmd If we are evaluating a command line we
24810d63b7dSRichard Lowe * turn \ quoting off
24910d63b7dSRichard Lowe *
25010d63b7dSRichard Lowe * Global variables used:
25110d63b7dSRichard Lowe * funny Vector of semantic tags for characters
25210d63b7dSRichard Lowe * is_conditional Set if a conditional macro is refd
25310d63b7dSRichard Lowe * make_word_mentioned Set if the word "MAKE" is mentioned
25410d63b7dSRichard Lowe * makefile_type We deliver extra msg when reading makefiles
25510d63b7dSRichard Lowe * query The Name "?", compared against
25610d63b7dSRichard Lowe * query_mentioned Set if the word "?" is mentioned
25710d63b7dSRichard Lowe */
25810d63b7dSRichard Lowe void
expand_macro(Source source,String destination,wchar_t * current_string,Boolean cmd)259*e7afc443SToomas Soome expand_macro(Source source, String destination, wchar_t *current_string, Boolean cmd)
26010d63b7dSRichard Lowe {
26110d63b7dSRichard Lowe static Name make = (Name)NULL;
26210d63b7dSRichard Lowe static wchar_t colon_sh[4];
26310d63b7dSRichard Lowe static wchar_t colon_shell[7];
26410d63b7dSRichard Lowe String_rec string;
26510d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
266*e7afc443SToomas Soome wchar_t *source_p = source->string.text.p;
267*e7afc443SToomas Soome wchar_t *source_end = source->string.text.end;
268*e7afc443SToomas Soome int closer = 0;
26910d63b7dSRichard Lowe wchar_t *block_start = (wchar_t *)NULL;
27010d63b7dSRichard Lowe int quote_seen = 0;
271*e7afc443SToomas Soome int closer_level = 1;
27210d63b7dSRichard Lowe Name name = (Name)NULL;
27310d63b7dSRichard Lowe wchar_t *colon = (wchar_t *)NULL;
27410d63b7dSRichard Lowe wchar_t *percent = (wchar_t *)NULL;
27510d63b7dSRichard Lowe wchar_t *eq = (wchar_t *) NULL;
27610d63b7dSRichard Lowe Property macro = NULL;
27710d63b7dSRichard Lowe wchar_t *p = (wchar_t*)NULL;
27810d63b7dSRichard Lowe String_rec extracted;
27910d63b7dSRichard Lowe wchar_t extracted_string[MAXPATHLEN];
28010d63b7dSRichard Lowe wchar_t *left_head = NULL;
28110d63b7dSRichard Lowe wchar_t *left_tail = NULL;
28210d63b7dSRichard Lowe wchar_t *right_tail = NULL;
28310d63b7dSRichard Lowe int left_head_len = 0;
28410d63b7dSRichard Lowe int left_tail_len = 0;
28510d63b7dSRichard Lowe int tmp_len = 0;
28610d63b7dSRichard Lowe wchar_t *right_hand[128];
28710d63b7dSRichard Lowe int i = 0;
28810d63b7dSRichard Lowe enum {
28910d63b7dSRichard Lowe no_extract,
29010d63b7dSRichard Lowe dir_extract,
29110d63b7dSRichard Lowe file_extract
29210d63b7dSRichard Lowe } extraction = no_extract;
29310d63b7dSRichard Lowe enum {
29410d63b7dSRichard Lowe no_replace,
29510d63b7dSRichard Lowe suffix_replace,
29610d63b7dSRichard Lowe pattern_replace,
29710d63b7dSRichard Lowe sh_replace
29810d63b7dSRichard Lowe } replacement = no_replace;
29910d63b7dSRichard Lowe
30010d63b7dSRichard Lowe if (make == NULL) {
30110d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "MAKE");
30210d63b7dSRichard Lowe make = GETNAME(wcs_buffer, FIND_LENGTH);
30310d63b7dSRichard Lowe
30410d63b7dSRichard Lowe MBSTOWCS(colon_sh, ":sh");
30510d63b7dSRichard Lowe MBSTOWCS(colon_shell, ":shell");
30610d63b7dSRichard Lowe }
30710d63b7dSRichard Lowe
30810d63b7dSRichard Lowe right_hand[0] = NULL;
30910d63b7dSRichard Lowe
31010d63b7dSRichard Lowe /* First copy the (macro-expanded) macro name into string. */
31110d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
31210d63b7dSRichard Lowe recheck_first_char:
31310d63b7dSRichard Lowe /* Check the first char of the macro name to figure out what to do. */
31410d63b7dSRichard Lowe switch (GET_CHAR()) {
31510d63b7dSRichard Lowe case nul_char:
31610d63b7dSRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
31710d63b7dSRichard Lowe if (source == NULL) {
31810d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, current_string);
31910d63b7dSRichard Lowe fatal_reader_mksh(gettext("'$' at end of string `%s'"),
32010d63b7dSRichard Lowe mbs_buffer);
32110d63b7dSRichard Lowe }
32210d63b7dSRichard Lowe if (source->error_converting) {
32310d63b7dSRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_macro()");
32410d63b7dSRichard Lowe }
32510d63b7dSRichard Lowe goto recheck_first_char;
32610d63b7dSRichard Lowe case parenleft_char:
32710d63b7dSRichard Lowe /* Multi char name. */
32810d63b7dSRichard Lowe closer = (int) parenright_char;
32910d63b7dSRichard Lowe break;
33010d63b7dSRichard Lowe case braceleft_char:
33110d63b7dSRichard Lowe /* Multi char name. */
33210d63b7dSRichard Lowe closer = (int) braceright_char;
33310d63b7dSRichard Lowe break;
33410d63b7dSRichard Lowe case newline_char:
33510d63b7dSRichard Lowe fatal_reader_mksh(gettext("'$' at end of line"));
33610d63b7dSRichard Lowe default:
33710d63b7dSRichard Lowe /* Single char macro name. Just suck it up */
33810d63b7dSRichard Lowe append_char(*source_p, &string);
33910d63b7dSRichard Lowe source->string.text.p = source_p + 1;
34010d63b7dSRichard Lowe goto get_macro_value;
34110d63b7dSRichard Lowe }
34210d63b7dSRichard Lowe
34310d63b7dSRichard Lowe /* Handle multi-char macro names */
34410d63b7dSRichard Lowe block_start = ++source_p;
34510d63b7dSRichard Lowe quote_seen = 0;
34610d63b7dSRichard Lowe for (; 1; source_p++) {
34710d63b7dSRichard Lowe switch (GET_CHAR()) {
34810d63b7dSRichard Lowe case nul_char:
34910d63b7dSRichard Lowe append_string(block_start,
35010d63b7dSRichard Lowe &string,
35110d63b7dSRichard Lowe source_p - block_start);
35210d63b7dSRichard Lowe GET_NEXT_BLOCK_NOCHK(source);
35310d63b7dSRichard Lowe if (source == NULL) {
35410d63b7dSRichard Lowe if (current_string != NULL) {
35510d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, current_string);
35610d63b7dSRichard Lowe fatal_reader_mksh(gettext("Unmatched `%c' in string `%s'"),
35710d63b7dSRichard Lowe closer ==
35810d63b7dSRichard Lowe (int) braceright_char ?
35910d63b7dSRichard Lowe (int) braceleft_char :
36010d63b7dSRichard Lowe (int) parenleft_char,
36110d63b7dSRichard Lowe mbs_buffer);
36210d63b7dSRichard Lowe } else {
36310d63b7dSRichard Lowe fatal_reader_mksh(gettext("Premature EOF"));
36410d63b7dSRichard Lowe }
36510d63b7dSRichard Lowe }
36610d63b7dSRichard Lowe if (source->error_converting) {
36710d63b7dSRichard Lowe fatal_reader_mksh("Internal error: Invalid byte sequence in expand_macro()");
36810d63b7dSRichard Lowe }
36910d63b7dSRichard Lowe block_start = source_p;
37010d63b7dSRichard Lowe source_p--;
37110d63b7dSRichard Lowe continue;
37210d63b7dSRichard Lowe case newline_char:
37310d63b7dSRichard Lowe fatal_reader_mksh(gettext("Unmatched `%c' on line"),
37410d63b7dSRichard Lowe closer == (int) braceright_char ?
37510d63b7dSRichard Lowe (int) braceleft_char :
37610d63b7dSRichard Lowe (int) parenleft_char);
37710d63b7dSRichard Lowe case backslash_char:
37810d63b7dSRichard Lowe /* Quote dollar in macro value. */
37910d63b7dSRichard Lowe if (!cmd) {
38010d63b7dSRichard Lowe quote_seen = ~quote_seen;
38110d63b7dSRichard Lowe }
38210d63b7dSRichard Lowe continue;
38310d63b7dSRichard Lowe case dollar_char:
38410d63b7dSRichard Lowe /*
38510d63b7dSRichard Lowe * Macro names may reference macros.
38610d63b7dSRichard Lowe * This expands the value of such macros into the
38710d63b7dSRichard Lowe * macro name string.
38810d63b7dSRichard Lowe */
38910d63b7dSRichard Lowe if (quote_seen) {
39010d63b7dSRichard Lowe append_string(block_start,
39110d63b7dSRichard Lowe &string,
39210d63b7dSRichard Lowe source_p - block_start - 1);
39310d63b7dSRichard Lowe block_start = source_p;
39410d63b7dSRichard Lowe break;
39510d63b7dSRichard Lowe }
39610d63b7dSRichard Lowe append_string(block_start,
39710d63b7dSRichard Lowe &string,
39810d63b7dSRichard Lowe source_p - block_start);
39910d63b7dSRichard Lowe source->string.text.p = ++source_p;
40010d63b7dSRichard Lowe UNCACHE_SOURCE();
40110d63b7dSRichard Lowe expand_macro(source, &string, current_string, cmd);
40210d63b7dSRichard Lowe CACHE_SOURCE(0);
40310d63b7dSRichard Lowe block_start = source_p;
40410d63b7dSRichard Lowe source_p--;
40510d63b7dSRichard Lowe break;
40610d63b7dSRichard Lowe case parenleft_char:
40710d63b7dSRichard Lowe /* Allow nested pairs of () in the macro name. */
40810d63b7dSRichard Lowe if (closer == (int) parenright_char) {
40910d63b7dSRichard Lowe closer_level++;
41010d63b7dSRichard Lowe }
41110d63b7dSRichard Lowe break;
41210d63b7dSRichard Lowe case braceleft_char:
41310d63b7dSRichard Lowe /* Allow nested pairs of {} in the macro name. */
41410d63b7dSRichard Lowe if (closer == (int) braceright_char) {
41510d63b7dSRichard Lowe closer_level++;
41610d63b7dSRichard Lowe }
41710d63b7dSRichard Lowe break;
41810d63b7dSRichard Lowe case parenright_char:
41910d63b7dSRichard Lowe case braceright_char:
42010d63b7dSRichard Lowe /*
42110d63b7dSRichard Lowe * End of the name. Save the string in the macro
42210d63b7dSRichard Lowe * name string.
42310d63b7dSRichard Lowe */
42410d63b7dSRichard Lowe if ((*source_p == closer) && (--closer_level <= 0)) {
42510d63b7dSRichard Lowe source->string.text.p = source_p + 1;
42610d63b7dSRichard Lowe append_string(block_start,
42710d63b7dSRichard Lowe &string,
42810d63b7dSRichard Lowe source_p - block_start);
42910d63b7dSRichard Lowe goto get_macro_value;
43010d63b7dSRichard Lowe }
43110d63b7dSRichard Lowe break;
43210d63b7dSRichard Lowe }
43310d63b7dSRichard Lowe quote_seen = 0;
43410d63b7dSRichard Lowe }
43510d63b7dSRichard Lowe /*
43610d63b7dSRichard Lowe * We got the macro name. We now inspect it to see if it
43710d63b7dSRichard Lowe * specifies any translations of the value.
43810d63b7dSRichard Lowe */
43910d63b7dSRichard Lowe get_macro_value:
44010d63b7dSRichard Lowe name = NULL;
44110d63b7dSRichard Lowe /* First check if we have a $(@D) type translation. */
44210d63b7dSRichard Lowe if ((get_char_semantics_value(string.buffer.start[0]) &
44310d63b7dSRichard Lowe (int) special_macro_sem) &&
44410d63b7dSRichard Lowe (string.text.p - string.buffer.start >= 2) &&
44510d63b7dSRichard Lowe ((string.buffer.start[1] == 'D') ||
44610d63b7dSRichard Lowe (string.buffer.start[1] == 'F'))) {
44710d63b7dSRichard Lowe switch (string.buffer.start[1]) {
44810d63b7dSRichard Lowe case 'D':
44910d63b7dSRichard Lowe extraction = dir_extract;
45010d63b7dSRichard Lowe break;
45110d63b7dSRichard Lowe case 'F':
45210d63b7dSRichard Lowe extraction = file_extract;
45310d63b7dSRichard Lowe break;
45410d63b7dSRichard Lowe default:
45510d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, string.buffer.start);
45610d63b7dSRichard Lowe fatal_reader_mksh(gettext("Illegal macro reference `%s'"),
45710d63b7dSRichard Lowe mbs_buffer);
45810d63b7dSRichard Lowe }
45910d63b7dSRichard Lowe /* Internalize the macro name using the first char only. */
46010d63b7dSRichard Lowe name = GETNAME(string.buffer.start, 1);
46110d63b7dSRichard Lowe (void) wcscpy(string.buffer.start, string.buffer.start + 2);
46210d63b7dSRichard Lowe }
46310d63b7dSRichard Lowe /* Check for other kinds of translations. */
46410d63b7dSRichard Lowe if ((colon = (wchar_t *) wcschr(string.buffer.start,
46510d63b7dSRichard Lowe (int) colon_char)) != NULL) {
46610d63b7dSRichard Lowe /*
46710d63b7dSRichard Lowe * We have a $(FOO:.c=.o) type translation.
46810d63b7dSRichard Lowe * Get the name of the macro proper.
46910d63b7dSRichard Lowe */
47010d63b7dSRichard Lowe if (name == NULL) {
47110d63b7dSRichard Lowe name = GETNAME(string.buffer.start,
47210d63b7dSRichard Lowe colon - string.buffer.start);
47310d63b7dSRichard Lowe }
47410d63b7dSRichard Lowe /* Pickup all the translations. */
47510d63b7dSRichard Lowe if (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell)) {
47610d63b7dSRichard Lowe replacement = sh_replace;
47710d63b7dSRichard Lowe } else if ((svr4) ||
47810d63b7dSRichard Lowe ((percent = (wchar_t *) wcschr(colon + 1,
47910d63b7dSRichard Lowe (int) percent_char)) == NULL)) {
48010d63b7dSRichard Lowe while (colon != NULL) {
48110d63b7dSRichard Lowe if ((eq = (wchar_t *) wcschr(colon + 1,
48210d63b7dSRichard Lowe (int) equal_char)) == NULL) {
48310d63b7dSRichard Lowe fatal_reader_mksh(gettext("= missing from replacement macro reference"));
48410d63b7dSRichard Lowe }
48510d63b7dSRichard Lowe left_tail_len = eq - colon - 1;
48610d63b7dSRichard Lowe if(left_tail) {
48710d63b7dSRichard Lowe retmem(left_tail);
48810d63b7dSRichard Lowe }
48910d63b7dSRichard Lowe left_tail = ALLOC_WC(left_tail_len + 1);
49010d63b7dSRichard Lowe (void) wcsncpy(left_tail,
49110d63b7dSRichard Lowe colon + 1,
49210d63b7dSRichard Lowe eq - colon - 1);
49310d63b7dSRichard Lowe left_tail[eq - colon - 1] = (int) nul_char;
49410d63b7dSRichard Lowe replacement = suffix_replace;
49510d63b7dSRichard Lowe if ((colon = (wchar_t *) wcschr(eq + 1,
49610d63b7dSRichard Lowe (int) colon_char)) != NULL) {
49710d63b7dSRichard Lowe tmp_len = colon - eq;
49810d63b7dSRichard Lowe if(right_tail) {
49910d63b7dSRichard Lowe retmem(right_tail);
50010d63b7dSRichard Lowe }
50110d63b7dSRichard Lowe right_tail = ALLOC_WC(tmp_len);
50210d63b7dSRichard Lowe (void) wcsncpy(right_tail,
50310d63b7dSRichard Lowe eq + 1,
50410d63b7dSRichard Lowe colon - eq - 1);
50510d63b7dSRichard Lowe right_tail[colon - eq - 1] =
50610d63b7dSRichard Lowe (int) nul_char;
50710d63b7dSRichard Lowe } else {
50810d63b7dSRichard Lowe if(right_tail) {
50910d63b7dSRichard Lowe retmem(right_tail);
51010d63b7dSRichard Lowe }
51110d63b7dSRichard Lowe right_tail = ALLOC_WC(wcslen(eq) + 1);
51210d63b7dSRichard Lowe (void) wcscpy(right_tail, eq + 1);
51310d63b7dSRichard Lowe }
51410d63b7dSRichard Lowe }
51510d63b7dSRichard Lowe } else {
51610d63b7dSRichard Lowe if ((eq = (wchar_t *) wcschr(colon + 1,
51710d63b7dSRichard Lowe (int) equal_char)) == NULL) {
51810d63b7dSRichard Lowe fatal_reader_mksh(gettext("= missing from replacement macro reference"));
51910d63b7dSRichard Lowe }
52010d63b7dSRichard Lowe if ((percent = (wchar_t *) wcschr(colon + 1,
52110d63b7dSRichard Lowe (int) percent_char)) == NULL) {
52210d63b7dSRichard Lowe fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
52310d63b7dSRichard Lowe }
52410d63b7dSRichard Lowe if (eq < percent) {
52510d63b7dSRichard Lowe fatal_reader_mksh(gettext("%% missing from replacement macro reference"));
52610d63b7dSRichard Lowe }
52710d63b7dSRichard Lowe
52810d63b7dSRichard Lowe if (percent > (colon + 1)) {
52910d63b7dSRichard Lowe tmp_len = percent - colon;
53010d63b7dSRichard Lowe if(left_head) {
53110d63b7dSRichard Lowe retmem(left_head);
53210d63b7dSRichard Lowe }
53310d63b7dSRichard Lowe left_head = ALLOC_WC(tmp_len);
53410d63b7dSRichard Lowe (void) wcsncpy(left_head,
53510d63b7dSRichard Lowe colon + 1,
53610d63b7dSRichard Lowe percent - colon - 1);
53710d63b7dSRichard Lowe left_head[percent-colon-1] = (int) nul_char;
53810d63b7dSRichard Lowe left_head_len = percent-colon-1;
53910d63b7dSRichard Lowe } else {
54010d63b7dSRichard Lowe left_head = NULL;
54110d63b7dSRichard Lowe left_head_len = 0;
54210d63b7dSRichard Lowe }
54310d63b7dSRichard Lowe
54410d63b7dSRichard Lowe if (eq > percent+1) {
54510d63b7dSRichard Lowe tmp_len = eq - percent;
54610d63b7dSRichard Lowe if(left_tail) {
54710d63b7dSRichard Lowe retmem(left_tail);
54810d63b7dSRichard Lowe }
54910d63b7dSRichard Lowe left_tail = ALLOC_WC(tmp_len);
55010d63b7dSRichard Lowe (void) wcsncpy(left_tail,
55110d63b7dSRichard Lowe percent + 1,
55210d63b7dSRichard Lowe eq - percent - 1);
55310d63b7dSRichard Lowe left_tail[eq-percent-1] = (int) nul_char;
55410d63b7dSRichard Lowe left_tail_len = eq-percent-1;
55510d63b7dSRichard Lowe } else {
55610d63b7dSRichard Lowe left_tail = NULL;
55710d63b7dSRichard Lowe left_tail_len = 0;
55810d63b7dSRichard Lowe }
55910d63b7dSRichard Lowe
56010d63b7dSRichard Lowe if ((percent = (wchar_t *) wcschr(++eq,
56110d63b7dSRichard Lowe (int) percent_char)) == NULL) {
56210d63b7dSRichard Lowe
56310d63b7dSRichard Lowe right_hand[0] = ALLOC_WC(wcslen(eq) + 1);
56410d63b7dSRichard Lowe right_hand[1] = NULL;
56510d63b7dSRichard Lowe (void) wcscpy(right_hand[0], eq);
56610d63b7dSRichard Lowe } else {
56710d63b7dSRichard Lowe i = 0;
56810d63b7dSRichard Lowe do {
56910d63b7dSRichard Lowe right_hand[i] = ALLOC_WC(percent-eq+1);
57010d63b7dSRichard Lowe (void) wcsncpy(right_hand[i],
57110d63b7dSRichard Lowe eq,
57210d63b7dSRichard Lowe percent - eq);
57310d63b7dSRichard Lowe right_hand[i][percent-eq] =
57410d63b7dSRichard Lowe (int) nul_char;
57510d63b7dSRichard Lowe if (i++ >= VSIZEOF(right_hand)) {
57610d63b7dSRichard Lowe fatal_mksh(gettext("Too many %% in pattern"));
57710d63b7dSRichard Lowe }
57810d63b7dSRichard Lowe eq = percent + 1;
57910d63b7dSRichard Lowe if (eq[0] == (int) nul_char) {
58010d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "");
58110d63b7dSRichard Lowe right_hand[i] = (wchar_t *) wcsdup(wcs_buffer);
58210d63b7dSRichard Lowe i++;
58310d63b7dSRichard Lowe break;
58410d63b7dSRichard Lowe }
58510d63b7dSRichard Lowe } while ((percent = (wchar_t *) wcschr(eq, (int) percent_char)) != NULL);
58610d63b7dSRichard Lowe if (eq[0] != (int) nul_char) {
58710d63b7dSRichard Lowe right_hand[i] = ALLOC_WC(wcslen(eq) + 1);
58810d63b7dSRichard Lowe (void) wcscpy(right_hand[i], eq);
58910d63b7dSRichard Lowe i++;
59010d63b7dSRichard Lowe }
59110d63b7dSRichard Lowe right_hand[i] = NULL;
59210d63b7dSRichard Lowe }
59310d63b7dSRichard Lowe replacement = pattern_replace;
59410d63b7dSRichard Lowe }
59510d63b7dSRichard Lowe }
59610d63b7dSRichard Lowe if (name == NULL) {
59710d63b7dSRichard Lowe /*
59810d63b7dSRichard Lowe * No translations found.
59910d63b7dSRichard Lowe * Use the whole string as the macro name.
60010d63b7dSRichard Lowe */
60110d63b7dSRichard Lowe name = GETNAME(string.buffer.start,
60210d63b7dSRichard Lowe string.text.p - string.buffer.start);
60310d63b7dSRichard Lowe }
60410d63b7dSRichard Lowe if (string.free_after_use) {
60510d63b7dSRichard Lowe retmem(string.buffer.start);
60610d63b7dSRichard Lowe }
60710d63b7dSRichard Lowe if (name == make) {
60810d63b7dSRichard Lowe make_word_mentioned = true;
60910d63b7dSRichard Lowe }
61010d63b7dSRichard Lowe if (name == query) {
61110d63b7dSRichard Lowe query_mentioned = true;
61210d63b7dSRichard Lowe }
61310d63b7dSRichard Lowe if ((name == host_arch) || (name == target_arch)) {
61410d63b7dSRichard Lowe if (!init_arch_done) {
61510d63b7dSRichard Lowe init_arch_done = true;
61610d63b7dSRichard Lowe init_arch_macros();
61710d63b7dSRichard Lowe }
61810d63b7dSRichard Lowe }
61910d63b7dSRichard Lowe if ((name == host_mach) || (name == target_mach)) {
62010d63b7dSRichard Lowe if (!init_mach_done) {
62110d63b7dSRichard Lowe init_mach_done = true;
62210d63b7dSRichard Lowe init_mach_macros();
62310d63b7dSRichard Lowe }
62410d63b7dSRichard Lowe }
62510d63b7dSRichard Lowe /* Get the macro value. */
62610d63b7dSRichard Lowe macro = get_prop(name->prop, macro_prop);
62710d63b7dSRichard Lowe if ((macro != NULL) && macro->body.macro.is_conditional) {
62810d63b7dSRichard Lowe conditional_macro_used = true;
62910d63b7dSRichard Lowe /*
63010d63b7dSRichard Lowe * Add this conditional macro to the beginning of the
63110d63b7dSRichard Lowe * global list.
63210d63b7dSRichard Lowe */
63310d63b7dSRichard Lowe add_macro_to_global_list(name);
63410d63b7dSRichard Lowe if (makefile_type == reading_makefile) {
63510d63b7dSRichard Lowe warning_mksh(gettext("Conditional macro `%s' referenced in file `%ws', line %d"),
63610d63b7dSRichard Lowe name->string_mb, file_being_read, line_number);
63710d63b7dSRichard Lowe }
63810d63b7dSRichard Lowe }
63910d63b7dSRichard Lowe /* Macro name read and parsed. Expand the value. */
64010d63b7dSRichard Lowe if ((macro == NULL) || (macro->body.macro.value == NULL)) {
64110d63b7dSRichard Lowe /* If the value is empty, we just get out of here. */
64210d63b7dSRichard Lowe goto exit;
64310d63b7dSRichard Lowe }
64410d63b7dSRichard Lowe if (replacement == sh_replace) {
64510d63b7dSRichard Lowe /* If we should do a :sh transform, we expand the command
64610d63b7dSRichard Lowe * and process it.
64710d63b7dSRichard Lowe */
64810d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
64910d63b7dSRichard Lowe /* Expand the value into a local string buffer and run cmd. */
65010d63b7dSRichard Lowe expand_value_with_daemon(name, macro, &string, cmd);
65110d63b7dSRichard Lowe sh_command2string(&string, destination);
65210d63b7dSRichard Lowe } else if ((replacement != no_replace) || (extraction != no_extract)) {
65310d63b7dSRichard Lowe /*
65410d63b7dSRichard Lowe * If there were any transforms specified in the macro
65510d63b7dSRichard Lowe * name, we deal with them here.
65610d63b7dSRichard Lowe */
65710d63b7dSRichard Lowe INIT_STRING_FROM_STACK(string, buffer);
65810d63b7dSRichard Lowe /* Expand the value into a local string buffer. */
65910d63b7dSRichard Lowe expand_value_with_daemon(name, macro, &string, cmd);
66010d63b7dSRichard Lowe /* Scan the expanded string. */
66110d63b7dSRichard Lowe p = string.buffer.start;
66210d63b7dSRichard Lowe while (*p != (int) nul_char) {
66310d63b7dSRichard Lowe wchar_t chr;
66410d63b7dSRichard Lowe
66510d63b7dSRichard Lowe /*
66610d63b7dSRichard Lowe * First skip over any white space and append
66710d63b7dSRichard Lowe * that to the destination string.
66810d63b7dSRichard Lowe */
66910d63b7dSRichard Lowe block_start = p;
67010d63b7dSRichard Lowe while ((*p != (int) nul_char) && iswspace(*p)) {
67110d63b7dSRichard Lowe p++;
67210d63b7dSRichard Lowe }
67310d63b7dSRichard Lowe append_string(block_start,
67410d63b7dSRichard Lowe destination,
67510d63b7dSRichard Lowe p - block_start);
67610d63b7dSRichard Lowe /* Then find the end of the next word. */
67710d63b7dSRichard Lowe block_start = p;
67810d63b7dSRichard Lowe while ((*p != (int) nul_char) && !iswspace(*p)) {
67910d63b7dSRichard Lowe p++;
68010d63b7dSRichard Lowe }
68110d63b7dSRichard Lowe /* If we cant find another word we are done */
68210d63b7dSRichard Lowe if (block_start == p) {
68310d63b7dSRichard Lowe break;
68410d63b7dSRichard Lowe }
68510d63b7dSRichard Lowe /* Then apply the transforms to the word */
68610d63b7dSRichard Lowe INIT_STRING_FROM_STACK(extracted, extracted_string);
68710d63b7dSRichard Lowe switch (extraction) {
68810d63b7dSRichard Lowe case dir_extract:
68910d63b7dSRichard Lowe /*
69010d63b7dSRichard Lowe * $(@D) type transform. Extract the
69110d63b7dSRichard Lowe * path from the word. Deliver "." if
69210d63b7dSRichard Lowe * none is found.
69310d63b7dSRichard Lowe */
69410d63b7dSRichard Lowe if (p != NULL) {
69510d63b7dSRichard Lowe chr = *p;
69610d63b7dSRichard Lowe *p = (int) nul_char;
69710d63b7dSRichard Lowe }
69810d63b7dSRichard Lowe eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
69910d63b7dSRichard Lowe if (p != NULL) {
70010d63b7dSRichard Lowe *p = chr;
70110d63b7dSRichard Lowe }
70210d63b7dSRichard Lowe if ((eq == NULL) || (eq > p)) {
70310d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, ".");
70410d63b7dSRichard Lowe append_string(wcs_buffer, &extracted, 1);
70510d63b7dSRichard Lowe } else {
70610d63b7dSRichard Lowe append_string(block_start,
70710d63b7dSRichard Lowe &extracted,
70810d63b7dSRichard Lowe eq - block_start);
70910d63b7dSRichard Lowe }
71010d63b7dSRichard Lowe break;
71110d63b7dSRichard Lowe case file_extract:
71210d63b7dSRichard Lowe /*
71310d63b7dSRichard Lowe * $(@F) type transform. Remove the path
71410d63b7dSRichard Lowe * from the word if any.
71510d63b7dSRichard Lowe */
71610d63b7dSRichard Lowe if (p != NULL) {
71710d63b7dSRichard Lowe chr = *p;
71810d63b7dSRichard Lowe *p = (int) nul_char;
71910d63b7dSRichard Lowe }
72010d63b7dSRichard Lowe eq = (wchar_t *) wcsrchr(block_start, (int) slash_char);
72110d63b7dSRichard Lowe if (p != NULL) {
72210d63b7dSRichard Lowe *p = chr;
72310d63b7dSRichard Lowe }
72410d63b7dSRichard Lowe if ((eq == NULL) || (eq > p)) {
72510d63b7dSRichard Lowe append_string(block_start,
72610d63b7dSRichard Lowe &extracted,
72710d63b7dSRichard Lowe p - block_start);
72810d63b7dSRichard Lowe } else {
72910d63b7dSRichard Lowe append_string(eq + 1,
73010d63b7dSRichard Lowe &extracted,
73110d63b7dSRichard Lowe p - eq - 1);
73210d63b7dSRichard Lowe }
73310d63b7dSRichard Lowe break;
73410d63b7dSRichard Lowe case no_extract:
73510d63b7dSRichard Lowe append_string(block_start,
73610d63b7dSRichard Lowe &extracted,
73710d63b7dSRichard Lowe p - block_start);
73810d63b7dSRichard Lowe break;
73910d63b7dSRichard Lowe }
74010d63b7dSRichard Lowe switch (replacement) {
74110d63b7dSRichard Lowe case suffix_replace:
74210d63b7dSRichard Lowe /*
74310d63b7dSRichard Lowe * $(FOO:.o=.c) type transform.
74410d63b7dSRichard Lowe * Maybe replace the tail of the word.
74510d63b7dSRichard Lowe */
74610d63b7dSRichard Lowe if (((extracted.text.p -
74710d63b7dSRichard Lowe extracted.buffer.start) >=
74810d63b7dSRichard Lowe left_tail_len) &&
74910d63b7dSRichard Lowe IS_WEQUALN(extracted.text.p - left_tail_len,
75010d63b7dSRichard Lowe left_tail,
75110d63b7dSRichard Lowe left_tail_len)) {
75210d63b7dSRichard Lowe append_string(extracted.buffer.start,
75310d63b7dSRichard Lowe destination,
75410d63b7dSRichard Lowe (extracted.text.p -
75510d63b7dSRichard Lowe extracted.buffer.start)
75610d63b7dSRichard Lowe - left_tail_len);
75710d63b7dSRichard Lowe append_string(right_tail,
75810d63b7dSRichard Lowe destination,
75910d63b7dSRichard Lowe FIND_LENGTH);
76010d63b7dSRichard Lowe } else {
76110d63b7dSRichard Lowe append_string(extracted.buffer.start,
76210d63b7dSRichard Lowe destination,
76310d63b7dSRichard Lowe FIND_LENGTH);
76410d63b7dSRichard Lowe }
76510d63b7dSRichard Lowe break;
76610d63b7dSRichard Lowe case pattern_replace:
76710d63b7dSRichard Lowe /* $(X:a%b=c%d) type transform. */
76810d63b7dSRichard Lowe if (((extracted.text.p -
76910d63b7dSRichard Lowe extracted.buffer.start) >=
77010d63b7dSRichard Lowe left_head_len+left_tail_len) &&
77110d63b7dSRichard Lowe IS_WEQUALN(left_head,
77210d63b7dSRichard Lowe extracted.buffer.start,
77310d63b7dSRichard Lowe left_head_len) &&
77410d63b7dSRichard Lowe IS_WEQUALN(left_tail,
77510d63b7dSRichard Lowe extracted.text.p - left_tail_len,
77610d63b7dSRichard Lowe left_tail_len)) {
77710d63b7dSRichard Lowe i = 0;
77810d63b7dSRichard Lowe while (right_hand[i] != NULL) {
77910d63b7dSRichard Lowe append_string(right_hand[i],
78010d63b7dSRichard Lowe destination,
78110d63b7dSRichard Lowe FIND_LENGTH);
78210d63b7dSRichard Lowe i++;
78310d63b7dSRichard Lowe if (right_hand[i] != NULL) {
78410d63b7dSRichard Lowe append_string(extracted.buffer.
78510d63b7dSRichard Lowe start +
78610d63b7dSRichard Lowe left_head_len,
78710d63b7dSRichard Lowe destination,
78810d63b7dSRichard Lowe (extracted.text.p - extracted.buffer.start)-left_head_len-left_tail_len);
78910d63b7dSRichard Lowe }
79010d63b7dSRichard Lowe }
79110d63b7dSRichard Lowe } else {
79210d63b7dSRichard Lowe append_string(extracted.buffer.start,
79310d63b7dSRichard Lowe destination,
79410d63b7dSRichard Lowe FIND_LENGTH);
79510d63b7dSRichard Lowe }
79610d63b7dSRichard Lowe break;
79710d63b7dSRichard Lowe case no_replace:
79810d63b7dSRichard Lowe append_string(extracted.buffer.start,
79910d63b7dSRichard Lowe destination,
80010d63b7dSRichard Lowe FIND_LENGTH);
80110d63b7dSRichard Lowe break;
80210d63b7dSRichard Lowe case sh_replace:
80310d63b7dSRichard Lowe break;
80410d63b7dSRichard Lowe }
80510d63b7dSRichard Lowe }
80610d63b7dSRichard Lowe if (string.free_after_use) {
80710d63b7dSRichard Lowe retmem(string.buffer.start);
80810d63b7dSRichard Lowe }
80910d63b7dSRichard Lowe } else {
81010d63b7dSRichard Lowe /*
81110d63b7dSRichard Lowe * This is for the case when the macro name did not
81210d63b7dSRichard Lowe * specify transforms.
81310d63b7dSRichard Lowe */
81410d63b7dSRichard Lowe if (!strncmp(name->string_mb, "GET", 3)) {
81510d63b7dSRichard Lowe dollarget_seen = true;
81610d63b7dSRichard Lowe }
81710d63b7dSRichard Lowe dollarless_flag = false;
81810d63b7dSRichard Lowe if (!strncmp(name->string_mb, "<", 1) &&
81910d63b7dSRichard Lowe dollarget_seen) {
82010d63b7dSRichard Lowe dollarless_flag = true;
82110d63b7dSRichard Lowe dollarget_seen = false;
82210d63b7dSRichard Lowe }
82310d63b7dSRichard Lowe expand_value_with_daemon(name, macro, destination, cmd);
82410d63b7dSRichard Lowe }
82510d63b7dSRichard Lowe exit:
82610d63b7dSRichard Lowe if(left_tail) {
82710d63b7dSRichard Lowe retmem(left_tail);
82810d63b7dSRichard Lowe }
82910d63b7dSRichard Lowe if(right_tail) {
83010d63b7dSRichard Lowe retmem(right_tail);
83110d63b7dSRichard Lowe }
83210d63b7dSRichard Lowe if(left_head) {
83310d63b7dSRichard Lowe retmem(left_head);
83410d63b7dSRichard Lowe }
83510d63b7dSRichard Lowe i = 0;
83610d63b7dSRichard Lowe while (right_hand[i] != NULL) {
83710d63b7dSRichard Lowe retmem(right_hand[i]);
83810d63b7dSRichard Lowe i++;
83910d63b7dSRichard Lowe }
84010d63b7dSRichard Lowe *destination->text.p = (int) nul_char;
84110d63b7dSRichard Lowe destination->text.end = destination->text.p;
84210d63b7dSRichard Lowe }
84310d63b7dSRichard Lowe
84410d63b7dSRichard Lowe static void
add_macro_to_global_list(Name macro_to_add)84510d63b7dSRichard Lowe add_macro_to_global_list(Name macro_to_add)
84610d63b7dSRichard Lowe {
84710d63b7dSRichard Lowe Macro_list new_macro;
84810d63b7dSRichard Lowe Macro_list macro_on_list;
84910d63b7dSRichard Lowe char *name_on_list = (char*)NULL;
85010d63b7dSRichard Lowe char *name_to_add = macro_to_add->string_mb;
85110d63b7dSRichard Lowe char *value_on_list = (char*)NULL;
85210d63b7dSRichard Lowe const char *value_to_add = (char*)NULL;
85310d63b7dSRichard Lowe
85410d63b7dSRichard Lowe if (macro_to_add->prop->body.macro.value != NULL) {
85510d63b7dSRichard Lowe value_to_add = macro_to_add->prop->body.macro.value->string_mb;
85610d63b7dSRichard Lowe } else {
85710d63b7dSRichard Lowe value_to_add = "";
85810d63b7dSRichard Lowe }
85910d63b7dSRichard Lowe
860*e7afc443SToomas Soome /*
86110d63b7dSRichard Lowe * Check if this macro is already on list, if so, do nothing
86210d63b7dSRichard Lowe */
86310d63b7dSRichard Lowe for (macro_on_list = cond_macro_list;
86410d63b7dSRichard Lowe macro_on_list != NULL;
86510d63b7dSRichard Lowe macro_on_list = macro_on_list->next) {
86610d63b7dSRichard Lowe
86710d63b7dSRichard Lowe name_on_list = macro_on_list->macro_name;
86810d63b7dSRichard Lowe value_on_list = macro_on_list->value;
86910d63b7dSRichard Lowe
87010d63b7dSRichard Lowe if (IS_EQUAL(name_on_list, name_to_add)) {
87110d63b7dSRichard Lowe if (IS_EQUAL(value_on_list, value_to_add)) {
87210d63b7dSRichard Lowe return;
87310d63b7dSRichard Lowe }
87410d63b7dSRichard Lowe }
87510d63b7dSRichard Lowe }
87610d63b7dSRichard Lowe new_macro = (Macro_list) malloc(sizeof(Macro_list_rec));
87710d63b7dSRichard Lowe new_macro->macro_name = strdup(name_to_add);
87810d63b7dSRichard Lowe new_macro->value = strdup(value_to_add);
87910d63b7dSRichard Lowe new_macro->next = cond_macro_list;
88010d63b7dSRichard Lowe cond_macro_list = new_macro;
88110d63b7dSRichard Lowe }
88210d63b7dSRichard Lowe
88310d63b7dSRichard Lowe /*
88410d63b7dSRichard Lowe * init_arch_macros(void)
88510d63b7dSRichard Lowe *
88610d63b7dSRichard Lowe * Set the magic macros TARGET_ARCH, HOST_ARCH,
88710d63b7dSRichard Lowe *
888*e7afc443SToomas Soome * Parameters:
88910d63b7dSRichard Lowe *
89010d63b7dSRichard Lowe * Global variables used:
891*e7afc443SToomas Soome * host_arch Property for magic macro HOST_ARCH
892*e7afc443SToomas Soome * target_arch Property for magic macro TARGET_ARCH
89310d63b7dSRichard Lowe *
89410d63b7dSRichard Lowe * Return value:
89510d63b7dSRichard Lowe * The function does not return a value, but can
89610d63b7dSRichard Lowe * call fatal() in case of error.
89710d63b7dSRichard Lowe */
89810d63b7dSRichard Lowe static void
init_arch_macros(void)89910d63b7dSRichard Lowe init_arch_macros(void)
90010d63b7dSRichard Lowe {
90110d63b7dSRichard Lowe String_rec result_string;
90210d63b7dSRichard Lowe wchar_t wc_buf[STRING_BUFFER_LENGTH];
90310d63b7dSRichard Lowe char mb_buf[STRING_BUFFER_LENGTH];
90410d63b7dSRichard Lowe FILE *pipe;
90510d63b7dSRichard Lowe Name value;
90610d63b7dSRichard Lowe int set_host, set_target;
90710d63b7dSRichard Lowe const char *mach_command = "/bin/mach";
90810d63b7dSRichard Lowe
90910d63b7dSRichard Lowe set_host = (get_prop(host_arch->prop, macro_prop) == NULL);
91010d63b7dSRichard Lowe set_target = (get_prop(target_arch->prop, macro_prop) == NULL);
91110d63b7dSRichard Lowe
91210d63b7dSRichard Lowe if (set_host || set_target) {
91310d63b7dSRichard Lowe INIT_STRING_FROM_STACK(result_string, wc_buf);
91410d63b7dSRichard Lowe append_char((int) hyphen_char, &result_string);
91510d63b7dSRichard Lowe
91610d63b7dSRichard Lowe if ((pipe = popen(mach_command, "r")) == NULL) {
91710d63b7dSRichard Lowe fatal_mksh(gettext("Execute of %s failed"), mach_command);
91810d63b7dSRichard Lowe }
91910d63b7dSRichard Lowe while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
92010d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, mb_buf);
92110d63b7dSRichard Lowe append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
92210d63b7dSRichard Lowe }
92310d63b7dSRichard Lowe if (pclose(pipe) != 0) {
92410d63b7dSRichard Lowe fatal_mksh(gettext("Execute of %s failed"), mach_command);
92510d63b7dSRichard Lowe }
92610d63b7dSRichard Lowe
92710d63b7dSRichard Lowe value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
92810d63b7dSRichard Lowe
92910d63b7dSRichard Lowe if (set_host) {
93010d63b7dSRichard Lowe (void) setvar_daemon(host_arch, value, false, no_daemon, true, 0);
93110d63b7dSRichard Lowe }
93210d63b7dSRichard Lowe if (set_target) {
93310d63b7dSRichard Lowe (void) setvar_daemon(target_arch, value, false, no_daemon, true, 0);
93410d63b7dSRichard Lowe }
93510d63b7dSRichard Lowe }
93610d63b7dSRichard Lowe }
93710d63b7dSRichard Lowe
93810d63b7dSRichard Lowe /*
93910d63b7dSRichard Lowe * init_mach_macros(void)
94010d63b7dSRichard Lowe *
94110d63b7dSRichard Lowe * Set the magic macros TARGET_MACH, HOST_MACH,
94210d63b7dSRichard Lowe *
943*e7afc443SToomas Soome * Parameters:
94410d63b7dSRichard Lowe *
94510d63b7dSRichard Lowe * Global variables used:
946*e7afc443SToomas Soome * host_mach Property for magic macro HOST_MACH
947*e7afc443SToomas Soome * target_mach Property for magic macro TARGET_MACH
94810d63b7dSRichard Lowe *
94910d63b7dSRichard Lowe * Return value:
95010d63b7dSRichard Lowe * The function does not return a value, but can
95110d63b7dSRichard Lowe * call fatal() in case of error.
95210d63b7dSRichard Lowe */
95310d63b7dSRichard Lowe static void
init_mach_macros(void)95410d63b7dSRichard Lowe init_mach_macros(void)
95510d63b7dSRichard Lowe {
95610d63b7dSRichard Lowe String_rec result_string;
95710d63b7dSRichard Lowe wchar_t wc_buf[STRING_BUFFER_LENGTH];
95810d63b7dSRichard Lowe char mb_buf[STRING_BUFFER_LENGTH];
95910d63b7dSRichard Lowe FILE *pipe;
96010d63b7dSRichard Lowe Name value;
96110d63b7dSRichard Lowe int set_host, set_target;
96210d63b7dSRichard Lowe const char *arch_command = "/bin/arch";
96310d63b7dSRichard Lowe
96410d63b7dSRichard Lowe set_host = (get_prop(host_mach->prop, macro_prop) == NULL);
96510d63b7dSRichard Lowe set_target = (get_prop(target_mach->prop, macro_prop) == NULL);
96610d63b7dSRichard Lowe
96710d63b7dSRichard Lowe if (set_host || set_target) {
96810d63b7dSRichard Lowe INIT_STRING_FROM_STACK(result_string, wc_buf);
96910d63b7dSRichard Lowe append_char((int) hyphen_char, &result_string);
97010d63b7dSRichard Lowe
97110d63b7dSRichard Lowe if ((pipe = popen(arch_command, "r")) == NULL) {
97210d63b7dSRichard Lowe fatal_mksh(gettext("Execute of %s failed"), arch_command);
97310d63b7dSRichard Lowe }
97410d63b7dSRichard Lowe while (fgets(mb_buf, sizeof(mb_buf), pipe) != NULL) {
97510d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, mb_buf);
97610d63b7dSRichard Lowe append_string(wcs_buffer, &result_string, wcslen(wcs_buffer));
97710d63b7dSRichard Lowe }
97810d63b7dSRichard Lowe if (pclose(pipe) != 0) {
97910d63b7dSRichard Lowe fatal_mksh(gettext("Execute of %s failed"), arch_command);
98010d63b7dSRichard Lowe }
98110d63b7dSRichard Lowe
98210d63b7dSRichard Lowe value = GETNAME(result_string.buffer.start, wcslen(result_string.buffer.start));
98310d63b7dSRichard Lowe
98410d63b7dSRichard Lowe if (set_host) {
98510d63b7dSRichard Lowe (void) setvar_daemon(host_mach, value, false, no_daemon, true, 0);
98610d63b7dSRichard Lowe }
98710d63b7dSRichard Lowe if (set_target) {
98810d63b7dSRichard Lowe (void) setvar_daemon(target_mach, value, false, no_daemon, true, 0);
98910d63b7dSRichard Lowe }
99010d63b7dSRichard Lowe }
99110d63b7dSRichard Lowe }
99210d63b7dSRichard Lowe
99310d63b7dSRichard Lowe /*
99410d63b7dSRichard Lowe * expand_value_with_daemon(name, macro, destination, cmd)
99510d63b7dSRichard Lowe *
99610d63b7dSRichard Lowe * Checks for daemons and then maybe calls expand_value().
99710d63b7dSRichard Lowe *
99810d63b7dSRichard Lowe * Parameters:
99910d63b7dSRichard Lowe * name Name of the macro (Added by the NSE)
100010d63b7dSRichard Lowe * macro The property block with the value to expand
100110d63b7dSRichard Lowe * destination Where the result should be deposited
100210d63b7dSRichard Lowe * cmd If we are evaluating a command line we
100310d63b7dSRichard Lowe * turn \ quoting off
100410d63b7dSRichard Lowe *
100510d63b7dSRichard Lowe * Global variables used:
100610d63b7dSRichard Lowe */
100710d63b7dSRichard Lowe static void
expand_value_with_daemon(Name,Property macro,String destination,Boolean cmd)1008*e7afc443SToomas Soome expand_value_with_daemon(Name, Property macro, String destination, Boolean cmd)
100910d63b7dSRichard Lowe {
1010*e7afc443SToomas Soome Chain chain;
101110d63b7dSRichard Lowe
101210d63b7dSRichard Lowe
101310d63b7dSRichard Lowe switch (macro->body.macro.daemon) {
101410d63b7dSRichard Lowe case no_daemon:
101510d63b7dSRichard Lowe if (!svr4 && !posix) {
101610d63b7dSRichard Lowe expand_value(macro->body.macro.value, destination, cmd);
101710d63b7dSRichard Lowe } else {
101810d63b7dSRichard Lowe if (dollarless_flag && tilde_rule) {
101910d63b7dSRichard Lowe expand_value(dollarless_value, destination, cmd);
102010d63b7dSRichard Lowe dollarless_flag = false;
102110d63b7dSRichard Lowe tilde_rule = false;
102210d63b7dSRichard Lowe } else {
102310d63b7dSRichard Lowe expand_value(macro->body.macro.value, destination, cmd);
102410d63b7dSRichard Lowe }
102510d63b7dSRichard Lowe }
102610d63b7dSRichard Lowe return;
102710d63b7dSRichard Lowe case chain_daemon:
102810d63b7dSRichard Lowe /* If this is a $? value we call the daemon to translate the */
102910d63b7dSRichard Lowe /* list of names to a string */
103010d63b7dSRichard Lowe for (chain = (Chain) macro->body.macro.value;
103110d63b7dSRichard Lowe chain != NULL;
103210d63b7dSRichard Lowe chain = chain->next) {
103310d63b7dSRichard Lowe APPEND_NAME(chain->name,
103410d63b7dSRichard Lowe destination,
103510d63b7dSRichard Lowe (int) chain->name->hash.length);
103610d63b7dSRichard Lowe if (chain->next != NULL) {
103710d63b7dSRichard Lowe append_char((int) space_char, destination);
103810d63b7dSRichard Lowe }
103910d63b7dSRichard Lowe }
104010d63b7dSRichard Lowe return;
104110d63b7dSRichard Lowe }
104210d63b7dSRichard Lowe }
104310d63b7dSRichard Lowe
104410d63b7dSRichard Lowe /*
104510d63b7dSRichard Lowe * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
104610d63b7dSRichard Lowe */
104710d63b7dSRichard Lowe char *sunpro_dependencies_buf = NULL;
104810d63b7dSRichard Lowe char *sunpro_dependencies_oldbuf = NULL;
104910d63b7dSRichard Lowe int sunpro_dependencies_buf_size = 0;
105010d63b7dSRichard Lowe
105110d63b7dSRichard Lowe /*
105210d63b7dSRichard Lowe * setvar_daemon(name, value, append, daemon, strip_trailing_spaces)
105310d63b7dSRichard Lowe *
105410d63b7dSRichard Lowe * Set a macro value, possibly supplying a daemon to be used
105510d63b7dSRichard Lowe * when referencing the value.
105610d63b7dSRichard Lowe *
105710d63b7dSRichard Lowe * Return value:
105810d63b7dSRichard Lowe * The property block with the new value
105910d63b7dSRichard Lowe *
106010d63b7dSRichard Lowe * Parameters:
106110d63b7dSRichard Lowe * name Name of the macro to set
106210d63b7dSRichard Lowe * value The value to set
106310d63b7dSRichard Lowe * append Should we reset or append to the current value?
106410d63b7dSRichard Lowe * daemon Special treatment when reading the value
106510d63b7dSRichard Lowe * strip_trailing_spaces from the end of value->string
106610d63b7dSRichard Lowe * debug_level Indicates how much tracing we should do
106710d63b7dSRichard Lowe *
106810d63b7dSRichard Lowe * Global variables used:
106910d63b7dSRichard Lowe * makefile_type Used to check if we should enforce read only
107010d63b7dSRichard Lowe * path_name The Name "PATH", compared against
107110d63b7dSRichard Lowe * virtual_root The Name "VIRTUAL_ROOT", compared against
107210d63b7dSRichard Lowe * vpath_defined Set if the macro VPATH is set
107310d63b7dSRichard Lowe * vpath_name The Name "VPATH", compared against
107410d63b7dSRichard Lowe * envvar A list of environment vars with $ in value
107510d63b7dSRichard Lowe */
107610d63b7dSRichard Lowe Property
setvar_daemon(Name name,Name value,Boolean append,Daemon daemon,Boolean strip_trailing_spaces,short debug_level)1077*e7afc443SToomas Soome setvar_daemon(Name name, Name value, Boolean append, Daemon daemon, Boolean strip_trailing_spaces, short debug_level)
107810d63b7dSRichard Lowe {
1079*e7afc443SToomas Soome Property macro = maybe_append_prop(name, macro_prop);
1080*e7afc443SToomas Soome Property macro_apx = get_prop(name->prop, macro_append_prop);
108110d63b7dSRichard Lowe int length = 0;
108210d63b7dSRichard Lowe String_rec destination;
108310d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
1084*e7afc443SToomas Soome Chain chain;
108510d63b7dSRichard Lowe Name val;
108610d63b7dSRichard Lowe wchar_t *val_string = (wchar_t*)NULL;
108710d63b7dSRichard Lowe Wstring wcb;
108810d63b7dSRichard Lowe
108910d63b7dSRichard Lowe
109010d63b7dSRichard Lowe if ((makefile_type != reading_nothing) &&
109110d63b7dSRichard Lowe macro->body.macro.read_only) {
109210d63b7dSRichard Lowe return macro;
109310d63b7dSRichard Lowe }
109410d63b7dSRichard Lowe /* Strip spaces from the end of the value */
109510d63b7dSRichard Lowe if (daemon == no_daemon) {
109610d63b7dSRichard Lowe if(value != NULL) {
109710d63b7dSRichard Lowe wcb.init(value);
109810d63b7dSRichard Lowe length = wcb.length();
109910d63b7dSRichard Lowe val_string = wcb.get_string();
110010d63b7dSRichard Lowe }
110110d63b7dSRichard Lowe if ((length > 0) && iswspace(val_string[length-1])) {
110210d63b7dSRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
110310d63b7dSRichard Lowe buffer[0] = 0;
110410d63b7dSRichard Lowe append_string(val_string, &destination, length);
110510d63b7dSRichard Lowe if (strip_trailing_spaces) {
110610d63b7dSRichard Lowe while ((length > 0) &&
110710d63b7dSRichard Lowe iswspace(destination.buffer.start[length-1])) {
110810d63b7dSRichard Lowe destination.buffer.start[--length] = 0;
110910d63b7dSRichard Lowe }
111010d63b7dSRichard Lowe }
111110d63b7dSRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
111210d63b7dSRichard Lowe }
111310d63b7dSRichard Lowe }
1114*e7afc443SToomas Soome
111510d63b7dSRichard Lowe if(macro_apx != NULL) {
111610d63b7dSRichard Lowe val = macro_apx->body.macro_appendix.value;
111710d63b7dSRichard Lowe } else {
111810d63b7dSRichard Lowe val = macro->body.macro.value;
111910d63b7dSRichard Lowe }
112010d63b7dSRichard Lowe
112110d63b7dSRichard Lowe if (append) {
112210d63b7dSRichard Lowe /*
112310d63b7dSRichard Lowe * If we are appending, we just tack the new value after
112410d63b7dSRichard Lowe * the old one with a space in between.
112510d63b7dSRichard Lowe */
112610d63b7dSRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
112710d63b7dSRichard Lowe buffer[0] = 0;
112810d63b7dSRichard Lowe if ((macro != NULL) && (val != NULL)) {
112910d63b7dSRichard Lowe APPEND_NAME(val,
113010d63b7dSRichard Lowe &destination,
113110d63b7dSRichard Lowe (int) val->hash.length);
113210d63b7dSRichard Lowe if (value != NULL) {
113310d63b7dSRichard Lowe wcb.init(value);
113410d63b7dSRichard Lowe if(wcb.length() > 0) {
113510d63b7dSRichard Lowe MBTOWC(wcs_buffer, " ");
113610d63b7dSRichard Lowe append_char(wcs_buffer[0], &destination);
113710d63b7dSRichard Lowe }
113810d63b7dSRichard Lowe }
113910d63b7dSRichard Lowe }
114010d63b7dSRichard Lowe if (value != NULL) {
114110d63b7dSRichard Lowe APPEND_NAME(value,
114210d63b7dSRichard Lowe &destination,
114310d63b7dSRichard Lowe (int) value->hash.length);
114410d63b7dSRichard Lowe }
114510d63b7dSRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
114610d63b7dSRichard Lowe wcb.init(value);
114710d63b7dSRichard Lowe if (destination.free_after_use) {
114810d63b7dSRichard Lowe retmem(destination.buffer.start);
114910d63b7dSRichard Lowe }
115010d63b7dSRichard Lowe }
115110d63b7dSRichard Lowe
115210d63b7dSRichard Lowe /* Debugging trace */
115310d63b7dSRichard Lowe if (debug_level > 1) {
115410d63b7dSRichard Lowe if (value != NULL) {
115510d63b7dSRichard Lowe switch (daemon) {
115610d63b7dSRichard Lowe case chain_daemon:
115710d63b7dSRichard Lowe (void) printf("%s =", name->string_mb);
115810d63b7dSRichard Lowe for (chain = (Chain) value;
115910d63b7dSRichard Lowe chain != NULL;
116010d63b7dSRichard Lowe chain = chain->next) {
116110d63b7dSRichard Lowe (void) printf(" %s", chain->name->string_mb);
116210d63b7dSRichard Lowe }
116310d63b7dSRichard Lowe (void) printf("\n");
116410d63b7dSRichard Lowe break;
116510d63b7dSRichard Lowe case no_daemon:
116610d63b7dSRichard Lowe (void) printf("%s= %s\n",
116710d63b7dSRichard Lowe name->string_mb,
116810d63b7dSRichard Lowe value->string_mb);
116910d63b7dSRichard Lowe break;
117010d63b7dSRichard Lowe }
117110d63b7dSRichard Lowe } else {
117210d63b7dSRichard Lowe (void) printf("%s =\n", name->string_mb);
117310d63b7dSRichard Lowe }
117410d63b7dSRichard Lowe }
117510d63b7dSRichard Lowe /* Set the new values in the macro property block */
117610d63b7dSRichard Lowe /**/
117710d63b7dSRichard Lowe if(macro_apx != NULL) {
117810d63b7dSRichard Lowe macro_apx->body.macro_appendix.value = value;
117910d63b7dSRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
118010d63b7dSRichard Lowe buffer[0] = 0;
118110d63b7dSRichard Lowe if (value != NULL) {
118210d63b7dSRichard Lowe APPEND_NAME(value,
118310d63b7dSRichard Lowe &destination,
118410d63b7dSRichard Lowe (int) value->hash.length);
118510d63b7dSRichard Lowe if (macro_apx->body.macro_appendix.value_to_append != NULL) {
118610d63b7dSRichard Lowe MBTOWC(wcs_buffer, " ");
118710d63b7dSRichard Lowe append_char(wcs_buffer[0], &destination);
118810d63b7dSRichard Lowe }
118910d63b7dSRichard Lowe }
119010d63b7dSRichard Lowe if (macro_apx->body.macro_appendix.value_to_append != NULL) {
119110d63b7dSRichard Lowe APPEND_NAME(macro_apx->body.macro_appendix.value_to_append,
119210d63b7dSRichard Lowe &destination,
119310d63b7dSRichard Lowe (int) macro_apx->body.macro_appendix.value_to_append->hash.length);
119410d63b7dSRichard Lowe }
119510d63b7dSRichard Lowe value = GETNAME(destination.buffer.start, FIND_LENGTH);
119610d63b7dSRichard Lowe if (destination.free_after_use) {
119710d63b7dSRichard Lowe retmem(destination.buffer.start);
119810d63b7dSRichard Lowe }
119910d63b7dSRichard Lowe }
120010d63b7dSRichard Lowe /**/
120110d63b7dSRichard Lowe macro->body.macro.value = value;
120210d63b7dSRichard Lowe macro->body.macro.daemon = daemon;
120310d63b7dSRichard Lowe /*
120410d63b7dSRichard Lowe * If the user changes the VIRTUAL_ROOT, we need to flush
120510d63b7dSRichard Lowe * the vroot package cache.
120610d63b7dSRichard Lowe */
120710d63b7dSRichard Lowe if (name == path_name) {
120810d63b7dSRichard Lowe flush_path_cache();
120910d63b7dSRichard Lowe }
121010d63b7dSRichard Lowe if (name == virtual_root) {
121110d63b7dSRichard Lowe flush_vroot_cache();
121210d63b7dSRichard Lowe }
121310d63b7dSRichard Lowe /* If this sets the VPATH we remember that */
121410d63b7dSRichard Lowe if ((name == vpath_name) &&
121510d63b7dSRichard Lowe (value != NULL) &&
121610d63b7dSRichard Lowe (value->hash.length > 0)) {
121710d63b7dSRichard Lowe vpath_defined = true;
121810d63b7dSRichard Lowe }
121910d63b7dSRichard Lowe /*
122010d63b7dSRichard Lowe * For environment variables we also set the
122110d63b7dSRichard Lowe * environment value each time.
122210d63b7dSRichard Lowe */
122310d63b7dSRichard Lowe if (macro->body.macro.exported) {
122410d63b7dSRichard Lowe static char *env;
122510d63b7dSRichard Lowe
122610d63b7dSRichard Lowe if (!reading_environment && (value != NULL)) {
122710d63b7dSRichard Lowe Envvar p;
122810d63b7dSRichard Lowe
122910d63b7dSRichard Lowe for (p = envvar; p != NULL; p = p->next) {
123010d63b7dSRichard Lowe if (p->name == name) {
123110d63b7dSRichard Lowe p->value = value;
123210d63b7dSRichard Lowe p->already_put = false;
123310d63b7dSRichard Lowe goto found_it;
123410d63b7dSRichard Lowe }
123510d63b7dSRichard Lowe }
123610d63b7dSRichard Lowe p = ALLOC(Envvar);
123710d63b7dSRichard Lowe p->name = name;
123810d63b7dSRichard Lowe p->value = value;
123910d63b7dSRichard Lowe p->next = envvar;
124010d63b7dSRichard Lowe p->env_string = NULL;
124110d63b7dSRichard Lowe p->already_put = false;
124210d63b7dSRichard Lowe envvar = p;
124310d63b7dSRichard Lowe found_it:;
124410d63b7dSRichard Lowe } if (reading_environment || (value == NULL) || !value->dollar) {
124510d63b7dSRichard Lowe length = 2 + strlen(name->string_mb);
124610d63b7dSRichard Lowe if (value != NULL) {
124710d63b7dSRichard Lowe length += strlen(value->string_mb);
124810d63b7dSRichard Lowe }
124910d63b7dSRichard Lowe Property env_prop = maybe_append_prop(name, env_mem_prop);
125010d63b7dSRichard Lowe /*
125110d63b7dSRichard Lowe * We use a permanent buffer to reset SUNPRO_DEPENDENCIES value.
125210d63b7dSRichard Lowe */
125310d63b7dSRichard Lowe if (!strncmp(name->string_mb, "SUNPRO_DEPENDENCIES", 19)) {
125410d63b7dSRichard Lowe if (length >= sunpro_dependencies_buf_size) {
125510d63b7dSRichard Lowe sunpro_dependencies_buf_size=length*2;
125610d63b7dSRichard Lowe if (sunpro_dependencies_buf_size < 4096)
125710d63b7dSRichard Lowe sunpro_dependencies_buf_size = 4096; // Default minimum size
125810d63b7dSRichard Lowe if (sunpro_dependencies_buf)
125910d63b7dSRichard Lowe sunpro_dependencies_oldbuf = sunpro_dependencies_buf;
126010d63b7dSRichard Lowe sunpro_dependencies_buf=getmem(sunpro_dependencies_buf_size);
126110d63b7dSRichard Lowe }
126210d63b7dSRichard Lowe env = sunpro_dependencies_buf;
126310d63b7dSRichard Lowe } else {
126410d63b7dSRichard Lowe env = getmem(length);
126510d63b7dSRichard Lowe }
126610d63b7dSRichard Lowe env_alloc_num++;
126710d63b7dSRichard Lowe env_alloc_bytes += length;
126810d63b7dSRichard Lowe (void) sprintf(env,
126910d63b7dSRichard Lowe "%s=%s",
127010d63b7dSRichard Lowe name->string_mb,
127110d63b7dSRichard Lowe value == NULL ?
127210d63b7dSRichard Lowe "" : value->string_mb);
127310d63b7dSRichard Lowe (void) putenv(env);
127410d63b7dSRichard Lowe env_prop->body.env_mem.value = env;
127510d63b7dSRichard Lowe if (sunpro_dependencies_oldbuf) {
127610d63b7dSRichard Lowe /* Return old buffer */
127710d63b7dSRichard Lowe retmem_mb(sunpro_dependencies_oldbuf);
127810d63b7dSRichard Lowe sunpro_dependencies_oldbuf = NULL;
127910d63b7dSRichard Lowe }
128010d63b7dSRichard Lowe }
128110d63b7dSRichard Lowe }
128210d63b7dSRichard Lowe if (name == target_arch) {
128310d63b7dSRichard Lowe Name ha = getvar(host_arch);
128410d63b7dSRichard Lowe Name ta = getvar(target_arch);
128510d63b7dSRichard Lowe Name vr = getvar(virtual_root);
128610d63b7dSRichard Lowe int length;
128710d63b7dSRichard Lowe wchar_t *new_value;
128810d63b7dSRichard Lowe wchar_t *old_vr;
128910d63b7dSRichard Lowe Boolean new_value_allocated = false;
129010d63b7dSRichard Lowe
129110d63b7dSRichard Lowe Wstring ha_str(ha);
129210d63b7dSRichard Lowe Wstring ta_str(ta);
129310d63b7dSRichard Lowe Wstring vr_str(vr);
129410d63b7dSRichard Lowe
129510d63b7dSRichard Lowe wchar_t * wcb_ha = ha_str.get_string();
129610d63b7dSRichard Lowe wchar_t * wcb_ta = ta_str.get_string();
129710d63b7dSRichard Lowe wchar_t * wcb_vr = vr_str.get_string();
129810d63b7dSRichard Lowe
129910d63b7dSRichard Lowe length = 32 +
130010d63b7dSRichard Lowe wcslen(wcb_ha) +
130110d63b7dSRichard Lowe wcslen(wcb_ta) +
130210d63b7dSRichard Lowe wcslen(wcb_vr);
130310d63b7dSRichard Lowe old_vr = wcb_vr;
130410d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "/usr/arch/");
130510d63b7dSRichard Lowe if (IS_WEQUALN(old_vr,
130610d63b7dSRichard Lowe wcs_buffer,
130710d63b7dSRichard Lowe wcslen(wcs_buffer))) {
130810d63b7dSRichard Lowe old_vr = (wchar_t *) wcschr(old_vr, (int) colon_char) + 1;
130910d63b7dSRichard Lowe }
131010d63b7dSRichard Lowe if ( (ha == ta) || (wcslen(wcb_ta) == 0) ) {
131110d63b7dSRichard Lowe new_value = old_vr;
131210d63b7dSRichard Lowe } else {
131310d63b7dSRichard Lowe new_value = ALLOC_WC(length);
131410d63b7dSRichard Lowe new_value_allocated = true;
131510d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, old_vr);
1316*e7afc443SToomas Soome (void) swprintf(new_value, length * SIZEOFWCHAR_T,
131710d63b7dSRichard Lowe L"/usr/arch/%s/%s:%s",
131810d63b7dSRichard Lowe ha->string_mb + 1,
131910d63b7dSRichard Lowe ta->string_mb + 1,
132010d63b7dSRichard Lowe mbs_buffer);
132110d63b7dSRichard Lowe }
132210d63b7dSRichard Lowe if (new_value[0] != 0) {
132310d63b7dSRichard Lowe (void) setvar_daemon(virtual_root,
132410d63b7dSRichard Lowe GETNAME(new_value, FIND_LENGTH),
132510d63b7dSRichard Lowe false,
132610d63b7dSRichard Lowe no_daemon,
132710d63b7dSRichard Lowe true,
132810d63b7dSRichard Lowe debug_level);
132910d63b7dSRichard Lowe }
133010d63b7dSRichard Lowe if (new_value_allocated) {
133110d63b7dSRichard Lowe retmem(new_value);
133210d63b7dSRichard Lowe }
133310d63b7dSRichard Lowe }
133410d63b7dSRichard Lowe return macro;
133510d63b7dSRichard Lowe }
1336