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 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 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 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 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 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 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 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 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