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