Logo Search packages:      
Sourcecode: 9base version File versions  Download package

main.c

#define     EXTERN
#include    "grep.h"

char *validflags = "bchiLlnsv";
void
usage(void)
{
      fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags);
      exits("usage");
}

void
main(int argc, char *argv[])
{
      int i, status;

      ARGBEGIN {
      default:
            if(utfrune(validflags, ARGC()) == nil)
                  usage();
            flags[ARGC()]++;
            break;

      case 'E':   /* ignore, turns gnu grep into egrep */
            break;

      case 'e':
            flags['e']++;
            lineno = 0;
            str2top(ARGF());
            break;

      case 'f':
            flags['f']++;
            filename = ARGF();
            rein = Bopen(filename, OREAD);
            if(rein == 0) {
                  fprint(2, "grep: can't open %s: %r\n", filename);
                  exits("open");
            }
            lineno = 1;
            str2top(filename);
            break;
      } ARGEND

      if(flags['f'] == 0 && flags['e'] == 0) {
            if(argc <= 0)
                  usage();
            str2top(argv[0]);
            argc--;
            argv++;
      }

      follow = mal(maxfollow*sizeof(*follow));
      state0 = initstate(topre.beg);

      Binit(&bout, 1, OWRITE);
      switch(argc) {
      case 0:
            status = search(0, 0);
            break;
      case 1:
            status = search(argv[0], 0);
            break;
      default:
            status = 0;
            for(i=0; i<argc; i++)
                  status |= search(argv[i], Hflag);
            break;
      }
      if(status)
            exits(0);
      exits("no matches");
}

int
search(char *file, int flag)
{
      State *s, *ns;
      int c, fid, eof, nl, empty;
      long count, lineno, n;
      uchar *elp, *lp, *bol;

      if(file == 0) {
            file = "stdin";
            fid = 0;
            flag |= Bflag;
      } else
            fid = open(file, OREAD);

      if(fid < 0) {
            fprint(2, "grep: can't open %s: %r\n", file);
            return 0;
      }

      if(flags['b'])
            flag ^= Bflag;          /* dont buffer output */
      if(flags['c'])
            flag |= Cflag;          /* count */
      if(flags['h'])
            flag &= ~Hflag;         /* do not print file name in output */
      if(flags['i'])
            flag |= Iflag;          /* fold upper-lower */
      if(flags['l'])
            flag |= Llflag;         /* print only name of file if any match */
      if(flags['L'])
            flag |= LLflag;         /* print only name of file if any non match */
      if(flags['n'])
            flag |= Nflag;          /* count only */
      if(flags['s'])
            flag |= Sflag;          /* status only */
      if(flags['v'])
            flag |= Vflag;          /* inverse match */

      s = state0;
      lineno = 0;
      count = 0;
      eof = 0;
      empty = 1;
      nl = 0;
      lp = u.u.buf;
      bol = lp;

loop0:
      n = lp-bol;
      if(n > sizeof(u.u.pre))
            n = sizeof(u.u.pre);
      memmove(u.u.buf-n, bol, n);
      bol = u.u.buf-n;
      n = read(fid, u.u.buf, sizeof(u.u.buf));
      /* if file has no final newline, simulate one to emit matches to last line */
      if(n > 0) {
            empty = 0;
            nl = u.u.buf[n-1]=='\n';
      } else {
            if(n < 0){
                  fprint(2, "grep: read error on %s: %r\n", file);
                  return count != 0;
            }
            if(!eof && !nl && !empty) {
                  u.u.buf[0] = '\n';
                  n = 1;
                  eof = 1;
            }
      }
      if(n <= 0) {
            close(fid);
            if(flag & Cflag) {
                  if(flag & Hflag)
                        Bprint(&bout, "%s:", file);
                  Bprint(&bout, "%ld\n", count);
            }
            if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))
                  Bprint(&bout, "%s\n", file);
            Bflush(&bout);
            return count != 0;
      }
      lp = u.u.buf;
      elp = lp+n;
      if(flag & Iflag)
            goto loopi;

/*
 * normal character loop
 */
loop:
      c = *lp;
      ns = s->next[c];
      if(ns == 0) {
            increment(s, c);
            goto loop;
      }
//    if(flags['2'])
//          if(s->match)
//                print("%d: %.2x**\n", s, c);
//          else
//                print("%d: %.2x\n", s, c);
      lp++;
      s = ns;
      if(c == '\n') {
            lineno++;
            if(!!s->match == !(flag&Vflag)) {
                  count++;
                  if(flag & (Cflag|Sflag|Llflag|LLflag))
                        goto cont;
                  if(flag & Hflag)
                        Bprint(&bout, "%s:", file);
                  if(flag & Nflag)
                        Bprint(&bout, "%ld: ", lineno);
                  /* suppress extra newline at EOF unless we are labeling matches with file name */
                  Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
                  if(flag & Bflag)
                        Bflush(&bout);
            }
            if((lineno & Flshcnt) == 0)
                  Bflush(&bout);
      cont:
            bol = lp;
      }
      if(lp != elp)
            goto loop;
      goto loop0;

/*
 * character loop for -i flag
 * for speed
 */
loopi:
      c = *lp;
      if(c >= 'A' && c <= 'Z')
            c += 'a'-'A';
      ns = s->next[c];
      if(ns == 0) {
            increment(s, c);
            goto loopi;
      }
      lp++;
      s = ns;
      if(c == '\n') {
            lineno++;
            if(!!s->match == !(flag&Vflag)) {
                  count++;
                  if(flag & (Cflag|Sflag|Llflag|LLflag))
                        goto conti;
                  if(flag & Hflag)
                        Bprint(&bout, "%s:", file);
                  if(flag & Nflag)
                        Bprint(&bout, "%ld: ", lineno);
                  /* suppress extra newline at EOF unless we are labeling matches with file name */
                  Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
                  if(flag & Bflag)
                        Bflush(&bout);
            }
            if((lineno & Flshcnt) == 0)
                  Bflush(&bout);
      conti:
            bol = lp;
      }
      if(lp != elp)
            goto loopi;
      goto loop0;
}

State*
initstate(Re *r)
{
      State *s;
      int i;

      addcase(r);
      if(flags['1'])
            reprint("r", r);
      nfollow = 0;
      gen++;
      fol1(r, Cbegin);
      follow[nfollow++] = r;
      qsort(follow, nfollow, sizeof(*follow), fcmp);

      s = sal(nfollow);
      for(i=0; i<nfollow; i++)
            s->re[i] = follow[i];
      return s;
}

Generated by  Doxygen 1.6.0   Back to index