🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

401 lines
9.8 KiB

/*
* Test program to try unicode file names.
*
* Copyright (C) 1998-2019 Toni Ronkko
* This file is part of dirent. Dirent may be freely distributed
* under the MIT license. For all details and documentation, see
* https://github.com/tronkko/dirent
*/
/* Silence warning about fopen being insecure */
#define _CRT_SECURE_NO_WARNINGS
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <time.h>
#include <locale.h>
#undef NDEBUG
#include <assert.h>
int
main(
int argc, char *argv[])
{
#ifdef WIN32
wchar_t wpath[MAX_PATH+1];
char path[MAX_PATH+1];
DWORD i, j, k, x;
BOOL ok;
HANDLE fh;
_WDIR *wdir;
struct _wdirent *wentry;
DIR *dir;
struct dirent *entry;
char buffer[100];
FILE *fp;
int counter = 0;
(void) argc;
(void) argv;
/* Initialize random number generator */
srand (((int) time (NULL)) * 257 + ((int) GetCurrentProcessId ()));
/* Set current locale */
if (argc > 1) {
printf ("Locale %s\n", argv[1]);
setlocale (LC_ALL, argv[1]);
} else {
setlocale (LC_ALL, "");
}
/****** CREATE FILE WITH UNICODE FILE NAME ******/
/* Get path to temporary directory (wide-character and ascii) */
i = GetTempPathW (MAX_PATH, wpath);
assert (i > 0);
j = GetTempPathA (MAX_PATH, path);
assert (j > 0);
/* Append random directory name */
for (k = 0; k < 10; k++) {
char c;
/* Generate random character */
c = "abcdefghijklmnopqrstuvwxyz"[rand() % 26];
/* Append character to paths */
assert (i < MAX_PATH && j < MAX_PATH);
wpath[i++] = c;
path[j++] = c;
}
/* Terminate paths */
assert (i < MAX_PATH && j < MAX_PATH);
wpath[i] = '\0';
path[j] = '\0';
/* Remember the end of directory name */
k = i;
/* Create directory using unicode */
ok = CreateDirectoryW (wpath, NULL);
if (!ok) {
DWORD e = GetLastError ();
wprintf (L"Cannot create directory %ls (code %u)\n", wpath, e);
abort ();
}
/* Overwrite zero terminator with path separator */
assert (i < MAX_PATH && j < MAX_PATH);
wpath[i++] = '\\';
/* Append a few unicode characters */
assert (i < MAX_PATH);
wpath[i++] = 0x6d4b;
assert (i < MAX_PATH);
wpath[i++] = 0x8bd5;
/* Terminate string */
assert (i < MAX_PATH);
wpath[i] = '\0';
/* Create file with unicode */
fh = CreateFileW(
wpath,
/* Access */ GENERIC_READ | GENERIC_WRITE,
/* Share mode */ 0,
/* Security attributes */ NULL,
/* Creation disposition */ CREATE_NEW,
/* Attributes */ FILE_ATTRIBUTE_NORMAL,
/* Template files */ NULL
);
assert (fh != INVALID_HANDLE_VALUE);
/* Write some data to file */
ok = WriteFile(
/* File handle */ fh,
/* Pointer to data */ "hep\n",
/* Number of bytes to write */ 4,
/* Number of bytes written */ NULL,
/* Overlapped */ NULL
);
assert (ok);
/* Close file */
ok = CloseHandle (fh);
assert (ok);
/****** MAKE SURE THAT UNICODE FILE NAME CAN BE READ BY _WREADDIR ******/
/* Zero terminate wide-character path and open directory stream */
wpath[k] = '\0';
wdir = _wopendir (wpath);
if (wdir == NULL) {
wprintf (L"Cannot open directory %ls\n", wpath);
abort ();
}
/* Read through entries */
counter = 0;
while ((wentry = _wreaddir (wdir)) != NULL) {
/* Skip pseudo directories */
if (wcscmp (wentry->d_name, L".") == 0) {
continue;
}
if (wcscmp (wentry->d_name, L"..") == 0) {
continue;
}
/* Found a file */
counter++;
assert (wentry->d_type == DT_REG);
/* Append file name to path */
i = k;
assert (i < MAX_PATH);
wpath[i++] = '\\';
x = 0;
while (wentry->d_name[x] != '\0') {
assert (i < MAX_PATH);
wpath[i++] = wentry->d_name[x++];
}
assert (i < MAX_PATH);
wpath[i] = '\0';
/* Open file for read */
fh = CreateFileW(
wpath,
/* Access */ GENERIC_READ,
/* Share mode */ 0,
/* Security attributes */ NULL,
/* Creation disposition */ OPEN_EXISTING,
/* Attributes */ FILE_ATTRIBUTE_NORMAL,
/* Template files */ NULL
);
assert (fh != INVALID_HANDLE_VALUE);
/* Read data from file */
ok = ReadFile(
/* File handle */ fh,
/* Output buffer */ buffer,
/* Maximum number of bytes to read */ sizeof (buffer) - 1,
/* Number of bytes actually read */ &x,
/* Overlapped */ NULL
);
assert (ok);
/* Make sure that we got the file contents right */
assert (x == 4);
assert (buffer[0] == 'h');
assert (buffer[1] == 'e');
assert (buffer[2] == 'p');
assert (buffer[3] == '\n');
/* Close file */
ok = CloseHandle (fh);
assert (ok);
}
assert (counter == 1);
/* Close directory */
_wclosedir (wdir);
/****** MAKE SURE THAT UNICODE FILE NAME CAN BE READ BY READDIR ******/
/* Zero terminate ascii path and open directory stream */
k = j;
path[k] = '\0';
dir = opendir (path);
if (dir == NULL) {
fprintf (stderr, "Cannot open directory %s\n", path);
abort ();
}
/* Read through entries */
counter = 0;
while ((entry = readdir (dir)) != NULL) {
/* Skip pseudo directories */
if (strcmp (entry->d_name, ".") == 0) {
continue;
}
if (strcmp (entry->d_name, "..") == 0) {
continue;
}
/* Found a file */
counter++;
assert (entry->d_type == DT_REG);
/* Append file name to path */
j = k;
assert (j < MAX_PATH);
path[j++] = '\\';
x = 0;
while (entry->d_name[x] != '\0') {
assert (j < MAX_PATH);
path[j++] = entry->d_name[x++];
}
assert (j < MAX_PATH);
path[j] = '\0';
/* Open file for read */
fp = fopen (path, "r");
if (!fp) {
fprintf (stderr, "Cannot open file %s\n", path);
abort ();
}
/* Read data from file */
if (fgets (buffer, sizeof (buffer), fp) == NULL) {
fprintf (stderr, "Cannot read file %s\n", path);
abort ();
}
/* Make sure that we got the file contents right */
assert (buffer[0] == 'h');
assert (buffer[1] == 'e');
assert (buffer[2] == 'p');
assert (buffer[3] == '\n');
assert (buffer[4] == '\0');
/* Close file */
fclose (fp);
}
assert (counter == 1);
/* Close directory */
closedir (dir);
/****** CREATE FILE WITH UTF-8 ******/
/* Append UTF-8 file name (åäö.txt) to path */
j = k;
path[j++] = '\\';
path[j++] = 0xc3;
path[j++] = 0xa5;
path[j++] = 0xc3;
path[j++] = 0xa4;
path[j++] = 0xc3;
path[j++] = 0xb6;
path[j++] = 0x2e;
path[j++] = 0x74;
path[j++] = 0x78;
path[j++] = 0x74;
assert (j < MAX_PATH);
path[j] = '\0';
/*
* Create file.
*
* Be ware that the code below creates a different file depending on the
* current locale! For example, if the current locale is
* english_us.65001, then the file name will be "åäö.txt" (7 characters).
* However, if the current locale is english_us.1252, then the file name
* will be "ÃċÃĊö.txt" (10 characters).
*/
printf ("Creating %s\n", path);
fp = fopen (path, "w");
if (!fp) {
fprintf (stderr, "Cannot open file %s\n", path);
abort ();
}
fputs ("hep\n", fp);
fclose (fp);
/* Open directory again */
path[k] = '\0';
dir = opendir (path);
if (dir == NULL) {
fprintf (stderr, "Cannot open directory %s\n", path);
abort ();
}
/* Read through entries */
counter = 0;
while ((entry = readdir (dir)) != NULL) {
/* Skip pseudo directories */
if (strcmp (entry->d_name, ".") == 0) {
continue;
}
if (strcmp (entry->d_name, "..") == 0) {
continue;
}
/* Found a file */
counter++;
assert (entry->d_type == DT_REG);
/* Append file name to path */
j = k;
assert (j < MAX_PATH);
path[j++] = '\\';
x = 0;
while (entry->d_name[x] != '\0') {
assert (j < MAX_PATH);
path[j++] = entry->d_name[x++];
}
assert (j < MAX_PATH);
path[j] = '\0';
/* Print file name for debugging */
printf ("Opening \"%s\" hex ", path + k + 1);
x = 0;
while (entry->d_name[x] != '\0') {
printf ("0x%02x ", (unsigned) (entry->d_name[x++] & 0xff));
}
printf ("\n");
/* Open file for read */
fp = fopen (path, "r");
if (!fp) {
fprintf (stderr, "Cannot open file %s\n", path);
abort ();
}
/* Read data from file */
if (fgets (buffer, sizeof (buffer), fp) == NULL) {
fprintf (stderr, "Cannot read file %s\n", path);
abort ();
}
/* Make sure that we got the file contents right */
assert (buffer[0] == 'h');
assert (buffer[1] == 'e');
assert (buffer[2] == 'p');
assert (buffer[3] == '\n');
assert (buffer[4] == '\0');
/* Close file */
fclose (fp);
}
assert (counter == 2);
/* Close directory */
closedir (dir);
#else
/* Linux */
(void) argc;
(void) argv;
#endif
return EXIT_SUCCESS;
}