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 #include "xsb_config.h"
00026 #include "xsb_debug.h"
00027
00028 #ifdef WIN_NT
00029 #include <direct.h>
00030 #include <io.h>
00031 #else
00032 #include <unistd.h>
00033 #endif
00034
00035 #include <stdio.h>
00036 #include <errno.h>
00037 #include <string.h>
00038 #include <stdlib.h>
00039 #include <ctype.h>
00040 #include <sys/types.h>
00041 #include <sys/stat.h>
00042
00043 #include "wind2unix.h"
00044 #include "export.h"
00045
00046 #if (!defined(WIN_NT))
00047 #include <pwd.h>
00048 #endif
00049
00050 #include "setjmp_xsb.h"
00051 #include "auxlry.h"
00052 #include "context.h"
00053 #include "psc_xsb.h"
00054 #include "cell_xsb.h"
00055 #include "cinterf.h"
00056 #include "error_xsb.h"
00057 #include "flags_xsb.h"
00058 #include "extensions_xsb.h"
00059 #include "memory_xsb.h"
00060
00061
00062
00063 #define DDOT ".."
00064 #define DOT "."
00065
00066 extern char *user_home_gl;
00067
00068 static char *rectify_pathname(char *, char *);
00069 extern void transform_cygwin_pathname(char *);
00070
00071
00072
00073
00074 xsbBool is_absolute_filename(char *filename) {
00075
00076 #if defined(WIN_NT)
00077
00078
00079
00080 if ( (filename[0] == SLASH) ||
00081 (isalpha(filename[0]) && filename[1] == ':') ||
00082 (filename[0] == '/')
00083 )
00084 return TRUE;
00085 #else
00086 if (filename[0] == '/')
00087 return TRUE;
00088 #endif
00089
00090 return FALSE;
00091 }
00092
00093
00094
00095
00096
00097
00098 char *dirname_canonic(char *filename) {
00099 char canonicized[MAXPATHLEN];
00100 int retcode, len = strlen(filename);
00101 struct stat fileinfo;
00102 rectify_pathname(filename, canonicized);
00103 retcode = stat(canonicized, &fileinfo);
00104
00105
00106 if ((retcode==0) && S_ISDIR(fileinfo.st_mode)
00107 && (canonicized[len-1] != SLASH)) {
00108 canonicized[len] = SLASH;
00109 canonicized[len+1] = '\0';
00110 }
00111 return string_find(canonicized,1);
00112 }
00113
00114
00115 static void normalize_file_slashes(char *path) {
00116 int ANTISLASH = (SLASH == '/' ? '\\' : '/');
00117
00118 path = strchr(path,ANTISLASH);
00119 while (path != NULL) {
00120 *path = SLASH;
00121 path = strchr(path,ANTISLASH);
00122 }
00123 }
00124
00125
00126 char *tilde_expand_filename_norectify(char *filename, char *expanded) {
00127
00128 #if defined(WIN_NT)
00129 strcpy(expanded, filename);
00130 transform_cygwin_pathname(expanded);
00131 normalize_file_slashes(expanded);
00132 return expanded;
00133
00134 #else
00135 char *path_prefix;
00136
00137 char *path_suffix;
00138
00139 char username[MAXNAME];
00140 int username_len;
00141 struct passwd *pw_struct;
00142
00143 if (filename[0] != '~') {
00144 strcpy(expanded, filename);
00145 normalize_file_slashes(expanded);
00146 return expanded;
00147 }
00148 if (filename[1] == '/' || filename[1] == '\0') {
00149
00150
00151 path_prefix = user_home_gl;
00152 path_suffix = filename + 1;
00153 } else {
00154
00155
00156 path_prefix = path_suffix = filename + 1;
00157 while ( (*path_suffix != '\0') && (*path_suffix != '/') )
00158 path_suffix++;
00159 username_len = path_suffix - path_prefix;
00160 memmove(username, path_prefix, username_len);
00161 username[username_len] = '\0';
00162
00163 pw_struct = (struct passwd *) getpwnam(username);
00164 if (!pw_struct) {
00165
00166
00167 char message[100];
00168 sprintf(message, "[PATHNAME] `%s': unknown user\n", username);
00169 xsb_abort(message);
00170 } else
00171 path_prefix = pw_struct -> pw_dir;
00172 }
00173
00174 sprintf(expanded, "%s%c%s", path_prefix, SLASH, path_suffix);
00175 normalize_file_slashes(expanded);
00176 return expanded;
00177 #endif
00178 }
00179
00180
00181
00182
00183
00184
00185 char *tilde_expand_filename(char *filename) {
00186 char aux_filename[MAXPATHLEN];
00187 char absolute_filename[MAXPATHLEN];
00188
00189 tilde_expand_filename_norectify(filename, aux_filename);
00190 return string_find(rectify_pathname(aux_filename, absolute_filename),1);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 char *expand_filename(char *filename) {
00201 char aux_filename[MAXPATHLEN],
00202 aux_filename2[MAXPATHLEN];
00203 char *absolute_filename = mem_alloc(MAXPATHLEN,OTHER_SPACE);
00204
00205 if (is_absolute_filename(filename)) {
00206 return rectify_pathname(filename, absolute_filename);
00207 #ifndef WIN_NT
00208 } else if (filename[0] == '~') {
00209 tilde_expand_filename_norectify(filename, aux_filename);
00210 return rectify_pathname(aux_filename, absolute_filename);
00211 #endif
00212 } else {
00213 getcwd(aux_filename2, MAXPATHLEN-1);
00214 sprintf(aux_filename, "%s%c%s", aux_filename2,
00215 SLASH, filename);
00216 return rectify_pathname(aux_filename, absolute_filename);
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 DllExport char * call_conv strip_names_from_path(char* path, int how_many)
00236 {
00237 int i, abort_flag=FALSE;
00238 char *cutoff_ptr;
00239 char *buffer = malloc(MAXPATHLEN);
00240
00241 #ifdef SIMPLESCALAR
00242 if (!buffer)
00243 printf("no space to allocate buffer in strip_names_from_path.\n");
00244
00245
00246 strcpy(buffer,path);
00247
00248 cutoff_ptr = buffer + strlen(buffer);
00249
00250 while (cutoff_ptr != buffer && how_many > 0) {
00251 if (*cutoff_ptr == SLASH) {
00252 how_many--;
00253 *cutoff_ptr = '\0';
00254 }
00255 cutoff_ptr--;
00256 }
00257
00258 if (how_many > 0)
00259 xsb_abort("[PATHNAME] There is no directory %d levels below %s",
00260 how_many, path);
00261 return buffer;
00262
00263 #endif
00264
00265 rectify_pathname(path,buffer);
00266
00267 for (i=0; i < how_many; i++) {
00268 if (abort_flag) {
00269 xsb_abort("[PATHNAME] There is no directory %d levels below %s",
00270 how_many, path);
00271 }
00272 cutoff_ptr = strrchr(buffer, SLASH);
00273 if (cutoff_ptr == NULL)
00274 return "";
00275 if ((cutoff_ptr - buffer) > 0)
00276
00277
00278 *cutoff_ptr = '\0';
00279 else {
00280 *(cutoff_ptr+1) = '\0';
00281 abort_flag=TRUE;
00282 }
00283 }
00284 return buffer;
00285 }
00286
00287
00288
00289
00290
00291 static char *get_file_basename(char *path) {
00292 char *ptr;
00293 ptr = strrchr(path, SLASH);
00294 if (ptr == NULL)
00295 return path;
00296 else
00297 return ptr+1;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 static char *get_file_dirname(char *path, char *dir) {
00309 char *ptr;
00310 ptr = strrchr(rectify_pathname(path,dir), SLASH);
00311 if (ptr == NULL)
00312
00313 return "";
00314
00315
00316 else if (*ptr==SLASH && *(ptr+1)=='\0')
00317 return dir;
00318 else {
00319 *(ptr+1) = '\0';
00320 return dir;
00321 }
00322 }
00323
00324
00325
00326
00327 static char *get_file_extension(char *path) {
00328 char *ptr, *base=get_file_basename(path);
00329 ptr = strrchr(base, '.');
00330 if ((ptr==base) || (ptr==NULL))
00331 return "";
00332 else return (ptr+1);
00333 }
00334
00335 #define MAXPATHNAMES 256
00336
00337
00338
00339
00340
00341
00342
00343 static char *rectify_pathname(char *inpath, char *outpath) {
00344 char names[MAXPATHNAMES][MAXNAME];
00345
00346
00347 char expanded_inpath[MAXPATHLEN];
00348 char *inptr1, *inptr2, *inpath_end;
00349 int length;
00350 int i, outidx=0, nameidx=0;
00351 xsbBool leading_slash, leading_slash2, trailing_slash;
00352
00353 tilde_expand_filename_norectify(inpath, expanded_inpath);
00354
00355
00356 inptr1 = inptr2 = expanded_inpath;
00357 inpath_end = expanded_inpath + strlen(expanded_inpath);
00358
00359
00360 leading_slash = (*expanded_inpath == SLASH ? TRUE : FALSE);
00361 #if defined(WIN_NT) || defined(CYGWIN)
00362
00363
00364 leading_slash2 = (*(expanded_inpath+1) == SLASH ? TRUE : FALSE);
00365 #else
00366 leading_slash2 = FALSE;
00367 #endif
00368 trailing_slash = (*(inpath_end - 1) == SLASH ? TRUE : FALSE);
00369
00370 while ( inptr2 < inpath_end ) {
00371 inptr2 = strchr(inptr1, SLASH);
00372 if (inptr2==NULL)
00373 inptr2 = inpath_end;
00374
00375
00376 if ((length = inptr2 - inptr1) == 0) {
00377 if (inptr2 == inpath_end)
00378 break;
00379 else {
00380 inptr2++;
00381 inptr1++;
00382 continue;
00383 }
00384 }
00385
00386 switch (length) {
00387 case 1:
00388 if (*inptr1 == '.' && inptr1 != expanded_inpath) {
00389 inptr1 = inptr2;
00390 continue;
00391 }
00392 break;
00393 case 2:
00394 if ((*inptr1 == '.') && (*(inptr1+1) == '.')) {
00395 nameidx--;
00396 if (nameidx < 0) {
00397
00398 nameidx++;
00399 break;
00400 } else if (strcmp(names[nameidx], "..") == 0) {
00401
00402
00403 nameidx++;
00404 } else {
00405
00406 inptr1 = inptr2;
00407 continue;
00408 }
00409 }
00410 break;
00411 }
00412
00413
00414 strncpy(names[nameidx], inptr1, length);
00415 names[nameidx][length] = '\0';
00416 nameidx++;
00417 inptr1=inptr2;
00418 if (nameidx >= MAXPATHNAMES)
00419 xsb_abort("[PATHNAME] Directory depth in pathname exceeds maximum, %s",
00420 inpath);
00421 }
00422
00423
00424
00425
00426
00427 if (leading_slash) {
00428 outpath[outidx] = SLASH;
00429 outidx++;
00430 }
00431 if (leading_slash && leading_slash2) {
00432 #if defined(CYGWIN)
00433 strncpy(outpath+outidx,"cygdrive",8);
00434 outidx += 8;
00435 #endif
00436 outpath[outidx] = SLASH;
00437 outidx++;
00438 }
00439
00440 for (i=0; i<nameidx; i++) {
00441 strcpy(outpath+outidx, names[i]);
00442 outidx = outidx + strlen(names[i]);
00443
00444 if (i < nameidx-1) {
00445 outpath[outidx] = SLASH;
00446 outidx++;
00447 }
00448 }
00449
00450
00451 if (trailing_slash && (nameidx > 0)) {
00452 outpath[outidx] = SLASH;
00453 outpath[outidx+1] = '\0';
00454 }
00455 return(outpath);
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465 void parse_filename(char *filename, char **dir, char **base, char **extension)
00466 {
00467 char absolute_dirname[MAXPATHLEN];
00468 char basename[MAXNAME];
00469
00470 *base = strcpy(basename, get_file_basename(filename));
00471 *dir = get_file_dirname(filename, absolute_dirname);
00472 *extension = get_file_extension(basename);
00473
00474 if (*extension != "")
00475 *(*extension-1) = '\0';
00476 *base = string_find(*base,1);
00477 *dir = string_find(*dir,1);
00478 *extension = string_find(*extension,1);
00479 return;
00480 }
00481
00482
00483
00484
00485
00486
00487 void transform_cygwin_pathname(char *filename)
00488 {
00489 char *pointer;
00490 char tmp[MAXPATHLEN];
00491 int diff;
00492
00493 if (filename[0] == '/') {
00494 if (filename[1] == '/') diff = 1;
00495 else if (filename[1] == 'c' &&
00496 filename[2] == 'y' &&
00497 filename[3] == 'g' &&
00498 filename[4] == 'd' &&
00499 filename[5] == 'r' &&
00500 filename[6] == 'i' &&
00501 filename[7] == 'v' &&
00502 filename[8] == 'e' &&
00503 filename[9] == '/') diff = 9;
00504 else {
00505 strcpy(tmp,filename);
00506 strcpy(filename,(char *)flags[USER_HOME]);
00507 strcpy(filename+strlen((char *)flags[USER_HOME]),tmp);
00508 return;
00509 }
00510
00511 pointer=filename+diff+1;
00512 filename[0]=*pointer;
00513 filename[1]=':';
00514 filename[2]='\\';
00515 for(pointer+=1;*pointer;pointer++)
00516 if (*pointer == '/')
00517 *(pointer-diff) = '\\';
00518 else
00519 *(pointer-diff) = *pointer;
00520
00521 *(pointer-diff) = '\0';
00522 return;
00523 }
00524 }
00525
00526
00527 #ifdef WIN_NT
00528 #define not_a_dir(fileinfo) !(fileinfo.st_mode & _S_IFDIR)
00529 #else
00530 #define not_a_dir(fileinfo) !(fileinfo.st_mode & S_IFDIR)
00531 #endif
00532
00533 char *existing_file_extension(char *basename)
00534 {
00535 char filename[MAXPATHLEN];
00536 struct stat fileinfo;
00537
00538 strcpy(filename, basename); strcat(filename, XSB_SRC_EXTENSION_STRING);
00539
00540 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return XSB_SRC_EXTENSION_STRING+1;
00541
00542 strcpy(filename, basename); strcat(filename, ".c");
00543 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return "c";
00544
00545 strcpy(filename, basename); strcat(filename, ".cpp");
00546 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return "cpp";
00547
00548 strcpy(filename, basename); strcat(filename, ".pl");
00549 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return "pl";
00550
00551 strcpy(filename, basename);
00552 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return "";
00553
00554 sprintf(filename, "%s%s", basename, XSB_OBJ_EXTENSION_STRING);
00555
00556 if (! stat(filename, &fileinfo) && not_a_dir(fileinfo)) return XSB_OBJ_EXTENSION_STRING+1;
00557
00558 return NULL;
00559 }
00560
00561
00562
00563 xsbBool almost_search_module(CTXTdeclc char *filename)
00564 {
00565 char *fullname, *dir, *basename, *extension;
00566 struct stat fileinfo;
00567
00568 fullname = tilde_expand_filename(filename);
00569 parse_filename(fullname, &dir, &basename, &extension);
00570 if (! strcmp(filename, basename)) {
00571
00572
00573
00574
00575
00576 ctop_string(CTXTc 2, dir);
00577 ctop_string(CTXTc 3, filename);
00578 } else {
00579 if (! strcmp(extension, "")) {
00580 extension = existing_file_extension(fullname);
00581 if (! extension) return FALSE;
00582 extension = string_find(extension,1);
00583 } else {
00584 if (stat(fullname, &fileinfo) && !strcmp(dir,"")) {
00585
00586 ctop_string(CTXTc 2, dir);
00587 ctop_string(CTXTc 3, basename);
00588 ctop_string(CTXTc 4, extension);
00589 return TRUE;
00590 }
00591 }
00592 if (! strcmp(dir, "")) {
00593 char dot_dir[MAXPATHLEN];
00594 dot_dir[0] = '.';
00595 dot_dir[1] = SLASH;
00596 dot_dir[2] = '\0';
00597 ctop_string(CTXTc 2, string_find(dot_dir, 1));
00598 strcat(dot_dir, basename);
00599 ctop_string(CTXTc 5, string_find(dot_dir, 1));
00600 } else {
00601 char dirtmp[MAXPATHLEN];
00602 ctop_string(CTXTc 2, dir);
00603 strcpy(dirtmp,dir);
00604 strcat(dirtmp, basename);
00605 ctop_string(CTXTc 5, string_find(dirtmp, 1));
00606 }
00607 ctop_string(CTXTc 3, basename);
00608 ctop_string(CTXTc 4, extension);
00609 }
00610 return TRUE;
00611 }
00612
00613