diff --git a/rosapps/cmdutils/find.c b/rosapps/cmdutils/find.c new file mode 100644 index 00000000000..c779be71453 --- /dev/null +++ b/rosapps/cmdutils/find.c @@ -0,0 +1,248 @@ +/* find.c */ + +/* Copyright (C) 1994-2002, Jim Hall */ + +/* Adapted for ReactOS */ + +/* + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* This program locates a string in a text file and prints those lines + * that contain the string. Multiple files are clearly separated. + */ + +#include +#include +#include +#include + +#include +#include + + +/* Symbol definition */ +#define MAX_STR 1024 + + +/* This function prints out all lines containing a substring. There are some + * conditions that may be passed to the function. + * + * RETURN: If the string was found at least once, returns 1. + * If the string was not found at all, returns 0. + */ +int +find_str (char *sz, FILE *p, int invert_search, + int count_lines, int number_output, int ignore_case) +{ + int i, length; + long line_number = 0, total_lines = 0; + char *c, temp_str[MAX_STR], this_line[MAX_STR]; + + /* Convert to upper if needed */ + if (ignore_case) + { + length = strlen (sz); + for (i = 0; i < length; i++) + sz[i] = toupper (sz[i]); + } + + /* Scan the file until EOF */ + while (fgets (temp_str, MAX_STR, p) != NULL) + { + /* Remove the trailing newline */ + length = strlen (temp_str); + if (temp_str[length-1] == '\n') + { + temp_str[length-1] = '\0'; + } + + /* Increment number of lines */ + line_number++; + strcpy (this_line, temp_str); + + /* Convert to upper if needed */ + if (ignore_case) + { + for (i = 0; i < length; i++) + { + temp_str[i] = toupper (temp_str[i]); + } + } + + /* Locate the substring */ + + /* strstr() returns a pointer to the first occurrence in the + string of the substring */ + c = strstr (temp_str, sz); + + if ( ((invert_search) ? (c == NULL) : (c != NULL)) ) + { + if (!count_lines) + { + if (number_output) + printf ("%ld:", line_number); + + /* Print the line of text */ + puts (this_line); + } + + total_lines++; + } /* long if */ + } /* while fgets */ + + if (count_lines) + { + /* Just show num. lines that contain the string */ + printf ("%ld\n", total_lines); + } + + + /* RETURN: If the string was found at least once, returns 1. + * If the string was not found at all, returns 0. + */ + return (total_lines > 0 ? 1 : 0); +} + + +/* Show usage */ +void +usage (void) +{ + fprintf (stderr, "FIND: Prints all lines of a file that contain a string\n"); + fprintf (stderr, "FIND [ /C ] [ /I ] [ /N ] [ /V ] \"string\" [ file... ]\n"); + fprintf (stderr, " /C Count the number of lines that contain string\n"); + fprintf (stderr, " /I Ignore case\n"); + fprintf (stderr, " /N Number the displayed lines, starting at 1\n"); + fprintf (stderr, " /V Print lines that do not contain the string\n"); +} + + +/* Main program */ +int +main (int argc, char **argv) +{ + char *opt, *needle = NULL; + int ret = 0; + + int invert_search = 0; /* flag to invert the search */ + int count_lines = 0; /* flag to whether/not count lines */ + int number_output = 0; /* flag to print line numbers */ + int ignore_case = 0; /* flag to be case insensitive */ + + FILE *pfile; /* file pointer */ + int hfind; /* search handle */ + struct _finddata_t finddata; /* _findfirst, filenext block */ + + /* Scan the command line */ + while ((--argc) && (needle == NULL)) + { + if (*(opt = *++argv) == '/') + { + switch (opt[1]) + { + case 'c': + case 'C': /* Count */ + count_lines = 1; + break; + + case 'i': + case 'I': /* Ignore */ + ignore_case = 1; + break; + + case 'n': + case 'N': /* Number */ + number_output = 1; + break; + + case 'v': + case 'V': /* Not with */ + invert_search = 1; + break; + + default: + usage (); + exit (2); /* syntax error .. return error 2 */ + break; + } + } + else + { + /* Get the string */ + if (needle == NULL) + { + /* Assign the string to find */ + needle = *argv; + } + } + } + + /* Check for search string */ + if (needle == NULL) + { + /* No string? */ + usage (); + exit (1); + } + + /* Scan the files for the string */ + if (argc == 0) + { + ret = find_str (needle, stdin, invert_search, count_lines, + number_output, ignore_case); + } + + while (--argc >= 0) + { + hfind = _findfirst (*++argv, &finddata); + if (hfind < 0) + { + /* We were not able to find a file. Display a message and + set the exit status. */ + fprintf (stderr, "FIND: %s: No such file\n", *argv); + } + else + { + /* repeat find next file to match the filemask */ + do + { + /* We have found a file, so try to open it */ + if ((pfile = fopen (finddata.name, "r")) != NULL) + { + printf ("---------------- %s\n", finddata.name); + ret = find_str (needle, pfile, invert_search, count_lines, + number_output, ignore_case); + fclose (pfile); + } + else + { + fprintf (stderr, "FIND: %s: Cannot open file\n", + finddata.name); + } + } + while (_findnext(hfind, &finddata) > 0); + } + _findclose(hfind); + } /* for each argv */ + + /* RETURN: If the string was found at least once, returns 0. + * If the string was not found at all, returns 1. + * (Note that find_str.c returns the exact opposite values.) + */ + exit ( (ret ? 0 : 1) ); +} + diff --git a/rosapps/cmdutils/find.rc b/rosapps/cmdutils/find.rc new file mode 100644 index 00000000000..03683a1351c --- /dev/null +++ b/rosapps/cmdutils/find.rc @@ -0,0 +1,38 @@ +#include +#include + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +VS_VERSION_INFO VERSIONINFO + FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD + PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", RES_STR_COMPANY_NAME + VALUE "FileDescription", "W32 find command\0" + VALUE "FileVersion", RES_STR_PRODUCT_VERSION + VALUE "InternalName", "find\0" + VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT + VALUE "OriginalFilename", "find.exe\0" + VALUE "ProductName", RES_STR_PRODUCT_NAME + VALUE "ProductVersion", RES_STR_PRODUCT_VERSION + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + diff --git a/rosapps/cmdutils/makefile b/rosapps/cmdutils/makefile index 4b343041f8e..9581b6078d2 100644 --- a/rosapps/cmdutils/makefile +++ b/rosapps/cmdutils/makefile @@ -4,13 +4,17 @@ PATH_TO_TOP=.. -TARGET=more.exe sort.exe tee.exe y.exe +TARGET=find.exe more.exe sort.exe tee.exe y.exe all: $(TARGET) CLEAN_FILES = *.o *.exe *.sym *.coff +find.exe: find.o find.coff + $(CC) find.o -lkernel32 -lmsvcrt -o find.exe find.coff + $(NM) --numeric-sort find.exe > find.sym + more.exe: more.o more.coff $(CC) more.o -lkernel32 -lmsvcrt -o more.exe more.coff $(NM) --numeric-sort more.exe > more.sym