delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2004/09/23/09:38:52

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Message-ID: <007501c4a172$a96aa9e0$b200a8c0@mindcooler>
From: =?iso-8859-1?Q?Mikael_=C5sberg?= <mikas493 AT student DOT liu DOT se>
To: <cygwin AT cygwin DOT com>
Subject: Same code, same script, different results
Date: Thu, 23 Sep 2004 15:38:50 +0200
MIME-Version: 1.0

Hello, I am using the latest Cygwin with all packages updated (running 
Windows XP Professional SP2) and I'm having a problem with a simple C++ 
program that uses the Win32 API to scan a directory (recursively or 
non-recursively, depending on user input). The code is as follows:

#include <windows.h>
#include <cstdio> /* sprintf() */
#include <cstdlib> /* EXIT_FAILURE, EXIT_SUCCESS */
#include <cstring> /* strcat(), strcmp(), strcpy(), strlen() */
#include <iostream>

using std::cerr;
using std::cout;
using std::endl;
using std::sprintf;
using std::strcat;
using std::strcmp;
using std::strcpy;
using std::strlen;

static void directory_scan(char* search_directory,
                                     bool recursive = true);

static bool ends_with_backslash(const char* const str);

static void handle_find_first_file_error(const char* const 
current_directory);

int
main(int argc, char* argv[])
{
   if(argc < 2)
   {
      cerr << "You must pass the (full) starting path as an argument." << 
endl;

      return EXIT_FAILURE;
   }

   bool recursive = true;

   if(argc >= 3)
   {
      if(strcmp(argv[2], "--non-recursive") == 0)
      {
         recursive = false;

         cout << "Will perform a non-recursive scan of directory "
              << argv[1] << "." << endl;
      }
      else
      {
         cerr << "Ignoring unknown option " << argv[2] << "." << endl;
      }
   }

   if(strlen(argv[1]) > MAX_PATH)
   {
      cerr << "Path too long! Max length is " << MAX_PATH << "." << endl;

      return EXIT_FAILURE;
   }

   /* Since directory_scan() may change the string passed to it, *
    * we don't pass argv[1] directly. Instead, we pass a pointer to a copy *
    * of the string in argv[1]. 
*/
   char directory[MAX_PATH + 1];

   strcpy(directory, argv[1]);

   directory_scan(directory, recursive);

   return EXIT_SUCCESS;
}

static void
directory_scan(char* current_directory, bool recursive)
{
   if(!ends_with_backslash(current_directory))
   {
      strcat(current_directory, "\\");
   }

   char find_first_file_string[MAX_PATH + 5];

   sprintf(find_first_file_string, "%s*.*", current_directory);

   WIN32_FIND_DATA find_data;

   HANDLE file_handle = FindFirstFile(find_first_file_string, &find_data);

   if(file_handle == INVALID_HANDLE_VALUE)
   {
      handle_find_first_file_error(current_directory);

      /* We don't throw an exception here, because it might just be this  *
       * one directory we can't open (maybe protected by the OS), and we  *
       * don't want to break any recursion because of it. Besides, if we  *
       * throw an exception here all previously opened file handles *
       * will not be closed.                                              */
      return;
   }

   do
   {
      if(strcmp(find_data.cFileName, ".") != 0 &&
         strcmp(find_data.cFileName, "..") != 0)
      {
         char complete_file_name[MAX_PATH + 1];

         sprintf(complete_file_name,
                 "%s%s",
                 current_directory,
                 find_data.cFileName);

         cout << complete_file_name << endl;

         if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
            recursive)
         {
            directory_scan(complete_file_name, recursive);
         }
      }
   }while(FindNextFile(file_handle, &find_data));

   FindClose(file_handle);
}

static bool
ends_with_backslash(const char* const str)
{
   return (str[strlen(str) - 1] == '\\');
}

static void
handle_find_first_file_error(const char* const current_directory)
{
   unsigned long error = GetLastError();

   char message[128];

   FormatMessage(
      FORMAT_MESSAGE_FROM_SYSTEM,
      NULL,
      error,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      message,
      sizeof(message),
      NULL
      );

    cerr << "FindFirstFile() returned INVALID_HANDLE_VALUE." << endl;
    cerr << "Current directory was " << current_directory << "." << endl;
    cerr << "error code was: " << message << endl;
}

If I test this program with the following bash script:
#!/bin/bash
echo "Performing a scan without using recursion"
./directory_scanner.exe c:\\coding\\cygwin\\c++\\ --non-recursive

the output is:
Performing a scan without using recursion
Ignoring unknown option --non-recursive.
[Recursive listing snipped]

If I compile the exactly the same code under MSVC++ 7.1 and invoke the 
executable it produces with the exactly the same script, the output is:
Performing a scan without using recursion
Will perform a non-recursive scan of directory c:\coding\cygwin\c++\.
[Non-recursive listing snipped]

What's going on here? Why doesn't strcmp() return 0 if compiled with g++ 
with the input given above?

/ Mikael 



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019