root/opal/util/basename.c

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

DEFINITIONS

This source file includes following definitions.
  1. opal_find_last_path_separator
  2. opal_basename
  3. opal_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-2015 Research Organization for Information Science
  14  *                         and Technology (RIST). All rights reserved.
  15  * Copyright (c) 2014      Intel, Inc. All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "opal_config.h"
  24 
  25 #include <stdlib.h>
  26 #include <string.h>
  27 #ifdef HAVE_LIBGEN_H
  28 #include <libgen.h>
  29 #endif  /* HAVE_LIBGEN_H */
  30 
  31 #include "opal/util/basename.h"
  32 #include "opal/util/os_path.h"
  33 
  34 /**
  35  * Return a pointer into the original string where the last PATH delimiter
  36  * was found. It does not modify the original string. Moreover, it does not
  37  * scan the full string, but only the part allowed by the specified number
  38  * of characters.
  39  * If the last character on the string is a path separator, it will be skipped.
  40  */
  41 static inline char* opal_find_last_path_separator( const char* filename, size_t n )
  42 {
  43     char* p = (char*)filename + n;
  44 
  45     /* First skip the latest separators */
  46     for ( ; p >= filename; p-- ) {
  47         if( *p != OPAL_PATH_SEP[0] )
  48             break;
  49     }
  50 
  51     for ( ; p >= filename; p-- ) {
  52         if( *p == OPAL_PATH_SEP[0] )
  53             return p;
  54     }
  55 
  56     return NULL;  /* nothing found inside the filename */
  57 }
  58 
  59 char *opal_basename(const char *filename)
  60 {
  61     size_t i;
  62     char *tmp, *ret = NULL;
  63     const char sep = OPAL_PATH_SEP[0];
  64 
  65     /* Check for the bozo case */
  66     if (NULL == filename) {
  67         return NULL;
  68     }
  69     if (0 == strlen(filename)) {
  70         return strdup("");
  71     }
  72     if (sep == filename[0] && '\0' == filename[1]) {
  73         return strdup(filename);
  74     }
  75 
  76     /* Remove trailing sep's (note that we already know that strlen > 0) */
  77     tmp = strdup(filename);
  78     for (i = strlen(tmp) - 1; i > 0; --i) {
  79         if (sep == tmp[i]) {
  80             tmp[i] = '\0';
  81         } else {
  82             break;
  83         }
  84     }
  85     if (0 == i) {
  86         tmp[0] = sep;
  87         return tmp;
  88     }
  89 
  90     /* Look for the final sep */
  91     ret = opal_find_last_path_separator( tmp, strlen(tmp) );
  92     if (NULL == ret) {
  93         return tmp;
  94     }
  95     ret = strdup(ret + 1);
  96     free(tmp);
  97     return ret;
  98 }
  99 
 100 char* opal_dirname(const char* filename)
 101 {
 102 #if defined(HAVE_DIRNAME) || OPAL_HAVE_DIRNAME
 103     char* safe_tmp = strdup(filename), *result;
 104     if (NULL == safe_tmp) {
 105         return NULL;
 106     }
 107     result = strdup(dirname(safe_tmp));
 108     free(safe_tmp);
 109     return result;
 110 #else
 111     const char* p = opal_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                 if (NULL == ret) {
 127                     return NULL;
 128                 }
 129                 opal_string_copy(ret, filename, p - filename);
 130                 ret[p - filename] = '\0';
 131                 return opal_make_filename_os_friendly(ret);
 132             }
 133             break;  /* return the duplicate of "." */
 134         }
 135     }
 136     return strdup(".");
 137 #endif  /* defined(HAVE_DIRNAME) || OPAL_HAVE_DIRNAME */
 138 }

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