/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2005 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2009-2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2014-2024 Research Organization for Information Science * and Technology (RIST). All rights reserved. * Copyright (c) 2014 Intel, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "opal_config.h" #include #include #ifdef HAVE_LIBGEN_H # include #endif /* HAVE_LIBGEN_H */ #include "opal/util/basename.h" #include "opal/util/os_path.h" /** * Return a pointer into the original string where the last PATH delimiter * was found. It does not modify the original string. Moreover, it does not * scan the full string, but only the part allowed by the specified number * of characters. * If the last character on the string is a path separator, it will be skipped. */ static inline char *opal_find_last_path_separator(const char *filename, size_t n) { char *p = (char *) filename + n; /* First skip the latest separators */ for (; p >= filename; p--) { if (*p != OPAL_PATH_SEP[0]) { break; } } for (; p >= filename; p--) { if (*p == OPAL_PATH_SEP[0]) { return p; } } return NULL; /* nothing found inside the filename */ } char *opal_basename(const char *filename) { size_t i; char *tmp, *ret = NULL; const char sep = OPAL_PATH_SEP[0]; /* Check for the bozo case */ if (NULL == filename) { return NULL; } if (0 == strlen(filename)) { return strdup(""); } if (sep == filename[0] && '\0' == filename[1]) { return strdup(filename); } /* Remove trailing sep's (note that we already know that strlen > 0) */ tmp = strdup(filename); if (1 < strlen(tmp)) { for (i = strlen(tmp) - 1; i > 0; --i) { if (sep == tmp[i]) { tmp[i] = '\0'; } else { break; } } if (0 == i) { tmp[0] = sep; return tmp; } } /* Look for the final sep */ ret = opal_find_last_path_separator(tmp, strlen(tmp)); if (NULL == ret) { return tmp; } ret = strdup(ret + 1); free(tmp); return ret; } char *opal_dirname(const char *filename) { #if defined(HAVE_DIRNAME) || OPAL_HAVE_DIRNAME char *safe_tmp = strdup(filename), *result; if (NULL == safe_tmp) { return NULL; } result = strdup(dirname(safe_tmp)); free(safe_tmp); return result; #else const char *p = opal_find_last_path_separator(filename, strlen(filename)); /* NOTE: p will be NULL if no path separator was in the filename - i.e., * if filename is just a local file */ for (; NULL != p && p != filename; p--) { if ((*p == '\\') || (*p == '/')) { /* If there are several delimiters remove them all */ for (--p; p != filename; p--) { if ((*p != '\\') && (*p != '/')) { p++; break; } } if (p != filename) { char *ret = (char *) malloc(p - filename + 1); if (NULL == ret) { return NULL; } opal_string_copy(ret, filename, p - filename); ret[p - filename] = '\0'; return opal_make_filename_os_friendly(ret); } break; /* return the duplicate of "." */ } } return strdup("."); #endif /* defined(HAVE_DIRNAME) || OPAL_HAVE_DIRNAME */ }