VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/path/RTPathCalcRelative.cpp@ 45356

最後變更 在這個檔案從45356是 44623,由 vboxsync 提交於 12 年 前

Runtime: RTPathCreateRelative -> RTPathCalcRelative

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 4.4 KB
 
1/* $Id: RTPathCalcRelative.cpp 44623 2013-02-11 10:14:24Z vboxsync $ */
2/** @file
3 * IPRT - RTPathCreateRelative.
4 */
5
6/*
7 * Copyright (C) 2013 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include "internal/iprt.h"
32#include <iprt/path.h>
33#include <iprt/assert.h>
34#include <iprt/err.h>
35#include <iprt/string.h>
36#include "internal/path.h"
37
38
39
40RTDECL(int) RTPathCalcRelative(char *pszPathDst, size_t cbPathDst,
41 const char *pszPathFrom,
42 const char *pszPathTo)
43{
44 int rc = VINF_SUCCESS;
45
46 AssertPtrReturn(pszPathDst, VERR_INVALID_POINTER);
47 AssertReturn(cbPathDst, VERR_INVALID_PARAMETER);
48 AssertPtrReturn(pszPathFrom, VERR_INVALID_POINTER);
49 AssertPtrReturn(pszPathTo, VERR_INVALID_POINTER);
50 AssertReturn(RTPathStartsWithRoot(pszPathFrom), VERR_INVALID_PARAMETER);
51 AssertReturn(RTPathStartsWithRoot(pszPathTo), VERR_INVALID_PARAMETER);
52 AssertReturn(RTStrCmp(pszPathFrom, pszPathTo), VERR_INVALID_PARAMETER);
53
54 /*
55 * Check for different root specifiers (drive letters), creating a relative path doesn't work here.
56 * @todo: How to handle case insensitive root specifiers correctly?
57 */
58 size_t offRootFrom = rtPathRootSpecLen(pszPathFrom);
59 size_t offRootTo = rtPathRootSpecLen(pszPathTo);
60
61 if ( offRootFrom != offRootTo
62 || RTStrNCmp(pszPathFrom, pszPathTo, offRootFrom))
63 return VERR_NOT_SUPPORTED;
64
65 /* Filter out the parent path which is equal to both paths. */
66 while ( *pszPathFrom == *pszPathTo
67 && *pszPathFrom != '\0'
68 && *pszPathTo != '\0')
69 {
70 pszPathFrom++;
71 pszPathTo++;
72 }
73
74 /*
75 * Because path components can start with an equal string but differ afterwards we
76 * need to go back to the beginning of the current component.
77 */
78 while (!RTPATH_IS_SEP(*pszPathFrom))
79 pszPathFrom--;
80
81 pszPathFrom++; /* Skip path separator. */
82
83 while (!RTPATH_IS_SEP(*pszPathTo))
84 pszPathTo--;
85
86 pszPathTo++; /* Skip path separator. */
87
88 /* Paths point to the first non equal component now. */
89
90 /* Count the number of remaining path components of the from path. */
91 char aszPathTmp[RTPATH_MAX + 1];
92 unsigned offPathTmp = 0;
93
94 /* Create the part to go up from pszPathFrom. */
95 while (*pszPathFrom != '\0')
96 {
97 while ( !RTPATH_IS_SEP(*pszPathFrom)
98 && *pszPathFrom != '\0')
99 pszPathFrom++;
100
101 if (RTPATH_IS_SEP(*pszPathFrom))
102 {
103 if (offPathTmp + 3 >= sizeof(aszPathTmp) - 1)
104 return VERR_FILENAME_TOO_LONG;
105 aszPathTmp[offPathTmp++] = '.';
106 aszPathTmp[offPathTmp++] = '.';
107 aszPathTmp[offPathTmp++] = RTPATH_SLASH;
108 pszPathFrom++;
109 }
110 }
111
112 aszPathTmp[offPathTmp] = '\0';
113
114 /* Now append the rest of pszPathTo to the final path. */
115 char *pszPathTmp = &aszPathTmp[offPathTmp];
116 size_t cbPathTmp = sizeof(aszPathTmp) - offPathTmp - 1;
117 rc = RTStrCatP(&pszPathTmp, &cbPathTmp, pszPathTo);
118 if (RT_SUCCESS(rc))
119 {
120 *pszPathTmp = '\0';
121
122 size_t cchPathTmp = strlen(aszPathTmp);
123 if (cchPathTmp >= cbPathDst)
124 return VERR_BUFFER_OVERFLOW;
125 memcpy(pszPathDst, aszPathTmp, cchPathTmp + 1);
126 }
127 else
128 rc = VERR_FILENAME_TOO_LONG;
129
130 return rc;
131}
132
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette