msvcrt/tests: Add more tests for setlocale().
[wine] / dlls / msvcrt / tests / dir.c
1 /*
2  * Unit test suite for dir functions
3  *
4  * Copyright 2006 CodeWeavers, Aric Stewart
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "wine/test.h"
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <io.h>
28 #include <windef.h>
29 #include <winbase.h>
30 #include <winnls.h>
31 #include <process.h>
32 #include <errno.h>
33
34 typedef struct
35 {
36     const char* buffer;
37     const char* drive;
38     const char* dir;
39     const char* file;
40     const char* ext;
41     const char* expected;
42 } makepath_case;
43
44 #define USE_BUFF ((char*)~0ul)
45 static const makepath_case makepath_cases[] =
46 {
47     { NULL, NULL, NULL, NULL, NULL, "" }, /* 0 */
48     { NULL, "c", NULL, NULL, NULL, "c:" },
49     { NULL, "c:", NULL, NULL, NULL, "c:" },
50     { NULL, "c:\\", NULL, NULL, NULL, "c:" },
51     { NULL, NULL, "dir", NULL, NULL, "dir\\" },
52     { NULL, NULL, "dir\\", NULL, NULL, "dir\\" },
53     { NULL, NULL, "\\dir", NULL, NULL, "\\dir\\" },
54     { NULL, NULL, NULL, "file", NULL, "file" },
55     { NULL, NULL, NULL, "\\file", NULL, "\\file" },
56     { NULL, NULL, NULL, "file", NULL, "file" },
57     { NULL, NULL, NULL, NULL, "ext", ".ext" }, /* 10 */
58     { NULL, NULL, NULL, NULL, ".ext", ".ext" },
59     { "foo", NULL, NULL, NULL, NULL, "" },
60     { "foo", USE_BUFF, NULL, NULL, NULL, "f:" },
61     { "foo", NULL, USE_BUFF, NULL, NULL, "foo\\" },
62     { "foo", NULL, NULL, USE_BUFF, NULL, "foo" },
63     { "foo", NULL, USE_BUFF, "file", NULL, "foo\\file" },
64     { "foo", NULL, USE_BUFF, "file", "ext", "foo\\file.ext" },
65     { "foo", NULL, NULL, USE_BUFF, "ext", "foo.ext" },
66     /* remaining combinations of USE_BUFF crash native */
67     { NULL, "c", "dir", "file", "ext", "c:dir\\file.ext" },
68     { NULL, "c:", "dir", "file", "ext", "c:dir\\file.ext" }, /* 20 */
69     { NULL, "c:\\", "dir", "file", "ext", "c:dir\\file.ext" }
70 };
71
72 static void test_makepath(void)
73 {
74     WCHAR driveW[MAX_PATH];
75     WCHAR dirW[MAX_PATH];
76     WCHAR fileW[MAX_PATH];
77     WCHAR extW[MAX_PATH];
78     WCHAR bufferW[MAX_PATH];
79     char buffer[MAX_PATH];
80
81     unsigned int i, n;
82
83     for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); ++i)
84     {
85         const makepath_case* p = &makepath_cases[i];
86
87         memset(buffer, 'X', MAX_PATH);
88         if (p->buffer)
89             strcpy(buffer, p->buffer);
90
91         /* Ascii */
92         _makepath(buffer,
93                   p->drive == USE_BUFF ? buffer : p->drive,
94                   p->dir == USE_BUFF ? buffer : p->dir,
95                   p->file == USE_BUFF? buffer : p->file,
96                   p->ext == USE_BUFF ? buffer : p->ext);
97
98         buffer[MAX_PATH - 1] = '\0';
99         ok(!strcmp(p->expected, buffer), "got '%s' for case %d\n", buffer, i);
100
101         /* Unicode */
102         if (p->drive != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->drive, -1, driveW, MAX_PATH);
103         if (p->dir != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->dir, -1, dirW, MAX_PATH);
104         if (p->file != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->file, -1, fileW, MAX_PATH);
105         if (p->ext != USE_BUFF) MultiByteToWideChar(CP_ACP, 0, p->ext, -1, extW, MAX_PATH);
106
107         memset(buffer, 0, MAX_PATH);
108         for (n = 0; n < MAX_PATH; ++n)
109             bufferW[n] = 'X';
110         if (p->buffer) MultiByteToWideChar( CP_ACP, 0, p->buffer, -1, bufferW, MAX_PATH);
111
112         _wmakepath(bufferW,
113                    p->drive == USE_BUFF ? bufferW : p->drive ? driveW : NULL,
114                    p->dir == USE_BUFF ? bufferW : p->dir ? dirW : NULL,
115                    p->file == USE_BUFF? bufferW : p->file ? fileW : NULL,
116                    p->ext == USE_BUFF ? bufferW : p->ext ? extW : NULL);
117
118         bufferW[MAX_PATH - 1] = '\0';
119         WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
120         ok(!strcmp(p->expected, buffer), "got '%s' for unicode case %d\n", buffer, i);
121     }
122 }
123
124 static void test_fullpath(void)
125 {
126     char full[MAX_PATH];
127     char tmppath[MAX_PATH];
128     char prevpath[MAX_PATH];
129     char level1[MAX_PATH];
130     char level2[MAX_PATH];
131     char teststring[MAX_PATH];
132     char *freeme;
133     BOOL rc,free1,free2;
134
135     free1=free2=TRUE;
136     GetCurrentDirectory(MAX_PATH, prevpath);
137     GetTempPath(MAX_PATH,tmppath);
138     strcpy(level1,tmppath);
139     strcat(level1,"msvcrt-test\\");
140
141     rc = CreateDirectory(level1,NULL);
142     if (!rc && GetLastError()==ERROR_ALREADY_EXISTS)
143         free1=FALSE;
144
145     strcpy(level2,level1);
146     strcat(level2,"nextlevel\\");
147     rc = CreateDirectory(level2,NULL);
148     if (!rc && GetLastError()==ERROR_ALREADY_EXISTS)
149         free2=FALSE;
150     SetCurrentDirectory(level2);
151
152     ok(_fullpath(full,"test", MAX_PATH)!=NULL,"_fullpath failed\n");
153     strcpy(teststring,level2);
154     strcat(teststring,"test");
155     ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
156     ok(_fullpath(full,"\\test", MAX_PATH)!=NULL,"_fullpath failed\n");
157     strncpy(teststring,level2,3);
158     teststring[3]=0;
159     strcat(teststring,"test");
160     ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
161     ok(_fullpath(full,"..\\test", MAX_PATH)!=NULL,"_fullpath failed\n");
162     strcpy(teststring,level1);
163     strcat(teststring,"test");
164     ok(strcmp(full,teststring)==0,"Invalid Path returned %s\n",full);
165     ok(_fullpath(full,"..\\test", 10)==NULL,"_fullpath failed to generate error\n");
166
167     freeme = _fullpath(NULL,"test", 0);
168     ok(freeme!=NULL,"No path returned\n");
169     strcpy(teststring,level2);
170     strcat(teststring,"test");
171     ok(strcmp(freeme,teststring)==0,"Invalid Path returned %s\n",freeme);
172     free(freeme);
173
174     SetCurrentDirectory(prevpath);
175     if (free2)
176         RemoveDirectory(level2);
177     if (free1)
178         RemoveDirectory(level1);
179 }
180
181 START_TEST(dir)
182 {
183     test_fullpath();
184     test_makepath();
185 }