home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume5
/
s5look
< prev
next >
Wrap
Text File
|
1989-02-03
|
5KB
|
260 lines
Path: xanth!nic.MR.NET!hal!ncoast!allbery
From: campbell@redsox.UUCP (Larry Campbell)
Newsgroups: comp.sources.misc
Subject: v05i007: Public domain look(1) for SysV
Message-ID: <491@redsox.UUCP>
Date: 28 Oct 88 02:25:50 GMT
Sender: allbery@ncoast.UUCP
Reply-To: campbell@redsox.UUCP (Larry Campbell)
Organization: The Boston Software Works, Inc.
Lines: 247
Approved: allbery@ncoast.UUCP
Posting-number: Volume 5, Issue 7
Submitted-by: "Larry Campbell" <campbell@redsox.UUCP>
Archive-name: s5look
Here's a quickie public domain implementation of look. It's not blazingly
fast, but it sure beats grep, it lints cleanly, and the price is right.
/*
* look.c
*
* <-xtx-*> cc -o look -O -s look.c
*
* An implementation of the V7/Berkeley look(1) utility, which
* is annoyingly lacking from System V. This code is in the public
* public domain. You may use this code for any purpose, commercial
* or noncommercial, as long as you don't try to claim you wrote it.
*
* This code hasn't been tuned; it runs about half the speed of the
* V7 version. That's good enough for me.
*
* If you find bugs, please send me the fixes.
*
* Written October, 1988 by:
*
* Larry Campbell
* The Boston Software Works, Inc.
* 120 Fulton Street, Boston, MA 02109
* campbell@bsw.com
******************************************************************
* usage:
*
* look [-f] words file
*
* Conducts a binary search in <file>, which must be sorted,
* for a line beginning with <words>. The -f switch means
* ignore (fold) case.
*
* If the input file is not sorted, the results are unpredictable.
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
extern void
perror(),
exit();
char
*words,
*filename,
buf[BUFSIZ];
int
fold_flag,
length;
FILE
*f;
long
left_offset,
offset,
right_offset,
size,
step;
/* Forward declarations */
void
search(),
start_of_line(),
strlwr(),
usage();
main(argc, argv)
char *argv[];
{
int
i;
struct stat
statb;
if (argc < 3 || argc > 4)
usage();
fold_flag = 0;
if (argc == 4)
if (argv[1][0] == '-' && argv[1][1] == 'f')
fold_flag = 1;
else
usage();
i = argc - 2;
words = argv[i];
length = strlen(words);
if (fold_flag)
strlwr(words);
filename = argv[i + 1];
f = fopen(filename, "r");
if (f == NULL)
perror("can't open input file");
if (fstat(fileno(f), &statb) < 0)
perror("stat failed on input file");
size = statb.st_size;
if (size == 0)
exit(0);
offset = size / 2;
step = offset / 2;
search();
return 0;
}
void
search()
{
int
compare;
char
buf2[BUFSIZ];
for (;;)
{
if (fseek(f, offset, 0) == -1)
perror("fseek");
start_of_line();
compare = strncmp(words, buf, length);
if (compare == 0)
{
while (offset > 0L) /* back up to first nonmatching line */
{
offset -= left_offset;
start_of_line();
compare = strncmp(words, buf, length);
if (compare != 0)
{
if (fseek(f, ++offset, 0) == -1) /* skip nonmatching line */
perror("fseek");
if (fgets(buf, BUFSIZ, f) == 0) /* reload matching line */
perror("fgets");
break;
}
}
for (;;)
{
(void) fputs(buf, stdout);
if (fgets(buf, BUFSIZ, f) == 0)
break;
(void) strcpy(buf2, buf);
if (fold_flag)
strlwr(buf2);
if (strncmp(words, buf2, length) != 0)
break;
}
exit(0);
}
if (step == 0)
exit(1);
if (compare < 0)
{
if (step < left_offset)
offset -= left_offset;
else
offset -= step;
if (offset <= 0L)
exit(1);
}
else
{
if (step < right_offset)
offset += right_offset;
else
offset += step;
if (offset > size)
exit(1);
}
step = step / 2;
}
}
void
start_of_line()
{
int
c;
long
toffset;
if (offset <= 0L)
return;
toffset = offset;
while (toffset > 0L)
{
c = fgetc(f);
if (c == '\n')
break;
if (fseek(f, --toffset, 0) == -1)
perror("fseek");
}
if (fgets(buf, BUFSIZ, f) == 0)
perror("prev_line: fgets");
if (fold_flag)
strlwr(buf);
left_offset = offset - toffset;
right_offset = (strlen(buf) - left_offset) + 1;
}
void
usage()
{
(void) fprintf(stderr, "usage: look [-f] string file\n");
exit(2);
}
/*
* This function is in ANSI C but AT&T is still behind the times.
*/
void
strlwr(s)
char *s;
{
register char
c;
while (c = *s)
{
if (isupper(c))
*s = tolower(c);
s++;
}
}
--
Larry Campbell The Boston Software Works, Inc.
campbell@bsw.com 120 Fulton Street
wjh12!redsox!campbell Boston, MA 02146