ReactOS 0.4.16-dev-334-g4d9f67c
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}
void ConPrintf(FILE *fp, LPCWSTR psz,...)
Definition: fc.c:20
#define StdOut
Definition: fc.c:14
static PWSTR StrStrCase(IN PCWSTR pszStr, IN PCWSTR pszSearch, IN BOOL bIgnoreCase)
Definition: find.c:52
static BOOL bDisplayLineNumbers
Definition: find.c:27
static BOOL bIgnoreCase
Definition: find.c:28
#define FIND_LINE_BUFFER_SIZE
Definition: find.c:23
static BOOL bCountLines
Definition: find.c:26
static BOOL bInvertSearch
Definition: find.c:25
#define NULL
Definition: types.h:112
unsigned int BOOL
Definition: ntddk_ex.h:94
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define _countof(array)
Definition: sndvol32.h:70
wchar_t * fgetws(wchar_t *buf, int bufsize, FILE *file)
Definition: wmain.c:22
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by 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 {
60 INT i, cch1, cch2;
61
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}
LCID WINAPI GetThreadLocale(void)
Definition: locale.c:2801
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
DWORD LCID
Definition: nls.h:13
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT
Definition: typedefs.h:58
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
#define NORM_IGNORECASE
Definition: winnls.h:178
#define CSTR_EQUAL
Definition: winnls.h:458

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':
207 break;
208 case L'N':
210 break;
211 case L'I':
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 iReturnValue = FindString(stdin, NULL, argv[iSearchedStringIndex]);
341 }
342
343 return iReturnValue;
344}
static int argc
Definition: ServiceArgs.c:12
#define IDS_USAGE
Definition: resource.h:3
#define ConInitStdStreams()
Definition: fc.c:13
void ConResPrintf(FILE *fp, UINT nID,...)
Definition: fc.c:33
#define StdErr
Definition: fc.c:15
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
#define IDS_CANNOT_OPEN
Definition: resource.h:8
#define IDS_INVALID_SWITCH
Definition: resource.h:7
static BOOL bDoNotSkipOfflineFiles
Definition: find.c:29
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 TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define wcsrchr
Definition: compat.h:16
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
_Check_return_ _CRTIMP FILE *__cdecl _wfopen(_In_z_ const wchar_t *_Filename, _In_z_ const wchar_t *_Mode)
#define stdin
Definition: stdio.h:98
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static PVOID ptr
Definition: dispmode.c:27
#define argv
Definition: mplay32.c:18
#define FILE_ATTRIBUTE_OFFLINE
Definition: nt_native.h:712
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl _wcsupr(_Inout_z_ wchar_t *_String)
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
#define towupper(c)
Definition: wctype.h:99
uint16_t * PWCHAR
Definition: typedefs.h:56

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(), GetHash(), StrStrCase(), and wmain().

◆ bInvertSearch

BOOL bInvertSearch = FALSE
static

Definition at line 25 of file find.c.

Referenced by FindString(), and wmain().