Sergey Pastor / 1

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file path.c
Sergunb 0:8918a71cdbe9 3 * @brief Path manipulation helper functions
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 10 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 11 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 12 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 13 *
Sergunb 0:8918a71cdbe9 14 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 17 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 18 *
Sergunb 0:8918a71cdbe9 19 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 20 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 22 *
Sergunb 0:8918a71cdbe9 23 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 24 * @version 1.7.6
Sergunb 0:8918a71cdbe9 25 **/
Sergunb 0:8918a71cdbe9 26
Sergunb 0:8918a71cdbe9 27 //Dependencies
Sergunb 0:8918a71cdbe9 28 #include <string.h>
Sergunb 0:8918a71cdbe9 29 #include <ctype.h>
Sergunb 0:8918a71cdbe9 30 #include "path.h"
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32
Sergunb 0:8918a71cdbe9 33 /**
Sergunb 0:8918a71cdbe9 34 * @brief Test if the path is absolute
Sergunb 0:8918a71cdbe9 35 * @param[in] path NULL-terminated string that contains the path
Sergunb 0:8918a71cdbe9 36 * @return TRUE is the path is absolute, else FALSE
Sergunb 0:8918a71cdbe9 37 **/
Sergunb 0:8918a71cdbe9 38
Sergunb 0:8918a71cdbe9 39 bool_t pathIsAbsolute(const char_t *path)
Sergunb 0:8918a71cdbe9 40 {
Sergunb 0:8918a71cdbe9 41 //Determine if the path is absolute or relative
Sergunb 0:8918a71cdbe9 42 if(path[0] == '/' || path[0] == '\\')
Sergunb 0:8918a71cdbe9 43 return TRUE;
Sergunb 0:8918a71cdbe9 44 else
Sergunb 0:8918a71cdbe9 45 return FALSE;
Sergunb 0:8918a71cdbe9 46 }
Sergunb 0:8918a71cdbe9 47
Sergunb 0:8918a71cdbe9 48
Sergunb 0:8918a71cdbe9 49 /**
Sergunb 0:8918a71cdbe9 50 * @brief Test if the path is relative
Sergunb 0:8918a71cdbe9 51 * @param[in] path NULL-terminated string that contains the path
Sergunb 0:8918a71cdbe9 52 * @return TRUE is the path is relative, else FALSE
Sergunb 0:8918a71cdbe9 53 **/
Sergunb 0:8918a71cdbe9 54
Sergunb 0:8918a71cdbe9 55 bool_t pathIsRelative(const char_t *path)
Sergunb 0:8918a71cdbe9 56 {
Sergunb 0:8918a71cdbe9 57 //Determine if the path is absolute or relative
Sergunb 0:8918a71cdbe9 58 if(path[0] == '/' || path[0] == '\\')
Sergunb 0:8918a71cdbe9 59 return FALSE;
Sergunb 0:8918a71cdbe9 60 else
Sergunb 0:8918a71cdbe9 61 return TRUE;
Sergunb 0:8918a71cdbe9 62 }
Sergunb 0:8918a71cdbe9 63
Sergunb 0:8918a71cdbe9 64
Sergunb 0:8918a71cdbe9 65 /**
Sergunb 0:8918a71cdbe9 66 * @brief Search a path for a file name
Sergunb 0:8918a71cdbe9 67 * @param[in] path NULL-terminated string that contains the path to search
Sergunb 0:8918a71cdbe9 68 * @return Pointer to the file name
Sergunb 0:8918a71cdbe9 69 **/
Sergunb 0:8918a71cdbe9 70
Sergunb 0:8918a71cdbe9 71 const char_t *pathFindFileName(const char_t *path)
Sergunb 0:8918a71cdbe9 72 {
Sergunb 0:8918a71cdbe9 73 size_t n;
Sergunb 0:8918a71cdbe9 74
Sergunb 0:8918a71cdbe9 75 //Retrieve the length of the path
Sergunb 0:8918a71cdbe9 76 n = strlen(path);
Sergunb 0:8918a71cdbe9 77
Sergunb 0:8918a71cdbe9 78 //Skip trailing slash or backslash characters
Sergunb 0:8918a71cdbe9 79 while(n > 0)
Sergunb 0:8918a71cdbe9 80 {
Sergunb 0:8918a71cdbe9 81 //Forward slash or backslash character found?
Sergunb 0:8918a71cdbe9 82 if(path[n - 1] != '/' && path[n - 1] != '\\')
Sergunb 0:8918a71cdbe9 83 break;
Sergunb 0:8918a71cdbe9 84
Sergunb 0:8918a71cdbe9 85 //Previous character
Sergunb 0:8918a71cdbe9 86 n--;
Sergunb 0:8918a71cdbe9 87 }
Sergunb 0:8918a71cdbe9 88
Sergunb 0:8918a71cdbe9 89 //Search the string for the last separator
Sergunb 0:8918a71cdbe9 90 while(n > 0)
Sergunb 0:8918a71cdbe9 91 {
Sergunb 0:8918a71cdbe9 92 //Forward slash or backslash character found?
Sergunb 0:8918a71cdbe9 93 if(path[n - 1] == '/' || path[n - 1] == '\\')
Sergunb 0:8918a71cdbe9 94 break;
Sergunb 0:8918a71cdbe9 95
Sergunb 0:8918a71cdbe9 96 //Previous character
Sergunb 0:8918a71cdbe9 97 n--;
Sergunb 0:8918a71cdbe9 98 }
Sergunb 0:8918a71cdbe9 99
Sergunb 0:8918a71cdbe9 100 //Return a pointer to the file name
Sergunb 0:8918a71cdbe9 101 return path + n;
Sergunb 0:8918a71cdbe9 102 }
Sergunb 0:8918a71cdbe9 103
Sergunb 0:8918a71cdbe9 104
Sergunb 0:8918a71cdbe9 105 /**
Sergunb 0:8918a71cdbe9 106 * @brief Simplify a path
Sergunb 0:8918a71cdbe9 107 * @param[in] path NULL-terminated string containing the path to be canonicalized
Sergunb 0:8918a71cdbe9 108 **/
Sergunb 0:8918a71cdbe9 109
Sergunb 0:8918a71cdbe9 110 void pathCanonicalize(char_t *path)
Sergunb 0:8918a71cdbe9 111 {
Sergunb 0:8918a71cdbe9 112 size_t i;
Sergunb 0:8918a71cdbe9 113 size_t j;
Sergunb 0:8918a71cdbe9 114 size_t k;
Sergunb 0:8918a71cdbe9 115
Sergunb 0:8918a71cdbe9 116 //Move to the beginning of the string
Sergunb 0:8918a71cdbe9 117 i = 0;
Sergunb 0:8918a71cdbe9 118 k = 0;
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 //Replace backslashes with forward slashes
Sergunb 0:8918a71cdbe9 121 while(path[i] != '\0')
Sergunb 0:8918a71cdbe9 122 {
Sergunb 0:8918a71cdbe9 123 //Forward slash or backslash separator found?
Sergunb 0:8918a71cdbe9 124 if(path[i] == '/' || path[i] == '\\')
Sergunb 0:8918a71cdbe9 125 {
Sergunb 0:8918a71cdbe9 126 path[k++] = '/';
Sergunb 0:8918a71cdbe9 127 while(path[i] == '/' || path[i] == '\\') i++;
Sergunb 0:8918a71cdbe9 128 }
Sergunb 0:8918a71cdbe9 129 else
Sergunb 0:8918a71cdbe9 130 {
Sergunb 0:8918a71cdbe9 131 path[k++] = path[i++];
Sergunb 0:8918a71cdbe9 132 }
Sergunb 0:8918a71cdbe9 133 }
Sergunb 0:8918a71cdbe9 134
Sergunb 0:8918a71cdbe9 135 //Properly terminate the string with a NULL character
Sergunb 0:8918a71cdbe9 136 path[k] = '\0';
Sergunb 0:8918a71cdbe9 137
Sergunb 0:8918a71cdbe9 138 //Move back to the beginning of the string
Sergunb 0:8918a71cdbe9 139 i = 0;
Sergunb 0:8918a71cdbe9 140 j = 0;
Sergunb 0:8918a71cdbe9 141 k = 0;
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 //Parse the entire string
Sergunb 0:8918a71cdbe9 144 do
Sergunb 0:8918a71cdbe9 145 {
Sergunb 0:8918a71cdbe9 146 //Forward slash separator found?
Sergunb 0:8918a71cdbe9 147 if(path[i] == '/' || path[i] == '\0')
Sergunb 0:8918a71cdbe9 148 {
Sergunb 0:8918a71cdbe9 149 //"." element found?
Sergunb 0:8918a71cdbe9 150 if((i - j) == 1 && !strncmp(path + j, ".", 1))
Sergunb 0:8918a71cdbe9 151 {
Sergunb 0:8918a71cdbe9 152 //Check whether the pathname is empty?
Sergunb 0:8918a71cdbe9 153 if(k == 0)
Sergunb 0:8918a71cdbe9 154 {
Sergunb 0:8918a71cdbe9 155 if(path[i] == '\0')
Sergunb 0:8918a71cdbe9 156 {
Sergunb 0:8918a71cdbe9 157 path[k++] = '.';
Sergunb 0:8918a71cdbe9 158 }
Sergunb 0:8918a71cdbe9 159 else if(path[i] == '/' && path[i + 1] == '\0')
Sergunb 0:8918a71cdbe9 160 {
Sergunb 0:8918a71cdbe9 161 path[k++] = '.';
Sergunb 0:8918a71cdbe9 162 path[k++] = '/';
Sergunb 0:8918a71cdbe9 163 }
Sergunb 0:8918a71cdbe9 164 }
Sergunb 0:8918a71cdbe9 165 else if(k > 1)
Sergunb 0:8918a71cdbe9 166 {
Sergunb 0:8918a71cdbe9 167 //Remove the final slash if necessary
Sergunb 0:8918a71cdbe9 168 if(path[i] == '\0')
Sergunb 0:8918a71cdbe9 169 k--;
Sergunb 0:8918a71cdbe9 170 }
Sergunb 0:8918a71cdbe9 171 }
Sergunb 0:8918a71cdbe9 172 //".." element found?
Sergunb 0:8918a71cdbe9 173 else if((i - j) == 2 && !strncmp(path + j, "..", 2))
Sergunb 0:8918a71cdbe9 174 {
Sergunb 0:8918a71cdbe9 175 //Check whether the pathname is empty?
Sergunb 0:8918a71cdbe9 176 if(k == 0)
Sergunb 0:8918a71cdbe9 177 {
Sergunb 0:8918a71cdbe9 178 path[k++] = '.';
Sergunb 0:8918a71cdbe9 179 path[k++] = '.';
Sergunb 0:8918a71cdbe9 180
Sergunb 0:8918a71cdbe9 181 //Append a slash if necessary
Sergunb 0:8918a71cdbe9 182 if(path[i] == '/')
Sergunb 0:8918a71cdbe9 183 path[k++] = '/';
Sergunb 0:8918a71cdbe9 184 }
Sergunb 0:8918a71cdbe9 185 else if(k > 1)
Sergunb 0:8918a71cdbe9 186 {
Sergunb 0:8918a71cdbe9 187 //Search the path for the previous slash
Sergunb 0:8918a71cdbe9 188 for(j = 1; j < k; j++)
Sergunb 0:8918a71cdbe9 189 {
Sergunb 0:8918a71cdbe9 190 if(path[k - j - 1] == '/')
Sergunb 0:8918a71cdbe9 191 break;
Sergunb 0:8918a71cdbe9 192 }
Sergunb 0:8918a71cdbe9 193
Sergunb 0:8918a71cdbe9 194 //Slash separator found?
Sergunb 0:8918a71cdbe9 195 if(j < k)
Sergunb 0:8918a71cdbe9 196 {
Sergunb 0:8918a71cdbe9 197 if(!strncmp(path + k - j, "..", 2))
Sergunb 0:8918a71cdbe9 198 {
Sergunb 0:8918a71cdbe9 199 path[k++] = '.';
Sergunb 0:8918a71cdbe9 200 path[k++] = '.';
Sergunb 0:8918a71cdbe9 201 }
Sergunb 0:8918a71cdbe9 202 else
Sergunb 0:8918a71cdbe9 203 {
Sergunb 0:8918a71cdbe9 204 k = k - j - 1;
Sergunb 0:8918a71cdbe9 205 }
Sergunb 0:8918a71cdbe9 206
Sergunb 0:8918a71cdbe9 207 //Append a slash if necessary
Sergunb 0:8918a71cdbe9 208 if(k == 0 && path[0] == '/')
Sergunb 0:8918a71cdbe9 209 path[k++] = '/';
Sergunb 0:8918a71cdbe9 210 else if(path[i] == '/')
Sergunb 0:8918a71cdbe9 211 path[k++] = '/';
Sergunb 0:8918a71cdbe9 212 }
Sergunb 0:8918a71cdbe9 213 //No slash separator found?
Sergunb 0:8918a71cdbe9 214 else
Sergunb 0:8918a71cdbe9 215 {
Sergunb 0:8918a71cdbe9 216 if(k == 3 && !strncmp(path, "..", 2))
Sergunb 0:8918a71cdbe9 217 {
Sergunb 0:8918a71cdbe9 218 path[k++] = '.';
Sergunb 0:8918a71cdbe9 219 path[k++] = '.';
Sergunb 0:8918a71cdbe9 220
Sergunb 0:8918a71cdbe9 221 //Append a slash if necessary
Sergunb 0:8918a71cdbe9 222 if(path[i] == '/')
Sergunb 0:8918a71cdbe9 223 path[k++] = '/';
Sergunb 0:8918a71cdbe9 224 }
Sergunb 0:8918a71cdbe9 225 else if(path[i] == '\0')
Sergunb 0:8918a71cdbe9 226 {
Sergunb 0:8918a71cdbe9 227 k = 0;
Sergunb 0:8918a71cdbe9 228 path[k++] = '.';
Sergunb 0:8918a71cdbe9 229 }
Sergunb 0:8918a71cdbe9 230 else if(path[i] == '/' && path[i + 1] == '\0')
Sergunb 0:8918a71cdbe9 231 {
Sergunb 0:8918a71cdbe9 232 k = 0;
Sergunb 0:8918a71cdbe9 233 path[k++] = '.';
Sergunb 0:8918a71cdbe9 234 path[k++] = '/';
Sergunb 0:8918a71cdbe9 235 }
Sergunb 0:8918a71cdbe9 236 else
Sergunb 0:8918a71cdbe9 237 {
Sergunb 0:8918a71cdbe9 238 k = 0;
Sergunb 0:8918a71cdbe9 239 }
Sergunb 0:8918a71cdbe9 240 }
Sergunb 0:8918a71cdbe9 241 }
Sergunb 0:8918a71cdbe9 242 }
Sergunb 0:8918a71cdbe9 243 else
Sergunb 0:8918a71cdbe9 244 {
Sergunb 0:8918a71cdbe9 245 //Copy directory name
Sergunb 0:8918a71cdbe9 246 memmove(path + k, path + j, i - j);
Sergunb 0:8918a71cdbe9 247 //Advance write pointer
Sergunb 0:8918a71cdbe9 248 k += i - j;
Sergunb 0:8918a71cdbe9 249
Sergunb 0:8918a71cdbe9 250 //Append a slash if necessary
Sergunb 0:8918a71cdbe9 251 if(path[i] == '/')
Sergunb 0:8918a71cdbe9 252 path[k++] = '/';
Sergunb 0:8918a71cdbe9 253 }
Sergunb 0:8918a71cdbe9 254
Sergunb 0:8918a71cdbe9 255 //Move to the next token
Sergunb 0:8918a71cdbe9 256 while(path[i] == '/') i++;
Sergunb 0:8918a71cdbe9 257 j = i;
Sergunb 0:8918a71cdbe9 258 }
Sergunb 0:8918a71cdbe9 259 } while(path[i++] != '\0');
Sergunb 0:8918a71cdbe9 260
Sergunb 0:8918a71cdbe9 261 //Properly terminate the string with a NULL character
Sergunb 0:8918a71cdbe9 262 path[k] = '\0';
Sergunb 0:8918a71cdbe9 263 }
Sergunb 0:8918a71cdbe9 264
Sergunb 0:8918a71cdbe9 265
Sergunb 0:8918a71cdbe9 266 /**
Sergunb 0:8918a71cdbe9 267 * @brief Add a slash to the end of a string
Sergunb 0:8918a71cdbe9 268 * @param[in,out] path NULL-terminated string that represents the path
Sergunb 0:8918a71cdbe9 269 * @param[in] maxLen Maximum pathname length
Sergunb 0:8918a71cdbe9 270 **/
Sergunb 0:8918a71cdbe9 271
Sergunb 0:8918a71cdbe9 272 void pathAddSlash(char_t *path, size_t maxLen)
Sergunb 0:8918a71cdbe9 273 {
Sergunb 0:8918a71cdbe9 274 size_t n;
Sergunb 0:8918a71cdbe9 275
Sergunb 0:8918a71cdbe9 276 //Retrieve the length of the string
Sergunb 0:8918a71cdbe9 277 n = strlen(path);
Sergunb 0:8918a71cdbe9 278
Sergunb 0:8918a71cdbe9 279 //Add a slash character only if necessary
Sergunb 0:8918a71cdbe9 280 if(!n)
Sergunb 0:8918a71cdbe9 281 {
Sergunb 0:8918a71cdbe9 282 //Check the length of the resulting string
Sergunb 0:8918a71cdbe9 283 if(maxLen >= 1)
Sergunb 0:8918a71cdbe9 284 strcpy(path, "/");
Sergunb 0:8918a71cdbe9 285 }
Sergunb 0:8918a71cdbe9 286 else if(path[n - 1] != '/' && path[n - 1] != '\\')
Sergunb 0:8918a71cdbe9 287 {
Sergunb 0:8918a71cdbe9 288 //Check the length of the resulting string
Sergunb 0:8918a71cdbe9 289 if(maxLen >= (n + 1))
Sergunb 0:8918a71cdbe9 290 strcat(path, "/");
Sergunb 0:8918a71cdbe9 291 }
Sergunb 0:8918a71cdbe9 292 }
Sergunb 0:8918a71cdbe9 293
Sergunb 0:8918a71cdbe9 294
Sergunb 0:8918a71cdbe9 295 /**
Sergunb 0:8918a71cdbe9 296 * @brief Remove the trailing slash from a given path
Sergunb 0:8918a71cdbe9 297 * @param[in,out] path NULL-terminated string that contains the path
Sergunb 0:8918a71cdbe9 298 **/
Sergunb 0:8918a71cdbe9 299
Sergunb 0:8918a71cdbe9 300 void pathRemoveSlash(char_t *path)
Sergunb 0:8918a71cdbe9 301 {
Sergunb 0:8918a71cdbe9 302 char_t *end;
Sergunb 0:8918a71cdbe9 303
Sergunb 0:8918a71cdbe9 304 //Skip the leading slash character
Sergunb 0:8918a71cdbe9 305 if(pathIsAbsolute(path))
Sergunb 0:8918a71cdbe9 306 path++;
Sergunb 0:8918a71cdbe9 307
Sergunb 0:8918a71cdbe9 308 //Search for the first slash character to be removed
Sergunb 0:8918a71cdbe9 309 for(end = NULL; *path != '\0'; path++)
Sergunb 0:8918a71cdbe9 310 {
Sergunb 0:8918a71cdbe9 311 if(*path != '/' && *path != '\\')
Sergunb 0:8918a71cdbe9 312 end = NULL;
Sergunb 0:8918a71cdbe9 313 else if(!end)
Sergunb 0:8918a71cdbe9 314 end = path;
Sergunb 0:8918a71cdbe9 315 }
Sergunb 0:8918a71cdbe9 316
Sergunb 0:8918a71cdbe9 317 //Remove the trailing slash characters
Sergunb 0:8918a71cdbe9 318 if(end) *end = '\0';
Sergunb 0:8918a71cdbe9 319 }
Sergunb 0:8918a71cdbe9 320
Sergunb 0:8918a71cdbe9 321
Sergunb 0:8918a71cdbe9 322 /**
Sergunb 0:8918a71cdbe9 323 * @brief Concatenate two paths
Sergunb 0:8918a71cdbe9 324 * @param[in,out] path NULL-terminated string containing the first path
Sergunb 0:8918a71cdbe9 325 * @param[in] more NULL-terminated string containing the second path
Sergunb 0:8918a71cdbe9 326 * @param[in] maxLen Maximum pathname length
Sergunb 0:8918a71cdbe9 327 **/
Sergunb 0:8918a71cdbe9 328
Sergunb 0:8918a71cdbe9 329 void pathCombine(char_t *path, const char_t *more, size_t maxLen)
Sergunb 0:8918a71cdbe9 330 {
Sergunb 0:8918a71cdbe9 331 size_t n1;
Sergunb 0:8918a71cdbe9 332 size_t n2;
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 //Append a slash character to the first path
Sergunb 0:8918a71cdbe9 335 if(*path != '\0')
Sergunb 0:8918a71cdbe9 336 pathAddSlash(path, maxLen);
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338 //Skip any slash character at the beginning of the second path
Sergunb 0:8918a71cdbe9 339 while(*more == '/' || *more == '\\') more++;
Sergunb 0:8918a71cdbe9 340
Sergunb 0:8918a71cdbe9 341 //Retrieve the length of the first path
Sergunb 0:8918a71cdbe9 342 n1 = strlen(path);
Sergunb 0:8918a71cdbe9 343 //Retrieve the length of second path
Sergunb 0:8918a71cdbe9 344 n2 = strlen(more);
Sergunb 0:8918a71cdbe9 345
Sergunb 0:8918a71cdbe9 346 //Check the length of the resulting string
Sergunb 0:8918a71cdbe9 347 if(n1 < maxLen)
Sergunb 0:8918a71cdbe9 348 {
Sergunb 0:8918a71cdbe9 349 //Limit the number of characters to be copied
Sergunb 0:8918a71cdbe9 350 n2 = MIN(n2, maxLen - n1);
Sergunb 0:8918a71cdbe9 351 //Concatenate the resulting string
Sergunb 0:8918a71cdbe9 352 strncpy(path + n1, more, n2);
Sergunb 0:8918a71cdbe9 353 //Properly terminate the string with a NULL character
Sergunb 0:8918a71cdbe9 354 path[n1 + n2] = '\0';
Sergunb 0:8918a71cdbe9 355 }
Sergunb 0:8918a71cdbe9 356 }
Sergunb 0:8918a71cdbe9 357
Sergunb 0:8918a71cdbe9 358
Sergunb 0:8918a71cdbe9 359 /**
Sergunb 0:8918a71cdbe9 360 * @brief Check whether a file name matches the specified pattern
Sergunb 0:8918a71cdbe9 361 * @param[in] path NULL-terminated string that contains the path to be matched
Sergunb 0:8918a71cdbe9 362 * @param[in] pattern NULL-terminated string that contains the pattern for
Sergunb 0:8918a71cdbe9 363 * which to search. The pattern may contain wildcard characters
Sergunb 0:8918a71cdbe9 364 * @return TRUE if the path matches the specified pattern, else FALSE
Sergunb 0:8918a71cdbe9 365 **/
Sergunb 0:8918a71cdbe9 366
Sergunb 0:8918a71cdbe9 367 bool_t pathMatch(const char_t *path, const char_t* pattern)
Sergunb 0:8918a71cdbe9 368 {
Sergunb 0:8918a71cdbe9 369 size_t i = 0;
Sergunb 0:8918a71cdbe9 370 size_t j = 0;
Sergunb 0:8918a71cdbe9 371
Sergunb 0:8918a71cdbe9 372 //Parse the pattern string
Sergunb 0:8918a71cdbe9 373 while(pattern[j] != '\0')
Sergunb 0:8918a71cdbe9 374 {
Sergunb 0:8918a71cdbe9 375 //Any wildcard character found?
Sergunb 0:8918a71cdbe9 376 if(pattern[j] == '?')
Sergunb 0:8918a71cdbe9 377 {
Sergunb 0:8918a71cdbe9 378 //The question mark matches a single character
Sergunb 0:8918a71cdbe9 379 if(path[i] == '\0')
Sergunb 0:8918a71cdbe9 380 {
Sergunb 0:8918a71cdbe9 381 return FALSE;
Sergunb 0:8918a71cdbe9 382 }
Sergunb 0:8918a71cdbe9 383 else
Sergunb 0:8918a71cdbe9 384 {
Sergunb 0:8918a71cdbe9 385 //Advance position in pathname
Sergunb 0:8918a71cdbe9 386 i++;
Sergunb 0:8918a71cdbe9 387 //Advance position in pattern string
Sergunb 0:8918a71cdbe9 388 j++;
Sergunb 0:8918a71cdbe9 389 }
Sergunb 0:8918a71cdbe9 390 }
Sergunb 0:8918a71cdbe9 391 else if(pattern[j] == '*')
Sergunb 0:8918a71cdbe9 392 {
Sergunb 0:8918a71cdbe9 393 //The asterisk sign matches zero or more characters
Sergunb 0:8918a71cdbe9 394 if(path[i] == '\0')
Sergunb 0:8918a71cdbe9 395 {
Sergunb 0:8918a71cdbe9 396 //Advance position in pattern string
Sergunb 0:8918a71cdbe9 397 j++;
Sergunb 0:8918a71cdbe9 398 }
Sergunb 0:8918a71cdbe9 399 else if(pathMatch(path + i, pattern + j + 1))
Sergunb 0:8918a71cdbe9 400 {
Sergunb 0:8918a71cdbe9 401 return TRUE;
Sergunb 0:8918a71cdbe9 402 }
Sergunb 0:8918a71cdbe9 403 else
Sergunb 0:8918a71cdbe9 404 {
Sergunb 0:8918a71cdbe9 405 //Advance position in pathname
Sergunb 0:8918a71cdbe9 406 i++;
Sergunb 0:8918a71cdbe9 407 }
Sergunb 0:8918a71cdbe9 408 }
Sergunb 0:8918a71cdbe9 409 else
Sergunb 0:8918a71cdbe9 410 {
Sergunb 0:8918a71cdbe9 411 //Case insensitive comparison
Sergunb 0:8918a71cdbe9 412 if(tolower((uint8_t) path[i]) != tolower((uint8_t) pattern[j]))
Sergunb 0:8918a71cdbe9 413 {
Sergunb 0:8918a71cdbe9 414 return FALSE;
Sergunb 0:8918a71cdbe9 415 }
Sergunb 0:8918a71cdbe9 416 else
Sergunb 0:8918a71cdbe9 417 {
Sergunb 0:8918a71cdbe9 418 //Advance position in pathname
Sergunb 0:8918a71cdbe9 419 i++;
Sergunb 0:8918a71cdbe9 420 //Advance position in pattern string
Sergunb 0:8918a71cdbe9 421 j++;
Sergunb 0:8918a71cdbe9 422 }
Sergunb 0:8918a71cdbe9 423 }
Sergunb 0:8918a71cdbe9 424 }
Sergunb 0:8918a71cdbe9 425
Sergunb 0:8918a71cdbe9 426 //Check whether the file name matches the specified pattern
Sergunb 0:8918a71cdbe9 427 if(path[i] == '\0' && pattern[j] == '\0')
Sergunb 0:8918a71cdbe9 428 return TRUE;
Sergunb 0:8918a71cdbe9 429 else
Sergunb 0:8918a71cdbe9 430 return FALSE;
Sergunb 0:8918a71cdbe9 431 }
Sergunb 0:8918a71cdbe9 432