rc-list - mailing list for the rc(1) shell
 help / color / mirror / Atom feed
From: "Mark K. Gardner" <mkg@boing.lanl.gov>
To: rc@hawkwind.utcs.toronto.edu
Subject: Re: tilde featuritis alert
Date: Thu, 9 Dec 1999 11:27:30 -0500	[thread overview]
Message-ID: <199912091627.JAA30396@boing.lanl.gov> (raw)
In-Reply-To: Your message of "Thu, 09 Dec 1999 02:52:05 EST." <19991209025205.B305@debian>

Hi Decklin,

Welcome to rc.

[clip...]

> I really miss my '~' for home directory from bash.

[clip...]

> One other thing - is there a replacement for the '~user' idiom?
> What's the rc way? grep through /etc/passwd?

I have a patch to rc that adds tilde expansion for both these cases. I
have also monkeyed with modifications to solve the "readline expands
it but rc doesn't grok it" problem. And I have had discussions with
Gert-Jan Vons, the author of vrl, about how to do tilde expansion in
vrl. Based on this experience (some may say bull-headed stubborness),
I make two observations.

 1) Tilde expansion for rc is fundamentally hard.

    The primary reason is the conflict with pattern matching. Tilde is
    already spoken for as the pattern matching operator. Its use as a
    file path component will always be problematic. My implementation
    of tilde expansion correctly interprets "ls ~", "ls ~/foo", "ls
    ~mkg" or "ls ~mkg/foo" but it cannot handle "ls ~ " (note the
    space after the tilde). You would have to type "ls ~/" instead to
    disambiguate with the use of tilde as the pattern matching
    operator.

    I tried snarfing % as the expansion character for a while, as it
		appears to be unencumbered by prior use. Its use in the place of
		tilde seemed... well ugly. Especially considering that tilde is
		still used in emacs, which I use alot. It was confusing switching
		back and forth between % and ~. Perhaps I just didn't give it
		enough time. Maybe I could have changed emacs, I don't know. I
		abandoned the idea.

 2) rc will never have tilde expansion as "standard equipment".

    The primary reason is cultural. Most of us were attracted to rc
    because of its simplicity. Nearly all changes are seen as
    creeping featuritis and soundly rejected (witness the "echo
    debate"). I have come to appreciate this view and even embrace it.

That said, I must confess that I am still lazily using a patched
version of rc with tilde expansion (along with "false", "true",
"version", "test" and "C-d trapping" features). Next to the bloat
caused by statically linking in GNU Readline, these features are
nearly free! However, I should warn you that my New Year's resolution
is to "go on a diet" by suffering through tilde withdrawals,
eliminating "false" and "true", and adopting vrl.

[PS: Since you are about to ask for it anyway, I am including my patch
for tilde expansion. Add -DTILDEHOME to CFLAGS and recompile. I will
answer simple questions, but I "...MAKE NO WARRANTY...EXPRESSED OR
IMPLIED...", yada, yada, yada.]

[PPS: I have been reluctant to waste bandwidth with its publication.
However, the question of tilde expansion frequently keeps popping up.
I hope by publishing it that requests can be answered by the archive.]

Mark

-- 
Mark K. Gardner
RADIANT Team
Network Engineering, CIC-5
Los Alamos National Laboratory
P.O. Box 1663, M.S. K766
Los Alamos, NM 87545
Email: mkg@lanl.gov
Phone: 1-505-665-4809
-- 

================================ Cut here ======================================
--- rc-1.6/lex.c	Fri Jul 24 09:48:27 1998
+++ rc-1.6-mkg/lex.c	Mon Oct 18 13:33:34 1999
@@ -3,6 +3,12 @@
 #include "rc.h"
 #include "parse.h"
 
+#if defined(TILDEHOME)
+#	include <assert.h>
+#	include <ctype.h>
+#	include <pwd.h>
+#endif /* TILDEHOME */
+
 /*
 	Special characters (i.e., "non-word") in rc:
 		\t \n # ; & | ^ $ = ~ ` ' { } @ ! ( ) < > \
@@ -33,6 +39,18 @@
 
 int lineno;
 
+#if defined(TILDEHOME)
+const char nw[] = {
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0,
+	1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, /* ~ */ 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+#else /* TILDEHOME */
 const char nw[] = {
 	1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
@@ -43,6 +61,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
+#endif /* TILDEHOME */
 
 const char dnw[] = {
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -97,9 +116,22 @@
 		checkfreecaret;
 		w = RW;
 		i = 0;
+#if defined(TILDEHOME)
+ 		if (c == '~') {
+ 			c = gchar();
+ 			ugchar(c);
+ 			if (c == ' ' || c == '\t')
+ 				return TWIDDLE;
+ 			c = '~';
+ 		}
+#endif /* TILDEHOME */
 	read:	do {
 			buf[i++] = c;
+#if defined(TILDEHOME)
+			if (c == '?' || c == '[' || c == '*' || c == '~')
+#else
 			if (c == '?' || c == '[' || c == '*')
+#endif /* TILDEHOME */
 				saw_meta = TRUE;
 			if (i >= bufsize)
 				buf = realbuf = erealloc(buf, bufsize *= 2);
@@ -137,6 +169,46 @@
 		if (streq(buf, "while")) return WHILE;
 		if (streq(buf, "case")) return CASE;
 		w = RW;
+#if defined(TILDEHOME)
+		if (buf[0] == '~') {
+		  if (buf[1] == '\0' || buf[1] == '/') {
+			/* ~ or ~/... */
+			char *home = varlookup("home")->w;
+			int hlen, blen;
+			hlen = strlen(home);
+			blen = strlen(buf) - 1;
+			if (i + hlen >= bufsize) {
+			  buf = realbuf = erealloc(buf, bufsize *= 2);
+			}
+			memmove(buf + hlen, &buf[1], blen);
+			memmove(buf, home, hlen);
+			buf[blen + hlen] = '\0';
+		  } else if (buf[1] != '\0' && buf[1] != '/') {
+			/* ~username */
+			char *n, name[256], *b;
+			struct passwd *pwentry;
+			n = name;
+			b = &buf[1];
+			while (isalnum(*b)) {
+			  *n++ = *b++;
+			}
+			*n = '\0';
+			pwentry = getpwnam(name);
+			if (pwentry != NULL) {
+			  char *path = pwentry->pw_dir;
+			  int plen, blen;
+			  plen = strlen(path);
+			  blen = strlen(buf) - 1;
+			  if (i + plen >= bufsize) {
+				buf = realbuf = erealloc(buf, bufsize *= 2);
+			  }
+			  memmove(buf + plen, &buf[strlen(name) + 1], blen);
+			  memmove(buf, path, plen);
+			  buf[blen + plen] = '\0';
+			}
+		  }
+		}
+#endif /* TILDEHOME */
 		y->word.w = ncpy(buf);
 		if (saw_meta) {
 			char *r, *s;
================================= End Cut ======================================


  parent reply	other threads:[~1999-12-09 21:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-12-09  7:52 Decklin Foster
1999-12-09  8:26 ` Markus Friedl
1999-12-09  8:52 ` Gert-Jan Vons
1999-12-09 14:20   ` Decklin Foster
1999-12-09 16:48   ` Paul Haahr
1999-12-09 16:27 ` Mark K. Gardner [this message]
1999-12-09 22:08 ` kim kubik
1999-12-10  7:45 Byron Rakitzis
1999-12-10  9:32 ` Gert-Jan Vons

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199912091627.JAA30396@boing.lanl.gov \
    --to=mkg@boing.lanl.gov \
    --cc=rc@hawkwind.utcs.toronto.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).