* pt.c (tsubst_decl <FUNCTION_DECL>): Move var decls to
[official-gcc.git] / liboffloadmic / runtime / offload_env.cpp
blobd1f52f143422f2eb88c3798aba1b51d525205f56
1 /*
2 Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "offload_env.h"
32 #include <string.h>
33 #include <ctype.h>
34 #include "offload_util.h"
35 #include "liboffload_error_codes.h"
37 // for environment variables valid on all cards
38 const int MicEnvVar::any_card = -1;
40 MicEnvVar::~MicEnvVar()
42 for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
43 it = card_spec_list.begin();
44 it != card_spec_list.end(); it++) {
45 CardEnvVars *card_data = *it;
46 delete card_data;
50 MicEnvVar::VarValue::~VarValue()
52 free(env_var_value);
55 MicEnvVar::CardEnvVars::~CardEnvVars()
57 for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
58 it != env_vars.end(); it++) {
59 VarValue *var_value = *it;
60 delete var_value;
64 // Searching for card in "card_spec_list" list with the same "number"
66 MicEnvVar::CardEnvVars* MicEnvVar::get_card(int number)
68 if (number == any_card) {
69 return &common_vars;
71 for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
72 it = card_spec_list.begin();
73 it != card_spec_list.end(); it++) {
74 CardEnvVars *card_data = *it;
75 if (card_data->card_number == number) {
76 return card_data;
79 return NULL;
82 // Searching for environment variable in "env_var" list with the same name
84 MicEnvVar::VarValue* MicEnvVar::CardEnvVars::find_var(
85 char* env_var_name,
86 int env_var_name_length
89 for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
90 it != env_vars.end(); it++) {
91 VarValue *var_value = *it;
92 if (var_value->length == env_var_name_length &&
93 !strncmp(var_value->env_var, env_var_name,
94 env_var_name_length)) {
95 return var_value;
98 return NULL;
101 void MicEnvVar::analyze_env_var(char *env_var_string)
103 char *env_var_name;
104 char *env_var_def;
105 int card_number;
106 int env_var_name_length;
107 MicEnvVarKind env_var_kind;
109 env_var_kind = get_env_var_kind(env_var_string,
110 &card_number,
111 &env_var_name,
112 &env_var_name_length,
113 &env_var_def);
114 switch (env_var_kind) {
115 case c_mic_var:
116 case c_mic_card_var:
117 add_env_var(card_number,
118 env_var_name,
119 env_var_name_length,
120 env_var_def);
121 break;
122 case c_mic_card_env:
123 mic_parse_env_var_list(card_number, env_var_def);
124 break;
125 case c_no_mic:
126 default:
127 break;
131 void MicEnvVar::add_env_var(
132 int card_number,
133 char *env_var_name,
134 int env_var_name_length,
135 char *env_var_def
138 VarValue *var;
139 CardEnvVars *card;
141 // The case corresponds to common env var definition of kind
142 // <mic-prefix>_<var>
143 if (card_number == any_card) {
144 card = &common_vars;
146 else {
147 card = get_card(card_number);
148 if (!card) {
149 // definition for new card occurred
150 card = new CardEnvVars(card_number);
151 card_spec_list.push_back(card);
155 var = card->find_var(env_var_name, env_var_name_length);
156 if (!var) {
157 // put new env var definition in "env_var" list
158 var = new VarValue(env_var_name, env_var_name_length, env_var_def);
159 card->env_vars.push_back(var);
163 // The routine analyses string pointed by "env_var_string" argument
164 // according to the following syntax:
166 // Specification of prefix for MIC environment variables
167 // MIC_ENV_PREFIX=<mic-prefix>
169 // Setting single MIC environment variable
170 // <mic-prefix>_<var>=<value>
171 // <mic-prefix>_<card-number>_<var>=<value>
173 // Setting multiple MIC environment variables
174 // <mic-prefix>_<card-number>_ENV=<env-vars>
176 MicEnvVarKind MicEnvVar::get_env_var_kind(
177 char *env_var_string,
178 int *card_number,
179 char **env_var_name,
180 int *env_var_name_length,
181 char **env_var_def
184 int len = strlen(prefix);
185 char *c = env_var_string;
186 int num = 0;
187 bool card_is_set = false;
189 if (strncmp(c, prefix, len) != 0 || c[len] != '_') {
190 return c_no_mic;
192 c += len + 1;
194 *card_number = any_card;
195 if (isdigit(*c)) {
196 while (isdigit (*c)) {
197 num = (*c++ - '0') + (num * 10);
199 if (*c != '_') {
200 return c_no_mic;
202 c++;
203 *card_number = num;
204 card_is_set = true;
206 if (!isalpha(*c)) {
207 return c_no_mic;
209 *env_var_name = *env_var_def = c;
210 if (strncmp(c, "ENV=", 4) == 0) {
211 if (!card_is_set) {
212 *env_var_name_length = 3;
213 *env_var_name = *env_var_def = c;
214 *env_var_def = strdup(*env_var_def);
215 if (*env_var_def == NULL)
216 LIBOFFLOAD_ERROR(c_malloc);
217 return c_mic_var;
219 *env_var_def = c + strlen("ENV=");
220 *env_var_def = strdup(*env_var_def);
221 if (*env_var_def == NULL)
222 LIBOFFLOAD_ERROR(c_malloc);
223 return c_mic_card_env;
225 if (isalpha(*c)) {
226 *env_var_name_length = 0;
227 while (isalnum(*c) || *c == '_') {
228 c++;
229 (*env_var_name_length)++;
232 if (*c != '=') {
233 return c_no_mic;
235 *env_var_def = strdup(*env_var_def);
236 if (*env_var_def == NULL)
237 LIBOFFLOAD_ERROR(c_malloc);
238 return card_is_set? c_mic_card_var : c_mic_var;
241 // analysing <env-vars> in form:
242 // <mic-prefix>_<card-number>_ENV=<env-vars>
243 // where:
245 // <env-vars>:
246 // <env-var>
247 // <env-vars> | <env-var>
249 // <env-var>:
250 // variable=value
251 // variable="value"
252 // variable=
254 void MicEnvVar::mic_parse_env_var_list(
255 int card_number, char *env_vars_def_list)
257 char *c = env_vars_def_list;
258 char *env_var_name;
259 int env_var_name_length;
260 char *env_var_def;
261 bool var_is_quoted;
263 if (*c == '"') {
264 c++;
266 while (*c != 0) {
267 var_is_quoted = false;
268 env_var_name = c;
269 env_var_name_length = 0;
270 if (isalpha(*c)) {
271 while (isalnum(*c) || *c == '_') {
272 c++;
273 env_var_name_length++;
276 else {
277 LIBOFFLOAD_ERROR(c_mic_parse_env_var_list1);
278 return;
280 if (*c != '=') {
281 LIBOFFLOAD_ERROR(c_mic_parse_env_var_list2);
282 return;
284 c++;
286 if (*c == '"') {
287 var_is_quoted = true;
288 c++;
290 // Environment variable values that contain | will need to be escaped.
291 while (*c != 0 && *c != '|' &&
292 (!var_is_quoted || *c != '"'))
294 // skip escaped symbol
295 if (*c == '\\') {
296 c++;
298 c++;
300 if (var_is_quoted) {
301 c++; // for "
302 while (*c != 0 && *c != '|') {
303 c++;
307 int sz = c - env_var_name;
308 env_var_def = (char*)malloc(sz);
309 if (env_var_def == NULL)
310 LIBOFFLOAD_ERROR(c_malloc);
311 memcpy(env_var_def, env_var_name, sz);
312 env_var_def[sz] = 0;
314 if (*c == '|') {
315 c++;
316 while (*c != 0 && *c == ' ') {
317 c++;
320 add_env_var(card_number,
321 env_var_name,
322 env_var_name_length,
323 env_var_def);
327 // Collect all definitions for the card with number "card_num".
328 // The returned result is vector of string pointers defining one
329 // environment variable. The vector is terminated by NULL pointer.
330 // In the beginning of the vector there are env vars defined as
331 // <mic-prefix>_<card-number>_<var>=<value>
332 // or
333 // <mic-prefix>_<card-number>_ENV=<env-vars>
334 // where <card-number> is equal to "card_num"
335 // They are followed by definitions valid for any card
336 // and absent in previous definitions.
338 char** MicEnvVar::create_environ_for_card(int card_num)
340 VarValue *var_value;
341 VarValue *var_value_find;
342 CardEnvVars *card_data = get_card(card_num);
343 CardEnvVars *card_data_common;
344 std::list<char*> new_env;
345 char **rez;
347 if (!prefix) {
348 return NULL;
350 // There is no personel env var definitions for the card with
351 // number "card_num"
352 if (!card_data) {
353 return create_environ_for_card(any_card);
356 for (std::list<MicEnvVar::VarValue*>::const_iterator
357 it = card_data->env_vars.begin();
358 it != card_data->env_vars.end(); it++) {
359 var_value = *it;
360 new_env.push_back(var_value->env_var_value);
363 if (card_num != any_card) {
364 card_data_common = get_card(any_card);
365 for (std::list<MicEnvVar::VarValue*>::const_iterator
366 it = card_data_common->env_vars.begin();
367 it != card_data_common->env_vars.end(); it++) {
368 var_value = *it;
369 var_value_find = card_data->find_var(var_value->env_var,
370 var_value->length);
371 if (!var_value_find) {
372 new_env.push_back(var_value->env_var_value);
377 int new_env_size = new_env.size();
378 rez = (char**) malloc((new_env_size + 1) * sizeof(char*));
379 if (rez == NULL)
380 LIBOFFLOAD_ERROR(c_malloc);
381 std::copy(new_env.begin(), new_env.end(), rez);
382 rez[new_env_size] = 0;
383 return rez;