rc-list - mailing list for the rc(1) shell
 help / color / mirror / Atom feed
* a small diversion
@ 1993-05-11 23:48 Byron Rakitzis
  0 siblings, 0 replies; only message in thread
From: Byron Rakitzis @ 1993-05-11 23:48 UTC (permalink / raw)
  To: rc

Hi, I am just posting a small piece of code for your amusement.

I've always been sick of /bin/find's syntax, so about a year ago I
wrote a little toy program to explore an alternative user interface.

I have a small yacc program which takes a C-like expression syntax on
stdin and produces find-compatible syntax on stdout. Doubtless it is
incomplete, which is why I call it a toy.

I also have an rc script which interfaces my preprocessor to /bin/find
itself.

Here are some examples of find pre-processor input and output:

	(type(d)||type(f))&&print

becomes

	( -type d -o -type f ) -a -print

and

	name(*.o)&&exec(rm {})

becomes

	-name *.o -a -exec rm {}

As I see it, the main advantages of my approach are:

1) You don't need to split up the find expression so that one token ==
one argv[] element. e.g., I find

	'(foo||bar)&&print'

much easier to type than

	'(' foo -o bar ')' -a -print

2) I find that /bin/find syntax is write-only, whereas it's easier for
me to parse visually what's going on, even with the above two simple
expressions.

Well, that's enough for now. I mostly just want to amuse, as well as provoke
thought. This is not a "production" solution.

Here's the script I use as a replacement to find, which I call "f":

# to unbundle, sh this file
# bundled by byron on ghoti at Tue May 11 16:43:31 PDT 1993
# contents of bundle:
# f
echo f
sed 's/^-//' > f <<'end of f'
-#!/bin/rc
-if (~ $#* 0 1) {
-	echo 'usage: f <files> <expr>' >[1=2]
-	exit 1
-}
-files=()
-while (! ~ $#* 1) {
-	files = ($1 $files)
-	shift
-}
-find $files `{echo $1 | prefind}
end of f

It is used as:

	f <files> <expr>

where expr is a *single* argument, usually surrounded in quotes. For
example:

	f . 'type(d)&&print'

The yacc source follows. Run through yacc, and compile it into
"prefind".

Byron.

# to unbundle, sh this file
# bundled by byron on ghoti at Tue May 11 16:44:00 PDT 1993
# contents of bundle:
# find.y
echo find.y
sed 's/^-//' > find.y <<'end of find.y'
-%term ORELSE ANDALSO CMD
-
-%{
-static int yylex(void);
-static char *sprint(const char *fmt,...);
-static void *ealloc(unsigned n);
-static void *erealloc(void *p, unsigned n);
-#define WORDSIZE 8
-#define CHECKSIZE() if (i >= size) buf = erealloc(buf, size *= 2)
-%}
-
-%union {
-	char *s;
-}
-
-%type <s> find expr or and not un clist
-%type <s> CMD
-
-%%
-
-find	: expr			{ printf("%s\n", $1); }
-
-expr	: or
-
-or	: and
-	| or ORELSE and		{ $$ = sprint("% -o %", $1, $3); }
-
-and	: not
-	| and ANDALSO not	{ $$ = sprint("% -a %", $1, $3); }
-
-not	: '!' un		{ $$ = sprint("! %", $2); }
-	| un
-
-un	: '(' expr ')'		{ $$ = sprint("( % )", $2); }
-	| CMD			{ $$ = sprint("-%", $1); }
-	| CMD '(' clist ')'	{ $$ = sprint("-% %", $1, $3); }
-
-clist	: CMD
-	| clist CMD		{ $$ = sprint("% %", $1, $2); }
-
-%%
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-static int yylex() {
-	char *buf;
-	int c;
-	unsigned i, size;
-
-top:	switch (c = getchar()) {
-	case ' ': case '\t': case '\n':
-		goto top;
-	case EOF: case '\0':
-	case '!': case ',':
-	case '(': case ')':
-		return c;
-	case '&':
-		if ((c = getchar()) == '&')
-			return ANDALSO;
-		return '?';
-	case '|':
-		if ((c = getchar()) == '|')
-			return ORELSE;
-		return '?';
-	default:
-		buf = ealloc(size = WORDSIZE);
-		i = 0;
-		while (1) {
-			buf[i++] = c;
-			CHECKSIZE();
-			switch (c = getchar()) {
-			default:
-				break;
-			case EOF: case '\0':
-			case ' ': case '\t': case '\n':
-			case '(': case ')': case ',':
-			case '!': case '&': case '|':
-				ungetc(c, stdin);
-				buf[i] = '\0';
-				yylval.s = buf;
-				return CMD;
-			}
-		}
-	}
-}
-
-static char *sprint(const char *fmt,...) {
-	va_list ap;
-	unsigned size, i = 0;
-	char *buf = ealloc(size = WORDSIZE);
-
-	va_start(ap, fmt);
-
-	while (*fmt != '\0') {
-		if (*fmt != '%') {
-			buf[i++] = *fmt++;
-			CHECKSIZE();
-		} else {
-			char *word = va_arg(ap, char *);
-			while (*word != '\0') {
-				buf[i++] = *word++;
-				CHECKSIZE();
-			}
-			fmt++;
-		}
-	}
-
-	va_end(ap);
-
-	buf[i] = '\0';
-	return buf;
-}
-
-static void *ealloc(unsigned n) {
-	void *p = malloc(n);
-	if (p == NULL) {
-		perror("malloc");
-		exit(1);
-	}
-	return p;
-}
-
-static void *erealloc(void *p, unsigned n) {
-	p = realloc(p, n);
-	if (p == NULL) {
-		perror("realloc");
-		exit(1);
-	}
-	return p;
-}
-
-static void yyerror(char *s) {
-	fprintf(stderr, "%s\n", s);
-	exit(1);
-}
-
-extern int main() {
-	yyparse();
-	return 0;
-}
end of find.y


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1993-05-11 23:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-05-11 23:48 a small diversion Byron Rakitzis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).