ReactOS  0.4.12-dev-36-g472787f
findstr.c
Go to the documentation of this file.
1 /* findstr.c */
2 
3 /* Copyright (C) 1994-2002, Jim Hall <jhall@freedos.org> */
4 
5 /* Adapted for ReactOS -Edited for Findstr.exe K'Williams */
6 
7 /*
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License along
19  with this program; if not, write to the Free Software Foundation, Inc.,
20  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22 
23 
24 /* This program locates a string in a text file and prints those lines
25  * that contain the string. Multiple files are clearly separated.
26  */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 //#include <string.h>
31 //#include <ctype.h>
32 #include <windef.h>
33 #include <winbase.h>
34 #include <winuser.h>
35 //#include <io.h>
36 #include <dos.h>
37 
38 #include "resource.h"
39 
40 /* Symbol definition */
41 #define MAX_STR 1024
42 
43 
44 /* This function prints out all lines containing a substring. There are some
45  * conditions that may be passed to the function.
46  *
47  * RETURN: If the string was found at least once, returns 1.
48  * If the string was not found at all, returns 0.
49  */
50 int
51 find_str (char *sz, FILE *p, int invert_search,
52  int count_lines, int number_output, int ignore_case, int at_start, int literal_search,
53  int at_end, int reg_express, int exact_match, int sub_dirs, int only_fname)
54 {
55  int i, length;
56  long line_number = 0, total_lines = 0;
57  char *c, temp_str[MAX_STR], this_line[MAX_STR];
58 
59  /* Convert to upper if needed */
60  if (ignore_case)
61  {
62  length = strlen (sz);
63  for (i = 0; i < length; i++)
64  sz[i] = toupper (sz[i]);
65  }
66 
67  /* Scan the file until EOF */
68  while (fgets (temp_str, MAX_STR, p) != NULL)
69  {
70  /* Remove the trailing newline */
71  length = strlen (temp_str);
72  if (temp_str[length-1] == '\n')
73  {
74  temp_str[length-1] = '\0';
75  }
76 
77  /* Increment number of lines */
78  line_number++;
79  strcpy (this_line, temp_str);
80 
81  /* Convert to upper if needed */
82  if (ignore_case)
83  {
84  for (i = 0; i < length; i++)
85  {
86  temp_str[i] = toupper (temp_str[i]);
87  }
88  }
89 
90  /* Locate the substring */
91 
92  /* strstr() returns a pointer to the first occurrence in the
93  string of the substring */
94  c = strstr (temp_str, sz);
95 
96  if ( ((invert_search) ? (c == NULL) : (c != NULL)) )
97  {
98  if (!count_lines)
99  {
100  if (number_output)
101  printf ("%ld:", line_number);
102 
103  /* Print the line of text */
104  puts (this_line);
105  }
106 
107  total_lines++;
108  } /* long if */
109  } /* while fgets */
110 
111  if (count_lines)
112  {
113  /* Just show num. lines that contain the string */
114  printf ("%ld\n", total_lines);
115  }
116 
117 
118  /* RETURN: If the string was found at least once, returns 1.
119  * If the string was not found at all, returns 0.
120  */
121  return (total_lines > 0 ? 1 : 0);
122 }
123 
124 /* Show usage */
125 void
126 usage (void)
127 {
128  TCHAR lpUsage[4096];
129 
130  LoadString( GetModuleHandle(NULL), IDS_USAGE, (LPTSTR)lpUsage, 4096);
131  CharToOem(lpUsage, lpUsage);
132  printf( lpUsage );
133 }
134 
135 
136 /* Main program */
137 int
138 main (int argc, char **argv)
139 {
140  char *opt, *needle = NULL;
141  int ret = 0;
142  TCHAR lpMessage[4096];
143 
144  int invert_search = 0; /* flag to invert the search */
145  int count_lines = 0; /* flag to whether/not count lines */
146  int number_output = 0; /* flag to print line numbers */
147  int ignore_case = 0; /* flag to be case insensitive */
148  int at_start = 0; /* flag to Match if at the beginning of a line. */
149  int at_end = 0; /* flag to Match if at the beginning of a line. */
150  int reg_express = 0; /* flag to use/not use regular expressions */
151  int exact_match = 0; /* flag to be exact match */
152  int sub_dirs= 0; /* this and all subdirectories */
153  int only_fname= 0; /* print only the name of the file*/
154  int literal_search=0;
155 
156  FILE *pfile; /* file pointer */
157  int hfind; /* search handle */
158  struct _finddata_t finddata; /* _findfirst, filenext block */
159 
160  /* Scan the command line */
161  while ((--argc) && (needle == NULL))
162  {
163  if (*(opt = *++argv) == '/')
164  {
165  switch (opt[1])
166  {
167  case 'b':
168  case 'B': /* Matches pattern if at the beginning of a line */
169  at_start = 1;
170  break;
171 
172  //case 'c':
173  //case 'C': /* Literal? */
174  // literal_search = 1;
175  // break;
176 
177  case 'e':
178  case 'E': /* matches pattern if at end of line */
179  at_end = 1;
180  break;
181 
182  case 'i':
183  case 'I': /* Ignore */
184  ignore_case = 1;
185  break;
186 
187  case 'm':
188  case 'M': /* only filename */
189  only_fname = 1;
190  break;
191 
192  case 'n':
193  case 'N': /* Number */
194  number_output = 1;
195  break;
196 
197  case 'r':
198  case 'R': /* search strings as regular expressions */
199  reg_express = 1;
200  break;
201 
202  case 's':
203  case 'S': /* search files in child directory too*/
204  sub_dirs = 1;
205  break;
206 
207  case 'v':
208  case 'V': /* Not with */
209  invert_search = 1;
210  break;
211 
212  case 'x':
213  case 'X': /* exact match */
214  exact_match = 1;
215  break;
216 
217  default:
218  usage ();
219  exit (2); /* syntax error .. return error 2 */
220  break;
221  }
222  }
223  else
224  {
225  /* Get the string */
226  if (needle == NULL)
227  {
228  /* Assign the string to find */
229  needle = *argv;
230  }
231  }
232  }
233 
234  /* Check for search string */
235  if (needle == NULL)
236  {
237  /* No string? */
238  usage ();
239  exit (1);
240  }
241 
242  /* Scan the files for the string */
243  if (argc == 0)
244  {
245  ret = find_str (needle, stdin, invert_search, count_lines,
246  number_output, ignore_case, at_start, literal_search, at_end, reg_express, exact_match,
247  sub_dirs, only_fname);
248  }
249 
250  while (--argc >= 0)
251  {
252  hfind = _findfirst (*++argv, &finddata);
253  if (hfind < 0)
254  {
255  /* We were not able to find a file. Display a message and
256  set the exit status. */
257  LoadString( GetModuleHandle(NULL), IDS_NO_SUCH_FILE, (LPTSTR)lpMessage, 4096);
258  CharToOem(lpMessage, lpMessage);
259  fprintf (stderr, lpMessage, *argv);//
260  }
261  else
262  {
263  /* repeat find next file to match the filemask */
264  do
265  {
266  /* We have found a file, so try to open it */
267  if ((pfile = fopen (finddata.name, "r")) != NULL)
268  {
269  printf ("---------------- %s\n", finddata.name);
270  ret = find_str (needle, pfile, invert_search, count_lines,
271  number_output, ignore_case, at_start, literal_search, at_end, reg_express, exact_match,
272  sub_dirs, only_fname);
273  fclose (pfile);
274  }
275  else
276  {
278  CharToOem(lpMessage, lpMessage);
279  fprintf (stderr, lpMessage,
280  finddata.name);
281  }
282  }
283  while (_findnext(hfind, &finddata) > 0);
284  }
285  _findclose(hfind);
286  } /* for each argv */
287 
288  /* RETURN: If the string was found at least once, returns 0.
289  * If the string was not found at all, returns 1.
290  * (Note that find_str.c returns the exact opposite values.)
291  */
292  exit ( (ret ? 0 : 1) );
293 }
294 
295 
static int argc
Definition: ServiceArgs.c:12
#define IDS_CANNOT_OPEN
Definition: resource.h:5
int main(int argc, char **argv)
Definition: findstr.c:138
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int find_str(char *sz, FILE *p, int invert_search, int count_lines, int number_output, int ignore_case, int at_start, int literal_search, int at_end, int reg_express, int exact_match, int sub_dirs, int only_fname)
Definition: findstr.c:51
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
FILE * stdin
#define IDS_USAGE
Definition: resource.h:3
int line_number
Definition: parser.yy.c:773
#define at_end(list, elem)
Definition: simple_list.h:167
static char ** argv
Definition: ServiceArgs.c:11
CHAR * LPTSTR
Definition: xmlstorage.h:192
GLenum GLclampf GLint i
Definition: glfuncs.h:14
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
void usage(void)
Definition: findstr.c:126
smooth NULL
Definition: ftsmooth.c:416
#define MAX_STR
Definition: findstr.c:41
_Check_return_opt_ _CRTIMP int __cdecl _findclose(_In_ intptr_t _FindHandle)
char TCHAR
Definition: xmlstorage.h:189
int toupper(int c)
Definition: utclib.c:881
char name[260]
Definition: io.h:43
_CRTIMP int __cdecl _findnext(intptr_t _FindHandle, struct _finddata_t *_FindData)
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
int ret
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
int puts(const char *string)
Definition: crtsupp.c:23
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
#define GetModuleHandle
Definition: winbase.h:3641
_CRTIMP intptr_t __cdecl _findfirst(const char *_Filename, struct _finddata_t *_FindData)
#define CharToOem
Definition: winuser.h:5609
static CHAR temp_str[MAX_PATH]
Definition: dispatch.c:32
#define IDS_NO_SUCH_FILE
Definition: resource.h:4
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define c
Definition: ke_i.h:80
FILE * stderr
Definition: io.h:37
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
#define LoadString
Definition: winuser.h:5685
#define printf
Definition: config.h:203