Author: tkreuzer Date: Tue May 31 17:29:49 2011 New Revision: 52023
URL: http://svn.reactos.org/svn/reactos?rev=52023&view=rev Log: [CRT] Rewrite _splitpath. See issue #6244 for more details.
Modified: trunk/reactos/lib/sdk/crt/string/splitp.c
Modified: trunk/reactos/lib/sdk/crt/string/splitp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/sdk/crt/string/splitp.c... ============================================================================== --- trunk/reactos/lib/sdk/crt/string/splitp.c [iso-8859-1] (original) +++ trunk/reactos/lib/sdk/crt/string/splitp.c [iso-8859-1] Tue May 31 17:29:49 2011 @@ -1,3 +1,10 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: BSD - See COPYING.ARM in the top level directory + * PURPOSE: CRT: implementation of _splitpath / _wsplitpath + * PROGRAMMERS: Timo Kreuzer + */ + #include <precomp.h> #include <tchar.h>
@@ -6,64 +13,72 @@ */ void _tsplitpath(const _TCHAR* path, _TCHAR* drive, _TCHAR* dir, _TCHAR* fname, _TCHAR* ext) { - _TCHAR* tmp_drive = NULL; - _TCHAR* tmp_dir = NULL; - _TCHAR* tmp_ext = NULL; + const _TCHAR *src, *dir_start, *file_start = 0, *ext_start = 0;
- tmp_drive = (_TCHAR*)_tcschr(path,':'); - if (drive) + /* Truncate all output strings */ + if (drive) drive[0] = '\0'; + if (dir) dir[0] = '\0'; + if (fname) fname[0] = '\0'; + if (ext) ext[0] = '\0'; + + /* Check parameter */ + if (!path) { - if (tmp_drive) - { - _tcsncpy(drive,tmp_drive-1,2); - *(drive+2) = 0; - } - else - { - *drive = 0; - } - } - if (!tmp_drive) - { - tmp_drive = (_TCHAR*)path - 1; + __set_errno(EINVAL); + return; }
- tmp_dir = (_TCHAR*)_tcsrchr(path,'\'); - if (dir) + /* Skip '\?' prefix */ + if ((path[0] == '\') && (path[1] == '\') && + (path[2] == '?') && (path[3] == '\')) path += 4; + + if (path[0] == '\0') return; + + /* Check if we have a drive letter (only 1 char supported) */ + if (path[1] == ':') { - if (tmp_dir) + if (drive) { - _tcsncpy(dir,tmp_drive+1,tmp_dir-tmp_drive); - *(dir+(tmp_dir-tmp_drive)) = 0; + drive[0] = path[0]; + drive[1] = ':'; + drive[2] = '\0'; } - else - { - *dir =0; - } + path += 2; + } + + /* Scan the rest of the string */ + dir_start = path; + while (*path != '\0') + { + /* Remember last path seperator and last dot */ + if ((*path == '\') || (*path == '/')) file_start = path + 1; + if (*path == '.') ext_start = path; + path++; }
- /* If the dot is before the last dir separator, it's part - * of a directory name, not the start of the extension */ - if (!tmp_ext || tmp_ext < tmp_dir) + /* Check if we got */ + if (!file_start) file_start = path; + if (!ext_start || ext_start < file_start) ext_start = path; + + if (dir) { - tmp_ext = (_TCHAR*)path+_tcslen(path); - } - if (ext) - { - _tcscpy(ext,tmp_ext); + src = dir_start; + while (src < file_start) *dir++ = *src++; + *dir = '\0'; }
- if (fname) + if (fname) { - if (tmp_dir) - { - _tcsncpy(fname,tmp_dir+1,tmp_ext-tmp_dir-1); - *(fname+(tmp_ext-tmp_dir-1)) = 0; - } - else - { - _tcsncpy(fname,tmp_drive+1,tmp_ext-tmp_drive-1); - *(fname+(tmp_ext-path))=0; - } + src = file_start; + while (src < ext_start) *fname++ = *src++; + *fname = '\0'; + } + + if (ext) + { + src = ext_start; + while (*src != '\0') *ext++ = *src++; + *ext = '\0'; } } +