1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * macro.cc 28 * 29 * Handle expansion of make macros 30 */ 31 32 /* 33 * Included files 34 */ 35 #ifdef DISTRIBUTED 36 #include <avo/strings.h> /* AVO_STRDUP() */ 37 #include <dm/Avo_DoJobMsg.h> 38 #endif 39 #include <mk/defs.h> 40 #include <mksh/macro.h> /* getvar(), expand_value() */ 41 #include <mksh/misc.h> /* getmem() */ 42 43 /* 44 * Defined macros 45 */ 46 47 /* 48 * typedefs & structs 49 */ 50 51 /* 52 * Static variables 53 */ 54 55 /* 56 * File table of contents 57 */ 58 59 void 60 setvar_append(register Name name, register Name value) 61 { 62 register Property macro_apx = get_prop(name->prop, macro_append_prop); 63 register Property macro = get_prop(name->prop, macro_prop); 64 int length; 65 String_rec destination; 66 wchar_t buffer[STRING_BUFFER_LENGTH]; 67 register Chain chain; 68 Name val = NULL; 69 70 if(macro_apx == NULL) { 71 macro_apx = append_prop(name, macro_append_prop); 72 if(macro != NULL) { 73 macro_apx->body.macro_appendix.value = macro->body.macro.value; 74 } 75 } 76 77 val = macro_apx->body.macro_appendix.value_to_append; 78 79 INIT_STRING_FROM_STACK(destination, buffer); 80 buffer[0] = 0; 81 if (val != NULL) { 82 APPEND_NAME(val, 83 &destination, 84 (int) val->hash.length); 85 if (value != NULL) { 86 MBTOWC(wcs_buffer, " "); 87 append_char(wcs_buffer[0], &destination); 88 } 89 } 90 if (value != NULL) { 91 APPEND_NAME(value, 92 &destination, 93 (int) value->hash.length); 94 } 95 value = GETNAME(destination.buffer.start, FIND_LENGTH); 96 if (destination.free_after_use) { 97 retmem(destination.buffer.start); 98 } 99 macro_apx->body.macro_appendix.value_to_append = value; 100 101 SETVAR(name, empty_name, true); 102 } 103 104 /* 105 * setvar_envvar() 106 * 107 * This function scans the list of environment variables that have 108 * dynamic values and sets them. 109 * 110 * Parameters: 111 * 112 * Global variables used: 113 * envvar A list of environment vars with $ in value 114 */ 115 void 116 #ifdef DISTRIBUTED 117 setvar_envvar(Avo_DoJobMsg *dmake_job_msg) 118 #else 119 setvar_envvar(void) 120 #endif 121 { 122 wchar_t buffer[STRING_BUFFER_LENGTH]; 123 int length; 124 #ifdef DISTRIBUTED 125 Property macro; 126 #endif 127 register char *mbs, *tmp_mbs_buffer = NULL; 128 register char *env, *tmp_mbs_buffer2 = NULL; 129 Envvar p; 130 String_rec value; 131 132 for (p = envvar; p != NULL; p = p->next) { 133 if (p->already_put 134 #ifdef DISTRIBUTED 135 && !dmake_job_msg 136 #endif 137 ) { 138 continue; 139 } 140 INIT_STRING_FROM_STACK(value, buffer); 141 expand_value(p->value, &value, false); 142 if ((length = wslen(value.buffer.start)) >= MAXPATHLEN) { 143 mbs = tmp_mbs_buffer = getmem((length + 1) * MB_LEN_MAX); 144 (void) wcstombs(mbs, 145 value.buffer.start, 146 (length + 1) * MB_LEN_MAX); 147 } else { 148 mbs = mbs_buffer; 149 WCSTOMBS(mbs, value.buffer.start); 150 } 151 length = 2 + strlen(p->name->string_mb) + strlen(mbs); 152 if (!p->already_put || length > (MAXPATHLEN * MB_LEN_MAX)) { 153 env = tmp_mbs_buffer2 = getmem(length); 154 } else { 155 env = mbs_buffer2; 156 } 157 (void) sprintf(env, 158 "%s=%s", 159 p->name->string_mb, 160 mbs); 161 if (!p->already_put) { 162 (void) putenv(env); 163 p->already_put = true; 164 if (p->env_string) { 165 retmem_mb(p->env_string); 166 } 167 p->env_string = env; 168 tmp_mbs_buffer2 = NULL; // We should not return this memory now 169 } 170 #ifdef DISTRIBUTED 171 if (dmake_job_msg) { 172 dmake_job_msg->appendVar(env); 173 } 174 #endif 175 if (tmp_mbs_buffer2) { 176 retmem_mb(tmp_mbs_buffer2); 177 tmp_mbs_buffer2 = NULL; 178 } 179 if (tmp_mbs_buffer) { 180 retmem_mb(tmp_mbs_buffer); 181 tmp_mbs_buffer = NULL; 182 } 183 } 184 #ifdef DISTRIBUTED 185 /* Append SUNPRO_DEPENDENCIES to the dmake_job_msg. */ 186 if (keep_state && dmake_job_msg) { 187 macro = get_prop(sunpro_dependencies->prop, macro_prop); 188 length = 2 + 189 strlen(sunpro_dependencies->string_mb) + 190 strlen(macro->body.macro.value->string_mb); 191 if (length > (MAXPATHLEN * MB_LEN_MAX)) { 192 env = tmp_mbs_buffer2 = getmem(length); 193 } else { 194 env = mbs_buffer2; 195 } 196 (void) sprintf(env, 197 "%s=%s", 198 sunpro_dependencies->string_mb, 199 macro->body.macro.value->string_mb); 200 dmake_job_msg->appendVar(env); 201 if (tmp_mbs_buffer2) { 202 retmem_mb(tmp_mbs_buffer2); 203 tmp_mbs_buffer2 = NULL; 204 } 205 } 206 #endif 207 } 208 209