[CRT]
[reactos.git] / reactos / lib / sdk / crt / string / splitp.c
index ea41fb0..5242d51 100644 (file)
@@ -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>
 
  */
 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)
-    {
-      if (tmp_drive)
-        {
-          _tcsncpy(drive,tmp_drive-1,2);
-          *(drive+2) = 0;
-        }
-      else
-        {
-          *drive = 0;
-        }
-    }
-  if (!tmp_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';
+
+#if WINVER >= 0x600
+    /* Check parameter */
+    if (!path)
     {
-      tmp_drive = (_TCHAR*)path - 1;
+#ifndef _LIBCNT_
+        _set_errno(EINVAL);
+#endif
+        return;
     }
+#endif
+
+    //_Analysis_assume_(path != 0);
+
+#if WINVER == 0x600
+    /* Skip '\\?\' prefix */
+    if ((path[0] == '\\') && (path[1] == '\\') &&
+        (path[2] == '?') && (path[3] == '\\')) path += 4;
+#endif
 
-  tmp_dir = (_TCHAR*)_tcsrchr(path,'\\');
-  if (dir)
+    if (path[0] == '\0') return;
+
+    /* Check if we have a drive letter (only 1 char supported) */
+    if (path[1] == ':')
     {
-      if (tmp_dir)
-        {
-          _tcsncpy(dir,tmp_drive+1,tmp_dir-tmp_drive);
-          *(dir+(tmp_dir-tmp_drive)) = 0;
-        }
-      else
+        if (drive)
         {
-          *dir =0;
+            drive[0] = path[0];
+            drive[1] = ':';
+            drive[2] = '\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 a file name / extension */
+    if (!file_start)
+        file_start = dir_start;
+    if (!ext_start || ext_start < file_start)
+        ext_start = path;
+
+    if (dir)
     {
-      tmp_ext = (_TCHAR*)path+_tcslen(path);
+        src = dir_start;
+        while (src < file_start) *dir++ = *src++;
+        *dir = '\0';
     }
-  if (ext)
+
+    if (fname)
     {
-      _tcscpy(ext,tmp_ext);
+        src = file_start;
+        while (src < ext_start) *fname++ = *src++;
+        *fname = '\0';
     }
 
-  if (fname)
+    if (ext)
     {
-      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 = ext_start;
+        while (*src != '\0') *ext++ = *src++;
+        *ext = '\0';
     }
 }
+