FindFirstFile matching regexp AND directories

183 views
Skip to first unread message

Denis Miletic

unread,
Mar 3, 2003, 1:44:55 AM3/3/03
to
I'll get right to the point, here is what I have:

void ParseDirectoryTree(
char *Path,
char *MatchFiles,
void (*ProcessFile)(char *Path, WIN32_FIND_DATA *FileData))
{
WIN32_FIND_DATA FileData;
HANDLE FileHandle;
char FullPath[MAX_PATH];
char SubDirPath[MAX_PATH];

sprintf(FullPath, "%s\\%s", Path, MatchFiles);
FileHandle = FindFirstFile(FullPath, &FileData);

if (FileHandle != INVALID_HANDLE_VALUE)
{
do
{
if (FileData.dwFileAttributes ^ FILE_ATTRIBUTE_DIRECTORY)
{
(*ProcessFile)(Path, &FileData);
}
}
while (FindNextFile(FileHandle, &FileData));
FindClose(FileHandle);
}

sprintf(FullPath, "%s\\*.*", Path);
FileHandle = FindFirstFile(FullPath, &FileData);

if (FileHandle != INVALID_HANDLE_VALUE)
{
do
{
if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (strcmp(FileData.cFileName, ".") != 0
&& strcmp(FileData.cFileName, "..") != 0)
{
sprintf(SubDirPath, "%s\\%s", Path, FileData.cFileName);
ParseDirectoryTree(SubDirPath, MatchFiles, ProcessFile);
}
}
}
while (FindNextFile(FileHandle, &FileData));
FindClose(FileHandle);
}
}

I don't like the fact that I'm going through all the files twice, so I
was wondering what are my other possibilities (other than using external
regexp library, or hacking up my own). So is there a way to make
FindFirstFile() search files that match a given pattern (say *.c)
AND directories that match any pattern (*.*)? If not is there a
function that would match simple regexp patterns for two strings,
similar to the way FindFirstFile() does it? Cheers.

Boris Dynin

unread,
Mar 3, 2003, 3:58:57 PM3/3/03
to
Hi,

Actually, it's pretty easy to write a basic regexp processor: it's a finite
state machine with just a few states.
As a matter of fact I wrote such a program some time ago. Here it's in case
you are interested.
Please notice that the code below WAS NOT thoroughly tested.

Boris

MAIN.CPP>>>>>>>>>>>>>>>>>>>>

#include <stdlib.h>
#include <stdio.h>

#include "regexp.h"

void Usage()
{
printf("Usage: REGEXP.EXE regexpStr filenameStr\n");
exit(2);
}
void main(int argc, char *argv[])
{
if ( argc != 3 )
{
Usage();
}

bool bMatch = MatchRegExp(argv[1],argv[2]);

printf(bMatch ? "Match\n" : "No match\n");
}

<<<<<<<MAIN.CPP

REGEXP.H>>>>>>>>>>>>>>>>
/*
Handles regular expressions like: aaa*bbb?ccc.ddd.fff

The wildcards are:
* - any char sequence of length>=0
? - any single character
For simplicity, wildcard chars aren't allowed to come back to back:
for example, a**b or a*?b aren't allowed.
*/


bool MatchRegExp
(
const char* strRegExp /*regexp string*/,
const char* strFilename /*filename string*/
);
<<<<<<<<<<<<<<REGEXP.H

REGEXP.CPP>>>>>>>>>>>>>>>>
enum RGState
{
e_inAsterisk,
e_inQuestionMark,
e_inPlainText,
e_error,
e_match
};

bool MatchRegExp
(
const char* strRegExp /*regexp string*/,
const char* strFilename /*filename string*/
)
{
RGState state = e_inPlainText;
int idxCharRegExp = 0;
int idxCharFileName = 0;
while (state != e_error && state != e_match)
{
switch (state)
{
case e_inPlainText:
if ( strFilename[idxCharFileName] == '\0' &&
( strRegExp[idxCharRegExp] == '\0' ||
strRegExp[idxCharRegExp] == '*' &&
strRegExp[idxCharRegExp+1] == '\0' ) )
{
state = e_match;
}
else
{
switch (strRegExp[idxCharRegExp])
{
case '\0':
state = e_error;
break;
case '*':
state = e_inAsterisk;
break;
case '?':
state = e_inQuestionMark;
break;
default:
if ( strRegExp[idxCharRegExp] == strFilename[idxCharFileName] )
{ // match so far
idxCharRegExp++;
idxCharFileName++;
}
else
{ // no match
state = e_error;
break;
}
break;
}; // switch ...
} // if ...
break;

case e_inAsterisk:
if ( strRegExp[idxCharRegExp+1] == '\0' &&
strFilename[idxCharFileName] == '\0' )
{
state = e_match;
}
else if ( strRegExp[idxCharRegExp+1] == strFilename[idxCharFileName] )
{
state = e_inPlainText;
idxCharRegExp++;
}
else
{
idxCharFileName++;
}
break;

case e_inQuestionMark:
if ( strRegExp[idxCharRegExp+1] == '\0' &&
strFilename[idxCharFileName] == '\0' )
{
state = e_match;
}
else
{
state = e_inPlainText;
idxCharRegExp++;
idxCharFileName++;
}
break;
}; // switch ...
} // while ...

return (state == e_match);
}


<<<<<<<<<<<<<<REGEXP.CPP


"Denis Miletic" <denisM...@zg.hinet.hr> wrote in message
news:MPG.18cd1851d...@news.hinet.hr...

Reply all
Reply to author
Forward
0 new messages