Implemented UnixFolder's IPersistPropertyBag::Load method.
[wine] / programs / winepath / winepath.c
1 /*
2  * Translate between Windows and Unix paths formats
3  *
4  * Copyright 2002 Mike Wetherell
5  * Copyright 2005 Dmitry Timoshkov
6  * Copyright 2005 Francois Gouget
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "config.h"
24
25 #include <windows.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include "wine/debug.h"
30
31 enum {
32     SHORTFORMAT   = 1,
33     LONGFORMAT    = 2,
34     UNIXFORMAT    = 4,
35     WINDOWSFORMAT = 8
36 };
37
38 static const char progname[] = "winepath";
39
40 /*
41  * handle an option
42  */
43 static int option(int shortopt, const WCHAR *longopt)
44 {
45     static const char helpmsg[] =
46     "Convert PATH(s) to Unix or Windows long or short paths.\n"
47     "\n"
48     "  -u, --unix    converts a Windows path to a Unix path\n"
49     "  -w, --windows converts a Unix path to a long Windows path\n"
50     "  -l, --long    converts a short Windows path to the long format\n"
51     "  -s, --short   converts a long Windows path to the short format\n"
52     "  -h, --help    output this help message and exit\n"
53     "  -v, --version output version information and exit\n"
54     "\n"
55     "If more than one option is given then the input paths are output in\n"
56     "all formats specified, in the order long, short, Unix, Windows.\n"
57     "If no option is given the default is Unix format.\n";
58
59     switch (shortopt) {
60         case 'h':
61             printf("Usage: %s [OPTION] [PATH]...\n", progname);
62             printf(helpmsg);
63             exit(0);
64         case 'v':
65             printf("%s version " PACKAGE_VERSION "\n", progname);
66             exit(0);
67         case 'l':
68             return LONGFORMAT;
69         case 's':
70             return SHORTFORMAT;
71         case 'u':
72             return UNIXFORMAT;
73         case 'w':
74             return WINDOWSFORMAT;
75     }
76
77     fprintf(stderr, "%s: invalid option ", progname);
78     if (longopt)
79         fprintf(stderr, "%s\n", wine_dbgstr_w(longopt));
80     else
81         fprintf(stderr, "'-%c'\n", shortopt);
82     fprintf(stderr, "Try '%s --help' for help\n", progname);
83     exit(2);
84 }
85
86 /*
87  * Parse command line options
88  */
89 static int parse_options(const WCHAR *argv[])
90 {
91     static const WCHAR longW[] = { 'l','o','n','g',0 };
92     static const WCHAR shortW[] = { 's','h','o','r','t',0 };
93     static const WCHAR unixW[] = { 'u','n','i','x',0 };
94     static const WCHAR windowsW[] = { 'w','i','n','d','o','w','s',0 };
95     static const WCHAR helpW[] = { 'h','e','l','p',0 };
96     static const WCHAR versionW[] = { 'v','e','r','s','i','o','n',0 };
97     static const WCHAR nullW[] = { 0 };
98     static const WCHAR *longopts[] = { longW, shortW, unixW, windowsW, helpW, versionW, nullW };
99     int outputformats = 0;
100     int done = 0;
101     int i, j;
102
103     for (i = 1; argv[i] && !done; )
104     {
105         if (argv[i][0] != '-') {
106             /* not an option */
107             i++;
108             continue;
109         }
110
111         if (argv[i][1] == '-') {
112             if (argv[i][2] == 0) {
113                 /* '--' end of options */
114                 done = 1;
115             } else {
116                 /* long option */
117                 for (j = 0; longopts[j][0]; j++)
118                     if (!lstrcmpiW(argv[i]+2, longopts[j]))
119                         break;
120                 outputformats |= option(longopts[j][0], argv[i]);
121             }
122         } else {
123             /* short options */
124             for (j = 1; argv[i][j]; j++)
125                 outputformats |= option(argv[i][j], NULL);
126         }
127
128         /* remove option */
129         for (j = i + 1; argv[j - 1]; j++)
130             argv[j - 1] = argv[j];
131     }
132
133     return outputformats;
134 }
135
136 /*
137  * Main function
138  */
139 int wmain(int argc, const WCHAR *argv[])
140 {
141     LPSTR (*wine_get_unix_file_name_ptr)(LPCWSTR) = NULL;
142     LPWSTR (*wine_get_dos_file_name_ptr)(LPCSTR) = NULL;
143     WCHAR dos_pathW[MAX_PATH];
144     char path[MAX_PATH];
145     int outputformats;
146     int i;
147
148     outputformats = parse_options(argv);
149     if (outputformats == 0)
150         outputformats = UNIXFORMAT;
151
152     if (outputformats & UNIXFORMAT) {
153         wine_get_unix_file_name_ptr = (void*)
154             GetProcAddress(GetModuleHandle("KERNEL32"),
155                            "wine_get_unix_file_name");
156         if (wine_get_unix_file_name_ptr == NULL) {
157             fprintf(stderr, "%s: cannot get the address of "
158                             "'wine_get_unix_file_name'\n", progname);
159             exit(3);
160         }
161     }
162
163     if (outputformats & WINDOWSFORMAT) {
164         wine_get_dos_file_name_ptr = (void*)
165             GetProcAddress(GetModuleHandle("KERNEL32"),
166                            "wine_get_dos_file_name");
167         if (wine_get_dos_file_name_ptr == NULL) {
168             fprintf(stderr, "%s: cannot get the address of "
169                             "'wine_get_dos_file_name'\n", progname);
170             exit(3);
171         }
172     }
173
174     for (i = 1; argv[i]; i++)
175     {
176         *path='\0';
177         if (outputformats & LONGFORMAT) {
178             if (GetFullPathNameW(argv[i], MAX_PATH, dos_pathW, NULL))
179                 WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL);
180             printf("%s\n", path);
181         }
182         if (outputformats & SHORTFORMAT) {
183             if (GetShortPathNameW(argv[i], dos_pathW, MAX_PATH))
184                 WideCharToMultiByte(CP_UNIXCP, 0, dos_pathW, -1, path, MAX_PATH, NULL, NULL);
185             printf("%s\n", path);
186         }
187         if (outputformats & UNIXFORMAT) {
188             char *unix_name;
189
190             if ((unix_name = wine_get_unix_file_name_ptr(argv[i])))
191             {
192                 printf("%s\n", unix_name);
193                 HeapFree( GetProcessHeap(), 0, unix_name );
194             }
195             else printf( "\n" );
196         }
197         if (outputformats & WINDOWSFORMAT) {
198             WCHAR* windows_name;
199             char* unix_name;
200             DWORD size;
201
202             size=WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, NULL, 0, NULL, NULL);
203             unix_name=HeapAlloc(GetProcessHeap(), 0, size);
204             WideCharToMultiByte(CP_UNIXCP, 0, argv[i], -1, unix_name, size, NULL, NULL);
205
206             if ((windows_name = wine_get_dos_file_name_ptr(unix_name)))
207             {
208                 WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL);
209                 printf("%s\n", path);
210                 HeapFree( GetProcessHeap(), 0, windows_name );
211             }
212             else printf( "\n" );
213             HeapFree( GetProcessHeap(), 0, unix_name );
214         }
215     }
216
217     exit(0);
218 }