* 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).