• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *    * Redistributions of source code must retain the above copyright
8  *      notice, this list of conditions and the following disclaimer.
9  *    * Redistributions in binary form must reproduce the above
10  *      copyright notice, this list of conditions and the following
11  *      disclaimer in the documentation and/or other materials provided
12  *      with the distribution.
13  *    * Neither the name of The Linux Foundation nor the names of its
14  *      contributors may be used to endorse or promote products derived
15  *      from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31 =======================================================================
32 
33 FILE:         std_path.c
34 
35 =======================================================================
36 =======================================================================
37 */
38 
39 #include "AEEstd.h"
40 #include "AEEBufBound.h"
41 #include <string.h>
42 /*===========================================================================
43 
44 ===========================================================================*/
std_makepath(const char * cpszDir,const char * cpszFile,char * pszOut,int nOutLen)45 int std_makepath(const char* cpszDir, const char* cpszFile,
46                  char* pszOut, int nOutLen)
47 {
48    BufBound bb;
49 
50    BufBound_Init(&bb, pszOut, nOutLen);
51 
52    BufBound_Puts(&bb, cpszDir);
53 
54    if (('\0' != cpszDir[0]) &&    /* non-empty dir */
55        ('/' != cpszDir[std_strlen(cpszDir)-1])) { /* no slash at end of dir */
56       BufBound_Putc(&bb, '/');
57    }
58    if ('/' == cpszFile[0]) {
59       cpszFile++;
60    }
61 
62    BufBound_Puts(&bb, cpszFile);
63 
64    BufBound_ForceNullTerm(&bb);
65 
66    return BufBound_Wrote(&bb) - 1;
67 
68 }
69 
70 /*===========================================================================
71 
72 ===========================================================================*/
std_splitpath(const char * cpszPath,const char * cpszDir)73 char* std_splitpath(const char* cpszPath, const char* cpszDir)
74 {
75    const char* cpsz = cpszPath;
76 
77    while ( ! ('\0' == cpszDir[0] ||
78               ('/' == cpszDir[0] && '\0' == cpszDir[1])) ){
79 
80       if (*cpszDir != *cpsz) {
81          return 0;
82       }
83 
84       ++cpsz;
85       ++cpszDir;
86    }
87 
88    /* Found the filename part of the path.
89       It should begin with a '/' unless there is no filename */
90    if ('/' == *cpsz) {
91       cpsz++;
92    }
93    else if ('\0' != *cpsz) {
94       cpsz = 0;
95    }
96 
97    return (char*)cpsz;
98 }
99 
std_cleanpath(char * pszPath)100 char* std_cleanpath(char* pszPath)
101 {
102    char* pszStart = pszPath;
103    char* pc;
104    char* pcEnd = pszStart+std_strlen(pszStart);
105 
106    /* preserve leading slash */
107    if ('/' == pszStart[0]) {
108       pszStart++;
109    }
110 
111    pc = pszStart;
112 
113    while ((char*)0 != (pc = std_strstr(pc, "/."))) {
114       char* pcDelFrom;
115 
116       if ('/' == pc[2] || '\0' == pc[2]) {
117          /*  delete "/." */
118          pcDelFrom = pc;
119          pc += 2;
120       } else if ('.' == pc[2] && ('/' == pc[3] || '\0' == pc[3])) {
121             /*  delete  "/element/.." */
122          pcDelFrom = std_memrchrbegin(pszStart, '/', pc - pszStart);
123          pc += 3;
124       } else {
125          pc += 2;
126          continue;
127       }
128 
129       std_memmove(pcDelFrom, pc, pcEnd-pcDelFrom);
130 
131       pc = pcDelFrom;
132    }
133 
134    /* eliminate leading "../" */
135    while (pszStart == std_strstr(pszStart, "../")) {
136       std_memmove(pszStart, pszStart+2, pcEnd-pszStart);
137    }
138 
139    /* eliminate leading "./" */
140    while (pszStart == std_strstr(pszStart, "./")) {
141       std_memmove(pszStart, pszStart+1, pcEnd-pszStart);
142    }
143 
144    if (!strncmp(pszStart,"..",2) || !strncmp(pszStart,".",1)) {
145       pszStart[0] = '\0';
146    }
147 
148    /* whack double '/' */
149    while ((char*)0 != (pc = std_strstr(pszPath, "//"))) {
150       std_memmove(pc, pc+1, pcEnd-pc);
151    }
152 
153    return pszPath;
154 }
155 
std_basename(const char * cpszFile)156 char* std_basename(const char* cpszFile)
157 {
158    const char* cpsz;
159 
160    if ((char*)0 != (cpsz = std_strrchr(cpszFile,'/'))) {
161       cpszFile = cpsz+1;
162    }
163 
164    return (char*)cpszFile;
165 }
166