aboutsummaryrefslogtreecommitdiffstats
path: root/src/sash/cmd_grep.c
diff options
context:
space:
mode:
authortcsullivan <tullivan99@gmail.com>2018-10-18 18:24:43 -0400
committertcsullivan <tullivan99@gmail.com>2018-10-18 18:24:43 -0400
commitf4149952ea4895356a3d4c0a9517893bb1e18cd2 (patch)
tree5620b42a4eb874a5b3a9679065c882066dca4f70 /src/sash/cmd_grep.c
parent6b5dfe3c09195118226180470eada4a51d8ec922 (diff)
wip forking, added sash source
Diffstat (limited to 'src/sash/cmd_grep.c')
-rw-r--r--src/sash/cmd_grep.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/sash/cmd_grep.c b/src/sash/cmd_grep.c
new file mode 100644
index 0000000..b9e0821
--- /dev/null
+++ b/src/sash/cmd_grep.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2014 by David I. Bell
+ * Permission is granted to use, distribute, or modify this source,
+ * provided that this copyright notice remains intact.
+ *
+ * The "grep" built-in command.
+ */
+
+#include <ctype.h>
+
+#include "sash.h"
+
+
+static BOOL search
+ (const char * string, const char * word, BOOL ignoreCase);
+
+
+int
+do_grep(int argc, const char ** argv)
+{
+ FILE * fp;
+ const char * word;
+ const char * name;
+ const char * cp;
+ BOOL tellName;
+ BOOL ignoreCase;
+ BOOL tellLine;
+ long line;
+ char buf[BUF_SIZE];
+ int r;
+
+ r = 1;
+ ignoreCase = FALSE;
+ tellLine = FALSE;
+
+ argc--;
+ argv++;
+
+ if (**argv == '-')
+ {
+ argc--;
+ cp = *argv++;
+
+ while (*++cp) switch (*cp)
+ {
+ case 'i':
+ ignoreCase = TRUE;
+ break;
+
+ case 'n':
+ tellLine = TRUE;
+ break;
+
+ default:
+ fprintf(stderr, "Unknown option\n");
+
+ return 1;
+ }
+ }
+
+ word = *argv++;
+ argc--;
+
+ tellName = (argc > 1);
+
+ while (argc-- > 0)
+ {
+ name = *argv++;
+
+ fp = fopen(name, "r");
+
+ if (fp == NULL)
+ {
+ perror(name);
+ r = 1;
+
+ continue;
+ }
+
+ line = 0;
+
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ if (intFlag)
+ {
+ fclose(fp);
+
+ return 1;
+ }
+
+ line++;
+
+ cp = &buf[strlen(buf) - 1];
+
+ if (*cp != '\n')
+ fprintf(stderr, "%s: Line too long\n", name);
+
+ if (search(buf, word, ignoreCase))
+ {
+ r = 0;
+ if (tellName)
+ printf("%s: ", name);
+
+ if (tellLine)
+ printf("%ld: ", line);
+
+ fputs(buf, stdout);
+ }
+ }
+
+ if (ferror(fp))
+ perror(name);
+
+ fclose(fp);
+ }
+
+ return r;
+}
+
+
+/*
+ * See if the specified word is found in the specified string.
+ */
+static BOOL
+search(const char * string, const char * word, BOOL ignoreCase)
+{
+ const char * cp1;
+ const char * cp2;
+ int len;
+ int lowFirst;
+ int ch1;
+ int ch2;
+
+ len = strlen(word);
+
+ if (!ignoreCase)
+ {
+ while (TRUE)
+ {
+ string = strchr(string, word[0]);
+
+ if (string == NULL)
+ return FALSE;
+
+ if (memcmp(string, word, len) == 0)
+ return TRUE;
+
+ string++;
+ }
+ }
+
+ /*
+ * Here if we need to check case independence.
+ * Do the search by lower casing both strings.
+ */
+ lowFirst = *word;
+
+ if (isupper(lowFirst))
+ lowFirst = tolower(lowFirst);
+
+ while (TRUE)
+ {
+ while (*string && (*string != lowFirst) &&
+ (!isupper(*string) || (tolower(*string) != lowFirst)))
+ {
+ string++;
+ }
+
+ if (*string == '\0')
+ return FALSE;
+
+ cp1 = string;
+ cp2 = word;
+
+ do
+ {
+ if (*cp2 == '\0')
+ return TRUE;
+
+ ch1 = *cp1++;
+
+ if (isupper(ch1))
+ ch1 = tolower(ch1);
+
+ ch2 = *cp2++;
+
+ if (isupper(ch2))
+ ch2 = tolower(ch2);
+
+ }
+ while (ch1 == ch2);
+
+ string++;
+ }
+}
+
+/* END CODE */