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=\
 | UPROGS=\
 | ||||||
| 	_cat\
 | 	_cat\
 | ||||||
|  | 	_echo\
 | ||||||
| 	_forktest\
 | 	_forktest\
 | ||||||
|  | 	_grep\
 | ||||||
| 	_init\
 | 	_init\
 | ||||||
| 	_kill\
 | 	_kill\
 | ||||||
| 	_ln\
 | 	_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