There is no repository for useful rc code snippets as yet, so I'm including a (short) file in the distribution with some helpful/intriguing pieces of rc code. A sample .rcrc -------------- Here is the .rcrc I use on archone: umask 022 path=(/bin /usr/bin /usr/ucb) ht=`/usr/arch/bin/hosttype h=$home history=$h/.history bin=$h/bin/$ht lib=$h/lib/$ht sh=$h/bin/sh include=$h/lib/include switch ($ht) { case sun* OBERON='. '$h/other/oberon p=/usr/ucb compiler='gcc -Wall -O -g' MANPATH=$h/man:/usr/arch/man:/usr/man if (! ~ $TERM ()) { stty dec /usr/arch/bin/msgs -q } case next p=(/usr/ucb /usr/bin /NextApps) compiler='cc -Wall -O -g -DNODIRENT' MANPATH=$h/man:/usr/arch/man:/usr/man if (! ~ $TERM ()) stty dec case sgi p=(/usr/ucb /usr/sbin /usr/bin) compiler='gcc -Wall -O -g -DNOSIGCLD' MANPATH=$h/man:/usr/arch/man:/usr/catman if (!{~ $TERM () || ~ $TERM *iris*}) stty line 1 intr '' erase '' kill '' case * echo .rcrc not configured for this machine } path=(. $sh $bin /usr/arch/bin $p /bin /usr/bin/X11 /etc /usr/etc) cdpath=(. .. $h $h/src $h/misc $h/other $h/adm) RNINIT=-d$h' -t -M -2400-h -2400+hfrom'; DOTDIR=$h/misc/news PRINTER=lw fn s { echo $status } fn cd { builtin cd $1 && \ switch ($1) { case () dir=$home case * dir=() } } fn pwd { if (~ $dir ()) dir=`/bin/pwd echo $dir } fn x { if (~ `tty /dev/console) clear_colormap clear exit } fn p { if (~ $history ()) { echo '$history not set' >[1=2] return 1 } if (! ~ $#* 0 1 2) { echo usage: $0 '[egrep pattern] [sed command]' >[1=2] return 1 } command=`{ egrep -v '^[ ]*p([ ]+|$)' $history | switch ($#*) { case 0 cat case 1 egrep $1 case 2 egrep $1 | sed $2 } | tail -1 } echo $command eval $command } if (~ $TERM dialup network) { TERM=vt100 biff y } A front-end to NeXT's "openfile" -------------------------------- Named after the sam "B" command for opening a file, this script was written by Paul Haahr. (Assumes the "pick" command from Kernighan and Pike is also in your path.) #!/bin/rc if (~ $#* 0) exec openfile create = () files = () for (i in $*) if (test -f $i) { files = ($files $i) } else { create = ($create $i) } create = `{ pick $create } files = ($files $create) for (i in $create) > $i if (! ~ $#files 0) openfile $files A read function --------------- Unlike sh, rc doesn't have a read. This clever alternative returns an exit status as well as fetch a variable. Use as read foo to set $foo to a single line from the terminal. (due to John Mackin ) fn read { x=() { x = `` ($nl) { awk '{print; print 0; exit}' ^ $nl ^ \ 'END {print 1; print 1}' } $1 = $x(1) return $x(2) } } From cs.wisc.edu!dws Fri Aug 2 18:16:14 1991 #------- # ls front end #------- fn ls \ { test -t 1 && * = (-FCb $*) builtin ls $* } #------- # nl - holds a newline, useful in certain command substitutions #------- nl=' ' #------- # show - tell me about a name # # Runs possibly dangerous things through cat -v in order to protect # me from the effects of control characters I might have in the # environment. #------- fn show \ { * = `` $nl {whatis -- $*} for(itis) { switch($^itis) { case 'fn '* ; echo $itis | cat -v -t case builtin* ; echo $itis case /* ; file $itis; ls -ld $itis case *'='* ; echo $itis | cat -v -t case * ; echo $itis: UNKNOWN: update show } } itis = () } #------- # Tell me automatically when a command has a nonzero status. #------- fn prompt \ { Status = $status ~ $Status 0 || echo '[status '$Status']' } #------- # chop - echo the given list, less its final member # # e.g. chop (a b c) -> (a b) #------- fn chop { ~ $#* 0 1 && return 0 ans = '' { # local variable ans = () while(! ~ $#* 1) { ans = ($ans $1) shift } echo $ans } } From arnold@audiofax.com Thu May 30 08:49:51 1991 # cd.rc --- souped up version of cd # this is designed to emulate the fancy version of cd in ksh, # so if you're a purist, feel free to gag _cwd=$home _oldcwd=$home fn cd { if (~ $#* 0) { if (~ $_cwd $home) { # do nothing } else { builtin cd && { _oldcwd=$_cwd ; _cwd=$home } } } else if (~ $#* 1) { if (~ $1 -) { _t=$_cwd builtin cd $_oldcwd && { _cwd=$_oldcwd _oldcwd=$_t echo $_cwd } _t=() } else { # if a cd happens through the cdpath, rc echos # the directory on its own. all we have to do # is track where we end up _dopwd = 1 { ~ $1 /* } && _dopwd = 0 # absolute path builtin cd $1 && { _oldcwd=$_cwd _cwd=$1 { ~ $_dopwd 1 } && _cwd=`/bin/pwd } _dopwd=() } } else if (~ $#* 2) { _t=`{ echo $_cwd | sed 's<'$1'<'$2'<' } builtin cd $_t && { _oldcwd=$_cwd _cwd=$_t echo $_cwd } _t=() } else { echo cd: takes 0, 1, or 2 arguments >[1=2] builtin cd $1 && { _oldcwd=$_cwd ; _cwd=`/bin/pwd ; echo $_cwd } } } fn pwd { echo $_cwd } From vlsi.cs.caltech.edu!drazen Tue Jan 21 16:03:14 1992 # A kill builtin. #ifdef B_KILL #include static void b_kill(char **av) { int signal = SIGTERM; int n = 1; pid_t pid; boolean res; if (!av[1]) { set(TRUE); return; } #undef STRCMP #define STRCMP strcmp if ( '-' == av[1][0]) { char *p = 1+av[1]; if (0 == strcmp(av[1], "-l")){ int r; const int nsig = NUMOFSIGNALS; const int C = 4, R = 1 + (int)((nsig-2)/C); for (r=1; r<=R; r++){ int j; for (j=r; j; Thu, 2 Apr 1992 02:50:56 -0600 Received: by thor.acc.stolaf.edu; Thu, 2 Apr 92 02:49:31 -0600 Date: Thu, 2 Apr 1992 02:49:31 -0600 From: quanstro@acc.stolaf.edu Message-Id: <9204020849.AA26566@thor.acc.stolaf.edu> To: byron@archone.tamu.edu Subject: EXAMPLES in 1.4beta Status: RO I have a little bit of code which might be a little more general than the souped-up version that is already there. Here it is, if you are interested. # directory functions ################################################### fn pwd { echo $PWD; } fn pushd { dirs = ($PWD $dirs); builtin cd $*; PWD = `{builtin pwd}; } fn popd { switch ($#*) { case 0 ; case 1 echo 'popd: argument '^$1^' ignored.' >[1=2]; case * echo 'popd: usage: popd [n].'; } if (! ~ $dirs ()) { builtin cd $dirs(1); PWD = $dirs(1); echo $PWD; * = $dirs; shift dirs = $*; } } fn cd { ~ $* () && * = $home; !~ $#* 1 && echo 'cd: too many arguments' >[1=2] && return 1; if (test -r $* ) { pushd $*; } else { echo cd: $* does not exist. >[1=2] return 1; } } fn back { popd $*; } fn Back { cd $home; PWD = $home; dirs = (); } fn dirs { echo $dirs; } PWD = `{builtin pwd} ; dirs = $PWD # kickstart From acc.stolaf.edu!quanstro Thu Apr 2 02:53:40 1992 Received: from thor.acc.stolaf.edu ([130.71.192.1]) by archone.tamu.edu with SMTP id <45339>; Thu, 2 Apr 1992 02:53:38 -0600 Received: by thor.acc.stolaf.edu; Thu, 2 Apr 92 02:51:46 -0600 Date: Thu, 2 Apr 1992 02:51:46 -0600 From: quanstro@acc.stolaf.edu Message-Id: <9204020851.AA26573@thor.acc.stolaf.edu> To: byron@archone.tamu.edu Subject: EXAMPLES Status: RO Little yp hack which act's like ~ w/o syntatic sugar (for those who do not have the luxury of seting up symbolic links to all user's homes # user function ######################################################### fn u user { info = () info = `` (':') {ypmatch $1 passwd >[2] /dev/null } if (~ $info ()) { echo user $1 unknown >[1=2]; return 1; } else { echo $info(6) if (~ $0 user) cd $info(6) } } From stolaf.edu!quanstro Sun Apr 5 04:53:34 1992 Date: Sun, 5 Apr 1992 04:53:08 -0500 From: quanstro@stolaf.edu (Erik Quanstrom) To: byron@archone.tamu.edu Subject: man written in rc Status: RO I whipped this up because the NeXTs here insist on using MANPAGER instead of PAGER and otherwise being obnoxious . . . Anyway ... I hope you approve #!/bin/rc ######################################################################### # file: man # # # # object: display man pages # # # # bugs: * slow # # * does not know about fmt files # # # # Erik Quanstrom # # 11. Februar 1992 # ######################################################################### PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:$PATH ; TROFF = (nroff -hq -Tcrt); macros=an; sections=(cat1 cat2 cat3 cat4 cat5 cat6 cat7 cat8 catl man1 man2 man3 man4 \ man5 man6 man7 man8 manl) $nl=' ' fn sigint sighup sigquit sigalrm sigterm { rm -f $Bat; exit 2;} fn usage { echo usage: $0 [-] [-t] [-M path] [-T macros] [[section] title] ...>[1=2]; exit 1; } n=(); fn shiftn { n=($n 1) } ~ $PAGER () && test -t 1 && PAGER=more; #default pager while (~ $1 -*) { switch ($1) { case - if (~ $PAGER troff) echo bad combination of flags >[1=2] && usage; PAGER=cat; case -t ~ TROFF () && TROFF = (troff -t); ~ TCAT () && PAGER=(lpr -t); case -M shift; ~ $1 () && usage; MANPATH=$1; case -T shift; ~ $1 () && usage; macros=$1; case -k fflag=(); kflag=1; shift; break; case -f # locate related too filenames kflag=(); fflag=1; shift; break; case -* echo bad flag '`'^$1^'''' >[1=2]; usage; } shift; } if (!~ $#* 1) { ~ $1 [l1-8] && { sname=$1 ; sections=(cat man)^$1 ; shift } #hack for sun-style man pages ~ $1 [l1-8]? && { sname=$1 ; sections=(cat man)^`{echo $1| cut -c1} ; shift } } if (~ 1 $fflag $kflag) { dirlist=(); for (d in ``(:$nl) {echo $MANPATH}) test -s $d^/whatis && dirlist=($dirlist $d^/whatis); ~ $1 () && usage; if (~ $fflag 1) { while (!~ $1 ()) { cmd=`{echo $1 | sed 's/^.*\///g'} egrep -h '^'^$cmd' ' $dirlist; shift; } } else { while (!~ $1 ()) { grep -h $1 $dirlist; shift; } } exit 0; } s=0; while (!~ $1 ()) { for (dir in ``(:$nl) {echo $MANPATH}) { filelist=($filelist `{echo $dir/^$sections^/$1^.* |\ tr ' ' '\12' | grep -v '*'}) # coment this out if you don't care about speed, but # would rather find all the pages. ~ $filelist () || break; } if (~ $filelist ()) { if (~ $#sections 2) { echo no entry for $1 in section '`'$sname'''' of the manual >[1=2]; } else { echo no entry for '`'$1'''' found. >[1=2]; } s=1; } else { echo $filelist '(' $#filelist ')' >[1=2]; for (file in $filelist) { if (~ $file */cat[1-8l]/*) { Cat = ($Cat $file); } else { # search for dups dont=() for (x in $Cat) { if (~ `{echo $x | sed 's/\/[mc]a[nt][1-8l]//'} \ `{echo $file | sed 's/\/[mc]a[nt][1-8l]//'}) { dont=1; break; } } if (~ $dont ()) { cd `{echo $file | sed 's/man[1-8].*//'} echo -n Formatting ... $TROFF -m^$macros $file > /tmp/man^$pid^$#n && \ Bat = ($Bat /tmp/man^$pid^$#n) shiftn; echo ' 'done. } } } } shift; } { !~ () $Cat || !~ () $Bat } && $PAGER $Cat $Bat; rm -f $Bat; ~ $s () || exit $s; exit 0; From osf.org!rsalz Thu Apr 23 16:22:32 1992 Date: Thu, 23 Apr 1992 16:22:07 -0500 From: rsalz@osf.org To: byron@archone.tamu.edu Subject: One for your EXAMPLES file Status: RO Use trimhist [-#lines] trims your history file back; useful for folks with dis quota's :-) fn trimhist { p1=-100 { cp $history $history^'~' ~ $#* 1 && p1=$1 tail $p1 <$history^'~' >$history rm $history^'~' } } From Pa.dec.com!uucp Mon Apr 27 12:25:02 1992 Date: Mon, 27 Apr 1992 12:15:18 -0500 From: haahr@adobe.com To: Byron Rakitzis Subject: a neat little rc script what you have to know to understand this: $md for me is usually obj.$machine my mkfiles build *.o, *.a, and the a.outs in $md this is my acc script, which i use for compiling adobe routines --- #! /user/haahr/bin/next/rc cc = cc proto = '-DPROTOTYPES=1' switch ($md) { case noproto.$machine; proto = '-DPROTOTYPES=0' case gprof.$machine; cc = ($cc -pg) case prof.$machine; cc = ($cc -p) case lcomp.$machine; cc = lcomp } exec $cc $proto '-DPACKAGE_SPECS="package.h"' '-DISP=isp_mc68020' '-DOS=os_mach' $* From rc-owner Tue May 12 14:54:10 1992 Received: from postman.osf.org ([130.105.1.152]) by archone.tamu.edu with SMTP id <45337>; Tue, 12 May 1992 14:38:16 -0500 Received: from earth.osf.org by postman.osf.org (5.64+/OSF 1.0) id AA14480; Tue, 12 May 92 13:25:03 -0400 Received: by earth.osf.org (5.64/4.7) id AA03499; Tue, 12 May 92 13:25:02 -0400 Date: Tue, 12 May 1992 12:25:02 -0500 From: rsalz@osf.org Message-Id: <9205121725.AA03499@earth.osf.org> To: rc@archone.tamu.edu Subject: Useful function Status: R It looks like line noise, but it turns things like /home/rsalz/foo/bar into ~/foo/bar Useful for when you put your current directory up in your icon title. By duplicating the $home section you can make things like /project/dce/build/dce1.0.1/src/rpc become $MYBT/src/rpc ## If a pathname starts with $home, turn $home into ~. Uses all built-ins. fn tildepath { p1=() i=() { p1=$1 switch ($p1) { case $home $home/* # Split arg into components *=`` (/) { echo -n $p1 } # Shift down by number of components in $home for (i in `` (/) { echo -n $home } ) shift # Glue back together p1='~' for (i) p1=$p1 ^ '/' ^ $i echo $p1 case * echo $p1 } return 0 } } From osf.org!rsalz Tue May 12 15:47:12 1992 Received: from postman.osf.org ([130.105.1.152]) by archone.tamu.edu with SMTP id <45316>; Tue, 12 May 1992 15:47:06 -0500 Received: from earth.osf.org by postman.osf.org (5.64+/OSF 1.0) id AA21070; Tue, 12 May 92 16:46:58 -0400 Received: by earth.osf.org (5.64/4.7) id AA09396; Tue, 12 May 92 16:46:56 -0400 Date: Tue, 12 May 1992 15:46:56 -0500 From: rsalz@osf.org Message-Id: <9205122046.AA09396@earth.osf.org> To: byron@archone.tamu.edu Subject: Re: Useful function Status: R >wow. thanks, i'll add it to EXAMPLES. Glad you like. Getting something added to EXAMPLES has been a goal of mine... I've been thinking, a bit, about a more general way of doing it. I want a "prefix-sub" function, like this prefix $some_path var1 var2 var3 var4 var5 That would take some_path and replace any leading $var1 (etc) values with the variable name. Return on the first match. Hmm -- come to think of it, that's very easy to do: # Use pathprefix filename var1 var2 var3 # returns filename, with leading prefixes (in $var1...) turned into the # string $var1... fn pathprefix { p1=() i=() j=() { p1=$1 ; shift for (i) { ~ $p1 $$i $$i^/* && { *=`` (/) { echo -n $p1 } for (j in `` (/) { echo -n $$i } ) shift p1='$'^$i for (j) p1=$p1 ^ '/' ^ $j echo $p1 return 0 } } echo $p1 return 0 } } home=/user/users/rsalz z=/usr/users pathprefix /usr/users/rsalz home usr # --> $home pathprefix /usr/users/rsalz z # --> $z/rsalz pathprefix /usr/users/rsalz/foo z home # --> $z/rsalz/foo pathprefix /usr/users/rsalz/foo home # --> $home/foo