root/opal/mca/pmix/pmix4x/pmix/src/util/basename.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pmix_find_last_path_separator
  2. pmix_basename
  3. pmix_dirname

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2009-2014 Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2014      Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * Copyright (c) 2014-2018 Intel, Inc.  All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include <src/include/pmix_config.h>
  24 
  25 
  26 #include <stdlib.h>
  27 #ifdef HAVE_STRING_H
  28 #include <string.h>
  29 #endif  /* HAVE_STRING_H */
  30 #ifdef HAVE_LIBGEN_H
  31 #include <libgen.h>
  32 #endif  /* HAVE_LIBGEN_H */
  33 
  34 #include "src/util/basename.h"
  35 #include "src/util/os_path.h"
  36 
  37 /**
  38  * Return a pointer into the original string where the last PATH delimiter
  39  * was found. It does not modify the original string. Moreover, it does not
  40  * scan the full string, but only the part allowed by the specified number
  41  * of characters.
  42  * If the last character on the string is a path separator, it will be skipped.
  43  */
  44 static inline char* pmix_find_last_path_separator( const char* filename, size_t n )
  45 {
  46     char* p = (char*)filename + n;
  47 
  48     /* First skip the latest separators */
  49     for ( ; p >= filename; p-- ) {
  50         if( *p != PMIX_PATH_SEP[0] )
  51             break;
  52     }
  53 
  54     for ( ; p >= filename; p-- ) {
  55         if( *p == PMIX_PATH_SEP[0] )
  56             return p;
  57     }
  58 
  59     return NULL;  /* nothing found inside the filename */
  60 }
  61 
  62 char *pmix_basename(const char *filename)
  63 {
  64     size_t i;
  65     char *tmp, *ret = NULL;
  66     const char sep = PMIX_PATH_SEP[0];
  67 
  68     /* Check for the bozo case */
  69     if (NULL == filename) {
  70         return NULL;
  71     }
  72     if (0 == strlen(filename)) {
  73         return strdup("");
  74     }
  75     if (sep == filename[0] && '\0' == filename[1]) {
  76         return strdup(filename);
  77     }
  78 
  79     /* Remove trailing sep's (note that we already know that strlen > 0) */
  80     tmp = strdup(filename);
  81     for (i = strlen(tmp) - 1; i > 0; --i) {
  82         if (sep == tmp[i]) {
  83             tmp[i] = '\0';
  84         } else {
  85             break;
  86         }
  87     }
  88     if (0 == i) {
  89         tmp[0] = sep;
  90         return tmp;
  91     }
  92 
  93     /* Look for the final sep */
  94     ret = pmix_find_last_path_separator( tmp, strlen(tmp) );
  95     if (NULL == ret) {
  96         return tmp;
  97     }
  98     ret = strdup(ret + 1);
  99     free(tmp);
 100     return ret;
 101 }
 102 
 103 char* pmix_dirname(const char* filename)
 104 {
 105 #if defined(HAVE_DIRNAME) || PMIX_HAVE_DIRNAME
 106     char* safe_tmp = strdup(filename), *result;
 107     result = strdup(dirname(safe_tmp));
 108     free(safe_tmp);
 109     return result;
 110 #else
 111     const char* p = pmix_find_last_path_separator(filename, strlen(filename));
 112     /* NOTE: p will be NULL if no path separator was in the filename - i.e.,
 113      * if filename is just a local file */
 114 
 115     for( ; NULL != p && p != filename; p-- ) {
 116         if( (*p == '\\') || (*p == '/') ) {
 117             /* If there are several delimiters remove them all */
 118             for( --p; p != filename; p-- ) {
 119                 if( (*p != '\\') && (*p != '/') ) {
 120                     p++;
 121                     break;
 122                 }
 123             }
 124             if( p != filename ) {
 125                 char* ret = (char*)malloc( p - filename + 1 );
 126                 pmix_strncpy(ret, filename, p - filename);
 127                 ret[p - filename] = '\0';
 128                 return pmix_make_filename_os_friendly(ret);
 129             }
 130             break;  /* return the duplicate of "." */
 131         }
 132     }
 133     return strdup(".");
 134 #endif  /* defined(HAVE_DIRNAME) || PMIX_HAVE_DIRNAME */
 135 }

/* [<][>][^][v][top][bottom][index][help] */