add grep; add lost echo
This commit is contained in:
		
							parent
							
								
									51c0c1a8fe
								
							
						
					
					
						commit
						1a89baa7c6
					
				
					 2 changed files with 108 additions and 0 deletions
				
			
		
							
								
								
									
										2
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -93,7 +93,9 @@ mkfs: mkfs.c fs.h
 | 
			
		|||
 | 
			
		||||
UPROGS=\
 | 
			
		||||
	_cat\
 | 
			
		||||
	_echo\
 | 
			
		||||
	_forktest\
 | 
			
		||||
	_grep\
 | 
			
		||||
	_init\
 | 
			
		||||
	_kill\
 | 
			
		||||
	_ln\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										106
									
								
								grep.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								grep.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,106 @@
 | 
			
		|||
// Simple grep.  Only supports ^ . * $ operators.
 | 
			
		||||
 | 
			
		||||
#include "types.h"
 | 
			
		||||
#include "stat.h"
 | 
			
		||||
#include "user.h"
 | 
			
		||||
 | 
			
		||||
char buf[1024];
 | 
			
		||||
int match(char*, char*);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
grep(char *pattern, int fd)
 | 
			
		||||
{
 | 
			
		||||
  int n, m;
 | 
			
		||||
  char *p, *q;
 | 
			
		||||
  
 | 
			
		||||
  m = 0;
 | 
			
		||||
  while((n = read(fd, buf+m, sizeof(buf)-m)) > 0){
 | 
			
		||||
    m += n;
 | 
			
		||||
    p = buf;
 | 
			
		||||
    while((q = strchr(p, '\n')) != 0){
 | 
			
		||||
      *q = 0;
 | 
			
		||||
      if(match(pattern, p)){
 | 
			
		||||
        *q = '\n';
 | 
			
		||||
        write(1, p, q+1 - p);
 | 
			
		||||
      }
 | 
			
		||||
      p = q+1;
 | 
			
		||||
    }
 | 
			
		||||
    if(p == buf)
 | 
			
		||||
      m = 0;
 | 
			
		||||
    if(m > 0){
 | 
			
		||||
      m -= p - buf;
 | 
			
		||||
      memmove(buf, p, m);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
  int fd, i;
 | 
			
		||||
  char *pattern;
 | 
			
		||||
  
 | 
			
		||||
  if(argc <= 1){
 | 
			
		||||
    printf(2, "usage: grep pattern [file ...]\n");
 | 
			
		||||
    exit();
 | 
			
		||||
  }
 | 
			
		||||
  pattern = argv[1];
 | 
			
		||||
  
 | 
			
		||||
  if(argc <= 2){
 | 
			
		||||
    grep(pattern, 0);
 | 
			
		||||
    exit();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for(i = 2; i < argc; i++){
 | 
			
		||||
    if((fd = open(argv[i], 0)) < 0){
 | 
			
		||||
      printf(1, "grep: cannot open %s\n", argv[i]);
 | 
			
		||||
      exit();
 | 
			
		||||
    }
 | 
			
		||||
    grep(pattern, fd);
 | 
			
		||||
    close(fd);
 | 
			
		||||
  }
 | 
			
		||||
  exit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Regexp matcher from Kernighan & Pike,
 | 
			
		||||
// The Practice of Programming, Chapter 9.
 | 
			
		||||
 | 
			
		||||
int matchhere(char*, char*);
 | 
			
		||||
int matchstar(int, char*, char*);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
match(char *re, char *text)
 | 
			
		||||
{
 | 
			
		||||
  if(re[0] == '^')
 | 
			
		||||
    return matchhere(re+1, text);
 | 
			
		||||
  do{  // must look at empty string
 | 
			
		||||
    if(matchhere(re, text))
 | 
			
		||||
      return 1;
 | 
			
		||||
  }while(*text++ != '\0');
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// matchhere: search for re at beginning of text
 | 
			
		||||
int matchhere(char *re, char *text)
 | 
			
		||||
{
 | 
			
		||||
  if(re[0] == '\0')
 | 
			
		||||
    return 1;
 | 
			
		||||
  if(re[1] == '*')
 | 
			
		||||
    return matchstar(re[0], re+2, text);
 | 
			
		||||
  if(re[0] == '$' && re[1] == '\0')
 | 
			
		||||
    return *text == '\0';
 | 
			
		||||
  if(*text!='\0' && (re[0]=='.' || re[0]==*text))
 | 
			
		||||
    return matchhere(re+1, text+1);
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// matchstar: search for c*re at beginning of text
 | 
			
		||||
int matchstar(int c, char *re, char *text)
 | 
			
		||||
{
 | 
			
		||||
  do{  // a * matches zero or more instances
 | 
			
		||||
    if(matchhere(re, text))
 | 
			
		||||
      return 1;
 | 
			
		||||
  }while(*text!='\0' && (*text++==c || c=='.'));
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue