|
|
- /*
- * 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;
- }
|