| /* |
| ** 2025-12-26 |
| ** |
| ** The author disclaims copyright to this source code. In place of |
| ** a legal notice, here is a blessing: |
| ** |
| ** May you do good and not evil. |
| ** May you find forgiveness for yourself and forgive others. |
| ** May you share freely, never taking more than you give. |
| ** |
| ************************************************************************* |
| ** |
| ** This file implements a substitute process entry point for windows |
| ** that correctly interprets command-line arguments as UTF-8. This is |
| ** a work-around for the (unfixed) Windows bug known as "WorstFit" and |
| ** described at: |
| ** |
| ** * https://news.ycombinator.com/item?id=42647101 |
| ** |
| ** USAGE: |
| ** |
| ** If you have a command-line program coded to C-language standard in which |
| ** the entry point is: |
| ** |
| ** int main(int argc, char **argv){...} |
| ** |
| ** That does not work on Windows if there are non-ASCII characters on the |
| ** command line. Programs are expected to use an alternative entry point: |
| ** |
| ** int wmain(int wargc, wchar_t **wargv){...} |
| ** |
| ** This file implements _wmain() but then converts all of the wargv elements |
| ** to UTF-8 and passes them off to utf8_main(). |
| ** |
| ** So, a command-line tool that implements the standard entry point can be |
| ** modified by adding the following lines just prior to main(): |
| ** |
| ** #ifdef _WIN32 |
| ** #define main utf8_main |
| ** #endif |
| ** |
| ** Then, include this file in the list of files that implement the program, |
| ** and the program will work correctly, even on Windows. |
| */ |
| #include <windows.h> |
| #include <stdio.h> |
| |
| extern int utf8_main(int,char**); |
| int wmain(int argc, wchar_t **wargv){ |
| int rc, i; |
| char **argv = malloc( sizeof(char*) * (argc+1) ); |
| char **orig = argv; |
| if( argv==0 ){ |
| fprintf(stderr, "malloc failed\n"); |
| exit(1); |
| } |
| for(i=0; i<argc; i++){ |
| int nByte = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, 0, 0, 0, 0); |
| if( nByte==0 ){ |
| argv[i] = 0; |
| }else{ |
| argv[i] = malloc( nByte ); |
| if( argv[i]==0 ){ |
| fprintf(stderr, "malloc failed\n"); |
| exit(1); |
| } |
| nByte = WideCharToMultiByte(CP_UTF8, 0, wargv[i], -1, argv[i],nByte,0,0); |
| if( nByte==0 ){ |
| free(argv[i]); |
| argv[i] = 0; |
| } |
| } |
| } |
| argv[argc] = 0; |
| rc = utf8_main(argc, argv); |
| for(i=0; i<argc; i++) free(orig[i]); |
| free(argv); |
| return rc; |
| } |