1
1

Add new utility function ompi_basename() for a portable version of

basename with stronger guarantees on its semantics.  See the doxygen
comments for how to call and use it.

This commit was SVN r5329.
Этот коммит содержится в:
Jeff Squyres 2005-04-14 14:04:41 +00:00
родитель 2c0207f409
Коммит 0cdcba3403
5 изменённых файлов: 250 добавлений и 1 удалений

Просмотреть файл

@ -28,6 +28,7 @@ noinst_LTLIBRARIES = libutil.la
headers = \
argv.h \
basename.h \
bit_ops.h \
cmd_line.h \
environ.h \
@ -55,6 +56,7 @@ headers = \
libutil_la_SOURCES = \
$(headers) \
argv.c \
basename.c \
cmd_line.c \
environ.c \
few.c \

94
src/util/basename.c Обычный файл
Просмотреть файл

@ -0,0 +1,94 @@
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* 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$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include <stdlib.h>
#include <string.h>
#include "include/constants.h"
#include "util/basename.h"
char *ompi_basename(const char *filename)
{
size_t i;
char *tmp, *ret = NULL;
#ifdef WIN32
const char sep = '\\';
#else
const char sep = '/';
#endif
/* Check for the bozo case */
if (NULL == filename) {
return NULL;
}
/* On Windows, automatically exclude a drive designator */
#ifdef WIN32
if (strlen(filename) == 2 &&
isalpha(filename[0]) && ':' == filename[1]) {
return strdup(filename);
} else if (strlen(filename) == 3 &&
isalpha(filename[0]) && ':' == filename[1] && sep == filename[2]) {
return strdup(filename);
}
if (':' == filename[1] && isalpha(filename[0])) {
filename += 2;
if (sep == filename[0]) {
++filename;
}
}
#endif
/* Check for the bozo cases */
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);
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 = strrchr(tmp, sep);
if (NULL == ret) {
return tmp;
}
ret = strdup(ret + 1);
free(tmp);
return ret;
}

70
src/util/basename.h Обычный файл
Просмотреть файл

@ -0,0 +1,70 @@
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* 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$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/**
* @file
*
* Returns an OS-independant basename() of a given filename.
*/
#ifndef OMPI_OS_BASENAME_H
#define OMPI_OS_BASENAME_H
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
/**
* Return the basename of a filename.
*
* @param filename The filename to examine
*
* @returns A string containing the basename, or NULL if there is an error
*
* The contents of the \em filename parameter are unchanged. This
* function returns a new string containing the basename of the
* filename (which must be eventually freed by the caller), or
* NULL if there is an error. Trailing "/" characters in the
* filename do not count, unless it is in the only part of the
* filename (e.g., "/" or "C:\").
*
* This function will do the Right Things on POSIX and
* Windows-based operating systems. For example:
*
* foo.txt returns "foo.txt"
*
* /foo/bar/baz returns "baz"
*
* /yow.c returns "yow.c"
*
* / returns "/"
*
* C:\foo\bar\baz returns "baz"
*
* D:foo.txt returns "foo.txt"
*
* E:\yow.c returns "yow.c"
*
* F: returns "F:"
*
* G:\ returns "G:"
*/
char *ompi_basename(const char* filename);
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
#endif /* OMPI_OS_BASENAME_H */

Просмотреть файл

@ -24,7 +24,8 @@ check_PROGRAMS = \
orte_sys_info \
orte_os_create_dirpath \
orte_session_dir \
ompi_argv
ompi_argv \
ompi_basename
TESTS = \
$(check_PROGRAMS)
@ -47,6 +48,12 @@ ompi_argv_LDADD = \
$(top_builddir)/test/support/libsupport.a
ompi_argv_DEPENDENCIES = $(ompi_argv_LDADD)
ompi_basename_SOURCES = ompi_basename.c
ompi_basename_LDADD = \
$(top_builddir)/src/libmpi.la \
$(top_builddir)/test/support/libsupport.a
ompi_basename_DEPENDENCIES = $(ompi_basename_LDADD)
orte_os_path_SOURCES = orte_os_path.c
orte_os_path_LDADD = \
$(top_builddir)/src/libmpi.la \

76
test/util/ompi_basename.c Обычный файл
Просмотреть файл

@ -0,0 +1,76 @@
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
* 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$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "support.h"
#include "include/constants.h"
#include "util/basename.h"
static void test(const char* in, const char* out);
int main(int argc, char* argv[])
{
test_init("ompi_basename()");
test("foo.txt", "foo.txt");
test("/foo/bar/baz", "baz");
test("/yow.c", "yow.c");
test("/", "/");
test("foo.txt/", "foo.txt");
test("/foo/bar/baz/", "baz");
test("/yow.c/", "yow.c");
test("//", "/");
#ifdef WIN32
test("C:\\foo\\bar\\baz", "baz");
test("D:foo.txt", "foo.txt");
test("E:\\yow.c", "yow.c");
test("F:", "F:");
test("G:\\", "G:\\");
#endif
/* All done */
return test_finalize();
}
void test(const char* in, const char* out)
{
char *msg;
char *ret = ompi_basename(in);
if (0 == strcmp(ret, out)) {
test_success();
} else {
asprintf(&msg, "Mismatch: input \"%s\", expected \"%s\", got \"%s\"\n",
in, out, ret);
test_failure(msg);
free(msg);
}
if (NULL != ret) {
free(ret);
}
}