00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #include "lib_phase_dir.h"
00049 #include "lang_defs.h"
00050 #include "file_utils.h"
00051 #include "string_utils.h"
00052 #include "errors.h"
00053 #if defined(_WIN32)
00054 #include <ctype.h>
00055 #endif
00056
00057 char *ldpath_for_pixie = NULL;
00058
00059
00060
00061
00062
00063
00064 #define MAX_LANG_NAMES 5
00065 typedef struct lang_struct {
00066 char key;
00067 mask_t mask;
00068 char *name[MAX_LANG_NAMES];
00069 } lang_info_t;
00070
00071 static lang_info_t language_info[] = {
00072 {'N', 0x00000000, {""}},
00073 {'A', 0x0fffffff, {""}},
00074 {'p', 0x00000001, {"cpp"}},
00075 #ifdef PSC_TO_OPEN64
00076 #if defined(TARG_NVISA)
00077 {'c', 0x00000002, {"cc", "opencc", OPEN64_NAME_PREFIX "cc", OPEN64_TARGET "-" OPEN64_NAME_PREFIX "cc", "c89"}},
00078 {'C', 0x00000004, {"CC", "openCC", OPEN64_NAME_PREFIX "CC", OPEN64_NAME_PREFIX "++"}},
00079 #else
00080 {'c', 0x00000002, {"cc", OPEN64_NAME_PREFIX "cc", OPEN64_TARGET "-" OPEN64_NAME_PREFIX "cc","gcc","c89"}},
00081 {'C', 0x00000004, {"CC", OPEN64_NAME_PREFIX "CC", OPEN64_NAME_PREFIX "++","g++"}},
00082 #endif
00083 {'f', 0x00000008, {"f77", OPEN64_NAME_PREFIX "f77","gf77","fort77"}},
00084 {'F', 0x00000010, {"f90", OPEN64_NAME_PREFIX "f95"}},
00085 {'a', 0x00000020, {"as", OPEN64_NAME_PREFIX "as","gas"}},
00086 {'l', 0x00000040, {"ld", OPEN64_NAME_PREFIX "ld"}},
00087 #endif
00088 {'I', 0x80000000, {"int"}},
00089 };
00090
00091 typedef struct phase_struct {
00092 char key;
00093 mask_t mask;
00094 char *name;
00095 char *dir;
00096 boolean set_ld_library_path;
00097
00098 boolean find_dir_by_path;
00099 } phase_info_t;
00100
00101 static phase_info_t phase_info[] = {
00102 {'N', 0x0000000000000000LL, "", "", FALSE, FALSE},
00103 {'A', 0x0fffffffffffffffLL, "", "", FALSE, FALSE},
00104
00105 {'m', 0x0000000000000008LL, "m4", BINPATH, FALSE, FALSE},
00106 {'r', 0x0000000000000001LL, "ratfor",BINPATH, FALSE, FALSE},
00107
00108 {'p', 0x0000000000000010LL, "cpp", PHASEPATH, FALSE, FALSE},
00109
00110
00111
00112 #ifndef TARG_SL
00113 {'p', 0x0000000000000020LL, NAMEPREFIX "gcc", ALTBINPATH, FALSE, TRUE},
00114 {'p', 0x0000000000000040LL, NAMEPREFIX "g++", ALTBINPATH, FALSE, TRUE},
00115 #else
00116 {'p', 0x0000000000000020LL, NAMEPREFIX "gcc", ALTBINPATH, FALSE, FALSE},
00117 {'p', 0x0000000000000040LL, NAMEPREFIX "g++", ALTBINPATH, FALSE, FALSE},
00118 #endif
00119 {'p', 0x0000000000000080LL, "fec", PHASEPATH, FALSE, FALSE},
00120 {'p', 0x0000000000000100LL, "cpp", PHASEPATH, FALSE, FALSE},
00121 {'p', 0x0000000000000200LL, "mfef77",PHASEPATH, FALSE, FALSE},
00122 {'p', 0x0000000000000400LL, "ftpp" ,PHASEPATH, FALSE, FALSE},
00123 #ifdef KEY // bug 9058
00124 {'p', 0x0000000000000800LL, "coco" ,PHASEPATH, FALSE, FALSE},
00125 #endif
00126
00127 {'p', 0x0000000000000ff0LL, "", "", FALSE, FALSE},
00128
00129 {'K', 0x0000000000001000LL, "pfa", PHASEPATH, FALSE, FALSE},
00130 {'K', 0x0000000000002000LL, "pca", PHASEPATH, FALSE, FALSE},
00131 {'M', 0x0000000000008000LL, "mpc", PHASEPATH, FALSE, FALSE},
00132
00133
00134 {'K', 0x0000000000007000LL, "", "", FALSE, FALSE},
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 {'f', 0x0000000000010000LL, "mfef77",PHASEPATH, FALSE, FALSE},
00148 {'f', 0x0000000000020000LL, "mfef77",PHASEPATH, FALSE, FALSE},
00149 {'f', 0x0000000000040000LL, "mfef95",PHASEPATH, FALSE, FALSE},
00150 {'f', 0x0000000000080000LL, "mfef95",PHASEPATH, FALSE, FALSE},
00151 {'f', 0x0000000000100000LL, "gfec",PHASEPATH, TRUE , FALSE},
00152 {'f', 0x0000000000200000LL, "gfecc",PHASEPATH, TRUE , FALSE},
00153 #ifdef KEY
00154 {'f', 0x0000000000400000LL, "cc1" ,PHASEPATH, TRUE , FALSE},
00155 {'f', 0x0000000000800000LL, "cc1plus",PHASEPATH, TRUE , FALSE},
00156 {'w', 0x0000000001000000LL, "wgen",PHASEPATH, TRUE , FALSE},
00157 #endif
00158
00159
00160 {'f', 0x0000000000ff0000LL, "", "", FALSE, FALSE},
00161 {'F', 0x00000000000f0000LL, "", "", FALSE, FALSE},
00162 {'C', 0x0000000000f00000LL, "", "", FALSE, FALSE},
00163
00164 {'X', 0x0000000002000000LL, "ftnlx", PHASEPATH, FALSE, FALSE},
00165
00166 {'i', 0x0000000010000000LL, "inline",PHASEPATH, TRUE, FALSE},
00167 {'i', 0x0000000020000000LL, "ipl", PHASEPATH, TRUE, FALSE},
00168 {'i', 0x00000000f0000000LL, "", "", TRUE, FALSE},
00169
00170 {'b', 0x0000000100000000LL, "be", PHASEPATH, TRUE, FALSE},
00171 #if defined(TARG_NVISA)
00172 {'b', 0x0000000200000000LL, "bec", PHASEPATH, TRUE, FALSE},
00173 {'b', 0x0000000f00000000LL, "", "", TRUE, FALSE},
00174 #endif
00175
00176
00177 {'a', 0x0000001000000000LL, "asm", PHASEPATH, FALSE, FALSE},
00178 #if defined(TARG_X8664) || ( defined(KEY) && !defined(CROSS_COMPILATION))
00179
00180 {'a', 0x0000002000000000LL, NAMEPREFIX "gcc", BINPATH, FALSE, TRUE},
00181 #elif defined(TARG_SL)
00182 {'a', 0x0000002000000000LL, NAMEPREFIX "as", BINPATH, FALSE, FALSE},
00183 #else
00184 {'a', 0x0000002000000000LL, "as", BINPATH, FALSE, TRUE},
00185 #endif
00186 {'a', 0x0000003000000000LL, "", "", FALSE, FALSE},
00187
00188 {'d', 0x0000008000000000LL, "dsm_prelink", PHASEPATH,FALSE, FALSE},
00189 #ifndef TARG_SL
00190 {'j', 0x0000010000000000LL, "ipa_link", GNUPHASEPATH, TRUE, FALSE},
00191 #else
00192 {'j', 0x0000010000000000LL, "ipa_link", BINPATH, TRUE, FALSE},
00193 #endif
00194 {'l', 0x0000020000000000LL, "ld", BINPATH, TRUE, TRUE},
00195 #if defined(TARG_X8664) || ( defined(KEY) && !defined(CROSS_COMPILATION))
00196
00197 {'l', 0x0000040000000000LL, NAMEPREFIX "gcc", BINPATH, FALSE, TRUE},
00198 {'l', 0x0000080000000000LL, NAMEPREFIX "g++", BINPATH, FALSE, TRUE},
00199 #elif defined(TARG_SL)
00200 {'l', 0x0000040000000000LL, NAMEPREFIX "ld", BINPATH, FALSE, FALSE},
00201 {'l', 0x0000080000000000LL, NAMEPREFIX "ld", BINPATH, FALSE, FALSE},
00202 #else
00203 {'l', 0x0000040000000000LL, "ld", BINPATH, FALSE, TRUE},
00204 {'l', 0x0000080000000000LL, "ld", BINPATH, FALSE, TRUE},
00205 #endif
00206 {'l', 0x01000f0000000000LL, "", "", TRUE, FALSE},
00207 {'c', 0x0000100000000000LL, "cord", BINPATH, FALSE, FALSE},
00208 {'x', 0x0000200000000000LL, "pixie", BINPATH, FALSE, FALSE},
00209 {'x', 0x0000400000000000LL, "prof", BINPATH, FALSE, FALSE},
00210
00211 {'R', 0x0001000000000000LL, "ar", BINPATH, FALSE, FALSE},
00212
00213 {'S', 0x0010000000000000LL, "crt", LIBPATH, FALSE, FALSE},
00214 {'I', 0x0020000000000000LL, "inc", "/include", FALSE, FALSE},
00215 {'L', 0x0040000000000000LL, "lib", LIBPATH, FALSE, FALSE},
00216 {'L', 0x0080000000000000LL, "alib", ALTLIBPATH, FALSE, FALSE},
00217 #ifdef TARG_SL
00218 {'S', 0x0010000000000000LL, "crt", "/usr/libsl2", FALSE, FALSE},
00219 #endif
00220 };
00221 mask_t OPEN64_PHASE_MASK=
00222 0x0000f19fffffff90LL;
00223 mask_t PHASE_MASK=
00224 0x000fffffffffffffLL;
00225 mask_t LIB_MASK =
00226 0xfff0000000000000LL;
00227
00228 #define MAX_SUFFIXES 8
00229 typedef struct source_struct {
00230 char *suffix[MAX_SUFFIXES];
00231 } source_info_t;
00232
00233 static source_info_t source_info[] = {
00234 #ifdef KEY // If no suffix, treat as linker object. Bug 9430.
00235 {},
00236 #else
00237 {""},
00238 #endif
00239 {"c"},
00240 {"C","CC","CPP","CXX","cc","cpp","cxx","c++"},
00241 {"f","for"},
00242 {"F","FOR"},
00243 {"f90","f95"},
00244 {"F90","F95"},
00245 {"r"},
00246 {"i"},
00247 {"ii"},
00248 #if defined(TARG_NVISA)
00249 {"ptx"},
00250 #else
00251 {"s"},
00252 #endif
00253 {"S"},
00254 #if defined(TARG_NVISA)
00255
00256 {"BI"},
00257 #else
00258 {"I"},
00259 #endif
00260 {"B"},
00261 {"N"},
00262 #if defined(TARG_NVISA)
00263
00264 {"W"},
00265 #else
00266 {"O"},
00267 #endif
00268 {"o"},
00269 };
00270
00271 languages_t invoked_lang;
00272 languages_t source_lang;
00273 phases_t first_phase = P_any_cpp;
00274 phases_t last_phase = P_cord;
00275 phases_t remember_last_phase = P_NONE;
00276 phases_t current_phase = P_NONE;
00277 source_kind_t source_kind = S_NONE;
00278 source_kind_t default_source_kind = S_NONE;
00279 boolean ignore_suffix = FALSE;
00280
00281
00282
00283 phases_t
00284 earliest_phase (phases_t a, phases_t b)
00285 {
00286 if (b < a)
00287 return b;
00288 else
00289 return a;
00290 }
00291
00292 languages_t
00293 get_language (char key)
00294 {
00295 languages_t i;
00296 for (i = L_NONE; i < L_LAST; i++) {
00297 if (language_info[i].key == key) {
00298 return i;
00299 }
00300 }
00301 internal_error("bad language key (%c)", key);
00302 return L_NONE;
00303 }
00304
00305 mask_t
00306 get_language_mask (languages_t i)
00307 {
00308 return language_info[i].mask;
00309 }
00310
00311 phases_t
00312 get_phase (char key)
00313 {
00314 int i;
00315 buffer_t buf;
00316
00317 for (i = P_LAST-1; i >= (int) P_NONE; i--) {
00318 if (phase_info[i].key == key) {
00319 return (phases_t) i;
00320 }
00321 }
00322 sprintf(buf, "phase key (%c) ", key);
00323 warn_no_longer_supported(buf);
00324 return P_NONE;
00325 }
00326
00327 mask_t
00328 get_phase_mask (phases_t i)
00329 {
00330 return phase_info[i].mask;
00331 }
00332
00333
00334 boolean
00335 is_matching_language (mask_t lang_mask, languages_t l)
00336 {
00337 return ((lang_mask & language_info[l].mask) != 0);
00338 }
00339
00340
00341 boolean
00342 is_matching_phase (mask_t phase_mask, phases_t p)
00343 {
00344 if (p == P_cppf_fe) {
00345 return (is_matching_phase (phase_mask, P_f_cpp)
00346 || is_matching_phase (phase_mask, P_f_fe) );
00347 } else {
00348 return ((phase_mask & phase_info[p].mask) != 0);
00349 }
00350 }
00351
00352
00353 void
00354 set_phase_dir (mask_t mask, char *path)
00355 {
00356
00357 phases_t i;
00358 for (i = P_NONE; i < P_LAST; i++) {
00359 if ((phase_info[i].mask & mask) != 0) {
00360 phase_info[i].dir = string_copy(path);
00361 phase_info[i].find_dir_by_path = FALSE;
00362 if (i == P_ld)
00363 ldpath_for_pixie = string_copy(path);
00364 }
00365 }
00366 }
00367
00368
00369
00370 void
00371 substitute_phase_dirs (char *orig_dir, char *new_dir, char *leaf)
00372 {
00373 phases_t i;
00374 char *odir;
00375 char *ndir;
00376
00377 ndir = concat_strings (new_dir, leaf);
00378 if (! is_directory (ndir))
00379 return;
00380
00381 for (i = P_NONE; i < P_LAST; i++) {
00382 if (strcmp(orig_dir, phase_info[i].dir) == 0) {
00383 phase_info[i].dir = ndir;
00384 if (i == P_ld)
00385 ldpath_for_pixie = ndir;
00386 }
00387 }
00388 }
00389
00390
00391 void
00392 prefix_all_phase_dirs (mask_t mask, char *path)
00393 {
00394 phases_t i;
00395 for (i = P_NONE; i < P_LAST; i++) {
00396 if ((phase_info[i].mask & mask) != 0)
00397 phase_info[i].dir =
00398 concat_strings(path, phase_info[i].dir);
00399 }
00400 }
00401
00402
00403 void
00404 append_all_phase_dirs (mask_t mask, char *path)
00405 {
00406 phases_t i;
00407 for (i = P_NONE; i < P_LAST; i++) {
00408 if ((phase_info[i].mask & mask) != 0) {
00409
00410 if (strcmp(phase_info[i].dir + strlen(phase_info[i].dir) -
00411 strlen(PHASEPATH), PHASEPATH) == 0)
00412 {
00413 phase_info[i].dir =
00414 concat_strings(phase_info[i].dir, path);
00415 }
00416 }
00417 }
00418 }
00419
00420
00421 void
00422 append_phase_dir (phases_t index, char *path)
00423 {
00424 phase_info[index].dir = concat_strings (phase_info[index].dir, path);
00425 }
00426
00427 #if defined(__linux__) || defined(__APPLE__)
00428
00429 char *
00430 read_cmd_out(char *cmd, char *out_buf)
00431 {
00432 char buf[PATH_BUF_LEN];
00433 FILE* fp;
00434 int tail;
00435
00436 if((fp = popen(cmd, "r")) == NULL)
00437 return NULL;
00438
00439 out_buf[0] = '\0';
00440 while(fgets(buf, PATH_BUF_LEN, fp) != NULL)
00441 strcat(out_buf, buf);
00442
00443 pclose(fp);
00444
00445 tail = strlen(out_buf);
00446 if(out_buf[tail - 1] == '\n')
00447 out_buf[tail - 1] = '\0';
00448
00449 return out_buf;
00450 }
00451 #endif
00452
00453
00454 char *
00455 get_phase_dir (phases_t index)
00456 {
00457 #if defined(__linux__) || defined(__APPLE__)
00458 if (index == P_ipa_link) {
00459 return phase_info[index].dir;
00460 }
00461 else if(phase_info[index].find_dir_by_path) {
00462 char cmd[PATH_BUF_LEN];
00463 char result[PATH_BUF_LEN];
00464
00465 sprintf(cmd, "dirname \"`which %s`\"", phase_info[index].name);
00466 if(read_cmd_out(cmd, result) == NULL)
00467 return phase_info[index].dir;
00468 return string_copy(result);
00469 }
00470 #endif
00471 return phase_info[index].dir;
00472 }
00473
00474 void
00475 get_phases_real_path (void) {
00476 #ifdef PATH_MAX
00477 char pathstr[PATH_MAX];
00478 #else
00479 char pathstr[4096];
00480 #endif
00481 phases_t i;
00482 for (i = P_NONE; i < P_LAST; i++) {
00483 if (!phase_info[i].dir) { continue; }
00484 char* p = realpath (phase_info[i].dir, pathstr);
00485 if (p && strcmp (p, phase_info[i].dir)) {
00486 phase_info[i].dir = string_copy (p);
00487 }
00488 }
00489 }
00490
00491
00492 char *
00493 get_phase_ld_library_path (phases_t index)
00494 {
00495 if (phase_info[index].set_ld_library_path)
00496 return phase_info[index].dir;
00497 else
00498 return 0;
00499 }
00500
00501
00502 char *
00503 get_phase_name (phases_t index)
00504 {
00505 #if defined(_WIN32)
00506 return concat_strings(phase_info[index].name, ".exe");
00507 #else
00508 return phase_info[index].name;
00509 #endif
00510 }
00511
00512
00513 void
00514 set_phase_name (phases_t index, char *s)
00515 {
00516 phase_info[index].name = s;
00517 }
00518
00519
00520 char *
00521 get_full_phase_name (phases_t index)
00522 {
00523 buffer_t tmp;
00524 strcpy(tmp, get_phase_dir(index));
00525 strcat(tmp, "/");
00526 return concat_strings (tmp, get_phase_name(index));
00527 }
00528
00529
00530 char *
00531 get_lang_name (languages_t index)
00532 {
00533 #if defined(_WIN32)
00534 return concat_strings(language_info[index].name[0], ".exe");
00535 #else
00536 return language_info[index].name[0];
00537 #endif
00538 }
00539
00540 languages_t
00541 get_named_language (char *name)
00542 {
00543 languages_t i, lang = L_NONE;
00544 int j;
00545 char *p;
00546 char *nomen = strdup(name);
00547
00548 #ifdef PSC_TO_OPEN64
00549 if ((p = strstr(nomen, "-" OPEN64_FULL_VERSION))) {
00550 #endif
00551 *p = '\0';
00552 name = nomen;
00553 #ifdef PSC_TO_OPEN64
00554 }
00555 #endif
00556
00557 #if defined(_WIN32)
00558
00559
00560
00561 int name_len = strlen(name);
00562 char *new_name = (char *) malloc(name_len + 5);
00563 for (j = 0; j < name_len; j++)
00564 new_name[j] = tolower(name[j]);
00565 new_name[name_len] = 0;
00566 name = new_name;
00567
00568
00569 if (strcmp(name + name_len - 4, ".exe") == 0) {
00570 name[name_len - 4] = NIL;
00571 }
00572 #endif
00573
00574 for (i = L_NONE; i < L_LAST; i++) {
00575 for (j = 0; j < MAX_LANG_NAMES && language_info[i].name[j] != NULL; j++) {
00576
00577 if (*language_info[i].name[j] == NIL)
00578 continue;
00579
00580 p = name+strlen(name)-strlen(language_info[i].name[j]);
00581 if (strcmp(language_info[i].name[j], p) == 0) {
00582
00583 if (i == L_as)
00584 last_phase = P_any_as;
00585 lang = i;
00586 goto done;
00587 }
00588 }
00589 }
00590 internal_error("unknown language (%s)", name);
00591
00592 done:
00593 free(nomen);
00594 #if defined(_WIN32)
00595 free(new_name);
00596 #endif
00597 return lang;
00598 }
00599
00600 source_kind_t
00601 get_source_kind_from_suffix (char *suf)
00602 {
00603 source_kind_t i;
00604 int j;
00605 if (suf == NULL) return S_o;
00606 for (i = S_NONE; i < S_LAST; i++) {
00607 for (j = 0; j < MAX_SUFFIXES && source_info[i].suffix[j] != NULL; j++) {
00608 if (strcmp(source_info[i].suffix[j], suf) == 0) {
00609 return i;
00610 }
00611 }
00612 }
00613
00614 return S_o;
00615 }
00616
00617 source_kind_t
00618 get_source_kind (char *src)
00619 {
00620 if (ignore_suffix) {
00621 if (default_source_kind != S_NONE)
00622 return default_source_kind;
00623 else {
00624
00625 switch (invoked_lang) {
00626 case L_cc: return S_c;
00627 case L_CC: return S_C;
00628 case L_f77: return S_f;
00629 case L_f90: return S_f90;
00630 case L_as: return S_s;
00631 }
00632 }
00633 }
00634 return get_source_kind_from_suffix (get_suffix(src));
00635 }
00636
00637 char *
00638 get_suffix_string (source_kind_t sk)
00639 {
00640 return source_info[sk].suffix[0];
00641 }
00642
00643
00644
00645 boolean
00646 is_object_source_kind(char *src)
00647 {
00648 int j;
00649 char *suf = get_suffix(src);
00650 if (suf == NULL) return FALSE;
00651 for (j = 0; j < MAX_SUFFIXES && source_info[S_o].suffix[j] != NULL; j++) {
00652 if (strcmp(source_info[S_o].suffix[j], suf) == 0) {
00653 return TRUE;
00654 }
00655
00656 }
00657 return FALSE;
00658 }
00659
00660
00661
00662 languages_t
00663 get_source_lang (source_kind_t sk)
00664 {
00665 switch (sk) {
00666 case S_i:
00667 case S_B:
00668 case S_I:
00669 case S_N:
00670 case S_O:
00671
00672 return invoked_lang;
00673 case S_ii:
00674 return L_CC;
00675 case S_c:
00676 if (invoked_lang == L_CC) return L_CC;
00677 else return L_cc;
00678 case S_C:
00679 return L_CC;
00680 case S_s:
00681 case S_S:
00682 return L_as;
00683 case S_r:
00684 return L_f77;
00685 case S_f:
00686 case S_F:
00687 case S_f90:
00688 case S_F90:
00689
00690 return L_f90;
00691 case S_o:
00692 return invoked_lang;
00693 }
00694 return L_NONE;
00695 }