--- toybox-ff22f24c9661/toys/posix/grep.c	2013-11-30 12:27:26.000000000 +0530
+++ b/toys/posix/grep.c	2013-12-06 18:35:56.037614111 +0530
@@ -1,10 +1,11 @@
 /* grep.c - print lines what match given regular expression
  *
  * Copyright 2013 CE Strake <strake888 at gmail.com>
+ * Copyright 2013 Bilal Qureshi <bilal.jmi@gmail.com>
  *
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html
 
-USE_GREP(NEWTOY(grep, "EFHabhinorsvwclqe*f*m#x[!wx][!EFw]", TOYFLAG_BIN))
+USE_GREP(NEWTOY(grep, "EFHabhinorsvwclqe*f*m#B#<0x[!wx][!EFw]", TOYFLAG_BIN))
 USE_GREP(OLDTOY(egrep, grep, OPTSTR_grep, TOYFLAG_BIN))
 USE_GREP(OLDTOY(fgrep, grep, OPTSTR_grep, TOYFLAG_BIN))
 
@@ -12,7 +13,7 @@
   bool "grep"
   default y
   help
-    usage: grep [-EFivwcloqsHbhn] [-m MAX] [-e REGEX]... [-f REGFILE] [FILE]...
+    usage: grep [-EFivwcloqsHbhn] [-m MAX] [-B N] [-e REGEX]... [-f REGFILE] [FILE]...
 
     Show lines matching regular expressions. If no -e, first argument is
     regular expression to match. With no files (or "-" filename) read stdin.
@@ -26,6 +27,7 @@
     -i  case insensitive         -m  stop after this many lines matched
     -r  recursive (on dir)       -v  invert match
     -w  whole word (implies -E)  -x  whole line
+    -B N  Print N lines of leading context
 
     display modes: (default: matched line)
     -c  count of matching lines  -l  show matching filenames
@@ -40,21 +42,96 @@
 #define FOR_grep
 #include "toys.h"
 #include <regex.h>
+#include <sys/queue.h>
 
 GLOBALS(
+  long bval;
   long m;
   struct arg_list *f;
   struct arg_list *e;
 
   struct arg_list *regex;
+  long bcount;
+  int separator;
 )
+// Support for -B option: BEGIN
+struct file_info {
+  char *line;
+  char *fname;
+  int line_no;
+};
+
+struct qentry {
+  STAILQ_ENTRY(qentry) list;
+  struct file_info data;
+};
+
+static STAILQ_HEAD(, qentry) queue = STAILQ_HEAD_INITIALIZER(queue);
+
+static struct qentry *dequeue(void)
+{
+  struct qentry *item = STAILQ_FIRST(&queue);
+
+  if (!item) return NULL;
+  STAILQ_REMOVE_HEAD(&queue, list);
+  --TT.bcount;
+  return item;
+}
+
+static void enqueue(struct file_info *f)
+{
+  struct qentry *item = xzalloc(sizeof(struct qentry));
+
+  item->data.line = xmsprintf("%s", f->line);
+  item->data.fname = xmsprintf("%s", f->fname);
+  item->data.line_no = f->line_no;
+  STAILQ_INSERT_TAIL(&queue, item, list);
+
+  if (++TT.bcount > TT.bval) {
+    if ((item = dequeue()) ) {
+      if (item->data.line) free(item->data.line);
+      if (item->data.fname) free(item->data.fname);
+      free(item);
+    }
+  }
+}
+
+static void printqueue(void)
+{
+  struct qentry *item;
+
+  while ((item = dequeue())) {
+    if ((toys.optflags & FLAG_H) && item->data.fname) {
+      printf("%s-", item->data.fname);
+      free(item->data.fname);
+    }
+    if (toys.optflags & FLAG_n) printf("%d-", item->data.line_no);
+    if (item->data.line) {
+      xprintf("%s\n", item->data.line);
+      free(item->data.line);
+    }
+    free(item);
+  }
+}
+
+static void clearqueue(void)
+{
+  struct qentry *item;
+
+  while ((item = dequeue())) {
+    if (item->data.line) free(item->data.line);
+    if (item->data.fname) free(item->data.fname);
+    free(item);
+  }
+}
+// Support for -B option: END
 
 static void do_grep(int fd, char *name)
 {
   FILE *file = fdopen(fd, "r");
   long offset = 0;
-  int lcount = 0, mcount = 0, which = toys.optflags & FLAG_w ? 2 : 0;
-
+  struct file_info f;
+  int lcount = 0, mcount = 0, llc = 0, which = toys.optflags & FLAG_w ? 2 : 0;
   if (!fd) name = "(standard input)";
 
   if (!file) {
@@ -109,7 +186,7 @@
         } else rc = 1;
       } else {
         rc = regexec((regex_t *)toybuf, start, 3, matches,
-                     start==line ? 0 : REG_NOTBOL);
+            start==line ? 0 : REG_NOTBOL);
         skip = matches[which].rm_eo;
       }
 
@@ -144,25 +221,39 @@
           break;
 
       if (!(toys.optflags & FLAG_c)) {
+        if ((toys.optflags & FLAG_B) && TT.separator && 
+            TT.bval < (lcount - llc-1)) printf("--\n");
+        if (!(toys.optflags & FLAG_o) && (toys.optflags & FLAG_B)) printqueue();
         if (toys.optflags & FLAG_H) printf("%s:", name);
         if (toys.optflags & FLAG_n) printf("%d:", lcount);
         if (toys.optflags & FLAG_b)
           printf("%ld:", offset + (start-line) +
               ((toys.optflags & FLAG_o) ? matches[which].rm_so : 0));
-        if (!(toys.optflags & FLAG_o)) xputs(line);
+        if (!(toys.optflags & FLAG_o)) {
+          if (toys.optflags & FLAG_B) {
+            xputs(line);
+            TT.separator = 1;
+          } else xputs(line);
+        }
         else {
           xprintf("%.*s\n", matches[which].rm_eo - matches[which].rm_so,
-                  start + matches[which].rm_so);
+              start + matches[which].rm_so);
+          TT.separator = 1;
         }
+        llc = lcount;
       }
 
       start += skip;
       if (!(toys.optflags & FLAG_o) || !*start) break;
     }
+    if ((toys.optflags & FLAG_B) && !mmatch) {
+      f.fname = name;
+      f.line = line;
+      f.line_no = lcount; 
+      enqueue(&f);
+    }
     offset += len;
-
     free(line);
-
     if (mmatch) mcount++;
     if ((toys.optflags & FLAG_m) && mcount >= TT.m) break;
   }
@@ -174,6 +265,7 @@
 
   // loopfiles will also close the fd, but this frees an (opaque) struct.
   fclose(file);
+  if (toys.optflags & FLAG_B) clearqueue();
 }
 
 static void parse_regex(void)
