ReactOS  0.4.13-dev-235-g7373cb3
find.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <windef.h>
#include <winbase.h>
#include <winnls.h>
#include <winuser.h>
#include <conutils.h>
#include <strsafe.h>
#include "resource.h"
Include dependency graph for find.c:

Go to the source code of this file.

Macros

#define FIND_LINE_BUFFER_SIZE   4096
 

Functions

StrStrCase

@implemented

Locates a substring inside a NULL-terminated wide string.

Parameters
[in]pszStrThe NULL-terminated string to be scanned.
[in]pszSearchThe NULL-terminated string to search for.
[in]bIgnoreCaseTRUE if case has to be ignored, FALSE otherwise.
Returns
Returns a pointer to the first occurrence of pszSearch in pszStr, or NULL if pszSearch does not appear in pszStr. If pszSearch points to a string of zero length, the function returns pszStr.
static PWSTR StrStrCase (IN PCWSTR pszStr, IN PCWSTR pszSearch, IN BOOL bIgnoreCase)
 
FindString

@implemented

Prints all lines of the stream that contain a string.

Parameters
[in]pStreamThe stream to read from.
[in]pszFilePathThe file name to print out. Can be NULL.
[in]pszSearchStringThe NULL-terminated string to search for.
Returns
0 if the string was found at least once, 1 otherwise.
static int FindString (IN FILE *pStream, IN PCWSTR pszFilePath OPTIONAL, IN PCWSTR pszSearchString)
 
int wmain (int argc, WCHAR *argv[])
 

Variables

static BOOL bInvertSearch = FALSE
 
static BOOL bCountLines = FALSE
 
static BOOL bDisplayLineNumbers = FALSE
 
static BOOL bIgnoreCase = FALSE
 
static BOOL bDoNotSkipOfflineFiles = FALSE
 

Macro Definition Documentation

◆ FIND_LINE_BUFFER_SIZE

#define FIND_LINE_BUFFER_SIZE   4096

Definition at line 23 of file find.c.

Function Documentation

◆ FindString()

static int FindString ( IN FILE pStream,
IN PCWSTR pszFilePath  OPTIONAL,
IN PCWSTR  pszSearchString 
)
static

Definition at line 106 of file find.c.

110 {
111  LONG lLineCount = 0;
112  LONG lLineNumber = 0;
113  BOOL bSubstringFound;
114  int iReturnValue = 1;
115  WCHAR szLineBuffer[FIND_LINE_BUFFER_SIZE];
116 
117  if (pszFilePath != NULL)
118  {
119  /* Print the file's header */
120  ConPrintf(StdOut, L"\n---------- %s%s",
121  pszFilePath, bCountLines ? L": " : L"\n");
122  }
123 
124  /* Loop through every line in the file */
125  // FIXME: What if the string we search for crosses the boundary of our szLineBuffer ?
126  while (fgetws(szLineBuffer, _countof(szLineBuffer), pStream) != NULL)
127  {
128  ++lLineNumber;
129 
130  bSubstringFound = (StrStrCase(szLineBuffer, pszSearchString, bIgnoreCase) != NULL);
131 
132  /* Check if this line can be counted */
133  if (bSubstringFound != bInvertSearch)
134  {
135  iReturnValue = 0;
136 
137  if (bCountLines)
138  {
139  ++lLineCount;
140  }
141  else
142  {
143  /* Display the line number if needed */
145  {
146  ConPrintf(StdOut, L"[%ld]", lLineNumber);
147  }
148  ConPrintf(StdOut, L"%s", szLineBuffer);
149  }
150  }
151  }
152 
153  if (bCountLines)
154  {
155  /* Print the matching line count */
156  ConPrintf(StdOut, L"%ld\n", lLineCount);
157  }
158 #if 0
159  else if (pszFilePath != NULL && iReturnValue == 0)
160  {
161  /* Print a newline for formatting */
162  ConPrintf(StdOut, L"\n");
163  }
164 #endif
165 
166  return iReturnValue;
167 }
static BOOL bIgnoreCase
Definition: find.c:28
static BOOL bDisplayLineNumbers
Definition: find.c:27
#define _countof(array)
Definition: fontsub.cpp:30
static PWSTR StrStrCase(IN PCWSTR pszStr, IN PCWSTR pszSearch, IN BOOL bIgnoreCase)
Definition: find.c:52
#define FIND_LINE_BUFFER_SIZE
Definition: find.c:23
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
INT __cdecl ConPrintf(IN PCON_STREAM Stream, IN LPWSTR szStr,...)
Definition: outstream.c:520
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR L[]
Definition: oid.c:1250
static BOOL bCountLines
Definition: find.c:26
#define StdOut
Definition: stream.h:76
wchar_t * fgetws(wchar_t *buf, int bufsize, FILE *file)
Definition: wmain.c:22
static BOOL bInvertSearch
Definition: find.c:25

Referenced by ATL::CStringT< BaseType, StringTraits >::Find(), ATL::CStringT< BaseType, StringTraits >::Replace(), and wmain().

◆ StrStrCase()

static PWSTR StrStrCase ( IN PCWSTR  pszStr,
IN PCWSTR  pszSearch,
IN BOOL  bIgnoreCase 
)
static

Definition at line 52 of file find.c.

56 {
57  if (bIgnoreCase)
58  {
59  LCID LocaleId;
60  INT i, cch1, cch2;
61 
62  LocaleId = GetThreadLocale();
63 
64  cch1 = wcslen(pszStr);
65  cch2 = wcslen(pszSearch);
66 
67  if (cch2 == 0)
68  return (PWSTR)pszStr;
69 
70  for (i = 0; i <= cch1 - cch2; ++i)
71  {
72  if (CompareStringW(LocaleId /* LOCALE_SYSTEM_DEFAULT */,
73  NORM_IGNORECASE /* | NORM_LINGUISTIC_CASING */,
74  pszStr + i, cch2, pszSearch, cch2) == CSTR_EQUAL)
75  {
76  return (PWSTR)(pszStr + i);
77  }
78  }
79  return NULL;
80  }
81  else
82  {
83  return wcsstr(pszStr, pszSearch);
84  }
85 }
static BOOL bIgnoreCase
Definition: find.c:28
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
uint16_t * PWSTR
Definition: typedefs.h:54
DWORD LCID
Definition: nls.h:13
#define NORM_IGNORECASE
Definition: winnls.h:173
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: lang.c:2275
#define CSTR_EQUAL
Definition: winnls.h:453
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1449

Referenced by FindString().

◆ wmain()

int wmain ( int  argc,
WCHAR argv[] 
)

Definition at line 169 of file find.c.

170 {
171  int i;
172  int iReturnValue = 2;
173  int iSearchedStringIndex = -1;
174  BOOL bFoundFileParameter = FALSE;
175  HANDLE hFindFile;
176  WIN32_FIND_DATAW FindData;
177  FILE* pOpenedFile;
178  PWCHAR ptr;
179  WCHAR szFullFilePath[MAX_PATH];
180 
181  /* Initialize the Console Standard Streams */
183 
184  if (argc == 1)
185  {
186  /* If no argument were provided by the user, display program usage and exit */
188  return 0;
189  }
190 
191  /* Parse the command line arguments */
192  for (i = 1; i < argc; ++i)
193  {
194  /* Check if this argument contains a switch */
195  if (wcslen(argv[i]) == 2 && argv[i][0] == L'/')
196  {
197  switch (towupper(argv[i][1]))
198  {
199  case L'?':
201  return 0;
202  case L'V':
204  break;
205  case L'C':
206  bCountLines = TRUE;
207  break;
208  case L'N':
210  break;
211  case L'I':
212  bIgnoreCase = TRUE;
213  break;
214  default:
215  /* Report invalid switch error */
217  return 2;
218  }
219  }
220  else if (wcslen(argv[i]) > 2 && argv[i][0] == L'/')
221  {
222  /* Check if this parameter is /OFF or /OFFLINE */
223  if (_wcsicmp(argv[i], L"/off") == 0 || _wcsicmp(argv[i], L"/offline") == 0)
224  {
226  }
227  else
228  {
229  /* Report invalid switch error */
231  return 2;
232  }
233  }
234  else
235  {
236  if (iSearchedStringIndex == -1)
237  {
238  iSearchedStringIndex = i;
239  }
240  else
241  {
242  /* There's a file specified in the parameters, no need to read from stdin */
243  bFoundFileParameter = TRUE;
244  }
245  }
246  }
247 
248  if (iSearchedStringIndex == -1)
249  {
250  /* User didn't provide the string to search for, display program usage and exit */
252  return 2;
253  }
254 
255  if (bFoundFileParameter)
256  {
257  /* After the command line arguments were parsed, iterate through them again to get the filenames */
258  for (i = 1; i < argc; ++i)
259  {
260  /* If the value is a switch or the searched string, continue */
261  if ((wcslen(argv[i]) > 0 && argv[i][0] == L'/') || i == iSearchedStringIndex)
262  {
263  continue;
264  }
265 
266  hFindFile = FindFirstFileW(argv[i], &FindData);
267  if (hFindFile == INVALID_HANDLE_VALUE)
268  {
270  continue;
271  }
272 
273  do
274  {
275  /* Check if the file contains offline attribute and should be skipped */
276  if ((FindData.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && !bDoNotSkipOfflineFiles)
277  {
278  continue;
279  }
280 
281  /* Skip directory */
282  // FIXME: Implement recursivity?
283  if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
284  {
285  continue;
286  }
287 
288  /*
289  * Build the full file path from the file specification pattern.
290  *
291  * Note that we could use GetFullPathName() instead, however
292  * we want to keep compatibility with Windows' find.exe utility
293  * that does not use this function as it keeps the file name
294  * directly based on the pattern.
295  */
296  ptr = wcsrchr(argv[i], L'\\'); // Check for last directory.
297  if (!ptr)
298  ptr = wcsrchr(argv[i], L':'); // Check for drive.
299  if (ptr)
300  {
301  /* The pattern contains a drive or directory part: keep it and concatenate the full file name */
302  StringCchCopyNW(szFullFilePath, _countof(szFullFilePath),
303  argv[i], ptr + 1 - argv[i]);
304  StringCchCatW(szFullFilePath, _countof(szFullFilePath),
305  FindData.cFileName);
306  }
307  else
308  {
309  /* The pattern does not contain any drive or directory part: just copy the full file name */
310  StringCchCopyW(szFullFilePath, _countof(szFullFilePath),
311  FindData.cFileName);
312  }
313 
314  // FIXME: Windows' find.exe supports searching inside binary files.
315  pOpenedFile = _wfopen(szFullFilePath, L"r");
316  if (pOpenedFile == NULL)
317  {
318  ConResPrintf(StdErr, IDS_CANNOT_OPEN, szFullFilePath);
319  continue;
320  }
321 
322  /* NOTE: Convert the file path to uppercase for formatting */
323  if (FindString(pOpenedFile, _wcsupr(szFullFilePath), argv[iSearchedStringIndex]) == 0)
324  {
325  iReturnValue = 0;
326  }
327  else if (iReturnValue != 0)
328  {
329  iReturnValue = 1;
330  }
331 
332  fclose(pOpenedFile);
333  } while (FindNextFileW(hFindFile, &FindData));
334 
335  FindClose(hFindFile);
336  }
337  }
338  else
339  {
340  FindString(stdin, NULL, argv[iSearchedStringIndex]);
341  }
342 
343  return iReturnValue;
344 }
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
#define IDS_INVALID_SWITCH
Definition: resource.h:6
static int argc
Definition: ServiceArgs.c:12
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
#define IDS_CANNOT_OPEN
Definition: resource.h:5
#define TRUE
Definition: types.h:120
static BOOL bIgnoreCase
Definition: find.c:28
static BOOL bDisplayLineNumbers
Definition: find.c:27
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
#define _countof(array)
Definition: fontsub.cpp:30
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
FILE * stdin
#define IDS_USAGE
Definition: resource.h:3
uint16_t * PWCHAR
Definition: typedefs.h:54
#define argv
Definition: mplay32.c:18
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ConInitStdStreams()
Definition: stream.h:122
unsigned int BOOL
Definition: ntddk_ex.h:94
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
static PVOID ptr
Definition: dispmode.c:27
static BOOL bDoNotSkipOfflineFiles
Definition: find.c:29
smooth NULL
Definition: ftsmooth.c:416
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcsrchr(_In_z_ const wchar_t *_Str, _In_ wchar_t _Ch)
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
INT __cdecl ConResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: outstream.c:781
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
#define StdErr
Definition: stream.h:77
INT ConResPuts(IN PCON_STREAM Stream, IN UINT uID)
Definition: outstream.c:610
static const WCHAR L[]
Definition: oid.c:1250
static BOOL bCountLines
Definition: find.c:26
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static int FindString(IN FILE *pStream, IN PCWSTR pszFilePath OPTIONAL, IN PCWSTR pszSearchString)
Definition: find.c:106
#define IDS_NO_SUCH_FILE
Definition: resource.h:4
#define StdOut
Definition: stream.h:76
#define towupper(c)
Definition: wctype.h:99
static BOOL bInvertSearch
Definition: find.c:25
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
#define FILE_ATTRIBUTE_OFFLINE
Definition: nt_native.h:712
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Variable Documentation

◆ bCountLines

BOOL bCountLines = FALSE
static

Definition at line 26 of file find.c.

Referenced by FindString(), and wmain().

◆ bDisplayLineNumbers

BOOL bDisplayLineNumbers = FALSE
static

Definition at line 27 of file find.c.

Referenced by FindString(), and wmain().

◆ bDoNotSkipOfflineFiles

BOOL bDoNotSkipOfflineFiles = FALSE
static

Definition at line 29 of file find.c.

Referenced by wmain().

◆ bIgnoreCase

BOOL bIgnoreCase = FALSE
static

Definition at line 28 of file find.c.

Referenced by FindString(), StrStrCase(), and wmain().

◆ bInvertSearch

BOOL bInvertSearch = FALSE
static

Definition at line 25 of file find.c.

Referenced by FindString(), and wmain().